From 5df7ce7424b8b4855a7e43f3df573726b91772a8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 16 Sep 2015 11:43:28 -0700 Subject: [PATCH 01/15] fix for missing jurisdiction listener in Agent --- assignment-client/src/Agent.cpp | 6 ++++++ libraries/entities/src/EntityScriptingInterface.h | 2 +- libraries/octree/src/OctreeHeadlessViewer.cpp | 6 ++---- libraries/octree/src/OctreeHeadlessViewer.h | 4 ++-- libraries/octree/src/OctreeScriptingInterface.cpp | 1 + libraries/octree/src/OctreeScriptingInterface.h | 7 +++---- libraries/script-engine/src/ScriptEngine.cpp | 3 ++- 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index fda226b934..f2d73bd1a6 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -191,8 +191,14 @@ void Agent::run() { auto entityScriptingInterface = DependencyManager::get(); _scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer); + + // we need to make sure that init has been called for our EntityScriptingInterface + // so that it actually has a jurisdiction listener when we ask it for it next + entityScriptingInterface->init(); _entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener()); + _entityViewer.init(); + entityScriptingInterface->setEntityTree(_entityViewer.getTree()); // wire up our additional agent related processing to the update signal diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 581eed184d..8d2b0b6892 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -1,6 +1,6 @@ // // EntityScriptingInterface.h -// libraries/models/src +// libraries/entities/src // // Created by Brad Hefta-Gaub on 12/6/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 3a80180008..88a77a4c53 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -23,9 +23,6 @@ OctreeHeadlessViewer::OctreeHeadlessViewer() : _viewFrustum.setProjection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), DEFAULT_ASPECT_RATIO, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); } -OctreeHeadlessViewer::~OctreeHeadlessViewer() { -} - void OctreeHeadlessViewer::init() { OctreeRenderer::init(); setViewFrustum(&_viewFrustum); @@ -34,8 +31,9 @@ void OctreeHeadlessViewer::init() { void OctreeHeadlessViewer::queryOctree() { char serverType = getMyNodeType(); PacketType packetType = getMyQueryMessageType(); + NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions(); - + bool wantExtraDebugging = false; if (wantExtraDebugging) { diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index be076e7b5f..5a17f48a19 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -29,7 +29,7 @@ class OctreeHeadlessViewer : public OctreeRenderer { Q_OBJECT public: OctreeHeadlessViewer(); - virtual ~OctreeHeadlessViewer(); + virtual ~OctreeHeadlessViewer() {}; virtual void renderElement(OctreeElementPointer element, RenderArgs* args) { /* swallow these */ } virtual void init(); @@ -65,7 +65,7 @@ public slots: private: ViewFrustum _viewFrustum; - JurisdictionListener* _jurisdictionListener; + JurisdictionListener* _jurisdictionListener = nullptr; OctreeQuery _octreeQuery; float _voxelSizeScale; int _boundaryLevelAdjust; diff --git a/libraries/octree/src/OctreeScriptingInterface.cpp b/libraries/octree/src/OctreeScriptingInterface.cpp index 97e7f67ff5..8913e88cf5 100644 --- a/libraries/octree/src/OctreeScriptingInterface.cpp +++ b/libraries/octree/src/OctreeScriptingInterface.cpp @@ -54,6 +54,7 @@ void OctreeScriptingInterface::init() { if (_initialized) { return; } + if (_jurisdictionListener) { _managedJurisdictionListener = false; } else { diff --git a/libraries/octree/src/OctreeScriptingInterface.h b/libraries/octree/src/OctreeScriptingInterface.h index ea897bbb4f..47b01c64f9 100644 --- a/libraries/octree/src/OctreeScriptingInterface.h +++ b/libraries/octree/src/OctreeScriptingInterface.h @@ -21,8 +21,7 @@ class OctreeScriptingInterface : public QObject { Q_OBJECT public: - OctreeScriptingInterface(OctreeEditPacketSender* packetSender = NULL, - JurisdictionListener* jurisdictionListener = NULL); + OctreeScriptingInterface(OctreeEditPacketSender* packetSender = NULL, JurisdictionListener* jurisdictionListener = NULL); ~OctreeScriptingInterface(); @@ -86,8 +85,8 @@ public slots: protected: /// attached OctreeEditPacketSender that handles queuing and sending of packets to VS - OctreeEditPacketSender* _packetSender; - JurisdictionListener* _jurisdictionListener; + OctreeEditPacketSender* _packetSender = nullptr; + JurisdictionListener* _jurisdictionListener = nullptr; bool _managedPacketSender; bool _managedJurisdictionListener; bool _initialized; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index a7136edd7b..cd9e9d2e6c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -263,7 +263,7 @@ void ScriptEngine::init() { } _isInitialized = true; - + auto entityScriptingInterface = DependencyManager::get(); entityScriptingInterface->init(); @@ -559,6 +559,7 @@ void ScriptEngine::run() { if (!_isInitialized) { init(); } + _isRunning = true; _isFinished = false; if (_wantSignals) { From bca00db4a8f4d0d74cc3b8e3d014333c847d1642 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 16 Sep 2015 11:48:15 -0700 Subject: [PATCH 02/15] use unique_ptr for Agent ScriptEngine --- assignment-client/src/Agent.cpp | 13 +++---------- assignment-client/src/Agent.h | 3 ++- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index f2d73bd1a6..58d8c931f8 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -153,11 +153,11 @@ void Agent::run() { qDebug() << "Downloaded script:" << scriptContents; - _scriptEngine = new ScriptEngine(scriptContents, _payload); + _scriptEngine = std::unique_ptr(new ScriptEngine(scriptContents, _payload)); _scriptEngine->setParent(this); // be the parent of the script engine so it gets moved when we do // setup an Avatar for the script to use - ScriptableAvatar scriptedAvatar(_scriptEngine); + ScriptableAvatar scriptedAvatar(_scriptEngine.get()); scriptedAvatar.setForceFaceTrackerConnected(true); // call model URL setters with empty URLs so our avatar, if user, will have the default models @@ -202,17 +202,10 @@ void Agent::run() { entityScriptingInterface->setEntityTree(_entityViewer.getTree()); // wire up our additional agent related processing to the update signal - QObject::connect(_scriptEngine, &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio); + QObject::connect(_scriptEngine.get(), &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio); _scriptEngine->run(); setFinished(true); - - // kill the avatar identity timer - delete _avatarIdentityTimer; - - // delete the script engine - delete _scriptEngine; - } void Agent::setIsAvatar(bool isAvatar) { diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 33a8eb58c2..ab000015d5 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -12,6 +12,7 @@ #ifndef hifi_Agent_h #define hifi_Agent_h +#include #include #include @@ -61,7 +62,7 @@ private slots: void processAgentAvatarAndAudio(float deltaTime); private: - ScriptEngine* _scriptEngine; + std::unique_ptr _scriptEngine; EntityEditPacketSender _entityEditSender; EntityTreeHeadlessViewer _entityViewer; QTimer* _pingTimer; From 229e73f88c4444bf3f8d9812ceb061192ea96477 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 16 Sep 2015 11:52:05 -0700 Subject: [PATCH 03/15] protect the agent from null timers in avatar stop --- assignment-client/src/Agent.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 58d8c931f8..157154606f 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -226,10 +226,17 @@ void Agent::setIsAvatar(bool isAvatar) { } if (!_isAvatar) { - delete _avatarIdentityTimer; - _avatarIdentityTimer = NULL; - delete _avatarBillboardTimer; - _avatarBillboardTimer = NULL; + if (_avatarIdentityTimer) { + _avatarIdentityTimer->stop(); + delete _avatarIdentityTimer; + _avatarIdentityTimer = nullptr; + } + + if (_avatarBillboardTimer) { + _avatarIdentityTimer->stop(); + delete _avatarIdentityTimer; + _avatarBillboardTimer = nullptr; + } } } From cbb8bee9621050be4c21cf8a0b3d473b6c1ca6f7 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 16 Sep 2015 14:59:38 -0700 Subject: [PATCH 04/15] Trying to fix ScriptEngine location property --- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index a7136edd7b..518279b21d 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -405,7 +405,7 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func QScriptValue setterFunction = newFunction(setter, 1); QScriptValue getterFunction = newFunction(getter); - if (!parent.isNull()) { + if (!parent.isNull() && !parent.isEmpty()) { QScriptValue object = globalObject().property(parent); if (object.isValid()) { object.setProperty(name, setterFunction, QScriptValue::PropertySetter); From fae4b08eb056a838e5265c25b0a26ca85effec70 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 16 Sep 2015 15:11:53 -0700 Subject: [PATCH 05/15] AnimController Node Bug fixes AnimController: proper support for alpha AnimController: bug fix for translation. AnimOverlay: renamed local var when building hand boneSets from head to hand. --- libraries/animation/src/AnimController.cpp | 24 ++++++++++++---------- libraries/animation/src/AnimOverlay.cpp | 8 ++++---- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/libraries/animation/src/AnimController.cpp b/libraries/animation/src/AnimController.cpp index c021124732..f74f30b631 100644 --- a/libraries/animation/src/AnimController.cpp +++ b/libraries/animation/src/AnimController.cpp @@ -9,6 +9,7 @@ // #include "AnimController.h" +#include "AnimUtil.h" #include "AnimationLogging.h" AnimController::AnimController(const std::string& id, float alpha) : @@ -40,38 +41,39 @@ const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float if (jointVar.jointIndex >= 0) { - AnimPose defaultPose; - glm::quat absRot; - glm::quat parentAbsRot; + AnimPose defaultAbsPose; + AnimPose parentAbsPose = AnimPose::identity; if (jointVar.jointIndex <= (int)underPoses.size()) { // jointVar is an absolute rotation, if it is not set we will use the underPose as our default value - defaultPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses); - absRot = animVars.lookup(jointVar.var, defaultPose.rot); + defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses); + defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); // because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose. int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex); if (parentIndex >= 0) { - parentAbsRot = _skeleton->getAbsolutePose(parentIndex, underPoses).rot; + parentAbsPose = _skeleton->getAbsolutePose(parentIndex, underPoses); } } else { // jointVar is an absolute rotation, if it is not set we will use the bindPose as our default value - defaultPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex); - absRot = animVars.lookup(jointVar.var, defaultPose.rot); + defaultAbsPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex); + defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); // because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose // here we use the bind pose int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex); if (parentIndex >= 0) { - parentAbsRot = _skeleton->getAbsoluteBindPose(parentIndex).rot; + parentAbsPose = _skeleton->getAbsoluteBindPose(parentIndex); } } // convert from absolute to relative - glm::quat relRot = glm::inverse(parentAbsRot) * absRot; - _poses[jointVar.jointIndex] = AnimPose(defaultPose.scale, relRot, defaultPose.trans); + AnimPose relPose = parentAbsPose.inverse() * defaultAbsPose; + + // blend with underPose + ::blend(1, &underPoses[jointVar.jointIndex], &relPose, _alpha, &_poses[jointVar.jointIndex]); } } diff --git a/libraries/animation/src/AnimOverlay.cpp b/libraries/animation/src/AnimOverlay.cpp index 1a0a16ca8a..760a683aa6 100644 --- a/libraries/animation/src/AnimOverlay.cpp +++ b/libraries/animation/src/AnimOverlay.cpp @@ -173,8 +173,8 @@ void AnimOverlay::buildEmptyBoneSet() { void AnimOverlay::buildLeftHandBoneSet() { assert(_skeleton); buildEmptyBoneSet(); - int headJoint = _skeleton->nameToJointIndex("LeftHand"); - for_each_child_joint(_skeleton, headJoint, [&](int i) { + int handJoint = _skeleton->nameToJointIndex("LeftHand"); + for_each_child_joint(_skeleton, handJoint, [&](int i) { _boneSetVec[i] = 1.0f; }); } @@ -182,8 +182,8 @@ void AnimOverlay::buildLeftHandBoneSet() { void AnimOverlay::buildRightHandBoneSet() { assert(_skeleton); buildEmptyBoneSet(); - int headJoint = _skeleton->nameToJointIndex("RightHand"); - for_each_child_joint(_skeleton, headJoint, [&](int i) { + int handJoint = _skeleton->nameToJointIndex("RightHand"); + for_each_child_joint(_skeleton, handJoint, [&](int i) { _boneSetVec[i] = 1.0f; }); } From 5aeebba90e565a43d0e0d3d23858de9fbdc0682d Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 16 Sep 2015 15:49:47 -0700 Subject: [PATCH 06/15] Renamed AnimController to AnimManipulator, Removed offsets on IK targets --- interface/src/avatar/MyAvatar.cpp | 2 +- ...AnimController.cpp => AnimManipulator.cpp} | 27 ++++++++++--------- .../{AnimController.h => AnimManipulator.h} | 18 ++++++------- libraries/animation/src/AnimNode.h | 2 +- libraries/animation/src/AnimNodeLoader.cpp | 20 +++++++------- libraries/animation/src/Rig.cpp | 9 +++---- tests/animation/src/data/avatar.json | 4 +-- 7 files changed, 41 insertions(+), 41 deletions(-) rename libraries/animation/src/{AnimController.cpp => AnimManipulator.cpp} (75%) rename libraries/animation/src/{AnimController.h => AnimManipulator.h} (79%) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e165b5c617..69f7516430 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1302,7 +1302,7 @@ void MyAvatar::initAnimGraph() { // or run a local web-server // python -m SimpleHTTPServer& //auto graphUrl = QUrl("http://localhost:8000/avatar.json"); - auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/04a02c47eb56d8bfaebb/raw/5f2a4e268d35147c83d44881e268f83a6296e89b/ik-avatar-hands.json"); + auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/04a02c47eb56d8bfaebb/raw/72517b231f606b724c5169e02642e401f9af5a54/ik-avatar-hands.json"); _rig->initAnimGraph(graphUrl, _skeletonModel.getGeometry()->getFBXGeometry()); } diff --git a/libraries/animation/src/AnimController.cpp b/libraries/animation/src/AnimManipulator.cpp similarity index 75% rename from libraries/animation/src/AnimController.cpp rename to libraries/animation/src/AnimManipulator.cpp index f74f30b631..c2951681e1 100644 --- a/libraries/animation/src/AnimController.cpp +++ b/libraries/animation/src/AnimManipulator.cpp @@ -1,5 +1,5 @@ // -// AnimController.cpp +// AnimManipulator.cpp // // Created by Anthony J. Thibault on 9/8/15. // Copyright (c) 2015 High Fidelity, Inc. All rights reserved. @@ -8,25 +8,25 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "AnimController.h" +#include "AnimManipulator.h" #include "AnimUtil.h" #include "AnimationLogging.h" -AnimController::AnimController(const std::string& id, float alpha) : - AnimNode(AnimNode::Type::Controller, id), +AnimManipulator::AnimManipulator(const std::string& id, float alpha) : + AnimNode(AnimNode::Type::Manipulator, id), _alpha(alpha) { } -AnimController::~AnimController() { +AnimManipulator::~AnimManipulator() { } -const AnimPoseVec& AnimController::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) { +const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) { return overlay(animVars, dt, triggersOut, _skeleton->getRelativeBindPoses()); } -const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { +const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { _alpha = animVars.lookup(_alphaVar, _alpha); for (auto& jointVar : _jointVars) { @@ -34,7 +34,7 @@ const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float QString qJointName = QString::fromStdString(jointVar.jointName); jointVar.jointIndex = _skeleton->nameToJointIndex(qJointName); if (jointVar.jointIndex < 0) { - qCWarning(animation) << "AnimController could not find jointName" << qJointName << "in skeleton"; + qCWarning(animation) << "AnimManipulator could not find jointName" << qJointName << "in skeleton"; } jointVar.hasPerformedJointLookup = true; } @@ -42,10 +42,12 @@ const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float if (jointVar.jointIndex >= 0) { AnimPose defaultAbsPose; + AnimPose defaultRelPose; AnimPose parentAbsPose = AnimPose::identity; if (jointVar.jointIndex <= (int)underPoses.size()) { // jointVar is an absolute rotation, if it is not set we will use the underPose as our default value + defaultRelPose = underPoses[jointVar.jointIndex]; defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses); defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); @@ -58,6 +60,7 @@ const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float } else { // jointVar is an absolute rotation, if it is not set we will use the bindPose as our default value + defaultRelPose = AnimPose::identity; defaultAbsPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex); defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); @@ -73,14 +76,14 @@ const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float AnimPose relPose = parentAbsPose.inverse() * defaultAbsPose; // blend with underPose - ::blend(1, &underPoses[jointVar.jointIndex], &relPose, _alpha, &_poses[jointVar.jointIndex]); + ::blend(1, &defaultRelPose, &relPose, _alpha, &_poses[jointVar.jointIndex]); } } return _poses; } -void AnimController::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { +void AnimManipulator::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { AnimNode::setSkeletonInternal(skeleton); // invalidate all jointVar indices @@ -99,10 +102,10 @@ void AnimController::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { } // for AnimDebugDraw rendering -const AnimPoseVec& AnimController::getPosesInternal() const { +const AnimPoseVec& AnimManipulator::getPosesInternal() const { return _poses; } -void AnimController::addJointVar(const JointVar& jointVar) { +void AnimManipulator::addJointVar(const JointVar& jointVar) { _jointVars.push_back(jointVar); } diff --git a/libraries/animation/src/AnimController.h b/libraries/animation/src/AnimManipulator.h similarity index 79% rename from libraries/animation/src/AnimController.h rename to libraries/animation/src/AnimManipulator.h index 15805d72fd..c04853b8e0 100644 --- a/libraries/animation/src/AnimController.h +++ b/libraries/animation/src/AnimManipulator.h @@ -1,5 +1,5 @@ // -// AnimController.h +// AnimManipulator.h // // Created by Anthony J. Thibault on 9/8/15. // Copyright (c) 2015 High Fidelity, Inc. All rights reserved. @@ -8,19 +8,19 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_AnimController_h -#define hifi_AnimController_h +#ifndef hifi_AnimManipulator_h +#define hifi_AnimManipulator_h #include "AnimNode.h" // Allows procedural control over a set of joints. -class AnimController : public AnimNode { +class AnimManipulator : public AnimNode { public: friend class AnimTests; - AnimController(const std::string& id, float alpha); - virtual ~AnimController() override; + AnimManipulator(const std::string& id, float alpha); + virtual ~AnimManipulator() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) override; virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override; @@ -50,9 +50,9 @@ protected: std::vector _jointVars; // no copies - AnimController(const AnimController&) = delete; - AnimController& operator=(const AnimController&) = delete; + AnimManipulator(const AnimManipulator&) = delete; + AnimManipulator& operator=(const AnimManipulator&) = delete; }; -#endif // hifi_AnimController_h +#endif // hifi_AnimManipulator_h diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index f994867181..b4992f95a3 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -40,7 +40,7 @@ public: BlendLinear, Overlay, StateMachine, - Controller, + Manipulator, InverseKinematics, NumTypes }; diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index 9d6eb12e44..23bea83e1c 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -20,7 +20,7 @@ #include "AnimOverlay.h" #include "AnimNodeLoader.h" #include "AnimStateMachine.h" -#include "AnimController.h" +#include "AnimManipulator.h" #include "AnimInverseKinematics.h" using NodeLoaderFunc = AnimNode::Pointer (*)(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); @@ -31,7 +31,7 @@ static AnimNode::Pointer loadClipNode(const QJsonObject& jsonObj, const QString& static AnimNode::Pointer loadBlendLinearNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadOverlayNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadStateMachineNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); -static AnimNode::Pointer loadControllerNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); +static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); // called after children have been loaded @@ -40,7 +40,7 @@ static bool processClipNode(AnimNode::Pointer node, const QJsonObject& jsonObj, static bool processBlendLinearNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; } static bool processOverlayNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; } bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); -static bool processControllerNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; } +static bool processManipulatorNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; } static bool processInverseKinematicsNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; } static const char* animNodeTypeToString(AnimNode::Type type) { @@ -49,7 +49,7 @@ static const char* animNodeTypeToString(AnimNode::Type type) { case AnimNode::Type::BlendLinear: return "blendLinear"; case AnimNode::Type::Overlay: return "overlay"; case AnimNode::Type::StateMachine: return "stateMachine"; - case AnimNode::Type::Controller: return "controller"; + case AnimNode::Type::Manipulator: return "manipulator"; case AnimNode::Type::InverseKinematics: return "inverseKinematics"; case AnimNode::Type::NumTypes: return nullptr; }; @@ -62,7 +62,7 @@ static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) { case AnimNode::Type::BlendLinear: return loadBlendLinearNode; case AnimNode::Type::Overlay: return loadOverlayNode; case AnimNode::Type::StateMachine: return loadStateMachineNode; - case AnimNode::Type::Controller: return loadControllerNode; + case AnimNode::Type::Manipulator: return loadManipulatorNode; case AnimNode::Type::InverseKinematics: return loadInverseKinematicsNode; case AnimNode::Type::NumTypes: return nullptr; }; @@ -75,7 +75,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) { case AnimNode::Type::BlendLinear: return processBlendLinearNode; case AnimNode::Type::Overlay: return processOverlayNode; case AnimNode::Type::StateMachine: return processStateMachineNode; - case AnimNode::Type::Controller: return processControllerNode; + case AnimNode::Type::Manipulator: return processManipulatorNode; case AnimNode::Type::InverseKinematics: return processInverseKinematicsNode; case AnimNode::Type::NumTypes: return nullptr; }; @@ -122,7 +122,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) { static AnimNode::Type stringToEnum(const QString& str) { // O(n), move to map when number of types becomes large. const int NUM_TYPES = static_cast(AnimNode::Type::NumTypes); - for (int i = 0; i < NUM_TYPES; i++ ) { + for (int i = 0; i < NUM_TYPES; i++) { AnimNode::Type type = static_cast(i); if (str == animNodeTypeToString(type)) { return type; @@ -288,10 +288,10 @@ static AnimNode::Pointer loadStateMachineNode(const QJsonObject& jsonObj, const return node; } -static AnimNode::Pointer loadControllerNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { +static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); - auto node = std::make_shared(id.toStdString(), alpha); + auto node = std::make_shared(id.toStdString(), alpha); READ_OPTIONAL_STRING(alphaVar, jsonObj); if (!alphaVar.isEmpty()) { @@ -315,7 +315,7 @@ static AnimNode::Pointer loadControllerNode(const QJsonObject& jsonObj, const QS READ_STRING(var, jointObj, id, jsonUrl, nullptr); READ_STRING(jointName, jointObj, id, jsonUrl, nullptr); - AnimController::JointVar jointVar(var.toStdString(), jointName.toStdString()); + AnimManipulator::JointVar jointVar(var.toStdString(), jointName.toStdString()); node->addJointVar(jointVar); }; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 7e1d9a27e4..8b5bad5605 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -742,12 +742,10 @@ void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::q if (_enableAnimGraph && _animSkeleton) { if (endIndex == _leftHandJointIndex) { - auto rootTrans = _animSkeleton->getAbsoluteBindPose(_rootJointIndex).trans; - _animVars.set("leftHandPosition", targetPosition + rootTrans); + _animVars.set("leftHandPosition", targetPosition); _animVars.set("leftHandRotation", targetRotation); } else if (endIndex == _rightHandJointIndex) { - auto rootTrans = _animSkeleton->getAbsoluteBindPose(_rootJointIndex).trans; - _animVars.set("rightHandPosition", targetPosition + rootTrans); + _animVars.set("rightHandPosition", targetPosition); _animVars.set("rightHandRotation", targetRotation); } return; @@ -995,10 +993,9 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { glm::angleAxis(glm::radians(-params.localHeadPitch), X_AXIS)); _animVars.set("headRotation", realLocalHeadOrientation); - auto rootTrans = _animSkeleton->getAbsoluteBindPose(_rootJointIndex).trans; // There's a theory that when not in hmd, we should _animVars.unset("headPosition"). // However, until that works well, let's always request head be positioned where requested by hmd, camera, or default. - _animVars.set("headPosition", params.localHeadPosition + rootTrans); + _animVars.set("headPosition", params.localHeadPosition); } else if (!_enableAnimGraph) { auto& state = _jointStates[index]; diff --git a/tests/animation/src/data/avatar.json b/tests/animation/src/data/avatar.json index f5adfe2bfd..d1f6166b3d 100644 --- a/tests/animation/src/data/avatar.json +++ b/tests/animation/src/data/avatar.json @@ -33,7 +33,7 @@ "children": [] }, { - "id": "controllerOverlay", + "id": "manipulatorOverlay", "type": "overlay", "data": { "alpha": 1.0, @@ -42,7 +42,7 @@ "children": [ { "id": "spineLean", - "type": "controller", + "type": "manipulator", "data": { "alpha": 1.0, "joints": [ From 882ca5d6c07198c273baae5a7e9c00ad33960f31 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 16 Sep 2015 15:57:35 -0700 Subject: [PATCH 07/15] Fix the lights not rendering roperly --- libraries/render-utils/src/DeferredLightingEffect.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 0ec8b4ad24..b19e2f62b7 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -373,7 +373,10 @@ void DeferredLightingEffect::render(RenderArgs* args) { projMats[0] = monoProjMat; deferredTransforms[0].projection = monoProjMat; + deferredTransforms[0].viewInverse = monoViewMat; + viewTransforms[0] = monoViewTransform; + deferredTransforms[0].stereoSide = 0.0f; clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight); From 7840f122dc6a90f54eb89e4d845b9ba2b62deed6 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 16 Sep 2015 16:45:26 -0700 Subject: [PATCH 08/15] add reload all support for entity scripts --- interface/src/Application.cpp | 2 ++ libraries/entities-renderer/src/EntityTreeRenderer.cpp | 10 ++++++++++ libraries/entities-renderer/src/EntityTreeRenderer.h | 4 ++++ libraries/script-engine/src/ScriptCache.cpp | 7 +++++++ libraries/script-engine/src/ScriptCache.h | 1 + libraries/script-engine/src/ScriptEngine.cpp | 5 ++++- libraries/script-engine/src/ScriptEngine.h | 4 ++-- 7 files changed, 30 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3cb75b55ec..a313308023 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4347,6 +4347,8 @@ void Application::stopScript(const QString &scriptName, bool restart) { } void Application::reloadAllScripts() { + DependencyManager::get()->clearCache(); + getEntities()->reloadEntityScripts(); stopAllScripts(true); } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 2fd760bbd3..fa186b15f8 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -93,6 +93,15 @@ void EntityTreeRenderer::clear() { OctreeRenderer::clear(); } +void EntityTreeRenderer::reloadEntityScripts() { + _entitiesScriptEngine->unloadAllEntityScripts(); + foreach(auto entity, _entitiesInScene) { + if (!entity->getScript().isEmpty()) { + _entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), entity->getScript(), true); + } + } +} + void EntityTreeRenderer::init() { OctreeRenderer::init(); EntityTreePointer entityTree = std::static_pointer_cast(_tree); @@ -769,6 +778,7 @@ void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) { void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID, const bool reload) { + qDebug() << "entitySciptChanging() entityID:" << entityID << "reload:" << reload; if (_tree && !_shuttingDown) { _entitiesScriptEngine->unloadEntityScript(entityID); checkAndCallPreload(entityID, reload); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index a2f343efd2..6bacb23a3f 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -62,6 +62,10 @@ public: /// clears the tree virtual void clear(); + /// reloads the entity scripts, calling unload and preload + void reloadEntityScripts(); + + /// if a renderable entity item needs a model, we will allocate it for them Q_INVOKABLE Model* allocateModel(const QString& url, const QString& collisionUrl); diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index e2c07c05d0..fb0edb1e49 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -27,6 +27,11 @@ ScriptCache::ScriptCache(QObject* parent) { // nothing to do here... } +void ScriptCache::clearCache() { + _scriptCache.clear(); +} + + QString ScriptCache::getScript(const QUrl& unnormalizedURL, ScriptUser* scriptUser, bool& isPending, bool reload) { QUrl url = ResourceManager::normalizeURL(unnormalizedURL); QString scriptContents; @@ -95,6 +100,8 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable return; } + qCDebug(scriptengine) << "ScriptCache::getScriptContents() scriptOrURL:" << scriptOrURL << " forceDownload:" << forceDownload << " on thread[" << QThread::currentThread() << "] expected thread[" << thread() << "]"; + if (_scriptCache.contains(url) && !forceDownload) { qCDebug(scriptengine) << "Found script in cache:" << url.toString(); #if 1 // def THREAD_DEBUGGING diff --git a/libraries/script-engine/src/ScriptCache.h b/libraries/script-engine/src/ScriptCache.h index 7de14a09f7..b786422b3f 100644 --- a/libraries/script-engine/src/ScriptCache.h +++ b/libraries/script-engine/src/ScriptCache.h @@ -28,6 +28,7 @@ class ScriptCache : public QObject, public Dependency { SINGLETON_DEPENDENCY public: + void clearCache(); void getScriptContents(const QString& scriptOrURL, contentAvailableCallback contentAvailable, bool forceDownload = false); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 692a320b4e..d8392f1598 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -909,7 +909,10 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& #ifdef THREAD_DEBUGGING qDebug() << "ScriptEngine::loadEntityScript() calling scriptCache->getScriptContents() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; #endif - DependencyManager::get()->getScriptContents(entityScript, [=](const QString& scriptOrURL, const QString& contents, bool isURL, bool success) { + + qDebug() << "ScriptEngine::loadEntityScript() calling scriptCache->getScriptContents() scriptOrURL:" << entityScript << "forceDownload:" << forceRedownload << "on thread[" << QThread::currentThread() << "] expected thread[" << thread() << "]"; + + DependencyManager::get()->getScriptContents(entityScript, [=](const QString& scriptOrURL, const QString& contents, bool isURL, bool success) { #ifdef THREAD_DEBUGGING qDebug() << "ScriptEngine::entityScriptContentAvailable() IN LAMBDA contentAvailable on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; #endif diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 83e65823a5..001f54221b 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -109,8 +109,8 @@ public: // Entity Script Related methods Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload = false); // will call the preload method once loaded Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID); // will call unload method - Q_INVOKABLE void unloadAllEntityScripts(); - Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName); + Q_INVOKABLE void unloadAllEntityScripts(); + Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName); Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const MouseEvent& event); Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision); From fa6396bbfa907b6ee8535dadf7e62b2770b37536 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 16 Sep 2015 16:53:20 -0700 Subject: [PATCH 09/15] fix white space --- .../entities-renderer/src/EntityTreeRenderer.cpp | 13 ++++++------- libraries/script-engine/src/ScriptCache.cpp | 5 +---- libraries/script-engine/src/ScriptCache.h | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 4 +--- libraries/script-engine/src/ScriptEngine.h | 4 ++-- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index fa186b15f8..c55eaaeff9 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -94,12 +94,12 @@ void EntityTreeRenderer::clear() { } void EntityTreeRenderer::reloadEntityScripts() { - _entitiesScriptEngine->unloadAllEntityScripts(); - foreach(auto entity, _entitiesInScene) { - if (!entity->getScript().isEmpty()) { - _entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), entity->getScript(), true); - } - } + _entitiesScriptEngine->unloadAllEntityScripts(); + foreach(auto entity, _entitiesInScene) { + if (!entity->getScript().isEmpty()) { + _entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), entity->getScript(), true); + } + } } void EntityTreeRenderer::init() { @@ -778,7 +778,6 @@ void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) { void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID, const bool reload) { - qDebug() << "entitySciptChanging() entityID:" << entityID << "reload:" << reload; if (_tree && !_shuttingDown) { _entitiesScriptEngine->unloadEntityScript(entityID); checkAndCallPreload(entityID, reload); diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index fb0edb1e49..96e624c187 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -28,10 +28,9 @@ ScriptCache::ScriptCache(QObject* parent) { } void ScriptCache::clearCache() { - _scriptCache.clear(); + _scriptCache.clear(); } - QString ScriptCache::getScript(const QUrl& unnormalizedURL, ScriptUser* scriptUser, bool& isPending, bool reload) { QUrl url = ResourceManager::normalizeURL(unnormalizedURL); QString scriptContents; @@ -100,8 +99,6 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable return; } - qCDebug(scriptengine) << "ScriptCache::getScriptContents() scriptOrURL:" << scriptOrURL << " forceDownload:" << forceDownload << " on thread[" << QThread::currentThread() << "] expected thread[" << thread() << "]"; - if (_scriptCache.contains(url) && !forceDownload) { qCDebug(scriptengine) << "Found script in cache:" << url.toString(); #if 1 // def THREAD_DEBUGGING diff --git a/libraries/script-engine/src/ScriptCache.h b/libraries/script-engine/src/ScriptCache.h index b786422b3f..da9f1a409c 100644 --- a/libraries/script-engine/src/ScriptCache.h +++ b/libraries/script-engine/src/ScriptCache.h @@ -28,7 +28,7 @@ class ScriptCache : public QObject, public Dependency { SINGLETON_DEPENDENCY public: - void clearCache(); + void clearCache(); void getScriptContents(const QString& scriptOrURL, contentAvailableCallback contentAvailable, bool forceDownload = false); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index d8392f1598..771906aa95 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -910,9 +910,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& qDebug() << "ScriptEngine::loadEntityScript() calling scriptCache->getScriptContents() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; #endif - qDebug() << "ScriptEngine::loadEntityScript() calling scriptCache->getScriptContents() scriptOrURL:" << entityScript << "forceDownload:" << forceRedownload << "on thread[" << QThread::currentThread() << "] expected thread[" << thread() << "]"; - - DependencyManager::get()->getScriptContents(entityScript, [=](const QString& scriptOrURL, const QString& contents, bool isURL, bool success) { + DependencyManager::get()->getScriptContents(entityScript, [=](const QString& scriptOrURL, const QString& contents, bool isURL, bool success) { #ifdef THREAD_DEBUGGING qDebug() << "ScriptEngine::entityScriptContentAvailable() IN LAMBDA contentAvailable on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; #endif diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 001f54221b..83e65823a5 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -109,8 +109,8 @@ public: // Entity Script Related methods Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload = false); // will call the preload method once loaded Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID); // will call unload method - Q_INVOKABLE void unloadAllEntityScripts(); - Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName); + Q_INVOKABLE void unloadAllEntityScripts(); + Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName); Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const MouseEvent& event); Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision); From 2021a15527daff4137e7225b16dae68cb0ec1f01 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 16 Sep 2015 16:54:21 -0700 Subject: [PATCH 10/15] fix white space --- libraries/entities-renderer/src/EntityTreeRenderer.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 6bacb23a3f..18874957fd 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -62,9 +62,8 @@ public: /// clears the tree virtual void clear(); - /// reloads the entity scripts, calling unload and preload - void reloadEntityScripts(); - + /// reloads the entity scripts, calling unload and preload + void reloadEntityScripts(); /// if a renderable entity item needs a model, we will allocate it for them Q_INVOKABLE Model* allocateModel(const QString& url, const QString& collisionUrl); From 089c71961288a777071c61ff1b3ac64037060f03 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 15 Sep 2015 15:47:50 -0700 Subject: [PATCH 11/15] minor cleanup --- .../animation/src/AnimInverseKinematics.cpp | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 49ff7feda6..89ed8141f9 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -9,6 +9,7 @@ #include "AnimInverseKinematics.h" +#include #include #include @@ -109,9 +110,6 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar } } - // RELAX! Don't do it. - // relaxTowardDefaults(dt); - if (_absoluteTargets.empty()) { // no IK targets but still need to enforce constraints std::map::iterator constraintItr = _constraints.begin(); @@ -277,10 +275,6 @@ void AnimInverseKinematics::clearConstraints() { _constraints.clear(); } -const glm::vec3 xAxis(1.0f, 0.0f, 0.0f); -const glm::vec3 yAxis(0.0f, 1.0f, 0.0f); -const glm::vec3 zAxis(0.0f, 0.0f, 1.0f); - void AnimInverseKinematics::initConstraints() { if (!_skeleton) { return; @@ -306,7 +300,7 @@ void AnimInverseKinematics::initConstraints() { // y | // | | // | O---O---O RightUpLeg - // z | | | + // z | | Hips2 | // \ | | | // \| | | // x -----+ O O RightLeg @@ -334,7 +328,7 @@ void AnimInverseKinematics::initConstraints() { _constraints.clear(); for (int i = 0; i < numJoints; ++i) { - // compute the joint's baseName and remember if it was Left or not + // compute the joint's baseName and remember whether its prefix was "Left" or not QString baseName = _skeleton->getJointName(i); bool isLeft = baseName.startsWith("Left", Qt::CaseInsensitive); float mirror = isLeft ? -1.0f : 1.0f; @@ -467,6 +461,18 @@ void AnimInverseKinematics::initConstraints() { minDots.push_back(cosf(MAX_SPINE_SWING)); stConstraint->setSwingLimits(minDots); + constraint = static_cast(stConstraint); + } else if (baseName.startsWith("Hips2", Qt::CaseInsensitive)) { + SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); + stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); + const float MAX_SPINE_TWIST = PI / 8.0f; + stConstraint->setTwistLimits(-MAX_SPINE_TWIST, MAX_SPINE_TWIST); + + std::vector minDots; + const float MAX_SPINE_SWING = PI / 14.0f; + minDots.push_back(cosf(MAX_SPINE_SWING)); + stConstraint->setSwingLimits(minDots); + constraint = static_cast(stConstraint); } else if (0 == baseName.compare("Neck", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); @@ -488,18 +494,18 @@ void AnimInverseKinematics::initConstraints() { // we determine the max/min angles by rotating the swing limit lines from parent- to child-frame // then measure the angles to swing the yAxis into alignment - glm::vec3 hingeAxis = - mirror * zAxis; + glm::vec3 hingeAxis = - mirror * Vectors::UNIT_Z; const float MIN_ELBOW_ANGLE = 0.05f; const float MAX_ELBOW_ANGLE = 11.0f * PI / 12.0f; glm::quat invReferenceRotation = glm::inverse(referenceRotation); - glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_ELBOW_ANGLE, hingeAxis) * yAxis; - glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_ELBOW_ANGLE, hingeAxis) * yAxis; + glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_ELBOW_ANGLE, hingeAxis) * Vectors::UNIT_Y; + glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_ELBOW_ANGLE, hingeAxis) * Vectors::UNIT_Y; // for the rest of the math we rotate hingeAxis into the child frame hingeAxis = referenceRotation * hingeAxis; eConstraint->setHingeAxis(hingeAxis); - glm::vec3 projectedYAxis = glm::normalize(yAxis - glm::dot(yAxis, hingeAxis) * hingeAxis); + glm::vec3 projectedYAxis = glm::normalize(Vectors::UNIT_Y - glm::dot(Vectors::UNIT_Y, hingeAxis) * hingeAxis); float minAngle = acosf(glm::dot(projectedYAxis, minSwingAxis)); if (glm::dot(hingeAxis, glm::cross(projectedYAxis, minSwingAxis)) < 0.0f) { minAngle = - minAngle; @@ -516,21 +522,21 @@ void AnimInverseKinematics::initConstraints() { ElbowConstraint* eConstraint = new ElbowConstraint(); glm::quat referenceRotation = _defaultRelativePoses[i].rot; eConstraint->setReferenceRotation(referenceRotation); - glm::vec3 hingeAxis = -1.0f * xAxis; + glm::vec3 hingeAxis = -1.0f * Vectors::UNIT_X; // we determine the max/min angles by rotating the swing limit lines from parent- to child-frame // then measure the angles to swing the yAxis into alignment const float MIN_KNEE_ANGLE = 0.0f; const float MAX_KNEE_ANGLE = 3.0f * PI / 4.0f; glm::quat invReferenceRotation = glm::inverse(referenceRotation); - glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_KNEE_ANGLE, hingeAxis) * yAxis; - glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_KNEE_ANGLE, hingeAxis) * yAxis; + glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_KNEE_ANGLE, hingeAxis) * Vectors::UNIT_Y; + glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_KNEE_ANGLE, hingeAxis) * Vectors::UNIT_Y; // for the rest of the math we rotate hingeAxis into the child frame hingeAxis = referenceRotation * hingeAxis; eConstraint->setHingeAxis(hingeAxis); - glm::vec3 projectedYAxis = glm::normalize(yAxis - glm::dot(yAxis, hingeAxis) * hingeAxis); + glm::vec3 projectedYAxis = glm::normalize(Vectors::UNIT_Y - glm::dot(Vectors::UNIT_Y, hingeAxis) * hingeAxis); float minAngle = acosf(glm::dot(projectedYAxis, minSwingAxis)); if (glm::dot(hingeAxis, glm::cross(projectedYAxis, minSwingAxis)) < 0.0f) { minAngle = - minAngle; @@ -550,8 +556,8 @@ void AnimInverseKinematics::initConstraints() { // these directions are approximate swing limits in parent-frame // NOTE: they don't need to be normalized std::vector swungDirections; - swungDirections.push_back(yAxis); - swungDirections.push_back(xAxis); + swungDirections.push_back(Vectors::UNIT_Y); + swungDirections.push_back(Vectors::UNIT_X); swungDirections.push_back(glm::vec3(1.0f, 1.0f, 1.0f)); swungDirections.push_back(glm::vec3(1.0f, 1.0f, -1.0f)); From 9a86fc2e62c0864f21d33117ee538f8f638a6600 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 16 Sep 2015 12:10:22 -0700 Subject: [PATCH 12/15] build local list of IK targets every frame --- .../animation/src/AnimInverseKinematics.cpp | 128 +++++++++++------- .../animation/src/AnimInverseKinematics.h | 10 +- libraries/animation/src/AnimVariant.h | 2 + 3 files changed, 85 insertions(+), 55 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 89ed8141f9..ca619f9641 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -55,7 +55,20 @@ void AnimInverseKinematics::computeAbsolutePoses(AnimPoseVec& absolutePoses) con void AnimInverseKinematics::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar) { // if there are dups, last one wins. - _targetVarVec.push_back(IKTargetVar(jointName, positionVar.toStdString(), rotationVar.toStdString())); + bool found = false; + for (auto& targetVar: _targetVarVec) { + if (targetVar.jointName == jointName) { + // update existing targetVar + targetVar.positionVar = positionVar.toStdString(); + targetVar.rotationVar = rotationVar.toStdString(); + found = true; + break; + } + } + if (!found) { + // create a new entry + _targetVarVec.push_back(IKTargetVar(jointName, positionVar.toStdString(), rotationVar.toStdString())); + } } static int findRootJointInSkeleton(AnimSkeleton::ConstPointer skeleton, int index) { @@ -69,6 +82,12 @@ static int findRootJointInSkeleton(AnimSkeleton::ConstPointer skeleton, int inde return rootIndex; } +struct IKTarget { + AnimPose pose; + int index; + int rootIndex; +}; + //virtual const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVars, float dt, AnimNode::Triggers& triggersOut) { @@ -77,40 +96,53 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar return _relativePoses; } - // evaluate target vars + // build a list of targets from _targetVarVec + std::vector targets; + bool removeUnfoundJoints = false; for (auto& targetVar : _targetVarVec) { - - // lazy look up of jointIndices and insertion into _absoluteTargets map - if (!targetVar.hasPerformedJointLookup) { - targetVar.jointIndex = _skeleton->nameToJointIndex(targetVar.jointName); - if (targetVar.jointIndex >= 0) { - // insert into _absoluteTargets map - IKTarget target; - target.pose = AnimPose::identity; - target.rootIndex = findRootJointInSkeleton(_skeleton, targetVar.jointIndex); - _absoluteTargets[targetVar.jointIndex] = target; - - if (targetVar.jointIndex > _maxTargetIndex) { - _maxTargetIndex = targetVar.jointIndex; - } + if (targetVar.jointIndex == -1) { + // this targetVar hasn't been validated yet... + int jointIndex = _skeleton->nameToJointIndex(targetVar.jointName); + if (jointIndex >= 0) { + // this targetVar has a valid joint --> cache the indices + targetVar.jointIndex = jointIndex; + targetVar.rootIndex = findRootJointInSkeleton(_skeleton, jointIndex); } else { qCWarning(animation) << "AnimInverseKinematics could not find jointName" << targetVar.jointName << "in skeleton"; + removeUnfoundJoints = true; } - targetVar.hasPerformedJointLookup = true; - } - - if (targetVar.jointIndex >= 0) { - // update pose in _absoluteTargets map - auto iter = _absoluteTargets.find(targetVar.jointIndex); - if (iter != _absoluteTargets.end()) { + } else { + // TODO: get this done without a double-lookup of each var in animVars + if (animVars.hasKey(targetVar.positionVar) || animVars.hasKey(targetVar.rotationVar)) { + IKTarget target; AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, _relativePoses); - iter->second.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans); - iter->second.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot); + target.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans); + target.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot); + target.rootIndex = targetVar.rootIndex; + target.index = targetVar.jointIndex; + targets.push_back(target); } } } - if (_absoluteTargets.empty()) { + if (removeUnfoundJoints) { + int numVars = _targetVarVec.size(); + int i = 0; + while (i < numVars) { + if (_targetVarVec[i].jointIndex == -1) { + if (numVars > 1) { + // swap i for last element + _targetVarVec[i] = _targetVarVec[numVars - 1]; + } + _targetVarVec.pop_back(); + --numVars; + } else { + ++i; + } + } + } + + if (targets.empty()) { // no IK targets but still need to enforce constraints std::map::iterator constraintItr = _constraints.begin(); while (constraintItr != _constraints.end()) { @@ -133,11 +165,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar quint64 expiry = usecTimestampNow() + MAX_IK_TIME; do { largestError = 0.0f; - for (auto& targetPair: _absoluteTargets) { + for (auto& target: targets) { int lowestMovedIndex = _relativePoses.size() - 1; - int tipIndex = targetPair.first; - AnimPose targetPose = targetPair.second.pose; - int rootIndex = targetPair.second.rootIndex; + int tipIndex = target.index; + AnimPose targetPose = target.pose; + int rootIndex = target.rootIndex; if (rootIndex != -1) { // transform targetPose into skeleton's absolute frame AnimPose& rootPose = _relativePoses[rootIndex]; @@ -148,11 +180,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar glm::vec3 tip = absolutePoses[tipIndex].trans; float error = glm::length(targetPose.trans - tip); - // descend toward root, rotating each joint to get tip closer to target - int index = _skeleton->getParentIndex(tipIndex); - while (index != -1 && error > ACCEPTABLE_RELATIVE_ERROR) { + // descend toward root, pivoting each joint to get tip closer to target + int pivotIndex = _skeleton->getParentIndex(tipIndex); + while (pivotIndex != -1 && error > ACCEPTABLE_RELATIVE_ERROR) { // compute the two lines that should be aligned - glm::vec3 jointPosition = absolutePoses[index].trans; + glm::vec3 jointPosition = absolutePoses[pivotIndex].trans; glm::vec3 leverArm = tip - jointPosition; glm::vec3 targetLine = targetPose.trans - jointPosition; @@ -171,29 +203,34 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar angle = 0.5f * angle; glm::quat deltaRotation = glm::angleAxis(angle, axis); - int parentIndex = _skeleton->getParentIndex(index); + int parentIndex = _skeleton->getParentIndex(pivotIndex); if (parentIndex == -1) { // TODO? apply constraints to root? // TODO? harvest the root's transform as movement of entire skeleton? } else { // compute joint's new parent-relative rotation // Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q - glm::quat newRot = glm::normalize(glm::inverse(absolutePoses[parentIndex].rot) * deltaRotation * absolutePoses[index].rot); - RotationConstraint* constraint = getConstraint(index); + glm::quat newRot = glm::normalize(glm::inverse( + absolutePoses[parentIndex].rot) * + deltaRotation * + absolutePoses[pivotIndex].rot); + RotationConstraint* constraint = getConstraint(pivotIndex); if (constraint) { bool constrained = constraint->apply(newRot); if (constrained) { // the constraint will modify the movement of the tip so we have to compute the modified // model-frame deltaRotation // Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^ - deltaRotation = absolutePoses[parentIndex].rot * newRot * glm::inverse(absolutePoses[index].rot); + deltaRotation = absolutePoses[parentIndex].rot * + newRot * + glm::inverse(absolutePoses[pivotIndex].rot); } } - _relativePoses[index].rot = newRot; + _relativePoses[pivotIndex].rot = newRot; } // this joint has been changed so we check to see if it has the lowest index - if (index < lowestMovedIndex) { - lowestMovedIndex = index; + if (pivotIndex < lowestMovedIndex) { + lowestMovedIndex = pivotIndex; } // keep track of tip's new position as we descend towards root @@ -201,7 +238,7 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar error = glm::length(targetPose.trans - tip); } } - index = _skeleton->getParentIndex(index); + pivotIndex = _skeleton->getParentIndex(pivotIndex); } if (largestError < error) { largestError = error; @@ -581,13 +618,10 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele AnimNode::setSkeletonInternal(skeleton); // invalidate all targetVars - for (auto& targetVar : _targetVarVec) { - targetVar.hasPerformedJointLookup = false; + for (auto& targetVar: _targetVarVec) { + targetVar.jointIndex = -1; } - // invalidate all targets - _absoluteTargets.clear(); - _maxTargetIndex = 0; if (skeleton) { diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index 41e380f64c..eabc3448de 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -50,23 +50,17 @@ protected: rotationVar(rotationVarIn), jointName(jointNameIn), jointIndex(-1), - hasPerformedJointLookup(false) {} + rootIndex(-1) {} std::string positionVar; std::string rotationVar; QString jointName; int jointIndex; // cached joint index - bool hasPerformedJointLookup = false; - }; - - struct IKTarget { - AnimPose pose; - int rootIndex; + int rootIndex; // cached root index }; std::map _constraints; std::vector _targetVarVec; - std::map _absoluteTargets; // IK targets of end-points AnimPoseVec _defaultRelativePoses; // poses of the relaxed state AnimPoseVec _relativePoses; // current relative poses diff --git a/libraries/animation/src/AnimVariant.h b/libraries/animation/src/AnimVariant.h index ac84aafc32..bcff4b2a9b 100644 --- a/libraries/animation/src/AnimVariant.h +++ b/libraries/animation/src/AnimVariant.h @@ -154,6 +154,8 @@ public: void setTrigger(const std::string& key) { _triggers.insert(key); } void clearTriggers() { _triggers.clear(); } + bool hasKey(const std::string& key) const { return _map.find(key) != _map.end(); } + protected: std::map _map; std::set _triggers; From d4ea661aca6adda2bc3c414e58d0c58e49478191 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 16 Sep 2015 12:18:59 -0700 Subject: [PATCH 13/15] cleanup whitespace --- libraries/animation/src/AnimInverseKinematics.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index ca619f9641..3b3af762bf 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -211,8 +211,8 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar // compute joint's new parent-relative rotation // Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q glm::quat newRot = glm::normalize(glm::inverse( - absolutePoses[parentIndex].rot) * - deltaRotation * + absolutePoses[parentIndex].rot) * + deltaRotation * absolutePoses[pivotIndex].rot); RotationConstraint* constraint = getConstraint(pivotIndex); if (constraint) { @@ -221,8 +221,8 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar // the constraint will modify the movement of the tip so we have to compute the modified // model-frame deltaRotation // Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^ - deltaRotation = absolutePoses[parentIndex].rot * - newRot * + deltaRotation = absolutePoses[parentIndex].rot * + newRot * glm::inverse(absolutePoses[pivotIndex].rot); } } @@ -319,7 +319,7 @@ void AnimInverseKinematics::initConstraints() { // We create constraints for the joints shown here // (and their Left counterparts if applicable). // - // + // // O RightHand // Head / // O / @@ -473,7 +473,7 @@ void AnimInverseKinematics::initConstraints() { const float MAX_HAND_SWING = PI / 2.0f; minDots.push_back(cosf(MAX_HAND_SWING)); stConstraint->setSwingLimits(minDots); - + constraint = static_cast(stConstraint); } else if (baseName.startsWith("Shoulder", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); From e1fc1900ab08af7418417c50fb2931a02558c6ed Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 16 Sep 2015 15:23:52 -0700 Subject: [PATCH 14/15] remove IK 'flutter' bug --- libraries/animation/src/AnimInverseKinematics.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 3b3af762bf..863970ccaa 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -283,12 +283,16 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars loadPoses(underPoses); } else { // relax toward underpose - const float RELAXATION_TIMESCALE = 0.125f; - const float alpha = glm::clamp(dt / RELAXATION_TIMESCALE, 0.0f, 1.0f); + // HACK: this relaxation needs to be constant per-frame rather than per-realtime + // in order to prevent IK "flutter" for bad FPS. The bad news is that the good parts + // of this relaxation will be FPS dependent (low FPS will make the limbs align slower + // in real-time), however most people will not notice this and this problem is less + // annoying than the flutter. + const float blend = (1.0f / 60.0f) / (0.25f); // effectively: dt / RELAXATION_TIMESCALE int numJoints = (int)_relativePoses.size(); for (int i = 0; i < numJoints; ++i) { float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot, underPoses[i].rot)); - _relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * underPoses[i].rot, alpha)); + _relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * underPoses[i].rot, blend)); } } return evaluate(animVars, dt, triggersOut); From b645d994123ce816ec15e5ad2b5b2c57729d9d27 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 16 Sep 2015 17:07:12 -0700 Subject: [PATCH 15/15] CR feedback --- libraries/script-engine/src/ScriptEngine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 771906aa95..692a320b4e 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -909,7 +909,6 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& #ifdef THREAD_DEBUGGING qDebug() << "ScriptEngine::loadEntityScript() calling scriptCache->getScriptContents() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; #endif - DependencyManager::get()->getScriptContents(entityScript, [=](const QString& scriptOrURL, const QString& contents, bool isURL, bool success) { #ifdef THREAD_DEBUGGING qDebug() << "ScriptEngine::entityScriptContentAvailable() IN LAMBDA contentAvailable on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";