From cbb8bee9621050be4c21cf8a0b3d473b6c1ca6f7 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 16 Sep 2015 14:59:38 -0700 Subject: [PATCH 1/8] 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 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 b645d994123ce816ec15e5ad2b5b2c57729d9d27 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 16 Sep 2015 17:07:12 -0700 Subject: [PATCH 8/8] 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() << "]";