mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 19:56:44 +02:00
Merge branch 'master' into fix_google_vr_height
This commit is contained in:
commit
77ce5234cf
34 changed files with 595 additions and 52 deletions
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <ClientServerUtils.h>
|
#include <ClientServerUtils.h>
|
||||||
#include <FBXBaker.h>
|
#include <FBXBaker.h>
|
||||||
|
#include <JSBaker.h>
|
||||||
#include <NodeType.h>
|
#include <NodeType.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
@ -49,10 +50,12 @@ static const int INTERFACE_RUNNING_CHECK_FREQUENCY_MS = 1000;
|
||||||
|
|
||||||
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
||||||
|
|
||||||
static const QStringList BAKEABLE_MODEL_EXTENSIONS = { "fbx" };
|
static const QStringList BAKEABLE_MODEL_EXTENSIONS = {"fbx"};
|
||||||
static QStringList BAKEABLE_TEXTURE_EXTENSIONS;
|
static QStringList BAKEABLE_TEXTURE_EXTENSIONS;
|
||||||
|
static const QStringList BAKEABLE_SCRIPT_EXTENSIONS = {"js"};
|
||||||
static const QString BAKED_MODEL_SIMPLE_NAME = "asset.fbx";
|
static const QString BAKED_MODEL_SIMPLE_NAME = "asset.fbx";
|
||||||
static const QString BAKED_TEXTURE_SIMPLE_NAME = "texture.ktx";
|
static const QString BAKED_TEXTURE_SIMPLE_NAME = "texture.ktx";
|
||||||
|
static const QString BAKED_SCRIPT_SIMPLE_NAME = "asset.js";
|
||||||
|
|
||||||
void AssetServer::bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) {
|
void AssetServer::bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) {
|
||||||
qDebug() << "Starting bake for: " << assetPath << assetHash;
|
qDebug() << "Starting bake for: " << assetPath << assetHash;
|
||||||
|
@ -99,6 +102,8 @@ std::pair<BakingStatus, QString> AssetServer::getAssetStatus(const AssetPath& pa
|
||||||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
||||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||||
|
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
} else {
|
} else {
|
||||||
return { Irrelevant, "" };
|
return { Irrelevant, "" };
|
||||||
}
|
}
|
||||||
|
@ -186,6 +191,8 @@ bool AssetServer::needsToBeBaked(const AssetPath& path, const AssetHash& assetHa
|
||||||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (loaded && BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit())) {
|
} else if (loaded && BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit())) {
|
||||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||||
|
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -488,6 +495,8 @@ void AssetServer::handleGetMappingOperation(ReceivedMessage& message, SharedNode
|
||||||
bakedRootFile = BAKED_MODEL_SIMPLE_NAME;
|
bakedRootFile = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(assetPathExtension.toLocal8Bit())) {
|
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(assetPathExtension.toLocal8Bit())) {
|
||||||
bakedRootFile = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedRootFile = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(assetPathExtension)) {
|
||||||
|
bakedRootFile = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto originalAssetHash = it->second;
|
auto originalAssetHash = it->second;
|
||||||
|
@ -1141,6 +1150,7 @@ bool AssetServer::renameMapping(AssetPath oldPath, AssetPath newPath) {
|
||||||
|
|
||||||
static const QString BAKED_ASSET_SIMPLE_FBX_NAME = "asset.fbx";
|
static const QString BAKED_ASSET_SIMPLE_FBX_NAME = "asset.fbx";
|
||||||
static const QString BAKED_ASSET_SIMPLE_TEXTURE_NAME = "texture.ktx";
|
static const QString BAKED_ASSET_SIMPLE_TEXTURE_NAME = "texture.ktx";
|
||||||
|
static const QString BAKED_ASSET_SIMPLE_JS_NAME = "asset.js";
|
||||||
|
|
||||||
QString getBakeMapping(const AssetHash& hash, const QString& relativeFilePath) {
|
QString getBakeMapping(const AssetHash& hash, const QString& relativeFilePath) {
|
||||||
return HIDDEN_BAKED_CONTENT_FOLDER + hash + "/" + relativeFilePath;
|
return HIDDEN_BAKED_CONTENT_FOLDER + hash + "/" + relativeFilePath;
|
||||||
|
@ -1204,14 +1214,14 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
|
||||||
// setup the mapping for this bake file
|
// setup the mapping for this bake file
|
||||||
auto relativeFilePath = QUrl(filePath).fileName();
|
auto relativeFilePath = QUrl(filePath).fileName();
|
||||||
qDebug() << "Relative file path is: " << relativeFilePath;
|
qDebug() << "Relative file path is: " << relativeFilePath;
|
||||||
|
|
||||||
if (relativeFilePath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
if (relativeFilePath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
||||||
// for an FBX file, we replace the filename with the simple name
|
// for an FBX file, we replace the filename with the simple name
|
||||||
// (to handle the case where two mapped assets have the same hash but different names)
|
// (to handle the case where two mapped assets have the same hash but different names)
|
||||||
relativeFilePath = BAKED_ASSET_SIMPLE_FBX_NAME;
|
relativeFilePath = BAKED_ASSET_SIMPLE_FBX_NAME;
|
||||||
|
} else if (relativeFilePath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||||
|
relativeFilePath = BAKED_ASSET_SIMPLE_JS_NAME;
|
||||||
} else if (!originalAssetPath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
} else if (!originalAssetPath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
||||||
relativeFilePath = BAKED_ASSET_SIMPLE_TEXTURE_NAME;
|
relativeFilePath = BAKED_ASSET_SIMPLE_TEXTURE_NAME;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString bakeMapping = getBakeMapping(originalAssetHash, relativeFilePath);
|
QString bakeMapping = getBakeMapping(originalAssetHash, relativeFilePath);
|
||||||
|
@ -1364,6 +1374,8 @@ bool AssetServer::setBakingEnabled(const AssetPathList& paths, bool enabled) {
|
||||||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
||||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||||
|
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <FBXBaker.h>
|
#include <FBXBaker.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
#include <JSBaker.h>
|
||||||
|
|
||||||
BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) :
|
BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) :
|
||||||
_assetHash(assetHash),
|
_assetHash(assetHash),
|
||||||
|
@ -52,6 +53,10 @@ void BakeAssetTask::run() {
|
||||||
_baker = std::unique_ptr<FBXBaker> {
|
_baker = std::unique_ptr<FBXBaker> {
|
||||||
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
||||||
};
|
};
|
||||||
|
} else if (_assetPath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||||
|
_baker = std::unique_ptr<JSBaker>{
|
||||||
|
new JSBaker(QUrl("file:///" + _filePath), PathUtils::generateTemporaryDir())
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
tempOutputDir = PathUtils::generateTemporaryDir();
|
tempOutputDir = PathUtils::generateTemporaryDir();
|
||||||
_baker = std::unique_ptr<TextureBaker> {
|
_baker = std::unique_ptr<TextureBaker> {
|
||||||
|
|
|
@ -124,7 +124,7 @@ Rectangle {
|
||||||
selectByMouse: false
|
selectByMouse: false
|
||||||
|
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
if (event.key == Qt.Key_Return) {
|
if (event.key == Qt.Key_Return || event.key == Qt.Key_Space) {
|
||||||
mirrorText.text = "";
|
mirrorText.text = "";
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,20 @@ TextField {
|
||||||
|
|
||||||
y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0
|
y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0
|
||||||
|
|
||||||
|
// workaround for https://bugreports.qt.io/browse/QTBUG-49297
|
||||||
|
Keys.onPressed: {
|
||||||
|
switch (event.key) {
|
||||||
|
case Qt.Key_Return:
|
||||||
|
case Qt.Key_Enter:
|
||||||
|
event.accepted = true;
|
||||||
|
|
||||||
|
// emit accepted signal manually
|
||||||
|
if (acceptableInput) {
|
||||||
|
accepted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
style: TextFieldStyle {
|
style: TextFieldStyle {
|
||||||
textColor: {
|
textColor: {
|
||||||
if (isLightColorScheme) {
|
if (isLightColorScheme) {
|
||||||
|
|
|
@ -3963,9 +3963,14 @@ void Application::calibrateEyeTracker5Points() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool Application::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs, const glm::vec3* givenOffset) {
|
bool Application::exportEntities(const QString& filename,
|
||||||
|
const QVector<EntityItemID>& entityIDs,
|
||||||
|
const glm::vec3* givenOffset) {
|
||||||
QHash<EntityItemID, EntityItemPointer> entities;
|
QHash<EntityItemID, EntityItemPointer> entities;
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
const QUuid myAvatarID = nodeList->getSessionUUID();
|
||||||
|
|
||||||
auto entityTree = getEntities()->getTree();
|
auto entityTree = getEntities()->getTree();
|
||||||
auto exportTree = std::make_shared<EntityTree>();
|
auto exportTree = std::make_shared<EntityTree>();
|
||||||
exportTree->createRootElement();
|
exportTree->createRootElement();
|
||||||
|
@ -3981,8 +3986,12 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
||||||
|
|
||||||
if (!givenOffset) {
|
if (!givenOffset) {
|
||||||
EntityItemID parentID = entityItem->getParentID();
|
EntityItemID parentID = entityItem->getParentID();
|
||||||
if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) {
|
bool parentIsAvatar = (parentID == AVATAR_SELF_ID || parentID == myAvatarID);
|
||||||
auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties.
|
if (!parentIsAvatar && (parentID.isInvalidID() ||
|
||||||
|
!entityIDs.contains(parentID) ||
|
||||||
|
!entityTree->findEntityByEntityItemID(parentID))) {
|
||||||
|
// If parent wasn't selected, we want absolute position, which isn't in properties.
|
||||||
|
auto position = entityItem->getPosition();
|
||||||
root.x = glm::min(root.x, position.x);
|
root.x = glm::min(root.x, position.x);
|
||||||
root.y = glm::min(root.y, position.y);
|
root.y = glm::min(root.y, position.y);
|
||||||
root.z = glm::min(root.z, position.z);
|
root.z = glm::min(root.z, position.z);
|
||||||
|
@ -4002,12 +4011,16 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
||||||
for (EntityItemPointer& entityDatum : entities) {
|
for (EntityItemPointer& entityDatum : entities) {
|
||||||
auto properties = entityDatum->getProperties();
|
auto properties = entityDatum->getProperties();
|
||||||
EntityItemID parentID = properties.getParentID();
|
EntityItemID parentID = properties.getParentID();
|
||||||
if (parentID.isInvalidID()) {
|
bool parentIsAvatar = (parentID == AVATAR_SELF_ID || parentID == myAvatarID);
|
||||||
properties.setPosition(properties.getPosition() - root);
|
if (parentIsAvatar) {
|
||||||
|
properties.setParentID(AVATAR_SELF_ID);
|
||||||
|
} else {
|
||||||
|
if (parentID.isInvalidID()) {
|
||||||
|
properties.setPosition(properties.getPosition() - root);
|
||||||
|
} else if (!entities.contains(parentID)) {
|
||||||
|
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
|
||||||
|
} // else valid parent -- don't offset
|
||||||
}
|
}
|
||||||
else if (!entities.contains(parentID)) {
|
|
||||||
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
|
|
||||||
} // else valid parent -- don't offset
|
|
||||||
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
|
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -53,7 +53,7 @@ const QUuid MY_AVATAR_KEY; // NULL key
|
||||||
|
|
||||||
AvatarManager::AvatarManager(QObject* parent) :
|
AvatarManager::AvatarManager(QObject* parent) :
|
||||||
_avatarsToFade(),
|
_avatarsToFade(),
|
||||||
_myAvatar(std::make_shared<MyAvatar>(qApp->thread()))
|
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
|
||||||
{
|
{
|
||||||
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
||||||
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
||||||
|
@ -297,7 +297,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
||||||
return std::make_shared<OtherAvatar>(qApp->thread());
|
return AvatarSharedPointer(new OtherAvatar(qApp->thread()), [](OtherAvatar* ptr) { ptr->deleteLater(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
|
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
|
||||||
|
|
|
@ -3238,3 +3238,9 @@ void MyAvatar::setModelScale(float scale) {
|
||||||
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpatialParentTree* MyAvatar::getParentTree() const {
|
||||||
|
auto entityTreeRenderer = qApp->getEntities();
|
||||||
|
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
||||||
|
return entityTree.get();
|
||||||
|
}
|
||||||
|
|
|
@ -544,6 +544,8 @@ public:
|
||||||
float getUserHeight() const;
|
float getUserHeight() const;
|
||||||
float getUserEyeHeight() const;
|
float getUserEyeHeight() const;
|
||||||
|
|
||||||
|
virtual SpatialParentTree* getParentTree() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void increaseSize();
|
void increaseSize();
|
||||||
void decreaseSize();
|
void decreaseSize();
|
||||||
|
|
|
@ -305,3 +305,9 @@ Transform Base3DOverlay::evalRenderTransform() {
|
||||||
void Base3DOverlay::setRenderTransform(const Transform& transform) {
|
void Base3DOverlay::setRenderTransform(const Transform& transform) {
|
||||||
_renderTransform = transform;
|
_renderTransform = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpatialParentTree* Base3DOverlay::getParentTree() const {
|
||||||
|
auto entityTreeRenderer = qApp->getEntities();
|
||||||
|
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
||||||
|
return entityTree.get();
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
virtual AABox getBounds() const override = 0;
|
virtual AABox getBounds() const override = 0;
|
||||||
|
|
||||||
void update(float deltatime) override;
|
void update(float deltatime) override;
|
||||||
|
|
||||||
void notifyRenderTransformChange() const;
|
void notifyRenderTransformChange() const;
|
||||||
|
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
|
@ -69,6 +69,8 @@ public:
|
||||||
return findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
return findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual SpatialParentTree* getParentTree() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void locationChanged(bool tellPhysics = true) override;
|
virtual void locationChanged(bool tellPhysics = true) override;
|
||||||
virtual void parentDeleted() override;
|
virtual void parentDeleted() override;
|
||||||
|
|
|
@ -161,33 +161,33 @@ OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties)
|
||||||
Overlay::Pointer thisOverlay = nullptr;
|
Overlay::Pointer thisOverlay = nullptr;
|
||||||
|
|
||||||
if (type == ImageOverlay::TYPE) {
|
if (type == ImageOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<ImageOverlay>();
|
thisOverlay = Overlay::Pointer(new ImageOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Image3DOverlay::TYPE || type == "billboard") { // "billboard" for backwards compatibility
|
} else if (type == Image3DOverlay::TYPE || type == "billboard") { // "billboard" for backwards compatibility
|
||||||
thisOverlay = std::make_shared<Image3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Image3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == TextOverlay::TYPE) {
|
} else if (type == TextOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<TextOverlay>();
|
thisOverlay = Overlay::Pointer(new TextOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Text3DOverlay::TYPE) {
|
} else if (type == Text3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Text3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Text3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Shape3DOverlay::TYPE) {
|
} else if (type == Shape3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Shape3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Shape3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Cube3DOverlay::TYPE) {
|
} else if (type == Cube3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Cube3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Cube3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Sphere3DOverlay::TYPE) {
|
} else if (type == Sphere3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Sphere3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Sphere3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Circle3DOverlay::TYPE) {
|
} else if (type == Circle3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Circle3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Circle3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Rectangle3DOverlay::TYPE) {
|
} else if (type == Rectangle3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Rectangle3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Rectangle3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Line3DOverlay::TYPE) {
|
} else if (type == Line3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Line3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Line3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Grid3DOverlay::TYPE) {
|
} else if (type == Grid3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Grid3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Grid3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == ModelOverlay::TYPE) {
|
} else if (type == ModelOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<ModelOverlay>();
|
thisOverlay = Overlay::Pointer(new ModelOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Web3DOverlay::TYPE) {
|
} else if (type == Web3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Web3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Web3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == RectangleOverlay::TYPE) {
|
} else if (type == RectangleOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<RectangleOverlay>();
|
thisOverlay = Overlay::Pointer(new RectangleOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thisOverlay) {
|
if (thisOverlay) {
|
||||||
|
@ -230,7 +230,7 @@ OverlayID Overlays::cloneOverlay(OverlayID id) {
|
||||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||||
|
|
||||||
if (thisOverlay) {
|
if (thisOverlay) {
|
||||||
OverlayID cloneId = addOverlay(Overlay::Pointer(thisOverlay->createClone()));
|
OverlayID cloneId = addOverlay(Overlay::Pointer(thisOverlay->createClone(), [](Overlay* ptr) { ptr->deleteLater(); }));
|
||||||
#if OVERLAY_PANELS
|
#if OVERLAY_PANELS
|
||||||
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(thisOverlay);
|
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(thisOverlay);
|
||||||
if (attachable && attachable->getParentPanel()) {
|
if (attachable && attachable->getParentPanel()) {
|
||||||
|
|
247
libraries/baking/src/JSBaker.cpp
Normal file
247
libraries/baking/src/JSBaker.cpp
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
//
|
||||||
|
// JSBaker.cpp
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <PathUtils.h>
|
||||||
|
|
||||||
|
#include "JSBaker.h"
|
||||||
|
#include "Baker.h"
|
||||||
|
|
||||||
|
const int ASCII_CHARACTERS_UPPER_LIMIT = 126;
|
||||||
|
|
||||||
|
JSBaker::JSBaker(const QUrl& jsURL, const QString& bakedOutputDir) :
|
||||||
|
_jsURL(jsURL),
|
||||||
|
_bakedOutputDir(bakedOutputDir)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSBaker::bake() {
|
||||||
|
qCDebug(js_baking) << "JS Baker " << _jsURL << "bake starting";
|
||||||
|
|
||||||
|
// Import file to start baking
|
||||||
|
QFile jsFile(_jsURL.toLocalFile());
|
||||||
|
if (!jsFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
handleError("Error opening " + _jsURL.fileName() + " for reading");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read file into an array
|
||||||
|
QByteArray inputJS = jsFile.readAll();
|
||||||
|
QByteArray outputJS;
|
||||||
|
|
||||||
|
// Call baking on inputJS and store result in outputJS
|
||||||
|
bool success = bakeJS(inputJS, outputJS);
|
||||||
|
if (!success) {
|
||||||
|
qCDebug(js_baking) << "Bake Failed";
|
||||||
|
handleError("Unterminated multi-line comment");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bake Successful. Export the file
|
||||||
|
auto fileName = _jsURL.fileName();
|
||||||
|
auto baseName = fileName.left(fileName.lastIndexOf('.'));
|
||||||
|
auto bakedFilename = baseName + BAKED_JS_EXTENSION;
|
||||||
|
|
||||||
|
_bakedJSFilePath = _bakedOutputDir + "/" + bakedFilename;
|
||||||
|
|
||||||
|
QFile bakedFile;
|
||||||
|
bakedFile.setFileName(_bakedJSFilePath);
|
||||||
|
if (!bakedFile.open(QIODevice::WriteOnly)) {
|
||||||
|
handleError("Error opening " + _bakedJSFilePath + " for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bakedFile.write(outputJS);
|
||||||
|
|
||||||
|
// Export successful
|
||||||
|
_outputFiles.push_back(_bakedJSFilePath);
|
||||||
|
qCDebug(js_baking) << "Exported" << _jsURL << "minified to" << _bakedJSFilePath;
|
||||||
|
|
||||||
|
// emit signal to indicate the JS baking is finished
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::bakeJS(const QByteArray& inputFile, QByteArray& outputFile) {
|
||||||
|
// Read from inputFile and write to outputFile per character
|
||||||
|
QTextStream in(inputFile, QIODevice::ReadOnly);
|
||||||
|
QTextStream out(outputFile, QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
// Algorithm requires the knowledge of previous and next character for each character read
|
||||||
|
QChar currentCharacter;
|
||||||
|
QChar nextCharacter;
|
||||||
|
// Initialize previousCharacter with new line
|
||||||
|
QChar previousCharacter = '\n';
|
||||||
|
|
||||||
|
in >> currentCharacter;
|
||||||
|
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
|
||||||
|
if (currentCharacter == '\r') {
|
||||||
|
out << '\n';
|
||||||
|
} else if (currentCharacter == '/') {
|
||||||
|
// Check if single line comment i.e. //
|
||||||
|
if (nextCharacter == '/') {
|
||||||
|
handleSingleLineComments(in);
|
||||||
|
|
||||||
|
//Start fresh after handling comments
|
||||||
|
previousCharacter = '\n';
|
||||||
|
in >> currentCharacter;
|
||||||
|
continue;
|
||||||
|
} else if (nextCharacter == '*') {
|
||||||
|
// Check if multi line comment i.e. /*
|
||||||
|
bool success = handleMultiLineComments(in);
|
||||||
|
if (!success) {
|
||||||
|
// Errors present return false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//Start fresh after handling comments
|
||||||
|
previousCharacter = '\n';
|
||||||
|
in >> currentCharacter;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// If '/' is not followed by '/' or '*' print '/'
|
||||||
|
out << currentCharacter;
|
||||||
|
}
|
||||||
|
} else if (isSpaceOrTab(currentCharacter)) {
|
||||||
|
// Check if white space or tab
|
||||||
|
|
||||||
|
// Skip multiple spaces or tabs
|
||||||
|
while (isSpaceOrTab(nextCharacter)) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
if (nextCharacter == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if space can be omitted
|
||||||
|
if (!canOmitSpace(previousCharacter, nextCharacter)) {
|
||||||
|
out << ' ';
|
||||||
|
}
|
||||||
|
} else if (currentCharacter == '\n') {
|
||||||
|
// Check if new line
|
||||||
|
|
||||||
|
//Skip multiple new lines
|
||||||
|
//Skip new line followed by space or tab
|
||||||
|
while (nextCharacter == '\n' || isSpaceOrTab(nextCharacter)) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if new line can be omitted
|
||||||
|
if (!canOmitNewLine(previousCharacter, nextCharacter)) {
|
||||||
|
out << '\n';
|
||||||
|
}
|
||||||
|
} else if (isQuote(currentCharacter)) {
|
||||||
|
// Print the current quote and nextCharacter as is
|
||||||
|
out << currentCharacter;
|
||||||
|
out << nextCharacter;
|
||||||
|
|
||||||
|
// Store the type of quote we are processing
|
||||||
|
QChar quote = currentCharacter;
|
||||||
|
|
||||||
|
// Don't modify the quoted strings
|
||||||
|
while (nextCharacter != quote) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
out << nextCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start fresh after handling quoted strings
|
||||||
|
previousCharacter = nextCharacter;
|
||||||
|
in >> currentCharacter;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// In all other cases write the currentCharacter to outputFile
|
||||||
|
out << currentCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousCharacter = currentCharacter;
|
||||||
|
currentCharacter = nextCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//write currentCharacter to output file when nextCharacter reaches EOF
|
||||||
|
if (currentCharacter != '\n') {
|
||||||
|
out << currentCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Successful bake. Return true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSBaker::handleSingleLineComments(QTextStream& in) {
|
||||||
|
QChar character;
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
in >> character;
|
||||||
|
if (character == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::handleMultiLineComments(QTextStream& in) {
|
||||||
|
QChar character;
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
in >> character;
|
||||||
|
if (character == '*') {
|
||||||
|
if (in.read(1) == '/') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::canOmitSpace(QChar previousCharacter, QChar nextCharacter) {
|
||||||
|
return(!((isAlphanum(previousCharacter) || isNonAscii(previousCharacter) || isSpecialCharacter(previousCharacter)) &&
|
||||||
|
(isAlphanum(nextCharacter) || isNonAscii(nextCharacter) || isSpecialCharacter(nextCharacter)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::canOmitNewLine(QChar previousCharacter, QChar nextCharacter) {
|
||||||
|
return (!((isAlphanum(previousCharacter) || isNonAscii(previousCharacter) || isSpecialCharacterPrevious(previousCharacter)) &&
|
||||||
|
(isAlphanum(nextCharacter) || isNonAscii(nextCharacter) || isSpecialCharacterNext(nextCharacter)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if character is alphabet, number or one of the following: '_', '$', '\\' or a non-ASCII character
|
||||||
|
bool JSBaker::isAlphanum(QChar c) {
|
||||||
|
return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')
|
||||||
|
|| c == '_' || c == '$' || c == '\\' || c > ASCII_CHARACTERS_UPPER_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::isNonAscii(QChar c) {
|
||||||
|
return ((int)c.toLatin1() > ASCII_CHARACTERS_UPPER_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If previous and next characters are special characters, don't omit space
|
||||||
|
bool JSBaker::isSpecialCharacter(QChar c) {
|
||||||
|
return (c == '\'' || c == '$' || c == '_' || c == '/' || c== '+' || c == '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If previous character is a special character, maybe don't omit new line (depends on next character as well)
|
||||||
|
bool JSBaker::isSpecialCharacterPrevious(QChar c) {
|
||||||
|
return (c == '\'' || c == '$' || c == '_' || c == '}' || c == ']' || c == ')' || c == '+' || c == '-'
|
||||||
|
|| c == '"' || c == "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If next character is a special character, maybe don't omit new line (depends on previous character as well)
|
||||||
|
bool JSBaker::isSpecialCharacterNext(QChar c) {
|
||||||
|
return (c == '\'' || c == '$' || c == '_' || c == '{' || c == '[' || c == '(' || c == '+' || c == '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if white space or tab
|
||||||
|
bool JSBaker::isSpaceOrTab(QChar c) {
|
||||||
|
return (c == ' ' || c == '\t');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check If the currentCharacter is " or ' or `
|
||||||
|
bool JSBaker::isQuote(QChar c) {
|
||||||
|
return (c == '"' || c == "'" || c == '`');
|
||||||
|
}
|
49
libraries/baking/src/JSBaker.h
Normal file
49
libraries/baking/src/JSBaker.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// JSBaker.h
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_JSBaker_h
|
||||||
|
#define hifi_JSBaker_h
|
||||||
|
|
||||||
|
#include "Baker.h"
|
||||||
|
#include "JSBakingLoggingCategory.h"
|
||||||
|
|
||||||
|
static const QString BAKED_JS_EXTENSION = ".baked.js";
|
||||||
|
|
||||||
|
class JSBaker : public Baker {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
JSBaker(const QUrl& jsURL, const QString& bakedOutputDir);
|
||||||
|
static bool bakeJS(const QByteArray& inputFile, QByteArray& outputFile);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void bake() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUrl _jsURL;
|
||||||
|
QString _bakedOutputDir;
|
||||||
|
QString _bakedJSFilePath;
|
||||||
|
|
||||||
|
static void handleSingleLineComments(QTextStream& in);
|
||||||
|
static bool handleMultiLineComments(QTextStream& in);
|
||||||
|
|
||||||
|
static bool canOmitSpace(QChar previousCharacter, QChar nextCharacter);
|
||||||
|
static bool canOmitNewLine(QChar previousCharacter, QChar nextCharacter);
|
||||||
|
|
||||||
|
static bool isAlphanum(QChar c);
|
||||||
|
static bool isNonAscii(QChar c);
|
||||||
|
static bool isSpecialCharacter(QChar c);
|
||||||
|
static bool isSpecialCharacterPrevious(QChar c);
|
||||||
|
static bool isSpecialCharacterNext(QChar c);
|
||||||
|
static bool isSpaceOrTab(QChar c);
|
||||||
|
static bool isQuote(QChar c);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !hifi_JSBaker_h
|
14
libraries/baking/src/JSBakingLoggingCategory.cpp
Normal file
14
libraries/baking/src/JSBakingLoggingCategory.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//
|
||||||
|
// JSBakingLoggingCategory.cpp
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "JSBakingLoggingCategory.h"
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(js_baking, "hifi.JS-baking");
|
19
libraries/baking/src/JSBakingLoggingCategory.h
Normal file
19
libraries/baking/src/JSBakingLoggingCategory.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// JSBakingLoggingCategory.h
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_JSBakingLoggingCategory_h
|
||||||
|
#define hifi_JSBakingLoggingCategory_h
|
||||||
|
|
||||||
|
#include <QtCore/QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(js_baking)
|
||||||
|
|
||||||
|
#endif // hifi_ModelBakingLoggingCategory_h
|
|
@ -60,7 +60,8 @@ bool ModelEntityWrapper::isModelLoaded() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity{ new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()) };
|
EntityItemPointer entity(new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()),
|
||||||
|
[](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ void loop3(const T& start, const T& end, F f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
std::shared_ptr<RenderablePolyVoxEntityItem> entity{ new RenderablePolyVoxEntityItem(entityID) };
|
std::shared_ptr<RenderablePolyVoxEntityItem> entity(new RenderablePolyVoxEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
entity->initializePolyVox();
|
entity->initializePolyVox();
|
||||||
return entity;
|
return entity;
|
||||||
|
|
|
@ -45,7 +45,7 @@ void EntityEditPacketSender::queueEditAvatarEntityMessage(PacketType type,
|
||||||
}
|
}
|
||||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(entityItemID);
|
EntityItemPointer entity = entityTree->findEntityByEntityItemID(entityItemID);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "EntityEditPacketSender::queueEditEntityMessage can't find entity.";
|
qCDebug(entities) << "EntityEditPacketSender::queueEditAvatarEntityMessage can't find entity: " << entityItemID;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1848,7 +1848,13 @@ bool EntityTree::sendEntitiesOperation(const OctreeElementPointer& element, void
|
||||||
|
|
||||||
QHash<EntityItemID, EntityItemID>::iterator iter = args->map->find(oldID);
|
QHash<EntityItemID, EntityItemID>::iterator iter = args->map->find(oldID);
|
||||||
if (iter == args->map->end()) {
|
if (iter == args->map->end()) {
|
||||||
EntityItemID newID = QUuid::createUuid();
|
EntityItemID newID;
|
||||||
|
if (oldID == AVATAR_SELF_ID) {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
newID = EntityItemID(nodeList->getSessionUUID());
|
||||||
|
} else {
|
||||||
|
newID = QUuid::createUuid();
|
||||||
|
}
|
||||||
args->map->insert(oldID, newID);
|
args->map->insert(oldID, newID);
|
||||||
return newID;
|
return newID;
|
||||||
}
|
}
|
||||||
|
@ -1865,8 +1871,8 @@ bool EntityTree::sendEntitiesOperation(const OctreeElementPointer& element, void
|
||||||
properties.setPosition(properties.getPosition() + args->root);
|
properties.setPosition(properties.getPosition() + args->root);
|
||||||
} else {
|
} else {
|
||||||
EntityItemPointer parentEntity = args->ourTree->findEntityByEntityItemID(oldParentID);
|
EntityItemPointer parentEntity = args->ourTree->findEntityByEntityItemID(oldParentID);
|
||||||
if (parentEntity) { // map the parent
|
if (parentEntity || oldParentID == AVATAR_SELF_ID) { // map the parent
|
||||||
properties.setParentID(getMapped(parentEntity->getID()));
|
properties.setParentID(getMapped(oldParentID));
|
||||||
// But do not add root offset in this case.
|
// But do not add root offset in this case.
|
||||||
} else { // Should not happen, but let's try to be helpful...
|
} else { // Should not happen, but let's try to be helpful...
|
||||||
item->globalizeProperties(properties, "Cannot find %3 parent of %2 %1", args->root);
|
item->globalizeProperties(properties, "Cannot find %3 parent of %2 %1", args->root);
|
||||||
|
@ -1941,6 +1947,12 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
||||||
entityItemID = EntityItemID(QUuid::createUuid());
|
entityItemID = EntityItemID(QUuid::createUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties.getClientOnly()) {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
const QUuid myNodeID = nodeList->getSessionUUID();
|
||||||
|
properties.setOwningAvatarID(myNodeID);
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer entity = addEntity(entityItemID, properties);
|
EntityItemPointer entity = addEntity(entityItemID, properties);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
||||||
|
|
|
@ -30,7 +30,7 @@ const float LightEntityItem::DEFAULT_CUTOFF = PI / 2.0f;
|
||||||
bool LightEntityItem::_lightsArePickable = false;
|
bool LightEntityItem::_lightsArePickable = false;
|
||||||
|
|
||||||
EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new LightEntityItem(entityID) };
|
EntityItemPointer entity(new LightEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ const int LineEntityItem::MAX_POINTS_PER_LINE = 70;
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new LineEntityItem(entityID) };
|
EntityItemPointer entity(new LineEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
@ -214,4 +214,4 @@ void LineEntityItem::resetPointsChanged() {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_pointsChanged = false;
|
_pointsChanged = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ const QString ModelEntityItem::DEFAULT_MODEL_URL = QString("");
|
||||||
const QString ModelEntityItem::DEFAULT_COMPOUND_SHAPE_URL = QString("");
|
const QString ModelEntityItem::DEFAULT_COMPOUND_SHAPE_URL = QString("");
|
||||||
|
|
||||||
EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new ModelEntityItem(entityID) };
|
EntityItemPointer entity(new ModelEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ uint64_t Properties::emitIntervalUsecs() const {
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new ParticleEffectEntityItem(entityID) };
|
EntityItemPointer entity(new ParticleEffectEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70;
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity{ new PolyLineEntityItem(entityID) };
|
EntityItemPointer entity(new PolyLineEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ const QString PolyVoxEntityItem::DEFAULT_Y_TEXTURE_URL = QString("");
|
||||||
const QString PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL = QString("");
|
const QString PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL = QString("");
|
||||||
|
|
||||||
EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new PolyVoxEntityItem(entityID) };
|
EntityItemPointer entity(new PolyVoxEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
Pointer entity { new ShapeEntityItem(entityID) };
|
Pointer entity(new ShapeEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0};
|
||||||
const bool TextEntityItem::DEFAULT_FACE_CAMERA = false;
|
const bool TextEntityItem::DEFAULT_FACE_CAMERA = false;
|
||||||
|
|
||||||
EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new TextEntityItem(entityID) };
|
EntityItemPointer entity(new TextEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
const QString WebEntityItem::DEFAULT_SOURCE_URL("http://www.google.com");
|
const QString WebEntityItem::DEFAULT_SOURCE_URL("http://www.google.com");
|
||||||
|
|
||||||
EntityItemPointer WebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer WebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new WebEntityItem(entityID) };
|
EntityItemPointer entity(new WebEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ const bool ZoneEntityItem::DEFAULT_GHOSTING_ALLOWED = true;
|
||||||
const QString ZoneEntityItem::DEFAULT_FILTER_URL = "";
|
const QString ZoneEntityItem::DEFAULT_FILTER_URL = "";
|
||||||
|
|
||||||
EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new ZoneEntityItem(entityID) };
|
EntityItemPointer entity(new ZoneEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,11 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer(bool& success) cons
|
||||||
if (parent && parent->getID() == parentID) {
|
if (parent && parent->getID() == parentID) {
|
||||||
// parent pointer is up-to-date
|
// parent pointer is up-to-date
|
||||||
if (!_parentKnowsMe) {
|
if (!_parentKnowsMe) {
|
||||||
parent->beParentOfChild(getThisPointer());
|
SpatialParentTree* parentTree = parent->getParentTree();
|
||||||
_parentKnowsMe = true;
|
if (!parentTree || parentTree == getParentTree()) {
|
||||||
|
parent->beParentOfChild(getThisPointer());
|
||||||
|
_parentKnowsMe = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
return parent;
|
return parent;
|
||||||
|
@ -129,8 +132,15 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer(bool& success) cons
|
||||||
|
|
||||||
parent = _parent.lock();
|
parent = _parent.lock();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent->beParentOfChild(getThisPointer());
|
|
||||||
_parentKnowsMe = true;
|
// it's possible for an entity with a parent of AVATAR_SELF_ID can be imported into a side-tree
|
||||||
|
// such as the clipboard's. if this is the case, we don't want the parent to consider this a
|
||||||
|
// child.
|
||||||
|
SpatialParentTree* parentTree = parent->getParentTree();
|
||||||
|
if (!parentTree || parentTree == getParentTree()) {
|
||||||
|
parent->beParentOfChild(getThisPointer());
|
||||||
|
_parentKnowsMe = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
success = (parent || parentID.isNull());
|
success = (parent || parentID.isNull());
|
||||||
|
|
|
@ -222,7 +222,7 @@ getControllerJointIndex = function (hand) {
|
||||||
return controllerJointIndex;
|
return controllerJointIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MyAvatar.getJointIndex("Head");
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
propsArePhysical = function (props) {
|
propsArePhysical = function (props) {
|
||||||
|
|
10
tests/baking/CMakeLists.txt
Normal file
10
tests/baking/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
# Declare dependencies
|
||||||
|
macro (setup_testcase_dependencies)
|
||||||
|
# link in the shared libraries
|
||||||
|
link_hifi_libraries(shared baking)
|
||||||
|
|
||||||
|
package_libraries_for_deployment()
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
setup_hifi_testcase()
|
92
tests/baking/src/JSBakerTest.cpp
Normal file
92
tests/baking/src/JSBakerTest.cpp
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
//
|
||||||
|
// JSBakerTest.cpp
|
||||||
|
// tests/networking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 09/26/17.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "JSBakerTest.h"
|
||||||
|
QTEST_MAIN(JSBakerTest)
|
||||||
|
|
||||||
|
void JSBakerTest::setTestCases() {
|
||||||
|
// Test cases contain a std::pair(input, desiredOutput)
|
||||||
|
|
||||||
|
_testCases.emplace_back("var a=1;", "var a=1;");
|
||||||
|
_testCases.emplace_back("var a=1;//single line comment\nvar b=2;", "var a=1;var b=2;");
|
||||||
|
_testCases.emplace_back("a\rb", "a\nb");
|
||||||
|
_testCases.emplace_back("a/*multi\n line \n comment*/ b", "ab");
|
||||||
|
_testCases.emplace_back("a/b", "a/b");
|
||||||
|
_testCases.emplace_back("var a = 1;", "var a=1;"); // Multiple spaces omitted
|
||||||
|
_testCases.emplace_back("var a=\t\t\t1;", "var a=1;"); // Multiple tabs omitted
|
||||||
|
|
||||||
|
// Cases for space not omitted
|
||||||
|
_testCases.emplace_back("var x", "var x");
|
||||||
|
_testCases.emplace_back("a '", "a '");
|
||||||
|
_testCases.emplace_back("a $", "a $");
|
||||||
|
_testCases.emplace_back("a _", "a _");
|
||||||
|
_testCases.emplace_back("a /", "a /");
|
||||||
|
_testCases.emplace_back("a 1", "a 1");
|
||||||
|
_testCases.emplace_back("1 a", "1 a");
|
||||||
|
_testCases.emplace_back("$ a", "$ a");
|
||||||
|
_testCases.emplace_back("_ a", "_ a");
|
||||||
|
_testCases.emplace_back("/ a", "/ a");
|
||||||
|
_testCases.emplace_back("$ $", "$ $");
|
||||||
|
_testCases.emplace_back("_ _", "_ _");
|
||||||
|
_testCases.emplace_back("/ /", "/ /");
|
||||||
|
|
||||||
|
_testCases.emplace_back("a\n\n\n\nb", "a\nb"); // Skip multiple new lines
|
||||||
|
_testCases.emplace_back("a\n\n b", "a\nb"); // Skip multiple new lines followed by whitespace
|
||||||
|
_testCases.emplace_back("a\n\n b", "a\nb"); // Skip multiple new lines followed by tab
|
||||||
|
|
||||||
|
//Cases for new line not omitted
|
||||||
|
_testCases.emplace_back("a\nb", "a\nb");
|
||||||
|
_testCases.emplace_back("a\n9", "a\n9");
|
||||||
|
_testCases.emplace_back("9\na", "9\na");
|
||||||
|
_testCases.emplace_back("a\n$", "a\n$");
|
||||||
|
_testCases.emplace_back("a\n[", "a\n[");
|
||||||
|
_testCases.emplace_back("a\n{", "a\n{");
|
||||||
|
_testCases.emplace_back("a\n(", "a\n(");
|
||||||
|
_testCases.emplace_back("a\n+", "a\n+");
|
||||||
|
_testCases.emplace_back("a\n'", "a\n'");
|
||||||
|
_testCases.emplace_back("a\n-", "a\n-");
|
||||||
|
_testCases.emplace_back("$\na", "$\na");
|
||||||
|
_testCases.emplace_back("$\na", "$\na");
|
||||||
|
_testCases.emplace_back("_\na", "_\na");
|
||||||
|
_testCases.emplace_back("]\na", "]\na");
|
||||||
|
_testCases.emplace_back("}\na", "}\na");
|
||||||
|
_testCases.emplace_back(")\na", ")\na");
|
||||||
|
_testCases.emplace_back("+\na", "+\na");
|
||||||
|
_testCases.emplace_back("-\na", "-\na");
|
||||||
|
|
||||||
|
// Cases to check quoted strings are not modified
|
||||||
|
_testCases.emplace_back("'abcd1234$%^&[](){}'\na", "'abcd1234$%^&[](){}'\na");
|
||||||
|
_testCases.emplace_back("\"abcd1234$%^&[](){}\"\na", "\"abcd1234$%^&[](){}\"\na");
|
||||||
|
_testCases.emplace_back("`abcd1234$%^&[](){}`\na", "`abcd1234$%^&[](){}`a");
|
||||||
|
|
||||||
|
// Edge Cases
|
||||||
|
|
||||||
|
//No semicolon to terminate an expression, instead a new line used for termination
|
||||||
|
_testCases.emplace_back("var x=5\nvar y=6;", "var x=5\nvar y=6;");
|
||||||
|
|
||||||
|
//a + ++b is minified as a+ ++b.
|
||||||
|
_testCases.emplace_back("a + ++b", "a + ++b");
|
||||||
|
|
||||||
|
//a - --b is minified as a- --b.
|
||||||
|
_testCases.emplace_back("a - --b", "a - --b");
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSBakerTest::testJSBaking() {
|
||||||
|
|
||||||
|
for (int i = 0;i < _testCases.size();i++) {
|
||||||
|
QByteArray output;
|
||||||
|
auto input = _testCases.at(i).first;
|
||||||
|
JSBaker::bakeJS(input, output);
|
||||||
|
|
||||||
|
auto desiredOutput = _testCases.at(i).second;
|
||||||
|
QCOMPARE(output, desiredOutput);
|
||||||
|
}
|
||||||
|
}
|
29
tests/baking/src/JSBakerTest.h
Normal file
29
tests/baking/src/JSBakerTest.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// JSBakerTest.h
|
||||||
|
// tests/networking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/26/17.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_JSBakerTest_h
|
||||||
|
#define hifi_JSBakerTest_h
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include <JSBaker.h>
|
||||||
|
|
||||||
|
class JSBakerTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void setTestCases();
|
||||||
|
void testJSBaking();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::pair<QByteArray, QByteArray>> _testCases;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue