From 58f1371ebac48e58eaa0f02b193cdbd93cb2c5fc Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 22 Dec 2015 15:08:03 +1300 Subject: [PATCH 01/43] Fix particle radius and rgba start, middle, finish interpolation Bezier interpolation of 3 points doesn't intersect the middle value. Instead, use separate Bezier interpolations for start-middle and middle- finish, so that the interpolated values intersect the middle value as a user would expect. --- examples/example/entities/particlesTest.js | 2 +- .../src/textured_particle.slv | 50 ++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index e7f88ce468..2ebbe6489e 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -71,7 +71,7 @@ Entities.editEntity(particles, { radiusSpread: 0.0, radiusStart: 0.0, - particleRadius: 2 * PARTICLE_RADIUS, // Bezier interpolation used means that middle value isn't intersected + particleRadius: PARTICLE_RADIUS, radiusFinish: 0.0 }); break; diff --git a/libraries/entities-renderer/src/textured_particle.slv b/libraries/entities-renderer/src/textured_particle.slv index e1f18c2b5f..d1552f7ba7 100644 --- a/libraries/entities-renderer/src/textured_particle.slv +++ b/libraries/entities-renderer/src/textured_particle.slv @@ -56,13 +56,51 @@ float bezierInterpolate(float y1, float y2, float y3, float u) { return (1.0 - u) * (1.0 - u) * y1 + 2.0 * (1.0 - u) * u * y2 + u * u * y3; } -vec4 interpolate3Vec4(vec4 y1, vec4 y2, vec4 y3, float u) { - return vec4(bezierInterpolate(y1.x, y2.x, y3.x, u), - bezierInterpolate(y1.y, y2.y, y3.y, u), - bezierInterpolate(y1.z, y2.z, y3.z, u), - bezierInterpolate(y1.w, y2.w, y3.w, u)); +float interpolate3Points(float y1, float y2, float y3, float u) { + // Makes the interpolated values intersect the middle value. + + if ((u <= 0.5f && y1 == y2) || (u >= 0.5f && y2 == y3)) { + // Flat line. + return y2; + } + + if ((y2 >= y1 && y2 >= y3) || (y2 <= y1 && y2 <= y3)) { + // U or inverted-U shape. + // Make the slope at y2 = 0, which means that the control points half way between the value points have the value y2. + if (u <= 0.5f) { + return bezierInterpolate(y1, y2, y2, 2.0f * u); + } else { + return bezierInterpolate(y2, y2, y3, 2.0f * u - 1.0f); + } + + } else { + // L or inverted and/or mirrored L shape. + // Make the slope at y2 be the slope between y1 and y3, up to a maximum of double the minimum of the slopes between y1 + // and y2, and y2 and y3. Use this slope to calculate the control points half way between the value points. + // Note: The maximum ensures that the control points and therefore the interpolated values stay between y1 and y3. + float slope = y3 - y1; + float slope12 = y2 - y1; + float slope23 = y3 - y2; + if (abs(slope) > abs(2.0f * slope12)) { + slope = 2.0f * slope12; + } else if (abs(slope) > abs(2.0f * slope23)) { + slope = 2.0f * slope23; + } + + if (u <= 0.5f) { + return bezierInterpolate(y1, y2 - slope / 2.0f, y2, 2.0f * u); + } else { + return bezierInterpolate(y2, y2 + slope / 2.0f, y3, 2.0f * u - 1.0f); + } + } } +vec4 interpolate3Vec4(vec4 y1, vec4 y2, vec4 y3, float u) { + return vec4(interpolate3Points(y1.x, y2.x, y3.x, u), + interpolate3Points(y1.y, y2.y, y3.y, u), + interpolate3Points(y1.z, y2.z, y3.z, u), + interpolate3Points(y1.w, y2.w, y3.w, u)); +} void main(void) { TransformCamera cam = getTransformCamera(); @@ -82,7 +120,7 @@ void main(void) { varColor = interpolate3Vec4(particle.color.start, particle.color.middle, particle.color.finish, age); // anchor point in eye space - float radius = bezierInterpolate(particle.radius.start, particle.radius.middle, particle.radius.finish, age); + float radius = interpolate3Points(particle.radius.start, particle.radius.middle, particle.radius.finish, age); vec4 quadPos = radius * UNIT_QUAD[twoTriID]; vec4 anchorPoint; From 24f6cfa0183bbf5cbc185d820ff7f8eb858b7bed Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 22 Dec 2015 15:26:41 +1300 Subject: [PATCH 02/43] Fix whitespace --- libraries/entities-renderer/src/textured_particle.slv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/textured_particle.slv b/libraries/entities-renderer/src/textured_particle.slv index d1552f7ba7..2f913e5527 100644 --- a/libraries/entities-renderer/src/textured_particle.slv +++ b/libraries/entities-renderer/src/textured_particle.slv @@ -111,21 +111,21 @@ void main(void) { // Which quad vertex pos? int twoTriID = gl_VertexID - particleID * NUM_VERTICES_PER_PARTICLE; - // Particle properties + // Particle properties float age = inColor.x / particle.lifespan; float seed = inColor.y; // Pass the texcoord and the z texcoord is representing the texture icon varTexcoord = vec2((UNIT_QUAD[twoTriID].xy + 1.0) * 0.5); varColor = interpolate3Vec4(particle.color.start, particle.color.middle, particle.color.finish, age); - + // anchor point in eye space - float radius = interpolate3Points(particle.radius.start, particle.radius.middle, particle.radius.finish, age); + float radius = interpolate3Points(particle.radius.start, particle.radius.middle, particle.radius.finish, age); vec4 quadPos = radius * UNIT_QUAD[twoTriID]; vec4 anchorPoint; <$transformModelToEyePos(cam, obj, inPosition, anchorPoint)$> - + vec4 eyePos = anchorPoint + quadPos; <$transformEyeToClipPos(cam, eyePos, gl_Position)$> } From 84bcfb7d7142648a27db9595d9d0eab06b09551c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 22 Dec 2015 17:43:01 -0800 Subject: [PATCH 03/43] hook up a way for scripts to set model-entity joint state --- libraries/animation/src/Rig.cpp | 8 +++++ libraries/animation/src/Rig.h | 2 ++ .../src/RenderableModelEntityItem.cpp | 34 +++++++++++++++++-- .../src/RenderableModelEntityItem.h | 9 +++++ libraries/entities/src/EntityItem.h | 2 ++ .../entities/src/EntityScriptingInterface.cpp | 20 +++++++++++ .../entities/src/EntityScriptingInterface.h | 2 ++ libraries/entities/src/ModelEntityItem.h | 1 - libraries/render-utils/src/Model.cpp | 8 +++++ libraries/render-utils/src/Model.h | 3 ++ libraries/shared/src/SpatiallyNestable.h | 4 ++- 11 files changed, 89 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 68f382d2d9..4b2d4facc8 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -386,6 +386,10 @@ bool Rig::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation } } +bool Rig::setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) { + return false; +} + bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const { QReadLocker readLock(&_externalPoseSetLock); if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._relativePoses.size()) { @@ -406,6 +410,10 @@ bool Rig::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& trans } } +bool Rig::setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) { + return false; +} + bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const { // AJT: TODO: used by attachments ASSERT(false); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9faf93e40b..3881b35dfb 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -134,6 +134,8 @@ public: // rig space (thread-safe) bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const; bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const; + bool setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation); + bool setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation); // legacy bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 9127e4ca22..61ad4d2c2a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -292,7 +292,21 @@ void RenderableModelEntityItem::render(RenderArgs* args) { } if (_model) { - // handle animations.. + // handle script updates... + _scriptSetFrameDataLock.withWriteLock([&] { + while (!_scriptSetFrameDataRotationsIndexes.empty()) { + int index = _scriptSetFrameDataRotationsIndexes.dequeue(); + glm::quat rotation = _scriptSetFrameDataRotations.dequeue(); + _model->setJointRotation(index, true, rotation, 1.0f); + } + while (!_scriptSetFrameDataTranslationsIndexes.empty()) { + int index = _scriptSetFrameDataTranslationsIndexes.dequeue(); + glm::vec3 translation = _scriptSetFrameDataTranslations.dequeue(); + _model->setJointTranslation(index, true, translation, 1.0f); + } + }); + + // handle animations... if (hasAnimation()) { if (!jointsMapped()) { QStringList modelJointNames = _model->getJointNames(); @@ -600,7 +614,7 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const { const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry(); return collisionGeometry.convexHullContains(worldToEntity(point)); } - + return false; } @@ -624,6 +638,22 @@ glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(in return glm::vec3(0.0f); } +bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) { + _scriptSetFrameDataLock.withWriteLock([&] { + _scriptSetFrameDataRotationsIndexes.enqueue(index); + _scriptSetFrameDataRotations.enqueue(rotation); + }); + return true; +} + +bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) { + _scriptSetFrameDataLock.withWriteLock([&] { + _scriptSetFrameDataTranslationsIndexes.enqueue(index); + _scriptSetFrameDataTranslations.enqueue(translation); + }); + return true; +} + void RenderableModelEntityItem::locationChanged() { EntityItem::locationChanged(); if (_model && _model->isActive()) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index cf948bd7a0..d0847b66cb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -71,6 +71,8 @@ public: // these are in the frame of this object (model space) virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; + virtual bool setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) override; + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) override; virtual void loader() override; virtual void locationChanged() override; @@ -91,6 +93,13 @@ private: render::ItemID _myMetaItem; bool _showCollisionHull = false; + + // these are used to let scripts set ModelEntityItem joint data + ReadWriteLockable _scriptSetFrameDataLock; + QQueue _scriptSetFrameDataRotations; + QQueue _scriptSetFrameDataRotationsIndexes; + QQueue _scriptSetFrameDataTranslations; + QQueue _scriptSetFrameDataTranslationsIndexes; }; #endif // hifi_RenderableModelEntityItem_h diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 244198f7b8..841f68ddc1 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -381,6 +381,8 @@ public: // these are in the frame of this object virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override { return glm::quat(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override { return glm::vec3(0.0f); } + virtual bool setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) override { return false; } + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) override { return false; } virtual void loader() {} // called indirectly when urls for geometry are updated diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index a0a6719521..c20db60601 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -826,3 +826,23 @@ glm::quat EntityScriptingInterface::getAbsoluteJointRotationInObjectFrame(const return glm::quat(); } } + +bool EntityScriptingInterface::setAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, + int jointIndex, glm::vec3 translation) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto modelEntity = std::dynamic_pointer_cast(entity); + return modelEntity->setAbsoluteJointTranslationInObjectFrame(jointIndex, translation); + } else { + return false; + } +} + +bool EntityScriptingInterface::setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, + int jointIndex, glm::quat rotation) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto modelEntity = std::dynamic_pointer_cast(entity); + return modelEntity->setAbsoluteJointRotationInObjectFrame(jointIndex, rotation); + } else { + return false; + } +} diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index f745b6b644..5d56ea2b99 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -151,6 +151,8 @@ public slots: Q_INVOKABLE glm::vec3 getAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex); Q_INVOKABLE glm::quat getAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex); + Q_INVOKABLE bool setAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex, glm::vec3 translation); + Q_INVOKABLE bool setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex, glm::quat rotation); signals: void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index b08fed5970..9978f3359a 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -129,7 +129,6 @@ protected: QVector _lastKnownFrameDataTranslations; int _lastKnownCurrentFrame; - bool isAnimatingSomething() const; rgbColor _color; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index dbd3a6289f..91ca8e60cb 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -699,6 +699,14 @@ void Model::setJointTranslation(int index, bool valid, const glm::vec3& translat _rig->setJointTranslation(index, valid, translation, priority); } +bool Model::setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) { + return _rig->setAbsoluteJointRotationInRigFrame(jointIndex, rotation); +} + +bool Model::setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) { + return _rig->setAbsoluteJointTranslationInRigFrame(jointIndex, translation); +} + int Model::getParentJointIndex(int jointIndex) const { return (isActive() && jointIndex != -1) ? _geometry->getFBXGeometry().joints.at(jointIndex).parentIndex : -1; } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index a93338e41a..327583c212 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -170,6 +170,9 @@ public: bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotationOut) const; bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translationOut) const; + bool setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation); + bool setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation); + bool getRelativeDefaultJointRotation(int jointIndex, glm::quat& rotationOut) const; bool getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& translationOut) const; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 7a43e2a563..f6a9678d34 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -91,7 +91,9 @@ public: virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const; virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { assert(false); return glm::quat(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { assert(false); return glm::vec3(); } - + virtual bool setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) { assert(false); return false; } + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) { assert(false); return false; } + SpatiallyNestablePointer getThisPointer() const; protected: From 1a51c9ddbeebbb45dac5b8cfba9ec0e24a1f88ba Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 22 Dec 2015 17:56:12 -0800 Subject: [PATCH 04/43] remove some unused stuff --- libraries/animation/src/Rig.cpp | 8 -------- libraries/animation/src/Rig.h | 2 -- libraries/render-utils/src/Model.cpp | 8 -------- libraries/render-utils/src/Model.h | 3 --- 4 files changed, 21 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 4b2d4facc8..68f382d2d9 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -386,10 +386,6 @@ bool Rig::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation } } -bool Rig::setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) { - return false; -} - bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const { QReadLocker readLock(&_externalPoseSetLock); if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._relativePoses.size()) { @@ -410,10 +406,6 @@ bool Rig::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& trans } } -bool Rig::setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) { - return false; -} - bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const { // AJT: TODO: used by attachments ASSERT(false); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 3881b35dfb..9faf93e40b 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -134,8 +134,6 @@ public: // rig space (thread-safe) bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const; bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const; - bool setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation); - bool setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation); // legacy bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 91ca8e60cb..dbd3a6289f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -699,14 +699,6 @@ void Model::setJointTranslation(int index, bool valid, const glm::vec3& translat _rig->setJointTranslation(index, valid, translation, priority); } -bool Model::setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) { - return _rig->setAbsoluteJointRotationInRigFrame(jointIndex, rotation); -} - -bool Model::setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) { - return _rig->setAbsoluteJointTranslationInRigFrame(jointIndex, translation); -} - int Model::getParentJointIndex(int jointIndex) const { return (isActive() && jointIndex != -1) ? _geometry->getFBXGeometry().joints.at(jointIndex).parentIndex : -1; } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 327583c212..a93338e41a 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -170,9 +170,6 @@ public: bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotationOut) const; bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translationOut) const; - bool setAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation); - bool setAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation); - bool getRelativeDefaultJointRotation(int jointIndex, glm::quat& rotationOut) const; bool getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& translationOut) const; From d878dde952669660023f3336e8b5275bc5797e6b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 22 Dec 2015 17:57:25 -0800 Subject: [PATCH 05/43] whitespace --- libraries/entities/src/ModelEntityItem.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 9978f3359a..b08fed5970 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -129,6 +129,7 @@ protected: QVector _lastKnownFrameDataTranslations; int _lastKnownCurrentFrame; + bool isAnimatingSomething() const; rgbColor _color; From 83f60d6e97b5f9a01f3610d917267250b3f772b7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 23 Dec 2015 15:43:50 -0800 Subject: [PATCH 06/43] make entity properties for model-entity joint-states --- .../src/RenderableModelEntityItem.cpp | 151 +++++++++++++---- .../src/RenderableModelEntityItem.h | 25 ++- .../entities/src/EntityItemProperties.cpp | 26 +++ libraries/entities/src/EntityItemProperties.h | 5 + .../entities/src/EntityItemPropertiesMacros.h | 14 ++ libraries/entities/src/EntityPropertyFlags.h | 6 + libraries/entities/src/ModelEntityItem.cpp | 155 +++++++++++------- libraries/entities/src/ModelEntityItem.h | 29 +++- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + libraries/octree/src/OctreePacketData.cpp | 46 +++++- libraries/octree/src/OctreePacketData.h | 18 +- libraries/shared/src/RegisteredMetaTypes.cpp | 98 +++++++++-- libraries/shared/src/RegisteredMetaTypes.h | 8 + 14 files changed, 449 insertions(+), 135 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 61ad4d2c2a..c77a274692 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -230,8 +231,8 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p return true; } - -void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, std::shared_ptr scene, + +void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { pendingChanges.removeItem(_myMetaItem); if (_model) { @@ -239,6 +240,80 @@ void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, std::sha } } +void RenderableModelEntityItem::resizeJointArrays(int newSize) { + if (newSize < 0) { + if (_model && _model->isActive() && _model->isLoaded() && !_needsInitialSimulation) { + newSize = _model->getJointStateCount(); + } + } + ModelEntityItem::resizeJointArrays(newSize); +} + +bool RenderableModelEntityItem::getAnimationFrame() { + bool newFrame = false; + + if (!_model || !_model->isActive() || !_model->isLoaded() || _needsInitialSimulation) { + return false; + } + + if (!hasAnimation() || !_jointMappingCompleted) { + return false; + } + AnimationPointer myAnimation = getAnimation(_animationProperties.getURL()); // FIXME: this could be optimized + if (myAnimation && myAnimation->isLoaded()) { + + const QVector& frames = myAnimation->getFramesReference(); // NOTE: getFrames() is too heavy + auto& fbxJoints = myAnimation->getGeometry().joints; + + int frameCount = frames.size(); + if (frameCount > 0) { + int animationCurrentFrame = (int)(glm::floor(getAnimationCurrentFrame())) % frameCount; + if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) { + animationCurrentFrame = 0; + } + + if (animationCurrentFrame != _lastKnownCurrentFrame) { + _lastKnownCurrentFrame = animationCurrentFrame; + newFrame = true; + + resizeJointArrays(); + if (_jointMapping.size() != _model->getJointStateCount()) { + qDebug() << "BLERG" << _jointMapping.size() << _model->getJointStateCount(); + assert(false); + } + for (int j = 0; j < _jointMapping.size(); j++) { + int index = _jointMapping[j]; + if (index >= 0) { + if (index >= frames[animationCurrentFrame].rotations.size() || + index >= frames[animationCurrentFrame].translations.size()) { + return false; + } + const glm::quat rotation = frames[animationCurrentFrame].rotations[index]; + const glm::vec3 translation = frames[animationCurrentFrame].translations[index]; + + glm::mat4 translationMat = glm::translate(translation); + glm::mat4 rotationMat = glm::mat4_cast(rotation); + glm::mat4 finalMat = (translationMat * fbxJoints[index].preTransform * + rotationMat * fbxJoints[index].postTransform); + _absoluteJointTranslationsInObjectFrame[j] = extractTranslation(finalMat); + _absoluteJointTranslationsInObjectFrameSet[j] = true; + _absoluteJointTranslationsInObjectFrameDirty[j] = true; + + // XXX Tony will fix this better in some other PR + // _absoluteJointRotationsInObjectFrame[j] = glmExtractRotation(finalMat); + _absoluteJointRotationsInObjectFrame[j] = fbxJoints[index].preRotation * rotation; + // XXX + + _absoluteJointRotationsInObjectFrameSet[j] = true; + _absoluteJointRotationsInObjectFrameDirty[j] = true; + } + } + } + } + } + + return newFrame; +} // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items, and it handles // the per frame simulation/update that might be required if the models properties changed. @@ -292,40 +367,32 @@ void RenderableModelEntityItem::render(RenderArgs* args) { } if (_model) { - // handle script updates... - _scriptSetFrameDataLock.withWriteLock([&] { - while (!_scriptSetFrameDataRotationsIndexes.empty()) { - int index = _scriptSetFrameDataRotationsIndexes.dequeue(); - glm::quat rotation = _scriptSetFrameDataRotations.dequeue(); - _model->setJointRotation(index, true, rotation, 1.0f); - } - while (!_scriptSetFrameDataTranslationsIndexes.empty()) { - int index = _scriptSetFrameDataTranslationsIndexes.dequeue(); - glm::vec3 translation = _scriptSetFrameDataTranslations.dequeue(); - _model->setJointTranslation(index, true, translation, 1.0f); - } - }); - - // handle animations... if (hasAnimation()) { if (!jointsMapped()) { QStringList modelJointNames = _model->getJointNames(); mapJoints(modelJointNames); } + } - if (jointsMapped()) { - bool newFrame; - QVector frameDataRotations; - QVector frameDataTranslations; - getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); - assert(frameDataRotations.size() == frameDataTranslations.size()); - if (newFrame) { - for (int i = 0; i < frameDataRotations.size(); i++) { - _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f); - } + _jointDataLock.withWriteLock([&] { + getAnimationFrame(); + + // relay any inbound joint changes from scripts/animation/network to the model/rig + for (int index = 0; index < _absoluteJointRotationsInObjectFrame.size(); index++) { + if (_absoluteJointRotationsInObjectFrameDirty[index]) { + glm::quat rotation = _absoluteJointRotationsInObjectFrame[index]; + _model->setJointRotation(index, true, rotation, 1.0f); + _absoluteJointRotationsInObjectFrameDirty[index] = false; } } - } + for (int index = 0; index < _absoluteJointTranslationsInObjectFrame.size(); index++) { + if (_absoluteJointTranslationsInObjectFrameDirty[index]) { + glm::vec3 translation = _absoluteJointTranslationsInObjectFrame[index]; + _model->setJointTranslation(index, true, translation, 1.0f); + _absoluteJointTranslationsInObjectFrameDirty[index] = false; + } + } + }); bool movingOrAnimating = isMoving() || isAnimatingSomething(); if ((movingOrAnimating || @@ -639,19 +706,31 @@ glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(in } bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) { - _scriptSetFrameDataLock.withWriteLock([&] { - _scriptSetFrameDataRotationsIndexes.enqueue(index); - _scriptSetFrameDataRotations.enqueue(rotation); + bool result = false; + _jointDataLock.withWriteLock([&] { + resizeJointArrays(); + if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size()) { + _absoluteJointRotationsInObjectFrame[index] = rotation; + _absoluteJointRotationsInObjectFrameSet[index] = true; + _absoluteJointRotationsInObjectFrameDirty[index] = true; + result = true; + } }); - return true; + return result; } bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) { - _scriptSetFrameDataLock.withWriteLock([&] { - _scriptSetFrameDataTranslationsIndexes.enqueue(index); - _scriptSetFrameDataTranslations.enqueue(translation); + bool result = false; + _jointDataLock.withWriteLock([&] { + resizeJointArrays(); + if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size()) { + _absoluteJointTranslationsInObjectFrame[index] = translation; + _absoluteJointTranslationsInObjectFrameSet[index] = true; + _absoluteJointTranslationsInObjectFrameDirty[index] = true; + result = true; + } }); - return true; + return result; } void RenderableModelEntityItem::locationChanged() { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index d0847b66cb..afb26d632d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -33,15 +33,15 @@ public: virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - + virtual void somethingChangedNotification() override { // FIX ME: this is overly aggressive. We only really need to simulate() if something about // the world space transform has changed and/or if some animation is occurring. - _needsInitialSimulation = true; + _needsInitialSimulation = true; } virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr); @@ -52,12 +52,12 @@ public: virtual void render(RenderArgs* args) override; virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const override; Model* getModel(EntityTreeRenderer* renderer); - + virtual bool needsToCallUpdate() const override; virtual void update(const quint64& now) override; @@ -65,7 +65,7 @@ public: virtual bool isReadyToComputeShape() override; virtual void computeShapeInfo(ShapeInfo& info) override; - + virtual bool contains(const glm::vec3& point) const override; // these are in the frame of this object (model space) @@ -77,9 +77,11 @@ public: virtual void loader() override; virtual void locationChanged() override; + virtual void resizeJointArrays(int newSize = -1) override; + private: void remapTextures(); - + Model* _model = nullptr; bool _needsInitialSimulation = true; bool _needsModelReload = true; @@ -89,17 +91,12 @@ private: bool _originalTexturesRead = false; QVector> _points; bool _dimensionsInitialized = true; - + render::ItemID _myMetaItem; bool _showCollisionHull = false; - // these are used to let scripts set ModelEntityItem joint data - ReadWriteLockable _scriptSetFrameDataLock; - QQueue _scriptSetFrameDataRotations; - QQueue _scriptSetFrameDataRotationsIndexes; - QQueue _scriptSetFrameDataTranslations; - QQueue _scriptSetFrameDataTranslationsIndexes; + bool getAnimationFrame(); }; #endif // hifi_RenderableModelEntityItem_h diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 3a2fdf55d4..ef373bc206 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -262,6 +262,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID); CHECK_PROPERTY_CHANGE(PROP_PARENT_ID, parentID); CHECK_PROPERTY_CHANGE(PROP_PARENT_JOINT_INDEX, parentJointIndex); + CHECK_PROPERTY_CHANGE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet); + CHECK_PROPERTY_CHANGE(PROP_JOINT_ROTATIONS, jointRotations); + CHECK_PROPERTY_CHANGE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); + CHECK_PROPERTY_CHANGE(PROP_JOINT_TRANSLATIONS, jointTranslations); changedProperties += _animation.getChangedProperties(); changedProperties += _keyLight.getChangedProperties(); @@ -363,6 +367,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool if (_type == EntityTypes::Model) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL); _animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations); } if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) { @@ -739,6 +747,14 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_Y_P_NEIGHBOR_ID, YPNeighborID, yPNeighborID, EntityItemID); ADD_PROPERTY_TO_MAP(PROP_Z_P_NEIGHBOR_ID, ZPNeighborID, zPNeighborID, EntityItemID); + ADD_PROPERTY_TO_MAP(PROP_PARENT_ID, ParentID, parentID, QUuid); + ADD_PROPERTY_TO_MAP(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, uint16_t); + + ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector); + ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); + ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector); + ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector); + ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_URL, Animation, animation, URL, url); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame); @@ -943,6 +959,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem _staticAnimation.setProperties(properties); _staticAnimation.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + + APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, properties.getJointRotationsSet()); + APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, properties.getJointRotations()); + APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet()); + APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, properties.getJointTranslations()); } if (properties.getType() == EntityTypes::Light) { @@ -1228,6 +1249,11 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS_SET, QVector, setJointRotationsSet); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector, setJointRotations); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector, setJointTranslations); } if (properties.getType() == EntityTypes::Light) { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 5420e75aed..f8bdfcc0dd 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -198,6 +198,11 @@ public: DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glmVec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION); + DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector, QVector()); + DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector, QVector()); + DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector, QVector()); + DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector, QVector()); + static QString getBackgroundModeString(BackgroundMode mode); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 304e6f672c..a8aa23a5c9 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -113,6 +113,8 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const xColor& v) { retu inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::quat& v) { return quatToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QScriptValue& v) { return v; } inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) {return qVectorVec3ToScriptValue(e, v); } +inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) {return qVectorQuatToScriptValue(e, v); } +inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) {return qVectorBoolToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) { return qVectorFloatToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) { @@ -173,6 +175,8 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) typedef glm::vec3 glmVec3; typedef glm::quat glmQuat; typedef QVector qVectorVec3; +typedef QVector qVectorQuat; +typedef QVector qVectorBool; typedef QVector qVectorFloat; inline float float_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toFloat(&isValid); } inline quint64 quint64_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toULongLong(&isValid); } @@ -235,6 +239,16 @@ inline qVectorVec3 qVectorVec3_convertFromScriptValue(const QScriptValue& v, boo return qVectorVec3FromScriptValue(v); } +inline qVectorQuat qVectorQuat_convertFromScriptValue(const QScriptValue& v, bool& isValid) { + isValid = true; + return qVectorQuatFromScriptValue(v); +} + +inline qVectorBool qVectorBool_convertFromScriptValue(const QScriptValue& v, bool& isValid) { + isValid = true; + return qVectorBoolFromScriptValue(v); +} + inline glmQuat glmQuat_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = false; /// assume it can't be converted QScriptValue x = v.property("x"); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 2ba86a491e..5e38e8bd7c 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -157,6 +157,12 @@ enum EntityPropertyList { PROP_LOCAL_POSITION, // only used to convert values to and from scripts PROP_LOCAL_ROTATION, // only used to convert values to and from scripts + // ModelEntity joint state + PROP_JOINT_ROTATIONS_SET, + PROP_JOINT_ROTATIONS, + PROP_JOINT_TRANSLATIONS_SET, + PROP_JOINT_TRANSLATIONS, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index a1f16ee251..4f8ba1cc6c 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -133,6 +133,11 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, somethingChanged = true; } + READ_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, QVector, setJointRotationsSet); + READ_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, QVector, setJointRotations); + READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); + READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, QVector, setJointTranslations); + return bytesRead; } @@ -145,6 +150,10 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& requestedProperties += PROP_TEXTURES; requestedProperties += PROP_SHAPE_TYPE; requestedProperties += _animationProperties.getEntityProperties(params); + requestedProperties += PROP_JOINT_ROTATIONS_SET; + requestedProperties += PROP_JOINT_ROTATIONS; + requestedProperties += PROP_JOINT_TRANSLATIONS_SET; + requestedProperties += PROP_JOINT_TRANSLATIONS; return requestedProperties; } @@ -168,6 +177,11 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit propertyFlags, propertiesDidntFit, propertyCount, appendState); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); + + APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, getJointRotationsSet()); + APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, getJointRotations()); + APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, getJointTranslationsSet()); + APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, getJointTranslations()); } @@ -214,62 +228,6 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { } } -void ModelEntityItem::getAnimationFrame(bool& newFrame, - QVector& rotationsResult, QVector& translationsResult) { - newFrame = false; - - if (!hasAnimation() || !_jointMappingCompleted) { - rotationsResult = _lastKnownFrameDataRotations; - translationsResult = _lastKnownFrameDataTranslations; - } - AnimationPointer myAnimation = getAnimation(_animationProperties.getURL()); // FIXME: this could be optimized - if (myAnimation && myAnimation->isLoaded()) { - - const QVector& frames = myAnimation->getFramesReference(); // NOTE: getFrames() is too heavy - auto& fbxJoints = myAnimation->getGeometry().joints; - - int frameCount = frames.size(); - if (frameCount > 0) { - int animationCurrentFrame = (int)(glm::floor(getAnimationCurrentFrame())) % frameCount; - if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) { - animationCurrentFrame = 0; - } - - if (animationCurrentFrame != _lastKnownCurrentFrame) { - _lastKnownCurrentFrame = animationCurrentFrame; - newFrame = true; - - const QVector& rotations = frames[animationCurrentFrame].rotations; - const QVector& translations = frames[animationCurrentFrame].translations; - - _lastKnownFrameDataRotations.resize(_jointMapping.size()); - _lastKnownFrameDataTranslations.resize(_jointMapping.size()); - - for (int j = 0; j < _jointMapping.size(); j++) { - int index = _jointMapping[j]; - if (index >= 0) { - glm::mat4 translationMat; - if (index < translations.size()) { - translationMat = glm::translate(translations[index]); - } - glm::mat4 rotationMat; - if (index < rotations.size()) { - rotationMat = glm::mat4_cast(rotations[index]); - } - glm::mat4 finalMat = (translationMat * fbxJoints[index].preTransform * - rotationMat * fbxJoints[index].postTransform); - _lastKnownFrameDataTranslations[j] = extractTranslation(finalMat); - _lastKnownFrameDataRotations[j] = glmExtractRotation(finalMat); - } - } - } - } - } - - rotationsResult = _lastKnownFrameDataRotations; - translationsResult = _lastKnownFrameDataTranslations; -} - bool ModelEntityItem::isAnimatingSomething() const { return getAnimationIsPlaying() && getAnimationFPS() != 0.0f && @@ -412,3 +370,88 @@ void ModelEntityItem::setAnimationFPS(float value) { bool ModelEntityItem::shouldBePhysical() const { return getShapeType() != SHAPE_TYPE_NONE; } + +void ModelEntityItem::resizeJointArrays(int newSize) { + if (newSize >= 0 && newSize > _absoluteJointRotationsInObjectFrame.size()) { + _absoluteJointRotationsInObjectFrame.resize(newSize); + _absoluteJointRotationsInObjectFrameSet.resize(newSize); + _absoluteJointRotationsInObjectFrameDirty.resize(newSize); + _absoluteJointTranslationsInObjectFrame.resize(newSize); + _absoluteJointTranslationsInObjectFrameSet.resize(newSize); + _absoluteJointTranslationsInObjectFrameDirty.resize(newSize); + } +} + +void ModelEntityItem::setJointRotations(const QVector& rotations) { + _jointDataLock.withWriteLock([&] { + resizeJointArrays(rotations.size()); + for (int index = 0; index < rotations.size(); index++) { + if (_absoluteJointRotationsInObjectFrameSet[index]) { + _absoluteJointRotationsInObjectFrame[index] = rotations[index]; + _absoluteJointRotationsInObjectFrameDirty[index] = true; + } + } + }); +} + +void ModelEntityItem::setJointRotationsSet(const QVector& rotationsSet) { + _jointDataLock.withWriteLock([&] { + resizeJointArrays(rotationsSet.size()); + for (int index = 0; index < rotationsSet.size(); index++) { + _absoluteJointRotationsInObjectFrameSet[index] = rotationsSet[index]; + } + }); +} + +void ModelEntityItem::setJointTranslations(const QVector& translations) { + _jointDataLock.withWriteLock([&] { + resizeJointArrays(translations.size()); + for (int index = 0; index < translations.size(); index++) { + if (_absoluteJointTranslationsInObjectFrameSet[index]) { + _absoluteJointTranslationsInObjectFrame[index] = translations[index]; + _absoluteJointTranslationsInObjectFrameSet[index] = true; + } + } + }); +} + +void ModelEntityItem::setJointTranslationsSet(const QVector& translationsSet) { + _jointDataLock.withWriteLock([&] { + resizeJointArrays(translationsSet.size()); + for (int index = 0; index < translationsSet.size(); index++) { + _absoluteJointTranslationsInObjectFrameSet[index] = translationsSet[index]; + } + }); +} + +QVector ModelEntityItem::getJointRotations() const { + QVector result; + _jointDataLock.withReadLock([&] { + result = _absoluteJointRotationsInObjectFrame; + }); + return result; +} + +QVector ModelEntityItem::getJointRotationsSet() const { + QVector result; + _jointDataLock.withReadLock([&] { + result = _absoluteJointRotationsInObjectFrameSet; + }); + return result; +} + +QVector ModelEntityItem::getJointTranslations() const { + QVector result; + _jointDataLock.withReadLock([&] { + result = _absoluteJointTranslationsInObjectFrame; + }); + return result; +} + +QVector ModelEntityItem::getJointTranslationsSet() const { + QVector result; + _jointDataLock.withReadLock([&] { + result = _absoluteJointTranslationsInObjectFrameSet; + }); + return result; +} diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index b08fed5970..232c5c677a 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -103,7 +103,6 @@ public: float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } void mapJoints(const QStringList& modelJointNames); - void getAnimationFrame(bool& newFrame, QVector& rotationsResult, QVector& translationsResult); bool jointsMapped() const { return _jointMappingURL == getAnimationURL() && _jointMappingCompleted; } bool getAnimationIsPlaying() const { return _animationLoop.getRunning(); } @@ -121,14 +120,34 @@ public: virtual glm::vec3 getJointPosition(int jointIndex) const { return glm::vec3(); } virtual glm::quat getJointRotation(int jointIndex) const { return glm::quat(); } + void setJointRotations(const QVector& rotations); + void setJointRotationsSet(const QVector& rotationsSet); + void setJointTranslations(const QVector& translations); + void setJointTranslationsSet(const QVector& translationsSet); + QVector getJointRotations() const; + QVector getJointRotationsSet() const; + QVector getJointTranslations() const; + QVector getJointTranslationsSet() const; + private: void setAnimationSettings(const QString& value); // only called for old bitstream format protected: - QVector _lastKnownFrameDataRotations; - QVector _lastKnownFrameDataTranslations; + // these are used: + // - to bounce joint data from an animation into the model/rig. + // - to relay changes from scripts to model/rig. + // - to relay between network and model/rig + // they aren't currently updated from data in the model/rig, and they don't have a direct effect + // on what's rendered. + ReadWriteLockable _jointDataLock; + QVector _absoluteJointRotationsInObjectFrame; + QVector _absoluteJointRotationsInObjectFrameSet; // ever set? + QVector _absoluteJointRotationsInObjectFrameDirty; // needs a relay to model/rig? + QVector _absoluteJointTranslationsInObjectFrame; + QVector _absoluteJointTranslationsInObjectFrameSet; // ever set? + QVector _absoluteJointTranslationsInObjectFrameDirty; // needs a relay to model/rig? int _lastKnownCurrentFrame; - + virtual void resizeJointArrays(int newSize = -1); bool isAnimatingSomething() const; @@ -145,7 +164,7 @@ protected: // used on client side bool _jointMappingCompleted; - QVector _jointMapping; + QVector _jointMapping; // domain is index into model-joints, range is index into animation-joints QString _jointMappingURL; static AnimationPointer getAnimation(const QString& url); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 4daf7f83b6..7a428aa0f2 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP; + return VERSION_MODEL_ENTITIES_JOINTS_ON_WIRE; case PacketType::AvatarData: case PacketType::BulkAvatarData: return 17; diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 5daa185af4..869da542e9 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -162,5 +162,6 @@ const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49; const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50; const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51; const PacketVersion VERSION_ENTITIES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52; +const PacketVersion VERSION_MODEL_ENTITIES_JOINTS_ON_WIRE = 53; #endif // hifi_PacketHeaders_h diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index f063c60fd7..d515244f64 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -392,6 +392,19 @@ bool OctreePacketData::appendValue(const QVector& value) { return success; } +bool OctreePacketData::appendValue(const QVector& value) { + uint16_t qVecSize = value.size(); + bool success = appendValue(qVecSize); + if (success) { + success = append((const unsigned char*)value.constData(), qVecSize * sizeof(glm::quat)); + if (success) { + _bytesOfValues += qVecSize * sizeof(glm::quat); + _totalBytesOfValues += qVecSize * sizeof(glm::quat); + } + } + return success; +} + bool OctreePacketData::appendValue(const QVector& value) { uint16_t qVecSize = value.size(); bool success = appendValue(qVecSize); @@ -405,6 +418,19 @@ bool OctreePacketData::appendValue(const QVector& value) { return success; } +bool OctreePacketData::appendValue(const QVector& value) { + uint16_t qVecSize = value.size(); + bool success = appendValue(qVecSize); + if (success) { + success = append((const unsigned char*)value.constData(), qVecSize * sizeof(bool)); + if (success) { + _bytesOfValues += qVecSize * sizeof(bool); + _totalBytesOfValues += qVecSize * sizeof(bool); + } + } + return success; +} + bool OctreePacketData::appendValue(const glm::quat& value) { const size_t VALUES_PER_QUAT = 4; const size_t PACKED_QUAT_SIZE = sizeof(uint16_t) * VALUES_PER_QUAT; @@ -621,6 +647,15 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto return sizeof(uint16_t) + length * sizeof(glm::vec3); } +int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVector& result) { + uint16_t length; + memcpy(&length, dataBytes, sizeof(uint16_t)); + dataBytes += sizeof(length); + result.resize(length); + memcpy(result.data(), dataBytes, length * sizeof(glm::quat)); + return sizeof(uint16_t) + length * sizeof(glm::quat); +} + int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVector& result) { uint16_t length; memcpy(&length, dataBytes, sizeof(uint16_t)); @@ -630,7 +665,16 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto return sizeof(uint16_t) + length * sizeof(float); } -int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result) { +int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVector& result) { + uint16_t length; + memcpy(&length, dataBytes, sizeof(uint16_t)); + dataBytes += sizeof(length); + result.resize(length); + memcpy(result.data(), dataBytes, length * sizeof(bool)); + return sizeof(uint16_t) + length * sizeof(bool); +} + +int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result) { uint16_t length; memcpy(&length, dataBytes, sizeof(length)); dataBytes += sizeof(length); diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 2c86d518ad..d87a456be5 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -165,19 +165,25 @@ public: /// appends a non-position vector to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const glm::vec3& value); - - //appends a QVector of vec3's to the end of the stream, may fail if new data stream is too long to fit in packet + + /// appends a QVector of vec3s to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const QVector& value); - - //appends a QVector of floats to the end of the stream, may fail if new data stream is too long to fit in packet + + /// appends a QVector of quats to the end of the stream, may fail if new data stream is too long to fit in packet + bool appendValue(const QVector& value); + + /// appends a QVector of floats to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const QVector& value); + /// appends a QVector of bools to the end of the stream, may fail if new data stream is too long to fit in packet + bool appendValue(const QVector& value); + /// appends a packed quat to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const glm::quat& value); /// appends a bool value to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(bool value); - + /// appends a string value to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const QString& string); @@ -251,7 +257,9 @@ public: static int unpackDataFromBytes(const unsigned char* dataBytes, QUuid& result); static int unpackDataFromBytes(const unsigned char* dataBytes, xColor& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); + static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); + static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result); private: diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 008ac238d5..d37cf4c73f 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -20,6 +20,8 @@ static int vec4MetaTypeId = qRegisterMetaType(); static int vec3MetaTypeId = qRegisterMetaType(); static int qVectorVec3MetaTypeId = qRegisterMetaType>(); +static int qVectorQuatMetaTypeId = qRegisterMetaType>(); +static int qVectorBoolMetaTypeId = qRegisterMetaType>(); static int vec2MetaTypeId = qRegisterMetaType(); static int quatMetaTypeId = qRegisterMetaType(); static int xColorMetaTypeId = qRegisterMetaType(); @@ -31,6 +33,8 @@ void registerMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue); qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue); qScriptRegisterMetaType(engine, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue); + qScriptRegisterMetaType(engine, qVectorQuatToScriptValue, qVectorQuatFromScriptValue); + qScriptRegisterMetaType(engine, qVectorBoolToScriptValue, qVectorBoolFromScriptValue); qScriptRegisterMetaType(engine, qVectorFloatToScriptValue, qVectorFloatFromScriptValue); qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue); qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue); @@ -87,6 +91,42 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVectornewObject(); + if (quat.x != quat.x || quat.y != quat.y || quat.z != quat.z || quat.w != quat.w) { + // if quat contains a NaN don't try to convert it + return obj; + } + obj.setProperty("x", quat.x); + obj.setProperty("y", quat.y); + obj.setProperty("z", quat.z); + obj.setProperty("w", quat.w); + return obj; +} + +void quatFromScriptValue(const QScriptValue &object, glm::quat &quat) { + quat.x = object.property("x").toVariant().toFloat(); + quat.y = object.property("y").toVariant().toFloat(); + quat.z = object.property("z").toVariant().toFloat(); + quat.w = object.property("w").toVariant().toFloat(); +} + +QScriptValue qVectorQuatToScriptValue(QScriptEngine* engine, const QVector& vector) { + QScriptValue array = engine->newArray(); + for (int i = 0; i < vector.size(); i++) { + array.setProperty(i, quatToScriptValue(engine, vector.at(i))); + } + return array; +} + +QScriptValue qVectorBoolToScriptValue(QScriptEngine* engine, const QVector& vector) { + QScriptValue array = engine->newArray(); + for (int i = 0; i < vector.size(); i++) { + array.setProperty(i, vector.at(i)); + } + return array; +} + QVector qVectorFloatFromScriptValue(const QScriptValue& array) { if(!array.isArray()) { return QVector(); @@ -149,7 +189,7 @@ QVector qVectorVec3FromScriptValue(const QScriptValue& array){ void qVectorVec3FromScriptValue(const QScriptValue& array, QVector& vector ) { int length = array.property("length").toInteger(); - + for (int i = 0; i < length; i++) { glm::vec3 newVec3 = glm::vec3(); vec3FromScriptValue(array.property(i), newVec3); @@ -157,6 +197,46 @@ void qVectorVec3FromScriptValue(const QScriptValue& array, QVector& v } } +QVector qVectorQuatFromScriptValue(const QScriptValue& array){ + QVector newVector; + int length = array.property("length").toInteger(); + + for (int i = 0; i < length; i++) { + glm::quat newQuat = glm::quat(); + quatFromScriptValue(array.property(i), newQuat); + newVector << newQuat; + } + return newVector; +} + +void qVectorQuatFromScriptValue(const QScriptValue& array, QVector& vector ) { + int length = array.property("length").toInteger(); + + for (int i = 0; i < length; i++) { + glm::quat newQuat = glm::quat(); + quatFromScriptValue(array.property(i), newQuat); + vector << newQuat; + } +} + +QVector qVectorBoolFromScriptValue(const QScriptValue& array){ + QVector newVector; + int length = array.property("length").toInteger(); + + for (int i = 0; i < length; i++) { + newVector << array.property(i).toBool(); + } + return newVector; +} + +void qVectorBoolFromScriptValue(const QScriptValue& array, QVector& vector ) { + int length = array.property("length").toInteger(); + + for (int i = 0; i < length; i++) { + vector << array.property(i).toBool(); + } +} + QScriptValue vec2toScriptValue(QScriptEngine* engine, const glm::vec2 &vec2) { QScriptValue obj = engine->newObject(); obj.setProperty("x", vec2.x); @@ -169,22 +249,6 @@ void vec2FromScriptValue(const QScriptValue &object, glm::vec2 &vec2) { vec2.y = object.property("y").toVariant().toFloat(); } -QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat) { - QScriptValue obj = engine->newObject(); - obj.setProperty("x", quat.x); - obj.setProperty("y", quat.y); - obj.setProperty("z", quat.z); - obj.setProperty("w", quat.w); - return obj; -} - -void quatFromScriptValue(const QScriptValue &object, glm::quat& quat) { - quat.x = object.property("x").toVariant().toFloat(); - quat.y = object.property("y").toVariant().toFloat(); - quat.z = object.property("z").toVariant().toFloat(); - quat.w = object.property("w").toVariant().toFloat(); -} - QScriptValue qRectToScriptValue(QScriptEngine* engine, const QRect& rect) { QScriptValue obj = engine->newObject(); obj.setProperty("x", rect.x()); diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index cd1e3b0d3e..a2941803ca 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -61,6 +61,14 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector& vector); QVector qVectorVec3FromScriptValue(const QScriptValue& array); +QScriptValue qVectorQuatToScriptValue(QScriptEngine* engine, const QVector& vector); +void qVectorQuatFromScriptValue(const QScriptValue& array, QVector& vector); +QVector qVectorQuatFromScriptValue(const QScriptValue& array); + +QScriptValue qVectorBoolToScriptValue(QScriptEngine* engine, const QVector& vector); +void qVectorBoolFromScriptValue(const QScriptValue& array, QVector& vector); +QVector qVectorBoolFromScriptValue(const QScriptValue& array); + QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector& vector); void qVectorFloatFromScriptValue(const QScriptValue& array, QVector& vector); QVector qVectorFloatFromScriptValue(const QScriptValue& array); From 175506bbf1d4739e02c7976e588cdc22f2f66608 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 23 Dec 2015 16:06:04 -0800 Subject: [PATCH 07/43] when a script sets joint-data on a model-entity, send an edit packet --- libraries/entities/src/EntityItemProperties.h | 7 ++-- .../entities/src/EntityScriptingInterface.cpp | 34 +++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index f8bdfcc0dd..9b8142d4c2 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -265,10 +265,13 @@ public: void setActionDataDirty() { _actionDataChanged = true; } QList listChangedProperties(); - + bool getDimensionsInitialized() const { return _dimensionsInitialized; } void setDimensionsInitialized(bool dimensionsInitialized) { _dimensionsInitialized = dimensionsInitialized; } - + + void setJointRotationsDirty() { _jointRotationsSetChanged = true; _jointRotationsChanged = true; } + void setJointTranslationsDirty() { _jointTranslationsSetChanged = true; _jointTranslationsChanged = true; } + private: QUuid _id; bool _idSet; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index c20db60601..9dc899e535 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -831,18 +831,40 @@ bool EntityScriptingInterface::setAbsoluteJointTranslationInObjectFrame(const QU int jointIndex, glm::vec3 translation) { if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { auto modelEntity = std::dynamic_pointer_cast(entity); - return modelEntity->setAbsoluteJointTranslationInObjectFrame(jointIndex, translation); - } else { - return false; + bool result = modelEntity->setAbsoluteJointTranslationInObjectFrame(jointIndex, translation); + if (result) { + EntityItemProperties properties; + _entityTree->withReadLock([&] { + properties = entity->getProperties(); + }); + + properties.setJointTranslationsDirty(); + auto now = usecTimestampNow(); + properties.setLastEdited(now); + queueEntityMessage(PacketType::EntityEdit, entityID, properties); + return true; + } } + return false; } bool EntityScriptingInterface::setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex, glm::quat rotation) { if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { auto modelEntity = std::dynamic_pointer_cast(entity); - return modelEntity->setAbsoluteJointRotationInObjectFrame(jointIndex, rotation); - } else { - return false; + bool result = modelEntity->setAbsoluteJointRotationInObjectFrame(jointIndex, rotation); + if (result) { + EntityItemProperties properties; + _entityTree->withReadLock([&] { + properties = entity->getProperties(); + }); + + properties.setJointRotationsDirty(); + auto now = usecTimestampNow(); + properties.setLastEdited(now); + queueEntityMessage(PacketType::EntityEdit, entityID, properties); + return true; + } } + return false; } From 3f73f83cf1322e05c1f570cfc57241660607c045 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sun, 27 Dec 2015 11:23:54 -0800 Subject: [PATCH 08/43] add doppelganger --- .../example/avatarcontrol/doppelganger.js | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 examples/example/avatarcontrol/doppelganger.js diff --git a/examples/example/avatarcontrol/doppelganger.js b/examples/example/avatarcontrol/doppelganger.js new file mode 100644 index 0000000000..6fb7026ea1 --- /dev/null +++ b/examples/example/avatarcontrol/doppelganger.js @@ -0,0 +1,84 @@ +var TEST_MODEL_URL = ''; + +var doppelgangers = []; + +function Doppelganger(avatar) { + this.initialProperties = { + name: 'Hifi-Doppelganger', + type: 'Model', + modelURL: TEST_MODEL_URL, + dimensions: getAvatarDimensions(avatar), + position: putDoppelgangerAcrossFromAvatar(this, avatar), + rotation: rotateDoppelgangerTowardAvatar(this, avatar), + }; + + this.id = createDoppelgangerEntity(this); + this.avatar = avatar; + return this; +} + +function getJointData() { + return jointData; +} + +function setJointData(doppelganger, jointData) { + return true; +} + +function mirrorJointData() { + return mirroredJointData; +} + +function createDoppelganger(avatar) { + return new Doppelganger(avatar); +} + +function createDoppelgangerEntity(doppelganger) { + return Entities.addEntitiy(doppelganger.initialProperties); +} + +function putDoppelgangerAcrossFromAvatar(doppelganger, avatar) { + return position; +} + +function getAvatarDimensions(avatar) { + return dimensions; +} + +function rotateDoppelgangerTowardAvatar(doppelganger, avatar) { + return rotation; +} + +function connectDoppelgangerUpdates() { + Script.update.connect(updateDoppelganger); +} + +function disconnectDoppelgangerUpdates() { + Script.update.disconnect(updateDoppelganger); +} + +function updateDoppelganger() { + doppelgangers.forEach(function(doppelganger) { + var joints = getJointData(doppelganger.avatar.id); + var mirroredJoints = mirrorJointData(joints); + setJointData(doppelganger, mirroredJoints); + }); + +} + +function makeDoppelgangerForMyAvatar() { + var doppelganger = createDoppelganger(MyAvatar); + doppelgangers.push(doppelganger); + connectDoppelgangerUpdates(); +} + +function cleanup() { + disconnectDoppelgangerUpdates(); + + doppelgangers.forEach(function(doppelganger) { + Entities.deleteEntity(doppelganger); + }); + +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 5e6e2bd11c60b88b69ed7f531dae857e930fee63 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 13:06:43 -0800 Subject: [PATCH 09/43] work --- .../example/avatarcontrol/doppelganger.js | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/examples/example/avatarcontrol/doppelganger.js b/examples/example/avatarcontrol/doppelganger.js index 6fb7026ea1..11b29cbb2a 100644 --- a/examples/example/avatarcontrol/doppelganger.js +++ b/examples/example/avatarcontrol/doppelganger.js @@ -1,4 +1,4 @@ -var TEST_MODEL_URL = ''; +var TEST_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/james/avatars/Jack_Skellington/Jack_Skellington.fbx'; var doppelgangers = []; @@ -7,7 +7,7 @@ function Doppelganger(avatar) { name: 'Hifi-Doppelganger', type: 'Model', modelURL: TEST_MODEL_URL, - dimensions: getAvatarDimensions(avatar), + // dimensions: getAvatarDimensions(avatar), position: putDoppelgangerAcrossFromAvatar(this, avatar), rotation: rotateDoppelgangerTowardAvatar(this, avatar), }; @@ -17,8 +17,17 @@ function Doppelganger(avatar) { return this; } -function getJointData() { - return jointData; +function getJointData(avatar) { + var allJointData; + var jointNames = MyAvatar.jointNames; + + jointNames.forEach(function(joint) { + print('getting info for joint:' + joint); + var jointData = MyAvatar.getJointPosition(joint); + print('joint data:'+JSON.stringify(jointData)); + }); + + return allJointData; } function setJointData(doppelganger, jointData) { @@ -34,11 +43,13 @@ function createDoppelganger(avatar) { } function createDoppelgangerEntity(doppelganger) { - return Entities.addEntitiy(doppelganger.initialProperties); + return Entities.addEntity(doppelganger.initialProperties); } function putDoppelgangerAcrossFromAvatar(doppelganger, avatar) { - return position; + var avatarRot = Quat.fromPitchYawRollDegrees(0, avatar.bodyYaw, 0.0); + var basePosition = Vec3.sum(avatar.position, Vec3.multiply(1.5, Quat.getFront(avatarRot))); + return basePosition; } function getAvatarDimensions(avatar) { @@ -46,7 +57,9 @@ function getAvatarDimensions(avatar) { } function rotateDoppelgangerTowardAvatar(doppelganger, avatar) { - return rotation; + var avatarRot = Quat.fromPitchYawRollDegrees(0, avatar.bodyYaw, 0.0); + avatarRot = Vec3.multiply(-1,avatarRot); + return avatarRot; } function connectDoppelgangerUpdates() { @@ -59,7 +72,7 @@ function disconnectDoppelgangerUpdates() { function updateDoppelganger() { doppelgangers.forEach(function(doppelganger) { - var joints = getJointData(doppelganger.avatar.id); + var joints = getJointData(MyAvatar); var mirroredJoints = mirrorJointData(joints); setJointData(doppelganger, mirroredJoints); }); @@ -69,9 +82,12 @@ function updateDoppelganger() { function makeDoppelgangerForMyAvatar() { var doppelganger = createDoppelganger(MyAvatar); doppelgangers.push(doppelganger); - connectDoppelgangerUpdates(); + // connectDoppelgangerUpdates(); } + +makeDoppelgangerForMyAvatar(); + function cleanup() { disconnectDoppelgangerUpdates(); @@ -81,4 +97,9 @@ function cleanup() { } -Script.scriptEnding.connect(cleanup); \ No newline at end of file +Script.scriptEnding.connect(cleanup); + +// APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, getJointRotationsSet()); +// APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, getJointRotations()); +// APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, getJointTranslationsSet()); +// APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, getJointTranslations()); \ No newline at end of file From d8ef19a01960d8b114a92cc8d1d5a667ed0e7573 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 18:32:49 -0800 Subject: [PATCH 10/43] working!! --- .../example/avatarcontrol/doppelganger.js | 60 ++++++++++++++----- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/examples/example/avatarcontrol/doppelganger.js b/examples/example/avatarcontrol/doppelganger.js index 11b29cbb2a..f8a1103772 100644 --- a/examples/example/avatarcontrol/doppelganger.js +++ b/examples/example/avatarcontrol/doppelganger.js @@ -1,3 +1,15 @@ +// +// doppelganger.js +// +// Created by James B. Pollack @imgntn on 12/28/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This script shows how to hook up a model entity to your avatar to act as a doppelganger. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + var TEST_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/james/avatars/Jack_Skellington/Jack_Skellington.fbx'; var doppelgangers = []; @@ -7,7 +19,7 @@ function Doppelganger(avatar) { name: 'Hifi-Doppelganger', type: 'Model', modelURL: TEST_MODEL_URL, - // dimensions: getAvatarDimensions(avatar), + // dimensions: getAvatarDimensions(avatar), position: putDoppelgangerAcrossFromAvatar(this, avatar), rotation: rotateDoppelgangerTowardAvatar(this, avatar), }; @@ -18,19 +30,39 @@ function Doppelganger(avatar) { } function getJointData(avatar) { - var allJointData; + var allJointData = []; var jointNames = MyAvatar.jointNames; - - jointNames.forEach(function(joint) { - print('getting info for joint:' + joint); - var jointData = MyAvatar.getJointPosition(joint); - print('joint data:'+JSON.stringify(jointData)); + jointNames.forEach(function(joint, index) { + var translation = MyAvatar.getJointTranslation(index); + var rotation = MyAvatar.getJointRotation(index) + allJointData.push({ + joint: joint, + index: index, + translation: translation, + rotation: rotation + }) }); return allJointData; } -function setJointData(doppelganger, jointData) { +function setJointData(doppelganger, allJointData) { + var jointRotationsSet = []; + var jointTranslationsSet = []; + var jointRotations = []; + var jointTranslations = []; + + allJointData.forEach(function(jointData, index) { + jointRotationsSet[index] = true; + jointTranslationsSet[index] = true; + jointRotations.push(jointData.rotation); + jointTranslations.push(jointData.translation); + + Entities.setAbsoluteJointTranslationInObjectFrame(doppelganger.id, index, jointData.translation); + Entities.setAbsoluteJointRotationInObjectFrame(doppelganger.id, index, jointData.rotation); + + }); + return true; } @@ -57,8 +89,8 @@ function getAvatarDimensions(avatar) { } function rotateDoppelgangerTowardAvatar(doppelganger, avatar) { - var avatarRot = Quat.fromPitchYawRollDegrees(0, avatar.bodyYaw, 0.0); - avatarRot = Vec3.multiply(-1,avatarRot); + var avatarRot = Quat.fromPitchYawRollDegrees(0, avatar.bodyYaw, 0.0); + avatarRot = Vec3.multiply(-1, avatarRot); return avatarRot; } @@ -73,8 +105,8 @@ function disconnectDoppelgangerUpdates() { function updateDoppelganger() { doppelgangers.forEach(function(doppelganger) { var joints = getJointData(MyAvatar); - var mirroredJoints = mirrorJointData(joints); - setJointData(doppelganger, mirroredJoints); + //var mirroredJoints = mirrorJointData(joints); + setJointData(doppelganger, joints); }); } @@ -82,10 +114,9 @@ function updateDoppelganger() { function makeDoppelgangerForMyAvatar() { var doppelganger = createDoppelganger(MyAvatar); doppelgangers.push(doppelganger); - // connectDoppelgangerUpdates(); + connectDoppelgangerUpdates(); } - makeDoppelgangerForMyAvatar(); function cleanup() { @@ -94,7 +125,6 @@ function cleanup() { doppelgangers.forEach(function(doppelganger) { Entities.deleteEntity(doppelganger); }); - } Script.scriptEnding.connect(cleanup); From bf296a36edea4f3cf4775d6974ad059634a5ade3 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 18:38:09 -0800 Subject: [PATCH 11/43] cleanup change model --- examples/example/avatarcontrol/doppelganger.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/example/avatarcontrol/doppelganger.js b/examples/example/avatarcontrol/doppelganger.js index f8a1103772..ed4079a211 100644 --- a/examples/example/avatarcontrol/doppelganger.js +++ b/examples/example/avatarcontrol/doppelganger.js @@ -9,8 +9,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// To-Do: mirror joints, rotate avatar fully, automatically get avatar fbx, make sure dimensions for avatar are right when u bring it in -var TEST_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/james/avatars/Jack_Skellington/Jack_Skellington.fbx'; +var TEST_MODEL_URL = 'https://s3.amazonaws.com/hifi-public/ozan/avatars/albert/albert/albert.fbx'; var doppelgangers = []; From a2d21ed5cbf78cb2d202673b78ac3245a684dc79 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 21:42:54 -0800 Subject: [PATCH 12/43] Update doppelganger.js delete correct id --- examples/example/avatarcontrol/doppelganger.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example/avatarcontrol/doppelganger.js b/examples/example/avatarcontrol/doppelganger.js index ed4079a211..f5878f0763 100644 --- a/examples/example/avatarcontrol/doppelganger.js +++ b/examples/example/avatarcontrol/doppelganger.js @@ -124,7 +124,7 @@ function cleanup() { disconnectDoppelgangerUpdates(); doppelgangers.forEach(function(doppelganger) { - Entities.deleteEntity(doppelganger); + Entities.deleteEntity(doppelganger.id); }); } @@ -133,4 +133,4 @@ Script.scriptEnding.connect(cleanup); // APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, getJointRotationsSet()); // APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, getJointRotations()); // APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, getJointTranslationsSet()); -// APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, getJointTranslations()); \ No newline at end of file +// APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, getJointTranslations()); From 4e312dd8f801ec3184078110ff762d2b06719f61 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Dec 2015 12:45:19 -0800 Subject: [PATCH 13/43] undo temporary hack --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c77a274692..f12e00fa1a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -299,10 +299,7 @@ bool RenderableModelEntityItem::getAnimationFrame() { _absoluteJointTranslationsInObjectFrameSet[j] = true; _absoluteJointTranslationsInObjectFrameDirty[j] = true; - // XXX Tony will fix this better in some other PR - // _absoluteJointRotationsInObjectFrame[j] = glmExtractRotation(finalMat); - _absoluteJointRotationsInObjectFrame[j] = fbxJoints[index].preRotation * rotation; - // XXX + _absoluteJointRotationsInObjectFrame[j] = glmExtractRotation(finalMat); _absoluteJointRotationsInObjectFrameSet[j] = true; _absoluteJointRotationsInObjectFrameDirty[j] = true; From 9e49fcf0a4041e74b3a12c8d0022fdc32dd86b77 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 11:29:01 -0800 Subject: [PATCH 14/43] include model-joints in debugging output --- libraries/entities/src/EntityItemProperties.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index ef373bc206..a540bc1476 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1811,6 +1811,18 @@ QList EntityItemProperties::listChangedProperties() { if (parentJointIndexChanged()) { out += "parentJointIndex"; } + if (jointRotationsSetChanged()) { + out += "jointRotationsSet"; + } + if (jointRotationsChanged()) { + out += "jointRotations"; + } + if (jointTranslationsSetChanged()) { + out += "jointTranslationsSet"; + } + if (jointTranslationsChanged()) { + out += "jointTranslations"; + } getAnimation().listChangedProperties(out); getKeyLight().listChangedProperties(out); From 768934ae11b9e0373d559f06f733a45f25b308a7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 11:29:15 -0800 Subject: [PATCH 15/43] update entity timestamps when sending joint information --- libraries/entities/src/EntityScriptingInterface.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 8df5d86ddd..10f74ef5cc 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -832,16 +832,18 @@ glm::quat EntityScriptingInterface::getAbsoluteJointRotationInObjectFrame(const bool EntityScriptingInterface::setAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex, glm::vec3 translation) { if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto now = usecTimestampNow(); auto modelEntity = std::dynamic_pointer_cast(entity); bool result = modelEntity->setAbsoluteJointTranslationInObjectFrame(jointIndex, translation); if (result) { EntityItemProperties properties; _entityTree->withReadLock([&] { properties = entity->getProperties(); + entity->setLastEdited(now); + entity->setLastBroadcast(now); }); properties.setJointTranslationsDirty(); - auto now = usecTimestampNow(); properties.setLastEdited(now); queueEntityMessage(PacketType::EntityEdit, entityID, properties); return true; @@ -853,16 +855,18 @@ bool EntityScriptingInterface::setAbsoluteJointTranslationInObjectFrame(const QU bool EntityScriptingInterface::setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex, glm::quat rotation) { if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto now = usecTimestampNow(); auto modelEntity = std::dynamic_pointer_cast(entity); bool result = modelEntity->setAbsoluteJointRotationInObjectFrame(jointIndex, rotation); if (result) { EntityItemProperties properties; _entityTree->withReadLock([&] { properties = entity->getProperties(); + entity->setLastEdited(now); + entity->setLastBroadcast(now); }); properties.setJointRotationsDirty(); - auto now = usecTimestampNow(); properties.setLastEdited(now); queueEntityMessage(PacketType::EntityEdit, entityID, properties); return true; From ef7438958bcfb9d7832d07599186369782b5fdf6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 12:30:55 -0800 Subject: [PATCH 16/43] better debugging prints for model joints --- libraries/entities/src/EntityTree.cpp | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index f0a03623c2..51c53a4e93 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -757,6 +757,35 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList= 0) { + auto value = properties.getJointRotationsSet().size(); + changedProperties[index] = QString("jointRotationsSet:") + QString::number((int)value); + } + } + if (properties.jointRotationsChanged()) { + int index = changedProperties.indexOf("jointRotations"); + if (index >= 0) { + auto value = properties.getJointRotations().size(); + changedProperties[index] = QString("jointRotations:") + QString::number((int)value); + } + } + if (properties.jointTranslationsSetChanged()) { + int index = changedProperties.indexOf("jointTranslationsSet"); + if (index >= 0) { + auto value = properties.getJointTranslationsSet().size(); + changedProperties[index] = QString("jointTranslationsSet:") + QString::number((int)value); + } + } + if (properties.jointTranslationsChanged()) { + int index = changedProperties.indexOf("jointTranslations"); + if (index >= 0) { + auto value = properties.getJointTranslations().size(); + changedProperties[index] = QString("jointTranslations:") + QString::number((int)value); + } + } } int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, From c9ed36f9a6513d204687761f376ce991dad3a57a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 12:31:45 -0800 Subject: [PATCH 17/43] include joint data in script properties --- libraries/entities/src/ModelEntityItem.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 4f8ba1cc6c..709cd67ef5 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -50,6 +50,11 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP COPY_ENTITY_PROPERTY_TO_PROPERTIES(glowLevel, getGlowLevel); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotationsSet, getJointRotationsSet); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotations, getJointRotations); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslations, getJointTranslations); + _animationProperties.getProperties(properties); return properties; } @@ -63,6 +68,10 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotationsSet, setJointRotationsSet); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotations, setJointRotations); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslations, setJointTranslations); bool somethingChangedInAnimations = _animationProperties.setProperties(properties); From 2147b0d78ee68cbfee7829cecf3d5de412f83779 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 12:31:58 -0800 Subject: [PATCH 18/43] fix locking --- libraries/entities/src/EntityScriptingInterface.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 10f74ef5cc..4904d7ae51 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -837,9 +837,8 @@ bool EntityScriptingInterface::setAbsoluteJointTranslationInObjectFrame(const QU bool result = modelEntity->setAbsoluteJointTranslationInObjectFrame(jointIndex, translation); if (result) { EntityItemProperties properties; - _entityTree->withReadLock([&] { + _entityTree->withWriteLock([&] { properties = entity->getProperties(); - entity->setLastEdited(now); entity->setLastBroadcast(now); }); @@ -860,9 +859,8 @@ bool EntityScriptingInterface::setAbsoluteJointRotationInObjectFrame(const QUuid bool result = modelEntity->setAbsoluteJointRotationInObjectFrame(jointIndex, rotation); if (result) { EntityItemProperties properties; - _entityTree->withReadLock([&] { + _entityTree->withWriteLock([&] { properties = entity->getProperties(); - entity->setLastEdited(now); entity->setLastBroadcast(now); }); From 7f2e0cd1032eb5638f43399af13933c4c5b7e1c7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 14:13:08 -0800 Subject: [PATCH 19/43] expose a way to set translation and rotation of all model joints at once --- .../src/RenderableModelEntityItem.cpp | 10 +++--- .../src/RenderableModelEntityItem.h | 4 +-- libraries/entities/src/EntityItem.h | 4 +-- .../entities/src/EntityScriptingInterface.cpp | 31 +++++++++++++++++++ .../entities/src/EntityScriptingInterface.h | 3 ++ libraries/shared/src/SpatiallyNestable.h | 4 +-- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 45350893fb..a5dbdb463c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -709,11 +709,12 @@ glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(in return glm::vec3(0.0f); } -bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) { +bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { bool result = false; _jointDataLock.withWriteLock([&] { resizeJointArrays(); - if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size()) { + if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size() && + _absoluteJointRotationsInObjectFrame[index] != rotation) { _absoluteJointRotationsInObjectFrame[index] = rotation; _absoluteJointRotationsInObjectFrameSet[index] = true; _absoluteJointRotationsInObjectFrameDirty[index] = true; @@ -723,11 +724,12 @@ bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, return result; } -bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) { +bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) { bool result = false; _jointDataLock.withWriteLock([&] { resizeJointArrays(); - if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size()) { + if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size() && + _absoluteJointTranslationsInObjectFrame[index] != translation) { _absoluteJointTranslationsInObjectFrame[index] = translation; _absoluteJointTranslationsInObjectFrameSet[index] = true; _absoluteJointTranslationsInObjectFrameDirty[index] = true; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index afb26d632d..eb7958ed47 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -71,8 +71,8 @@ public: // these are in the frame of this object (model space) virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; - virtual bool setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) override; - virtual bool setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) override; + virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override; + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override; virtual void loader() override; virtual void locationChanged() override; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 841f68ddc1..00780501fa 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -381,8 +381,8 @@ public: // these are in the frame of this object virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override { return glm::quat(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override { return glm::vec3(0.0f); } - virtual bool setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) override { return false; } - virtual bool setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) override { return false; } + virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } virtual void loader() {} // called indirectly when urls for geometry are updated diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 4904d7ae51..ac5a9b754c 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -872,3 +872,34 @@ bool EntityScriptingInterface::setAbsoluteJointRotationInObjectFrame(const QUuid } return false; } + + +bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& entityID, + const QVector& rotations, + const QVector& translations) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto now = usecTimestampNow(); + auto modelEntity = std::dynamic_pointer_cast(entity); + + int count = glm::max(rotations.size(), translations.size()); + bool result = false; + for (int index = 0; index < count; index++) { + result |= modelEntity->setAbsoluteJointRotationInObjectFrame(index, rotations[index]); + result |= modelEntity->setAbsoluteJointTranslationInObjectFrame(index, translations[index]); + } + if (result) { + EntityItemProperties properties; + _entityTree->withWriteLock([&] { + properties = entity->getProperties(); + entity->setLastBroadcast(now); + }); + + properties.setJointRotationsDirty(); + properties.setJointTranslationsDirty(); + properties.setLastEdited(now); + queueEntityMessage(PacketType::EntityEdit, entityID, properties); + return true; + } + } + return false; +} diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 4adbedc5bd..f0751d74b6 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -153,6 +153,9 @@ public slots: Q_INVOKABLE glm::quat getAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex); Q_INVOKABLE bool setAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex, glm::vec3 translation); Q_INVOKABLE bool setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex, glm::quat rotation); + Q_INVOKABLE bool setAbsoluteJointsDataInObjectFrame(const QUuid& entityID, + const QVector& rotations, + const QVector& translations); signals: void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index f6a9678d34..a858fa2e97 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -91,8 +91,8 @@ public: virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const; virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { assert(false); return glm::quat(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { assert(false); return glm::vec3(); } - virtual bool setAbsoluteJointRotationInObjectFrame(int index, glm::quat& rotation) { assert(false); return false; } - virtual bool setAbsoluteJointTranslationInObjectFrame(int index, glm::vec3& translation) { assert(false); return false; } + virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { assert(false); return false; } + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) { assert(false); return false; } SpatiallyNestablePointer getThisPointer() const; From 9a979f4abfb618e7b531a2d915bfe89c7359e965 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 14:18:24 -0800 Subject: [PATCH 20/43] update doppelganger script --- .../example/avatarcontrol/doppelganger.js | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/examples/example/avatarcontrol/doppelganger.js b/examples/example/avatarcontrol/doppelganger.js index f5878f0763..f918dd85e9 100644 --- a/examples/example/avatarcontrol/doppelganger.js +++ b/examples/example/avatarcontrol/doppelganger.js @@ -48,20 +48,9 @@ function getJointData(avatar) { } function setJointData(doppelganger, allJointData) { - var jointRotationsSet = []; - var jointTranslationsSet = []; - var jointRotations = []; - var jointTranslations = []; - allJointData.forEach(function(jointData, index) { - jointRotationsSet[index] = true; - jointTranslationsSet[index] = true; - jointRotations.push(jointData.rotation); - jointTranslations.push(jointData.translation); - Entities.setAbsoluteJointTranslationInObjectFrame(doppelganger.id, index, jointData.translation); Entities.setAbsoluteJointRotationInObjectFrame(doppelganger.id, index, jointData.rotation); - }); return true; @@ -96,7 +85,8 @@ function rotateDoppelgangerTowardAvatar(doppelganger, avatar) { } function connectDoppelgangerUpdates() { - Script.update.connect(updateDoppelganger); + // Script.update.connect(updateDoppelganger); + Script.setInterval(updateDoppelganger, 500); } function disconnectDoppelgangerUpdates() { @@ -109,7 +99,6 @@ function updateDoppelganger() { //var mirroredJoints = mirrorJointData(joints); setJointData(doppelganger, joints); }); - } function makeDoppelgangerForMyAvatar() { @@ -129,8 +118,3 @@ function cleanup() { } Script.scriptEnding.connect(cleanup); - -// APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, getJointRotationsSet()); -// APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, getJointRotations()); -// APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, getJointTranslationsSet()); -// APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, getJointTranslations()); From 6c8eb90ee03cafc9596ec34fcfda07ad71f76507 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 14:42:37 -0800 Subject: [PATCH 21/43] debugging --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 8 ++++---- libraries/entities/src/EntityScriptingInterface.cpp | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a5dbdb463c..5e0682bd93 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -713,8 +713,8 @@ bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, bool result = false; _jointDataLock.withWriteLock([&] { resizeJointArrays(); - if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size() && - _absoluteJointRotationsInObjectFrame[index] != rotation) { + if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size() /* && + _absoluteJointRotationsInObjectFrame[index] != rotation*/) { _absoluteJointRotationsInObjectFrame[index] = rotation; _absoluteJointRotationsInObjectFrameSet[index] = true; _absoluteJointRotationsInObjectFrameDirty[index] = true; @@ -728,8 +728,8 @@ bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int ind bool result = false; _jointDataLock.withWriteLock([&] { resizeJointArrays(); - if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size() && - _absoluteJointTranslationsInObjectFrame[index] != translation) { + if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size() /* && + _absoluteJointTranslationsInObjectFrame[index] != translation*/) { _absoluteJointTranslationsInObjectFrame[index] = translation; _absoluteJointTranslationsInObjectFrameSet[index] = true; _absoluteJointTranslationsInObjectFrameDirty[index] = true; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index ac5a9b754c..f759afe288 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -891,6 +891,7 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e EntityItemProperties properties; _entityTree->withWriteLock([&] { properties = entity->getProperties(); + entity->setLastEdited(now); entity->setLastBroadcast(now); }); From 9a708f2e7421127464d056395a8a34f4310e8cb8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 14:48:49 -0800 Subject: [PATCH 22/43] try splitting edit into 2 packets --- .../entities/src/EntityScriptingInterface.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f759afe288..94c68bfe78 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -885,7 +885,6 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e bool result = false; for (int index = 0; index < count; index++) { result |= modelEntity->setAbsoluteJointRotationInObjectFrame(index, rotations[index]); - result |= modelEntity->setAbsoluteJointTranslationInObjectFrame(index, translations[index]); } if (result) { EntityItemProperties properties; @@ -896,6 +895,23 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e }); properties.setJointRotationsDirty(); + properties.setLastEdited(now); + queueEntityMessage(PacketType::EntityEdit, entityID, properties); + return true; + } + + result = false; + for (int index = 0; index < count; index++) { + result |= modelEntity->setAbsoluteJointTranslationInObjectFrame(index, translations[index]); + } + if (result) { + EntityItemProperties properties; + _entityTree->withWriteLock([&] { + properties = entity->getProperties(); + entity->setLastEdited(now); + entity->setLastBroadcast(now); + }); + properties.setJointTranslationsDirty(); properties.setLastEdited(now); queueEntityMessage(PacketType::EntityEdit, entityID, properties); From cd92a9fa1ad1c00620a76123f49b3c5201ac22d1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 14:51:43 -0800 Subject: [PATCH 23/43] adjust timestamps --- libraries/entities/src/EntityScriptingInterface.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 94c68bfe78..7837e1c59d 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -895,7 +895,7 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e }); properties.setJointRotationsDirty(); - properties.setLastEdited(now); + // properties.setLastEdited(now); queueEntityMessage(PacketType::EntityEdit, entityID, properties); return true; } @@ -904,11 +904,12 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e for (int index = 0; index < count; index++) { result |= modelEntity->setAbsoluteJointTranslationInObjectFrame(index, translations[index]); } + now = usecTimestampNow(); if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { properties = entity->getProperties(); - entity->setLastEdited(now); + // entity->setLastEdited(now); entity->setLastBroadcast(now); }); From ef8673610fdddaa28dda7de75a1f4a23db648c04 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 14:58:13 -0800 Subject: [PATCH 24/43] debugging --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 8 ++++---- libraries/entities/src/EntityScriptingInterface.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 5e0682bd93..a5dbdb463c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -713,8 +713,8 @@ bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, bool result = false; _jointDataLock.withWriteLock([&] { resizeJointArrays(); - if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size() /* && - _absoluteJointRotationsInObjectFrame[index] != rotation*/) { + if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size() && + _absoluteJointRotationsInObjectFrame[index] != rotation) { _absoluteJointRotationsInObjectFrame[index] = rotation; _absoluteJointRotationsInObjectFrameSet[index] = true; _absoluteJointRotationsInObjectFrameDirty[index] = true; @@ -728,8 +728,8 @@ bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int ind bool result = false; _jointDataLock.withWriteLock([&] { resizeJointArrays(); - if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size() /* && - _absoluteJointTranslationsInObjectFrame[index] != translation*/) { + if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size() && + _absoluteJointTranslationsInObjectFrame[index] != translation) { _absoluteJointTranslationsInObjectFrame[index] = translation; _absoluteJointTranslationsInObjectFrameSet[index] = true; _absoluteJointTranslationsInObjectFrameDirty[index] = true; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 7837e1c59d..26e0eb3ff5 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -908,10 +908,10 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { - properties = entity->getProperties(); - // entity->setLastEdited(now); - entity->setLastBroadcast(now); - }); + properties = entity->getProperties(); + entity->setLastEdited(now); + entity->setLastBroadcast(now); + }); properties.setJointTranslationsDirty(); properties.setLastEdited(now); From bd35532c5dcd8fb201c2433c8782272d574ddb6d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 15:02:45 -0800 Subject: [PATCH 25/43] debugging --- libraries/entities/src/EntityScriptingInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 26e0eb3ff5..5a82460634 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -890,7 +890,7 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e EntityItemProperties properties; _entityTree->withWriteLock([&] { properties = entity->getProperties(); - entity->setLastEdited(now); + // entity->setLastEdited(now); entity->setLastBroadcast(now); }); @@ -909,7 +909,7 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e EntityItemProperties properties; _entityTree->withWriteLock([&] { properties = entity->getProperties(); - entity->setLastEdited(now); + // entity->setLastEdited(now); entity->setLastBroadcast(now); }); From 5beba58e5f6a39f98c7cb17d364cd2da3441f8bf Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 15:05:08 -0800 Subject: [PATCH 26/43] debugging --- libraries/entities/src/EntityScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 5a82460634..4f4b801ac1 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -895,7 +895,7 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e }); properties.setJointRotationsDirty(); - // properties.setLastEdited(now); + properties.setLastEdited(now); queueEntityMessage(PacketType::EntityEdit, entityID, properties); return true; } From 9304477233369fb88a11b0061b8b41cfaf7b1021 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 15:29:06 -0800 Subject: [PATCH 27/43] split out calls for rotation and translation --- .../example/avatarcontrol/doppelganger.js | 7 ++-- .../entities/src/EntityScriptingInterface.cpp | 35 +++++++++++++------ .../entities/src/EntityScriptingInterface.h | 4 +++ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/examples/example/avatarcontrol/doppelganger.js b/examples/example/avatarcontrol/doppelganger.js index f918dd85e9..ffd24f09b2 100644 --- a/examples/example/avatarcontrol/doppelganger.js +++ b/examples/example/avatarcontrol/doppelganger.js @@ -48,10 +48,11 @@ function getJointData(avatar) { } function setJointData(doppelganger, allJointData) { + var jointRotations = []; allJointData.forEach(function(jointData, index) { - Entities.setAbsoluteJointTranslationInObjectFrame(doppelganger.id, index, jointData.translation); - Entities.setAbsoluteJointRotationInObjectFrame(doppelganger.id, index, jointData.rotation); + jointRotations.push(jointData.rotation); }); + Entities.setAbsoluteJointRotationsInObjectFrame(doppelganger.id, jointRotations); return true; } @@ -86,7 +87,7 @@ function rotateDoppelgangerTowardAvatar(doppelganger, avatar) { function connectDoppelgangerUpdates() { // Script.update.connect(updateDoppelganger); - Script.setInterval(updateDoppelganger, 500); + Script.setInterval(updateDoppelganger, 100); } function disconnectDoppelgangerUpdates() { diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 4f4b801ac1..4f10139372 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -874,23 +874,21 @@ bool EntityScriptingInterface::setAbsoluteJointRotationInObjectFrame(const QUuid } -bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& entityID, - const QVector& rotations, - const QVector& translations) { + +bool EntityScriptingInterface::setAbsoluteJointRotationsInObjectFrame(const QUuid& entityID, + const QVector& rotations) { if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { auto now = usecTimestampNow(); auto modelEntity = std::dynamic_pointer_cast(entity); - int count = glm::max(rotations.size(), translations.size()); bool result = false; - for (int index = 0; index < count; index++) { + for (int index = 0; index < rotations.size(); index++) { result |= modelEntity->setAbsoluteJointRotationInObjectFrame(index, rotations[index]); } if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { properties = entity->getProperties(); - // entity->setLastEdited(now); entity->setLastBroadcast(now); }); @@ -899,17 +897,25 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e queueEntityMessage(PacketType::EntityEdit, entityID, properties); return true; } + } + return false; +} - result = false; - for (int index = 0; index < count; index++) { + +bool EntityScriptingInterface::setAbsoluteJointTranslationsInObjectFrame(const QUuid& entityID, + const QVector& translations) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto now = usecTimestampNow(); + auto modelEntity = std::dynamic_pointer_cast(entity); + + bool result = false; + for (int index = 0; index < translations.size(); index++) { result |= modelEntity->setAbsoluteJointTranslationInObjectFrame(index, translations[index]); } - now = usecTimestampNow(); if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { properties = entity->getProperties(); - // entity->setLastEdited(now); entity->setLastBroadcast(now); }); @@ -921,3 +927,12 @@ bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& e } return false; } + + +bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& entityID, + const QVector& rotations, + const QVector& translations) { + // for a model with 80 joints, sending both these in one edit packet causes the packet to be too large. + return setAbsoluteJointRotationsInObjectFrame(entityID, rotations) || + setAbsoluteJointTranslationsInObjectFrame(entityID, translations); +} diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index f0751d74b6..5c22d7f6b8 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -153,6 +153,10 @@ public slots: Q_INVOKABLE glm::quat getAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex); Q_INVOKABLE bool setAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex, glm::vec3 translation); Q_INVOKABLE bool setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex, glm::quat rotation); + Q_INVOKABLE bool setAbsoluteJointRotationsInObjectFrame(const QUuid& entityID, + const QVector& rotations); + Q_INVOKABLE bool setAbsoluteJointTranslationsInObjectFrame(const QUuid& entityID, + const QVector& translations); Q_INVOKABLE bool setAbsoluteJointsDataInObjectFrame(const QUuid& entityID, const QVector& rotations, const QVector& translations); From ccf29e37725a811f9fb105651b3be6bbcc858bcd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 15:52:58 -0800 Subject: [PATCH 28/43] debugging --- libraries/entities/src/EntityScriptingInterface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 4f10139372..ba47a84311 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -888,8 +888,9 @@ bool EntityScriptingInterface::setAbsoluteJointRotationsInObjectFrame(const QUui if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { - properties = entity->getProperties(); + entity->setLastEdited(now); entity->setLastBroadcast(now); + properties = entity->getProperties(); }); properties.setJointRotationsDirty(); @@ -915,8 +916,9 @@ bool EntityScriptingInterface::setAbsoluteJointTranslationsInObjectFrame(const Q if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { - properties = entity->getProperties(); + entity->setLastEdited(now); entity->setLastBroadcast(now); + properties = entity->getProperties(); }); properties.setJointTranslationsDirty(); From 202a6ae29437d9d331bacd186d0fe170595b1e65 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 15:56:08 -0800 Subject: [PATCH 29/43] debugging --- libraries/entities/src/EntityScriptingInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index ba47a84311..0000e7f85f 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -888,7 +888,7 @@ bool EntityScriptingInterface::setAbsoluteJointRotationsInObjectFrame(const QUui if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { - entity->setLastEdited(now); + // entity->setLastEdited(now); entity->setLastBroadcast(now); properties = entity->getProperties(); }); @@ -916,7 +916,7 @@ bool EntityScriptingInterface::setAbsoluteJointTranslationsInObjectFrame(const Q if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { - entity->setLastEdited(now); + // entity->setLastEdited(now); entity->setLastBroadcast(now); properties = entity->getProperties(); }); From 3026415f0333fb16fb5f6f8e80a5ebe7143f8886 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 16:17:00 -0800 Subject: [PATCH 30/43] add some missing property handling boilerplate --- libraries/entities/src/EntityItemProperties.cpp | 15 +++++++++++++++ .../entities/src/EntityScriptingInterface.cpp | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index a540bc1476..fadf0200f2 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -485,6 +485,11 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations); + // FIXME - I don't think these properties are supported any more //COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel); //COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha); @@ -613,6 +618,11 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(localPosition, glmVec3, setLocalPosition); COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation); + COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet); + COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations); + COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslationsSet, qVectorBool, setJointTranslationsSet); + COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslations, qVectorVec3, setJointTranslations); + _lastEdited = usecTimestampNow(); } @@ -1486,6 +1496,11 @@ void EntityItemProperties::markAllChanged() { _parentIDChanged = true; _parentJointIndexChanged = true; + + _jointRotationsSetChanged = true; + _jointRotationsChanged = true; + _jointTranslationsSetChanged = true; + _jointTranslationsChanged = true; } /// The maximum bounding cube for the entity, independent of it's rotation. diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 0000e7f85f..ba47a84311 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -888,7 +888,7 @@ bool EntityScriptingInterface::setAbsoluteJointRotationsInObjectFrame(const QUui if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { - // entity->setLastEdited(now); + entity->setLastEdited(now); entity->setLastBroadcast(now); properties = entity->getProperties(); }); @@ -916,7 +916,7 @@ bool EntityScriptingInterface::setAbsoluteJointTranslationsInObjectFrame(const Q if (result) { EntityItemProperties properties; _entityTree->withWriteLock([&] { - // entity->setLastEdited(now); + entity->setLastEdited(now); entity->setLastBroadcast(now); properties = entity->getProperties(); }); From 69839b4b16462e401eca672a84a04a89fe725f73 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 17:50:25 -0800 Subject: [PATCH 31/43] better packing of qvector of quats --- libraries/octree/src/OctreePacketData.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index d515244f64..909e0889c3 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -395,13 +395,17 @@ bool OctreePacketData::appendValue(const QVector& value) { bool OctreePacketData::appendValue(const QVector& value) { uint16_t qVecSize = value.size(); bool success = appendValue(qVecSize); + if (success) { - success = append((const unsigned char*)value.constData(), qVecSize * sizeof(glm::quat)); - if (success) { - _bytesOfValues += qVecSize * sizeof(glm::quat); - _totalBytesOfValues += qVecSize * sizeof(glm::quat); + QByteArray dataByteArray(udt::MAX_PACKET_SIZE, 0); + unsigned char* start = reinterpret_cast(dataByteArray.data()); + unsigned char* destinationBuffer = start; + for (int index = 0; index < value.size(); index++) { + destinationBuffer += packOrientationQuatToBytes(destinationBuffer, value[index]); } + success = append(start, destinationBuffer - start); } + return success; } @@ -649,11 +653,16 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVector& result) { uint16_t length; + const unsigned char *start = dataBytes; memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); result.resize(length); - memcpy(result.data(), dataBytes, length * sizeof(glm::quat)); - return sizeof(uint16_t) + length * sizeof(glm::quat); + + for (int i = 0; i < length; i++) { + dataBytes += unpackOrientationQuatFromBytes(dataBytes, result[i]); + } + + return dataBytes - start; } int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVector& result) { From 0b9f92e50f99f2e51e2879f728dc358766ca8d4e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 18:01:48 -0800 Subject: [PATCH 32/43] fix quat (un)packing --- libraries/octree/src/OctreePacketData.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 909e0889c3..87a2b9ccae 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -403,7 +403,12 @@ bool OctreePacketData::appendValue(const QVector& value) { for (int index = 0; index < value.size(); index++) { destinationBuffer += packOrientationQuatToBytes(destinationBuffer, value[index]); } - success = append(start, destinationBuffer - start); + int quatsSize = destinationBuffer - start; + success = append(start, quatsSize); + if (success) { + _bytesOfValues += quatsSize; + _totalBytesOfValues += quatsSize; + } } return success; @@ -653,16 +658,16 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVector& result) { uint16_t length; - const unsigned char *start = dataBytes; memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); result.resize(length); + const unsigned char *start = dataBytes; for (int i = 0; i < length; i++) { dataBytes += unpackOrientationQuatFromBytes(dataBytes, result[i]); } - return dataBytes - start; + return (dataBytes - start) + sizeof(uint16_t); } int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVector& result) { From a265ffb6311da8b3d0a8eab5d256ddb4b97db529 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 5 Jan 2016 15:13:22 +1300 Subject: [PATCH 33/43] Get rid of a couple of if statements and duplicate calls Courtesy of Clement --- .../src/textured_particle.slv | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/libraries/entities-renderer/src/textured_particle.slv b/libraries/entities-renderer/src/textured_particle.slv index 2f913e5527..5c47fdd1e9 100644 --- a/libraries/entities-renderer/src/textured_particle.slv +++ b/libraries/entities-renderer/src/textured_particle.slv @@ -64,14 +64,11 @@ float interpolate3Points(float y1, float y2, float y3, float u) { return y2; } + float slope; if ((y2 >= y1 && y2 >= y3) || (y2 <= y1 && y2 <= y3)) { // U or inverted-U shape. // Make the slope at y2 = 0, which means that the control points half way between the value points have the value y2. - if (u <= 0.5f) { - return bezierInterpolate(y1, y2, y2, 2.0f * u); - } else { - return bezierInterpolate(y2, y2, y3, 2.0f * u - 1.0f); - } + slope = 0.0f; } else { // L or inverted and/or mirrored L shape. @@ -79,20 +76,22 @@ float interpolate3Points(float y1, float y2, float y3, float u) { // and y2, and y2 and y3. Use this slope to calculate the control points half way between the value points. // Note: The maximum ensures that the control points and therefore the interpolated values stay between y1 and y3. float slope = y3 - y1; - float slope12 = y2 - y1; - float slope23 = y3 - y2; - if (abs(slope) > abs(2.0f * slope12)) { - slope = 2.0f * slope12; - } else if (abs(slope) > abs(2.0f * slope23)) { - slope = 2.0f * slope23; - } - - if (u <= 0.5f) { - return bezierInterpolate(y1, y2 - slope / 2.0f, y2, 2.0f * u); - } else { - return bezierInterpolate(y2, y2 + slope / 2.0f, y3, 2.0f * u - 1.0f); + float doubleSlope12 = 2.0f * (y2 - y1); + float doubleSlope23 = 2.0f * (y3 - y2); + if (abs(slope) > abs(doubleSlope12)) { + slope = doubleSlope12; + } else if (abs(slope) > abs(doubleSlope23)) { + slope = doubleSlope23; } } + + float stepU = step(0.5f, u); // 0.0 if u < 0.5, 1.0 otherwise. + float slopeSign = 2.0f * stepU - 1.0f; // -1.0 if u < 0.5, 1.0 otherwise + float start = (1.0f - stepU) * y1 + stepU * y2; // y1 if u < 0.5, y2 otherwise + float middle = y2 + slopeSign * slope / 2.0f; + float finish = (1.0f - stepU) * y2 + stepU * y3; // y2 if u < 0.5, y3 otherwise + float v = 2.0f * u - step(0.5f, u); // 0.0-0.5 -> 0.0-1.0 and 0.5-1.0 -> 0.0-1.0 + return bezierInterpolate(start, middle, finish, v); } vec4 interpolate3Vec4(vec4 y1, vec4 y2, vec4 y3, float u) { From 2d246a840f7207ddaaaafda5e1e8024108a4592b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 18:14:29 -0800 Subject: [PATCH 34/43] better packing for qvector of bools --- libraries/octree/src/OctreePacketData.cpp | 37 ++++++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 87a2b9ccae..a3fa99c5b9 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -14,6 +14,7 @@ #include "OctreeLogging.h" #include "OctreePacketData.h" +#include "NumericalConstants.h" bool OctreePacketData::_debug = false; AtomicUIntStat OctreePacketData::_totalBytesOfOctalCodes { 0 }; @@ -430,11 +431,26 @@ bool OctreePacketData::appendValue(const QVector& value) { bool OctreePacketData::appendValue(const QVector& value) { uint16_t qVecSize = value.size(); bool success = appendValue(qVecSize); + if (success) { - success = append((const unsigned char*)value.constData(), qVecSize * sizeof(bool)); + QByteArray dataByteArray(udt::MAX_PACKET_SIZE, 0); + unsigned char* start = reinterpret_cast(dataByteArray.data()); + unsigned char* destinationBuffer = start; + int bit = 0; + for (int index = 0; index < value.size(); index++) { + if (value[index]) { + (*destinationBuffer) |= (1 << bit); + } + if (++bit == BITS_IN_BYTE) { + destinationBuffer++; + bit = 0; + } + } + int boolsSize = destinationBuffer - start; + success = append(start, boolsSize); if (success) { - _bytesOfValues += qVecSize * sizeof(bool); - _totalBytesOfValues += qVecSize * sizeof(bool); + _bytesOfValues += boolsSize; + _totalBytesOfValues += boolsSize; } } return success; @@ -684,8 +700,19 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto memcpy(&length, dataBytes, sizeof(uint16_t)); dataBytes += sizeof(length); result.resize(length); - memcpy(result.data(), dataBytes, length * sizeof(bool)); - return sizeof(uint16_t) + length * sizeof(bool); + + int bit = 0; + unsigned char current = 0; + const unsigned char *start = dataBytes; + for (int i = 0; i < length; i ++) { + if (bit == 0) { + current = *dataBytes++; + } + result[i] = (bool)(current & (1 << bit)); + bit = (bit + 1) % BITS_IN_BYTE; + } + + return (dataBytes - start) + sizeof(uint16_t); } int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result) { From 3db68e31510c47c357e64e2e6fc7eeac3d6e3d06 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 4 Jan 2016 18:16:20 -0800 Subject: [PATCH 35/43] add model joints to debugging --- libraries/entities/src/EntityItemProperties.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 9b8142d4c2..bfd2d405ef 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -406,6 +406,11 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentID, parentID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentJointIndex, parentJointIndex, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointRotationsSet, jointRotationsSet, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointRotations, jointRotations, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslationsSet, jointTranslationsSet, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslations, jointTranslations, ""); + properties.getAnimation().debugDump(); properties.getAtmosphere().debugDump(); properties.getSkybox().debugDump(); From 16d4234d559d2a88d9a89e42dc8cf9d3c1eab19c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 5 Jan 2016 15:23:25 +1300 Subject: [PATCH 36/43] Get rid of a couple of multiplies --- .../src/textured_particle.slv | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/entities-renderer/src/textured_particle.slv b/libraries/entities-renderer/src/textured_particle.slv index 5c47fdd1e9..dd503caee2 100644 --- a/libraries/entities-renderer/src/textured_particle.slv +++ b/libraries/entities-renderer/src/textured_particle.slv @@ -64,31 +64,31 @@ float interpolate3Points(float y1, float y2, float y3, float u) { return y2; } - float slope; + float halfSlope; if ((y2 >= y1 && y2 >= y3) || (y2 <= y1 && y2 <= y3)) { // U or inverted-U shape. // Make the slope at y2 = 0, which means that the control points half way between the value points have the value y2. - slope = 0.0f; + halfSlope = 0.0f; } else { // L or inverted and/or mirrored L shape. // Make the slope at y2 be the slope between y1 and y3, up to a maximum of double the minimum of the slopes between y1 // and y2, and y2 and y3. Use this slope to calculate the control points half way between the value points. // Note: The maximum ensures that the control points and therefore the interpolated values stay between y1 and y3. - float slope = y3 - y1; - float doubleSlope12 = 2.0f * (y2 - y1); - float doubleSlope23 = 2.0f * (y3 - y2); - if (abs(slope) > abs(doubleSlope12)) { - slope = doubleSlope12; - } else if (abs(slope) > abs(doubleSlope23)) { - slope = doubleSlope23; + halfSlope = (y3 - y1) / 2.0f; + float slope12 = y2 - y1; + float slope23 = y3 - y2; + if (abs(halfSlope) > abs(slope12)) { + halfSlope = slope12; + } else if (abs(halfSlope) > abs(slope23)) { + halfSlope = slope23; } } float stepU = step(0.5f, u); // 0.0 if u < 0.5, 1.0 otherwise. float slopeSign = 2.0f * stepU - 1.0f; // -1.0 if u < 0.5, 1.0 otherwise float start = (1.0f - stepU) * y1 + stepU * y2; // y1 if u < 0.5, y2 otherwise - float middle = y2 + slopeSign * slope / 2.0f; + float middle = y2 + slopeSign * halfSlope; float finish = (1.0f - stepU) * y2 + stepU * y3; // y2 if u < 0.5, y3 otherwise float v = 2.0f * u - step(0.5f, u); // 0.0-0.5 -> 0.0-1.0 and 0.5-1.0 -> 0.0-1.0 return bezierInterpolate(start, middle, finish, v); From b222c1285787925891b2da6c4801621c7c1763ca Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 5 Jan 2016 12:21:50 -0800 Subject: [PATCH 37/43] unmangle merge --- interface/src/avatar/Avatar.h | 2 ++ libraries/avatars/src/AvatarData.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 8f89027d2f..a9a3bd14f4 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -112,6 +112,8 @@ public: virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; + virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } virtual void setFaceModelURL(const QUrl& faceModelURL) override; virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index c0fe62c7c4..f19164fe45 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -358,6 +358,8 @@ public slots: virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; + virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } protected: glm::vec3 _handPosition; From f7041136ff07f30d18ab198cf9a7b38d0aef44e6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 5 Jan 2016 13:26:16 -0800 Subject: [PATCH 38/43] put new property in right place --- libraries/entities/src/EntityPropertyFlags.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 9b605f864e..c59ed7141b 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -157,14 +157,14 @@ enum EntityPropertyList { PROP_LOCAL_POSITION, // only used to convert values to and from scripts PROP_LOCAL_ROTATION, // only used to convert values to and from scripts + PROP_QUERY_AA_CUBE, // how the EntityTree considers the size and position on an entity + // ModelEntity joint state PROP_JOINT_ROTATIONS_SET, PROP_JOINT_ROTATIONS, PROP_JOINT_TRANSLATIONS_SET, PROP_JOINT_TRANSLATIONS, - PROP_QUERY_AA_CUBE, // how the EntityTree considers the size and position on an entity - //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, From 1e69f695b4291cba602e392884f11ee1cfc33378 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 5 Jan 2016 16:06:59 -0800 Subject: [PATCH 39/43] update polyvox shader to track changes in packDeferredFragment --- libraries/entities-renderer/src/polyvox.slf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf index c694630770..2bdecbf9fe 100644 --- a/libraries/entities-renderer/src/polyvox.slf +++ b/libraries/entities-renderer/src/polyvox.slf @@ -28,6 +28,9 @@ void main(void) { vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz)); worldNormal = normalize(worldNormal); + vec3 specular = DEFAULT_SPECULAR; + float shininess = DEFAULT_SHININESS; + float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x; float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y; float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z; @@ -41,5 +44,5 @@ void main(void) { vec3 yzDiffuseScaled = yzDiffuse.rgb * abs(worldNormal.x); vec4 diffuse = vec4(xyDiffuseScaled + xzDiffuseScaled + yzDiffuseScaled, 1.0); - packDeferredFragment(_normal, 0.0, vec3(diffuse), vec3(0.01, 0.01, 0.01), 10.0); + packDeferredFragment(_normal, 1.0, vec3(diffuse), specular, shininess); } From 981c6c7af52e75ef8be94891a4a60dedf46af7a3 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 5 Jan 2016 16:08:25 -0800 Subject: [PATCH 40/43] Cleanup web entity connections --- .../src/RenderableWebEntityItem.cpp | 13 +++++++++---- .../entities-renderer/src/RenderableWebEntityItem.h | 5 +++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 8aae853f5e..979ec32878 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -54,6 +54,11 @@ RenderableWebEntityItem::~RenderableWebEntityItem() { webSurface->deleteLater(); }); } + + QObject::disconnect(_mousePressConnection); + QObject::disconnect(_mouseReleaseConnection); + QObject::disconnect(_mouseMoveConnection); + QObject::disconnect(_hoverLeaveConnection); qDebug() << "Destroyed web entity " << getID(); } @@ -156,10 +161,10 @@ void RenderableWebEntityItem::render(RenderArgs* args) { }; EntityTreeRenderer* renderer = static_cast(args->_renderer); - QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardMouseEvent); - QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardMouseEvent); - QObject::connect(renderer, &EntityTreeRenderer::mouseMoveOnEntity, forwardMouseEvent); - QObject::connect(renderer, &EntityTreeRenderer::hoverLeaveEntity, [=](const EntityItemID& entityItemID, const MouseEvent& event) { + _mousePressConnection = QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardMouseEvent); + _mouseReleaseConnection = QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardMouseEvent); + _mouseMoveConnection = QObject::connect(renderer, &EntityTreeRenderer::mouseMoveOnEntity, forwardMouseEvent); + _hoverLeaveConnection = QObject::connect(renderer, &EntityTreeRenderer::hoverLeaveEntity, [=](const EntityItemID& entityItemID, const MouseEvent& event) { if (this->_pressed && this->getID() == entityItemID) { // If the user mouses off the entity while the button is down, simulate a mouse release QMouseEvent mappedEvent(QEvent::MouseButtonRelease, diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 2266401b5d..799a414151 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -40,6 +40,11 @@ private: ivec2 _lastPress{ INT_MIN }; bool _pressed{ false }; ivec2 _lastMove{ INT_MIN }; + + QMetaObject::Connection _mousePressConnection; + QMetaObject::Connection _mouseReleaseConnection; + QMetaObject::Connection _mouseMoveConnection; + QMetaObject::Connection _hoverLeaveConnection; }; From 4d7ed6b68f7506452f1beef3b93a6b9a5b2f402b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 6 Jan 2016 13:20:44 +1300 Subject: [PATCH 41/43] Whitespace --- libraries/entities-renderer/src/textured_particle.slv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/textured_particle.slv b/libraries/entities-renderer/src/textured_particle.slv index dd503caee2..4d819d389f 100644 --- a/libraries/entities-renderer/src/textured_particle.slv +++ b/libraries/entities-renderer/src/textured_particle.slv @@ -64,11 +64,11 @@ float interpolate3Points(float y1, float y2, float y3, float u) { return y2; } - float halfSlope; + float halfSlope; if ((y2 >= y1 && y2 >= y3) || (y2 <= y1 && y2 <= y3)) { // U or inverted-U shape. // Make the slope at y2 = 0, which means that the control points half way between the value points have the value y2. - halfSlope = 0.0f; + halfSlope = 0.0f; } else { // L or inverted and/or mirrored L shape. From 9ab5ef358aa3c10f5fcf5235a6c4bdf397113811 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 5 Jan 2016 16:43:57 -0800 Subject: [PATCH 42/43] remove dangling whitespace --- interface/src/Application.cpp | 10 ++-- interface/src/avatar/AvatarManager.cpp | 10 ++-- interface/src/avatar/AvatarManager.h | 4 +- interface/src/ui/PreferencesDialog.cpp | 38 +++++++-------- libraries/avatars/src/AvatarData.cpp | 16 +++---- libraries/avatars/src/AvatarData.h | 48 +++++++++---------- .../entities/src/AnimationPropertyGroup.cpp | 12 ++--- .../entities/src/AnimationPropertyGroup.h | 16 +++---- .../entities/src/EntityItemProperties.cpp | 18 +++---- libraries/entities/src/ModelEntityItem.h | 20 ++++---- .../networking/src/udt/PacketHeaders.cpp | 2 +- plugins/hifiSixense/src/SixenseManager.cpp | 6 +-- plugins/hifiSixense/src/SixenseManager.h | 2 +- 13 files changed, 101 insertions(+), 101 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 81b70866d7..e8673e7eac 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -349,7 +349,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - + #if defined(Q_OS_MAC) || defined(Q_OS_WIN) DependencyManager::set(); @@ -380,7 +380,7 @@ PluginContainer* _pluginContainer; // FIXME hack access to the internal share context for the Chromium helper -// Normally we'd want to use QWebEngine::initialize(), but we can't because +// Normally we'd want to use QWebEngine::initialize(), but we can't because // our primary context is a QGLWidget, which can't easily be initialized to share // from a QOpenGLContext. // @@ -1037,7 +1037,7 @@ void Application::cleanupBeforeQuit() { // destroy the AudioClient so it and its thread have a chance to go down safely DependencyManager::destroy(); - + // destroy the AudioInjectorManager so it and its thread have a chance to go down safely // this will also stop any ongoing network injectors DependencyManager::destroy(); @@ -1266,7 +1266,7 @@ void Application::initializeUi() { } void Application::paintGL() { - // paintGL uses a queued connection, so we can get messages from the queue even after we've quit + // paintGL uses a queued connection, so we can get messages from the queue even after we've quit // and the plugins have shutdown if (_aboutToQuit) { return; @@ -5085,7 +5085,7 @@ void Application::updateDisplayMode() { foreach(auto displayPlugin, displayPlugins) { addDisplayPluginToMenu(displayPlugin, first); // This must be a queued connection to avoid a deadlock - QObject::connect(displayPlugin.get(), &DisplayPlugin::requestRender, + QObject::connect(displayPlugin.get(), &DisplayPlugin::requestRender, this, &Application::paintGL, Qt::QueuedConnection); QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, [this](const QSize & size) { diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 7d8d5e4c9b..2ef3956d99 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -113,21 +113,21 @@ void AvatarManager::updateMyAvatar(float deltaTime) { void AvatarManager::updateOtherAvatars(float deltaTime) { // lock the hash for read to check the size QReadLocker lock(&_hashLock); - + if (_avatarHash.size() < 2 && _avatarFades.isEmpty()) { return; } - + lock.unlock(); - + bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); PerformanceTimer perfTimer("otherAvatars"); - + // simulate avatars auto hashCopy = getHashCopy(); - + AvatarHash::iterator avatarIterator = hashCopy.begin(); while (avatarIterator != hashCopy.end()) { auto avatar = std::static_pointer_cast(avatarIterator.value()); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index f34a784ba5..8494ce0b40 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -41,9 +41,9 @@ public: void updateMyAvatar(float deltaTime); void updateOtherAvatars(float deltaTime); - + void clearOtherAvatars(); - + bool shouldShowReceiveStats() const { return _shouldShowReceiveStats; } class LocalLight { diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 5cc88f123c..216c11a05c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -139,22 +139,22 @@ void PreferencesDialog::openFullAvatarModelBrowser() { } void PreferencesDialog::resizeEvent(QResizeEvent *resizeEvent) { - + // keep buttons panel at the bottom ui.buttonsPanel->setGeometry(0, size().height() - ui.buttonsPanel->height(), size().width(), ui.buttonsPanel->height()); - + // set width and height of srcollarea to match bottom panel and width ui.scrollArea->setGeometry(ui.scrollArea->geometry().x(), ui.scrollArea->geometry().y(), size().width(), size().height() - ui.buttonsPanel->height() - ui.scrollArea->geometry().y()); - + } void PreferencesDialog::loadPreferences() { - + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); Menu* menuInstance = Menu::getInstance(); @@ -175,14 +175,14 @@ void PreferencesDialog::loadPreferences() { ui.pupilDilationSlider->setValue(myAvatar->getHead()->getPupilDilation() * ui.pupilDilationSlider->maximum()); - + auto dde = DependencyManager::get(); - ui.ddeEyeClosingThresholdSlider->setValue(dde->getEyeClosingThreshold() * + ui.ddeEyeClosingThresholdSlider->setValue(dde->getEyeClosingThreshold() * ui.ddeEyeClosingThresholdSlider->maximum()); ui.faceTrackerEyeDeflectionSider->setValue(FaceTracker::getEyeDeflection() * ui.faceTrackerEyeDeflectionSider->maximum()); - + auto faceshift = DependencyManager::get(); ui.faceshiftHostnameEdit->setText(faceshift->getHostname()); @@ -208,12 +208,12 @@ void PreferencesDialog::loadPreferences() { ui.realWorldFieldOfViewSpin->setValue(myAvatar->getRealWorldFieldOfView()); ui.fieldOfViewSpin->setValue(qApp->getFieldOfView()); - + ui.leanScaleSpin->setValue(myAvatar->getLeanScale()); ui.avatarScaleSpin->setValue(myAvatar->getUniformScale()); ui.avatarAnimationEdit->setText(myAvatar->getAnimGraphUrl().toString()); - + ui.maxOctreePPSSpin->setValue(qApp->getMaxOctreePacketsPerSecond()); #if 0 @@ -232,11 +232,11 @@ void PreferencesDialog::loadPreferences() { } void PreferencesDialog::savePreferences() { - + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); bool shouldDispatchIdentityPacket = false; - + QString displayNameStr(ui.displayNameEdit->text()); if (displayNameStr != _displayNameString) { myAvatar->setDisplayName(displayNameStr); @@ -247,7 +247,7 @@ void PreferencesDialog::savePreferences() { if (shouldDispatchIdentityPacket) { myAvatar->sendIdentityPacket(); } - + myAvatar->setCollisionSoundURL(ui.collisionSoundURLEdit->text()); // MyAvatar persists its own data. If it doesn't agree with what the user has explicitly accepted, set it back to old values. @@ -276,28 +276,28 @@ void PreferencesDialog::savePreferences() { } myAvatar->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value()); - + qApp->setFieldOfView(ui.fieldOfViewSpin->value()); - + auto dde = DependencyManager::get(); - dde->setEyeClosingThreshold(ui.ddeEyeClosingThresholdSlider->value() / + dde->setEyeClosingThreshold(ui.ddeEyeClosingThresholdSlider->value() / (float)ui.ddeEyeClosingThresholdSlider->maximum()); FaceTracker::setEyeDeflection(ui.faceTrackerEyeDeflectionSider->value() / (float)ui.faceTrackerEyeDeflectionSider->maximum()); - + auto faceshift = DependencyManager::get(); faceshift->setHostname(ui.faceshiftHostnameEdit->text()); - + qApp->setMaxOctreePacketsPerSecond(ui.maxOctreePPSSpin->value()); qApp->getApplicationCompositor().setHmdUIAngularSize(ui.oculusUIAngularSizeSpin->value()); - + controller::InputDevice::setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value()); auto audio = DependencyManager::get(); MixedProcessedAudioStream& stream = audio->getReceivedAudioStream(); - + stream.setDynamicJitterBuffers(ui.dynamicJitterBuffersCheckBox->isChecked()); stream.setStaticDesiredJitterBufferFrames(ui.staticDesiredJitterBufferFramesSpin->value()); stream.setMaxFramesOverDesired(ui.maxFramesOverDesiredSpin->value()); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 1848845a07..0015a064fb 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1211,7 +1211,7 @@ void AvatarData::setJointMappingsFromNetworkReply() { void AvatarData::sendAvatarDataPacket() { auto nodeList = DependencyManager::get(); - + // about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed. // this is to guard against a joint moving once, the packet getting lost, and the joint never moving again. bool sendFullUpdate = randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO; @@ -1219,7 +1219,7 @@ void AvatarData::sendAvatarDataPacket() { doneEncoding(true); static AvatarDataSequenceNumber sequenceNumber = 0; - + auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size() + sizeof(sequenceNumber)); avatarPacket->writePrimitive(sequenceNumber++); avatarPacket->write(avatarByteArray); @@ -1241,13 +1241,13 @@ void AvatarData::sendIdentityPacket() { void AvatarData::sendBillboardPacket() { if (!_billboard.isEmpty()) { auto nodeList = DependencyManager::get(); - + // This makes sure the billboard won't be too large to send. // Once more protocol changes are done and we can send blocks of data we can support sending > MTU sized billboards. if (_billboard.size() <= NLPacket::maxPayloadSize(PacketType::AvatarBillboard)) { auto billboardPacket = NLPacket::create(PacketType::AvatarBillboard, _billboard.size()); billboardPacket->write(_billboard); - + nodeList->broadcastToNodes(std::move(billboardPacket), NodeSet() << NodeType::AvatarMixer); } } @@ -1495,7 +1495,7 @@ QJsonObject AvatarData::toJson() const { } void AvatarData::fromJson(const QJsonObject& json) { - // The head setOrientation likes to overwrite the avatar orientation, + // The head setOrientation likes to overwrite the avatar orientation, // so lets do the head first // Most head data is relative to the avatar, and needs no basis correction, // but the lookat vector does need correction @@ -1531,7 +1531,7 @@ void AvatarData::fromJson(const QJsonObject& json) { if (json.contains(JSON_AVATAR_RELATIVE)) { // During playback you can either have the recording basis set to the avatar current state // meaning that all playback is relative to this avatars starting position, or - // the basis can be loaded from the recording, meaning the playback is relative to the + // the basis can be loaded from the recording, meaning the playback is relative to the // original avatar location // The first is more useful for playing back recordings on your own avatar, while // the latter is more useful for playing back other avatars within your scene. @@ -1580,8 +1580,8 @@ void AvatarData::fromJson(const QJsonObject& json) { } // Every frame will store both a basis for the recording and a relative transform -// This allows the application to decide whether playback should be relative to an avatar's -// transform at the start of playback, or relative to the transform of the recorded +// This allows the application to decide whether playback should be relative to an avatar's +// transform at the start of playback, or relative to the transform of the recorded // avatar QByteArray AvatarData::toFrame(const AvatarData& avatar) { QJsonObject root = avatar.toJson(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index c0fe62c7c4..62b318bf0d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -267,9 +267,9 @@ public: Q_INVOKABLE virtual QVector getJointRotations() const; Q_INVOKABLE virtual void setJointRotations(QVector jointRotations); Q_INVOKABLE virtual void setJointTranslations(QVector jointTranslations); - + Q_INVOKABLE virtual void clearJointsData(); - + /// Returns the index of the joint with the specified name, or -1 if not found/unknown. Q_INVOKABLE virtual int getJointIndex(const QString& name) const { return _jointIndices.value(name) - 1; } @@ -288,42 +288,42 @@ public: bool hasIdentityChangedAfterParsing(const QByteArray& data); QByteArray identityByteArray(); - + bool hasBillboardChangedAfterParsing(const QByteArray& data); - + const QUrl& getFaceModelURL() const { return _faceModelURL; } QString getFaceModelURLString() const { return _faceModelURL.toString(); } const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } const QString& getDisplayName() const { return _displayName; } virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); - + virtual void setDisplayName(const QString& displayName); - + Q_INVOKABLE QVector getAttachmentData() const; Q_INVOKABLE virtual void setAttachmentData(const QVector& attachmentData); - + Q_INVOKABLE virtual void attach(const QString& modelURL, const QString& jointName = QString(), const glm::vec3& translation = glm::vec3(), const glm::quat& rotation = glm::quat(), float scale = 1.0f, bool allowDuplicates = false, bool useSaved = true); - + Q_INVOKABLE void detachOne(const QString& modelURL, const QString& jointName = QString()); Q_INVOKABLE void detachAll(const QString& modelURL, const QString& jointName = QString()); - + virtual void setBillboard(const QByteArray& billboard); const QByteArray& getBillboard() const { return _billboard; } - + void setBillboardFromURL(const QString& billboardURL); const QString& getBillboardURL() { return _billboardURL; } - + QString getFaceModelURLFromScript() const { return _faceModelURL.toString(); } void setFaceModelURLFromScript(const QString& faceModelString) { setFaceModelURL(faceModelString); } - + QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); } void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); } - + void setOwningAvatarMixer(const QWeakPointer& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; } - + const AABox& getLocalAABox() const { return _localAABox; } int getUsecsSinceLastUpdate() const { return _averageBytesReceived.getUsecsSinceLastEvent(); } @@ -351,7 +351,7 @@ public slots: void sendAvatarDataPacket(); void sendIdentityPacket(); void sendBillboardPacket(); - + void setBillboardFromNetworkReply(); void setJointMappingsFromNetworkReply(); void setSessionUUID(const QUuid& sessionUUID) { setID(sessionUUID); } @@ -392,14 +392,14 @@ protected: QByteArray _billboard; QString _billboardURL; - + QHash _jointIndices; ///< 1-based, since zero is returned for missing keys QStringList _jointNames; ///< in order of depth-first traversal quint64 _errorLogExpiry; ///< time in future when to log an error - + QWeakPointer _owningAvatarMixer; - + /// Loads the joint indices, names from the FST file (if any) virtual void updateJointMappings(); @@ -411,7 +411,7 @@ protected: SimpleMovingAverage _averageBytesReceived; QMutex avatarLock; // Name is redundant, but it aids searches. - + // During recording, this holds the starting position, orientation & scale of the recorded avatar // During playback, it holds the origin from which to play the relative positions in the clip TransformPointer _recordingBasis; @@ -468,19 +468,19 @@ class AttachmentDataObject : public QObject, protected QScriptable { Q_PROPERTY(float scale READ getScale WRITE setScale) public: - + Q_INVOKABLE void setModelURL(const QString& modelURL) const; Q_INVOKABLE QString getModelURL() const; - + Q_INVOKABLE void setJointName(const QString& jointName) const; Q_INVOKABLE QString getJointName() const; - + Q_INVOKABLE void setTranslation(const glm::vec3& translation) const; Q_INVOKABLE glm::vec3 getTranslation() const; - + Q_INVOKABLE void setRotation(const glm::quat& rotation) const; Q_INVOKABLE glm::quat getRotation() const; - + Q_INVOKABLE void setScale(float scale) const; Q_INVOKABLE float getScale() const; }; diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index ef89128e30..97c8a1816a 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -169,7 +169,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, + int& propertyCount, OctreeElement::AppendState& appendState) const { bool successPropertyFits = true; @@ -248,7 +248,7 @@ void AnimationPropertyGroup::markAllChanged() { EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { EntityPropertyFlags changedProperties; - + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, url); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, fps); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, currentFrame); @@ -321,13 +321,13 @@ EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamP return requestedProperties; } - -void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + +void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, + int& propertyCount, OctreeElement::AppendState& appendState) const { bool successPropertyFits = true; @@ -352,7 +352,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En } } -int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, +int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) { diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 8e85d8bc99..3ee452cc5f 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -39,11 +39,11 @@ public: virtual void debugDump() const; virtual void listChangedProperties(QList& out); - virtual bool appendToEditPacket(OctreePacketData* packetData, + virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, + int& propertyCount, OctreeElement::AppendState& appendState) const; virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes); @@ -53,25 +53,25 @@ public: // EntityItem related helpers // methods for getting/setting all properties of an entity virtual void getProperties(EntityItemProperties& propertiesOut) const; - + /// returns true if something changed virtual bool setProperties(const EntityItemProperties& properties); virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; - - virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, + int& propertyCount, OctreeElement::AppendState& appendState) const; - virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged); - + DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString, ""); DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float, 30.0f); DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, CurrentFrame, currentFrame, float, 0.0f); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index e069e53244..a1857baea1 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -82,7 +82,7 @@ void EntityItemProperties::debugDump() const { getAtmosphere().debugDump(); getSkybox().debugDump(); getKeyLight().debugDump(); - + qCDebug(entities) << " changed properties..."; EntityPropertyFlags props = getChangedProperties(); props.debugDumpBits(); @@ -399,7 +399,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Zones only if (_type == EntityTypes::Zone) { _keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); - + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BACKGROUND_MODE, backgroundMode, getBackgroundModeAsString()); _stage.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); @@ -651,7 +651,7 @@ static QHash _propertyStringsToEnums; void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) { static std::once_flag initMap; - std::call_once(initMap, [](){ + std::call_once(initMap, [](){ ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool); ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3); @@ -992,7 +992,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem if (properties.getType() == EntityTypes::Zone) { _staticKeyLight.setProperties(properties); _staticKeyLight.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); - + _staticStage.setProperties(properties); _staticStage.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); @@ -1027,7 +1027,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth()); APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints()); } - + if (properties.getType() == EntityTypes::PolyLine) { APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth()); APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints()); @@ -1035,7 +1035,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); } - + APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID()); APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL()); @@ -1123,7 +1123,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes, EntityItemID& entityID, EntityItemProperties& properties) { bool valid = false; - + const unsigned char* dataAt = data; processedBytes = 0; @@ -1305,8 +1305,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector, setLinePoints); } - - + + if (properties.getType() == EntityTypes::PolyLine) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector, setLinePoints); diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index b08fed5970..7984e54c05 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -32,16 +32,16 @@ public: // TODO: eventually only include properties changed since the params.lastViewFrustumSent time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; - virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, + int& propertyCount, OctreeElement::AppendState& appendState) const; - virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged); @@ -92,20 +92,20 @@ public: void setAnimationLoop(bool loop) { _animationLoop.setLoop(loop); } bool getAnimationLoop() const { return _animationLoop.getLoop(); } - + void setAnimationHold(bool hold) { _animationLoop.setHold(hold); } bool getAnimationHold() const { return _animationLoop.getHold(); } - + void setAnimationFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); } float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); } - + void setAnimationLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); } float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } - + void mapJoints(const QStringList& modelJointNames); void getAnimationFrame(bool& newFrame, QVector& rotationsResult, QVector& translationsResult); bool jointsMapped() const { return _jointMappingURL == getAnimationURL() && _jointMappingCompleted; } - + bool getAnimationIsPlaying() const { return _animationLoop.getRunning(); } float getAnimationCurrentFrame() const { return _animationLoop.getCurrentFrame(); } float getAnimationFPS() const { return _animationLoop.getFPS(); } @@ -115,9 +115,9 @@ public: void setTextures(const QString& textures) { _textures = textures; } virtual bool shouldBePhysical() const; - + static void cleanupLoadedAnimations(); - + virtual glm::vec3 getJointPosition(int jointIndex) const { return glm::vec3(); } virtual glm::quat getJointRotation(int jointIndex) const { return glm::quat(); } diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 42ee77b02b..43f4b5dcc9 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -60,7 +60,7 @@ QDebug operator<<(QDebug debug, const PacketType& type) { QMetaObject metaObject = PacketTypeEnum::staticMetaObject; QMetaEnum metaEnum = metaObject.enumerator(metaObject.enumeratorOffset()); QString typeName = metaEnum.valueToKey((int) type); - + debug.nospace().noquote() << (uint8_t) type << " (" << typeName << ")"; return debug.space(); } diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 455fdd2b5e..768dbf9007 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -73,7 +73,7 @@ bool SixenseManager::isSupported() const { #else return true; #endif - + #else return false; #endif @@ -81,7 +81,7 @@ bool SixenseManager::isSupported() const { void SixenseManager::activate() { InputPlugin::activate(); - + #ifdef HAVE_SIXENSE _container->addMenu(MENU_PATH); _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, TOGGLE_SMOOTH, @@ -307,7 +307,7 @@ void SixenseManager::InputDevice::updateCalibration(SixenseControllerData* contr switch (_calibrationState) { case CALIBRATION_STATE_IDLE: return; - + case CALIBRATION_STATE_COMPLETE: { // compute calibration results _avatarPosition = -0.5f * (_reachLeft + _reachRight); // neck is midway between right and left hands diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index 37da7358e0..753974e996 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -98,7 +98,7 @@ private: static const QString NAME; static const QString HYDRA_ID_STRING; - + static bool _sixenseLoaded; }; From 8c7c436ef20ac48aa28b8afc40d393b18125c6de Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 5 Jan 2016 16:54:18 -0800 Subject: [PATCH 43/43] fix --- examples/grab.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index 1637e1bcf2..cb0723b8eb 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -309,7 +309,7 @@ Grabber.prototype.computeNewGrabPlane = function() { } Grabber.prototype.pressEvent = function(event) { - if (!event.isLeftButton) { + if (event.isLeftButton!==true ||event.isRightButton===true || event.isMiddleButton===true) { return; } @@ -374,7 +374,11 @@ Grabber.prototype.pressEvent = function(event) { //Audio.playSound(grabSound, { position: entityProperties.position, volume: VOLUME }); } -Grabber.prototype.releaseEvent = function() { +Grabber.prototype.releaseEvent = function(event) { + if (event.isLeftButton!==true ||event.isRightButton===true || event.isMiddleButton===true) { + return; + } + if (this.isGrabbing) { this.deactivateEntity(this.entityID); this.isGrabbing = false