diff --git a/interface/resources/html/img/controls-help-oculus.png b/interface/resources/html/img/controls-help-oculus.png
index 0bd0a656de..8887bc9ab1 100644
Binary files a/interface/resources/html/img/controls-help-oculus.png and b/interface/resources/html/img/controls-help-oculus.png differ
diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp
index 843d654d0e..23d689e339 100644
--- a/interface/src/Menu.cpp
+++ b/interface/src/Menu.cpp
@@ -515,6 +515,8 @@ Menu::Menu() {
avatar.get(), SLOT(setEnableInverseKinematics(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSensorToWorldMatrix, 0, false,
avatar.get(), SLOT(setEnableDebugDrawSensorToWorldMatrix(bool)));
+ addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderIKTargets, 0, false,
+ avatar.get(), SLOT(setEnableDebugDrawIKTargets(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ActionMotorControl,
Qt::CTRL | Qt::SHIFT | Qt::Key_K, true, avatar.get(), SLOT(updateMotionBehaviorFromMenu()),
diff --git a/interface/src/Menu.h b/interface/src/Menu.h
index b4eaf56758..14b2f4aeaa 100644
--- a/interface/src/Menu.h
+++ b/interface/src/Menu.h
@@ -161,6 +161,7 @@ namespace MenuOption {
const QString RenderResolutionThird = "1/3";
const QString RenderResolutionQuarter = "1/4";
const QString RenderSensorToWorldMatrix = "Show SensorToWorld Matrix";
+ const QString RenderIKTargets = "Show IK Targets";
const QString ResetAvatarSize = "Reset Avatar Size";
const QString ResetSensors = "Reset Sensors";
const QString RunningScripts = "Running Scripts...";
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index e0f4b55393..0d0390a365 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -491,6 +491,11 @@ void MyAvatar::simulate(float deltaTime) {
{
PerformanceTimer perfTimer("skeleton");
+
+ if (_rig) {
+ _rig->setEnableDebugDrawIKTargets(_enableDebugDrawIKTargets);
+ }
+
_skeletonModel->simulate(deltaTime);
}
@@ -916,6 +921,10 @@ void MyAvatar::setEnableDebugDrawSensorToWorldMatrix(bool isEnabled) {
}
}
+void MyAvatar::setEnableDebugDrawIKTargets(bool isEnabled) {
+ _enableDebugDrawIKTargets = isEnabled;
+}
+
void MyAvatar::setEnableMeshVisible(bool isEnabled) {
render::ScenePointer scene = qApp->getMain3DScene();
_skeletonModel->setVisibleInScene(isEnabled, scene);
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 9f93fa1bd2..add57cf5be 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -482,6 +482,7 @@ public slots:
void setEnableDebugDrawPosition(bool isEnabled);
void setEnableDebugDrawHandControllers(bool isEnabled);
void setEnableDebugDrawSensorToWorldMatrix(bool isEnabled);
+ void setEnableDebugDrawIKTargets(bool isEnabled);
bool getEnableMeshVisible() const { return _skeletonModel->isVisible(); }
void setEnableMeshVisible(bool isEnabled);
void setUseAnimPreAndPostRotations(bool isEnabled);
@@ -668,6 +669,7 @@ private:
bool _enableDebugDrawAnimPose { false };
bool _enableDebugDrawHandControllers { false };
bool _enableDebugDrawSensorToWorldMatrix { false };
+ bool _enableDebugDrawIKTargets { false };
AudioListenerMode _audioListenerMode;
glm::vec3 _customListenPosition;
diff --git a/libraries/animation/src/AnimBlendLinear.cpp b/libraries/animation/src/AnimBlendLinear.cpp
index 52c440a14e..936126bf52 100644
--- a/libraries/animation/src/AnimBlendLinear.cpp
+++ b/libraries/animation/src/AnimBlendLinear.cpp
@@ -24,7 +24,7 @@ AnimBlendLinear::~AnimBlendLinear() {
}
-const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
+const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) {
_alpha = animVars.lookup(_alphaVar, _alpha);
@@ -33,7 +33,7 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, flo
pose = AnimPose::identity;
}
} else if (_children.size() == 1) {
- _poses = _children[0]->evaluate(animVars, dt, triggersOut);
+ _poses = _children[0]->evaluate(animVars, context, dt, triggersOut);
} else {
float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
@@ -41,7 +41,7 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, flo
size_t nextPoseIndex = glm::ceil(clampedAlpha);
float alpha = glm::fract(clampedAlpha);
- evaluateAndBlendChildren(animVars, triggersOut, alpha, prevPoseIndex, nextPoseIndex, dt);
+ evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, dt);
}
return _poses;
}
@@ -51,15 +51,15 @@ const AnimPoseVec& AnimBlendLinear::getPosesInternal() const {
return _poses;
}
-void AnimBlendLinear::evaluateAndBlendChildren(const AnimVariantMap& animVars, Triggers& triggersOut, float alpha,
+void AnimBlendLinear::evaluateAndBlendChildren(const AnimVariantMap& animVars, const AnimContext& context, Triggers& triggersOut, float alpha,
size_t prevPoseIndex, size_t nextPoseIndex, float dt) {
if (prevPoseIndex == nextPoseIndex) {
// this can happen if alpha is on an integer boundary
- _poses = _children[prevPoseIndex]->evaluate(animVars, dt, triggersOut);
+ _poses = _children[prevPoseIndex]->evaluate(animVars, context, dt, triggersOut);
} else {
// need to eval and blend between two children.
- auto prevPoses = _children[prevPoseIndex]->evaluate(animVars, dt, triggersOut);
- auto nextPoses = _children[nextPoseIndex]->evaluate(animVars, dt, triggersOut);
+ auto prevPoses = _children[prevPoseIndex]->evaluate(animVars, context, dt, triggersOut);
+ auto nextPoses = _children[nextPoseIndex]->evaluate(animVars, context, dt, triggersOut);
if (prevPoses.size() > 0 && prevPoses.size() == nextPoses.size()) {
_poses.resize(prevPoses.size());
diff --git a/libraries/animation/src/AnimBlendLinear.h b/libraries/animation/src/AnimBlendLinear.h
index 2478f9b473..0dae6aabdb 100644
--- a/libraries/animation/src/AnimBlendLinear.h
+++ b/libraries/animation/src/AnimBlendLinear.h
@@ -30,7 +30,7 @@ public:
AnimBlendLinear(const QString& id, float alpha);
virtual ~AnimBlendLinear() override;
- virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) override;
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) override;
void setAlphaVar(const QString& alphaVar) { _alphaVar = alphaVar; }
@@ -38,7 +38,7 @@ protected:
// for AnimDebugDraw rendering
virtual const AnimPoseVec& getPosesInternal() const override;
- void evaluateAndBlendChildren(const AnimVariantMap& animVars, Triggers& triggersOut, float alpha,
+ void evaluateAndBlendChildren(const AnimVariantMap& animVars, const AnimContext& context, Triggers& triggersOut, float alpha,
size_t prevPoseIndex, size_t nextPoseIndex, float dt);
AnimPoseVec _poses;
diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp
index 609b464512..40fbb5a6f7 100644
--- a/libraries/animation/src/AnimBlendLinearMove.cpp
+++ b/libraries/animation/src/AnimBlendLinearMove.cpp
@@ -26,7 +26,7 @@ AnimBlendLinearMove::~AnimBlendLinearMove() {
}
-const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
+const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) {
assert(_children.size() == _characteristicSpeeds.size());
@@ -43,7 +43,7 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
const int nextPoseIndex = 0;
float prevDeltaTime, nextDeltaTime;
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
- evaluateAndBlendChildren(animVars, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
+ evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
} else {
auto clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
@@ -52,7 +52,7 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
auto alpha = glm::fract(clampedAlpha);
float prevDeltaTime, nextDeltaTime;
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
- evaluateAndBlendChildren(animVars, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
+ evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
}
return _poses;
}
@@ -62,16 +62,16 @@ const AnimPoseVec& AnimBlendLinearMove::getPosesInternal() const {
return _poses;
}
-void AnimBlendLinearMove::evaluateAndBlendChildren(const AnimVariantMap& animVars, Triggers& triggersOut, float alpha,
+void AnimBlendLinearMove::evaluateAndBlendChildren(const AnimVariantMap& animVars, const AnimContext& context, Triggers& triggersOut, float alpha,
size_t prevPoseIndex, size_t nextPoseIndex,
float prevDeltaTime, float nextDeltaTime) {
if (prevPoseIndex == nextPoseIndex) {
// this can happen if alpha is on an integer boundary
- _poses = _children[prevPoseIndex]->evaluate(animVars, prevDeltaTime, triggersOut);
+ _poses = _children[prevPoseIndex]->evaluate(animVars, context, prevDeltaTime, triggersOut);
} else {
// need to eval and blend between two children.
- auto prevPoses = _children[prevPoseIndex]->evaluate(animVars, prevDeltaTime, triggersOut);
- auto nextPoses = _children[nextPoseIndex]->evaluate(animVars, nextDeltaTime, triggersOut);
+ auto prevPoses = _children[prevPoseIndex]->evaluate(animVars, context, prevDeltaTime, triggersOut);
+ auto nextPoses = _children[nextPoseIndex]->evaluate(animVars, context, nextDeltaTime, triggersOut);
if (prevPoses.size() > 0 && prevPoses.size() == nextPoses.size()) {
_poses.resize(prevPoses.size());
diff --git a/libraries/animation/src/AnimBlendLinearMove.h b/libraries/animation/src/AnimBlendLinearMove.h
index 4e04ce29cb..083858f873 100644
--- a/libraries/animation/src/AnimBlendLinearMove.h
+++ b/libraries/animation/src/AnimBlendLinearMove.h
@@ -39,7 +39,7 @@ public:
AnimBlendLinearMove(const QString& id, float alpha, float desiredSpeed, const std::vector& characteristicSpeeds);
virtual ~AnimBlendLinearMove() override;
- virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) override;
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) override;
void setAlphaVar(const QString& alphaVar) { _alphaVar = alphaVar; }
void setDesiredSpeedVar(const QString& desiredSpeedVar) { _desiredSpeedVar = desiredSpeedVar; }
@@ -48,7 +48,7 @@ protected:
// for AnimDebugDraw rendering
virtual const AnimPoseVec& getPosesInternal() const override;
- void evaluateAndBlendChildren(const AnimVariantMap& animVars, Triggers& triggersOut, float alpha,
+ void evaluateAndBlendChildren(const AnimVariantMap& animVars, const AnimContext& context, Triggers& triggersOut, float alpha,
size_t prevPoseIndex, size_t nextPoseIndex,
float prevDeltaTime, float nextDeltaTime);
diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp
index cb1d058576..1118e21c91 100644
--- a/libraries/animation/src/AnimClip.cpp
+++ b/libraries/animation/src/AnimClip.cpp
@@ -31,7 +31,7 @@ AnimClip::~AnimClip() {
}
-const AnimPoseVec& AnimClip::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
+const AnimPoseVec& AnimClip::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) {
// lookup parameters from animVars, using current instance variables as defaults.
_startFrame = animVars.lookup(_startFrameVar, _startFrame);
diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h
index 7989f6d172..c7e7ebf3ee 100644
--- a/libraries/animation/src/AnimClip.h
+++ b/libraries/animation/src/AnimClip.h
@@ -30,7 +30,7 @@ public:
AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag);
virtual ~AnimClip() override;
- virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) override;
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) override;
void setStartFrameVar(const QString& startFrameVar) { _startFrameVar = startFrameVar; }
void setEndFrameVar(const QString& endFrameVar) { _endFrameVar = endFrameVar; }
diff --git a/libraries/animation/src/AnimContext.cpp b/libraries/animation/src/AnimContext.cpp
new file mode 100644
index 0000000000..c8d3e7bcda
--- /dev/null
+++ b/libraries/animation/src/AnimContext.cpp
@@ -0,0 +1,16 @@
+//
+// AnimContext.cpp
+//
+// Created by Anthony J. Thibault on 9/19/16.
+// Copyright (c) 2016 High Fidelity, Inc. All rights reserved.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include "AnimContext.h"
+
+AnimContext::AnimContext(bool enableDebugDrawIKTargets, const glm::mat4& geometryToRigMatrix) :
+ _enableDebugDrawIKTargets(enableDebugDrawIKTargets),
+ _geometryToRigMatrix(geometryToRigMatrix) {
+}
diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h
new file mode 100644
index 0000000000..3170911e14
--- /dev/null
+++ b/libraries/animation/src/AnimContext.h
@@ -0,0 +1,30 @@
+//
+// AnimContext.h
+//
+// Created by Anthony J. Thibault on 9/19/16.
+// Copyright (c) 2016 High Fidelity, Inc. All rights reserved.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef hifi_AnimContext_h
+#define hifi_AnimContext_h
+
+#include
+#include
+
+class AnimContext {
+public:
+ AnimContext(bool enableDebugDrawIKTargets, const glm::mat4& geometryToRigMatrix);
+
+ bool getEnableDebugDrawIKTargets() const { return _enableDebugDrawIKTargets; }
+ const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; }
+
+protected:
+
+ bool _enableDebugDrawIKTargets { false };
+ glm::mat4 _geometryToRigMatrix;
+};
+
+#endif // hifi_AnimContext_h
diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp
index fa8e4654f6..2c9376d591 100644
--- a/libraries/animation/src/AnimInverseKinematics.cpp
+++ b/libraries/animation/src/AnimInverseKinematics.cpp
@@ -14,6 +14,8 @@
#include
#include
#include
+#include
+#include "Rig.h"
#include "ElbowConstraint.h"
#include "SwingTwistConstraint.h"
@@ -378,14 +380,14 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe
}
//virtual
-const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVars, float dt, AnimNode::Triggers& triggersOut) {
+const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimNode::Triggers& triggersOut) {
// don't call this function, call overlay() instead
assert(false);
return _relativePoses;
}
//virtual
-const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
+const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
const float MAX_OVERLAY_DT = 1.0f / 30.0f; // what to clamp delta-time to in AnimInverseKinematics::overlay
if (dt > MAX_OVERLAY_DT) {
@@ -439,6 +441,28 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
computeTargets(animVars, targets, underPoses);
}
+ // debug render ik targets
+ if (context.getEnableDebugDrawIKTargets()) {
+ const vec4 WHITE(1.0f);
+ glm::mat4 rigToAvatarMat = createMatFromQuatAndPos(Quaternions::Y_180, glm::vec3());
+
+ for (auto& target : targets) {
+ glm::mat4 geomTargetMat = createMatFromQuatAndPos(target.getRotation(), target.getTranslation());
+ glm::mat4 avatarTargetMat = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat;
+
+ QString name = QString("ikTarget%1").arg(target.getIndex());
+ DebugDraw::getInstance().addMyAvatarMarker(name, glmExtractRotation(avatarTargetMat), extractTranslation(avatarTargetMat), WHITE);
+ }
+ } else if (context.getEnableDebugDrawIKTargets() != _previousEnableDebugIKTargets) {
+ // remove markers if they were added last frame.
+ for (auto& target : targets) {
+ QString name = QString("ikTarget%1").arg(target.getIndex());
+ DebugDraw::getInstance().removeMyAvatarMarker(name);
+ }
+ }
+
+ _previousEnableDebugIKTargets = context.getEnableDebugDrawIKTargets();
+
if (targets.empty()) {
// no IK targets but still need to enforce constraints
std::map::iterator constraintItr = _constraints.begin();
diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h
index 892a5616b2..366e5f765e 100644
--- a/libraries/animation/src/AnimInverseKinematics.h
+++ b/libraries/animation/src/AnimInverseKinematics.h
@@ -34,8 +34,8 @@ public:
void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, const QString& typeVar);
- virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, AnimNode::Triggers& triggersOut) override;
- virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override;
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimNode::Triggers& triggersOut) override;
+ virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override;
void clearIKJointLimitHistory();
@@ -97,6 +97,7 @@ protected:
int _maxTargetIndex { 0 };
float _maxErrorOnLastSolve { FLT_MAX };
+ bool _previousEnableDebugIKTargets { false };
};
#endif // hifi_AnimInverseKinematics_h
diff --git a/libraries/animation/src/AnimManipulator.cpp b/libraries/animation/src/AnimManipulator.cpp
index f2bd2d983a..111501898a 100644
--- a/libraries/animation/src/AnimManipulator.cpp
+++ b/libraries/animation/src/AnimManipulator.cpp
@@ -22,11 +22,11 @@ AnimManipulator::~AnimManipulator() {
}
-const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
- return overlay(animVars, dt, triggersOut, _skeleton->getRelativeBindPoses());
+const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) {
+ return overlay(animVars, context, dt, triggersOut, _skeleton->getRelativeBindPoses());
}
-const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
+const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
_alpha = animVars.lookup(_alphaVar, _alpha);
_poses = underPoses;
diff --git a/libraries/animation/src/AnimManipulator.h b/libraries/animation/src/AnimManipulator.h
index 8534b9c269..26f50a7dd9 100644
--- a/libraries/animation/src/AnimManipulator.h
+++ b/libraries/animation/src/AnimManipulator.h
@@ -22,8 +22,8 @@ public:
AnimManipulator(const QString& 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;
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) override;
+ virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override;
void setAlphaVar(const QString& alphaVar) { _alphaVar = alphaVar; }
diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h
index 23f2e1c7b3..10db38f42e 100644
--- a/libraries/animation/src/AnimNode.h
+++ b/libraries/animation/src/AnimNode.h
@@ -20,6 +20,7 @@
#include "AnimSkeleton.h"
#include "AnimVariant.h"
+#include "AnimContext.h"
class QJsonObject;
@@ -72,9 +73,10 @@ public:
AnimSkeleton::ConstPointer getSkeleton() const { return _skeleton; }
- virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) = 0;
- virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
- return evaluate(animVars, dt, triggersOut);
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) = 0;
+ virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut,
+ const AnimPoseVec& underPoses) {
+ return evaluate(animVars, context, dt, triggersOut);
}
void setCurrentFrame(float frame);
diff --git a/libraries/animation/src/AnimOverlay.cpp b/libraries/animation/src/AnimOverlay.cpp
index 8f60b972ce..dbc635af66 100644
--- a/libraries/animation/src/AnimOverlay.cpp
+++ b/libraries/animation/src/AnimOverlay.cpp
@@ -39,7 +39,7 @@ void AnimOverlay::buildBoneSet(BoneSet boneSet) {
}
}
-const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
+const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) {
// lookup parameters from animVars, using current instance variables as defaults.
// NOTE: switching bonesets can be an expensive operation, let's try to avoid it.
@@ -51,8 +51,8 @@ const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, float d
_alpha = animVars.lookup(_alphaVar, _alpha);
if (_children.size() >= 2) {
- auto& underPoses = _children[1]->evaluate(animVars, dt, triggersOut);
- auto& overPoses = _children[0]->overlay(animVars, dt, triggersOut, underPoses);
+ auto& underPoses = _children[1]->evaluate(animVars, context, dt, triggersOut);
+ auto& overPoses = _children[0]->overlay(animVars, context, dt, triggersOut, underPoses);
if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) {
_poses.resize(underPoses.size());
diff --git a/libraries/animation/src/AnimOverlay.h b/libraries/animation/src/AnimOverlay.h
index eda8847d40..2f34c07309 100644
--- a/libraries/animation/src/AnimOverlay.h
+++ b/libraries/animation/src/AnimOverlay.h
@@ -43,7 +43,7 @@ public:
AnimOverlay(const QString& id, BoneSet boneSet, float alpha);
virtual ~AnimOverlay() override;
- virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) override;
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) override;
void setBoneSetVar(const QString& boneSetVar) { _boneSetVar = boneSetVar; }
void setAlphaVar(const QString& alphaVar) { _alphaVar = alphaVar; }
diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp
index 41d8a94b0a..4e86b92c0b 100644
--- a/libraries/animation/src/AnimStateMachine.cpp
+++ b/libraries/animation/src/AnimStateMachine.cpp
@@ -21,7 +21,7 @@ AnimStateMachine::~AnimStateMachine() {
}
-const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
+const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) {
QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID());
if (_currentState->getID() != desiredStateID) {
@@ -29,7 +29,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl
bool foundState = false;
for (auto& state : _states) {
if (state->getID() == desiredStateID) {
- switchState(animVars, state);
+ switchState(animVars, context, state);
foundState = true;
break;
}
@@ -42,7 +42,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl
// evaluate currentState transitions
auto desiredState = evaluateTransitions(animVars);
if (desiredState != _currentState) {
- switchState(animVars, desiredState);
+ switchState(animVars, context, desiredState);
}
assert(_currentState);
@@ -62,7 +62,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl
} else if (_interpType == InterpType::SnapshotPrev) {
// interp between the prev snapshot and evaluated next target.
// this is useful for interping into a blend
- localNextPoses = currentStateNode->evaluate(animVars, dt, triggersOut);
+ localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
prevPoses = &_prevPoses;
nextPoses = &localNextPoses;
} else {
@@ -79,7 +79,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl
}
}
if (!_duringInterp) {
- _poses = currentStateNode->evaluate(animVars, dt, triggersOut);
+ _poses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
}
return _poses;
}
@@ -92,7 +92,7 @@ void AnimStateMachine::addState(State::Pointer state) {
_states.push_back(state);
}
-void AnimStateMachine::switchState(const AnimVariantMap& animVars, State::Pointer desiredState) {
+void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimContext& context, State::Pointer desiredState) {
const float FRAMES_PER_SECOND = 30.0f;
@@ -114,7 +114,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, State::Pointe
_prevPoses = _poses;
// snapshot next pose at the target frame.
nextStateNode->setCurrentFrame(desiredState->_interpTarget);
- _nextPoses = nextStateNode->evaluate(animVars, dt, triggers);
+ _nextPoses = nextStateNode->evaluate(animVars, context, dt, triggers);
} else if (_interpType == InterpType::SnapshotPrev) {
// snapshot previoius pose
_prevPoses = _poses;
diff --git a/libraries/animation/src/AnimStateMachine.h b/libraries/animation/src/AnimStateMachine.h
index d92b94d1b5..711326a9ae 100644
--- a/libraries/animation/src/AnimStateMachine.h
+++ b/libraries/animation/src/AnimStateMachine.h
@@ -113,7 +113,7 @@ public:
explicit AnimStateMachine(const QString& id);
virtual ~AnimStateMachine() override;
- virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) override;
+ virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) override;
void setCurrentStateVar(QString& currentStateVar) { _currentStateVar = currentStateVar; }
@@ -123,7 +123,7 @@ protected:
void addState(State::Pointer state);
- void switchState(const AnimVariantMap& animVars, State::Pointer desiredState);
+ void switchState(const AnimVariantMap& animVars, const AnimContext& context, State::Pointer desiredState);
State::Pointer evaluateTransitions(const AnimVariantMap& animVars) const;
// for AnimDebugDraw rendering
diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp
index 0520e5c5a1..8b54f0ee92 100644
--- a/libraries/animation/src/Rig.cpp
+++ b/libraries/animation/src/Rig.cpp
@@ -950,9 +950,11 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
updateAnimationStateHandlers();
_animVars.setRigToGeometryTransform(_rigToGeometryTransform);
+ AnimContext context(_enableDebugDrawIKTargets, getGeometryToRigTransform());
+
// evaluate the animation
AnimNode::Triggers triggersOut;
- _internalPoseSet._relativePoses = _animNode->evaluate(_animVars, deltaTime, triggersOut);
+ _internalPoseSet._relativePoses = _animNode->evaluate(_animVars, context, deltaTime, triggersOut);
if ((int)_internalPoseSet._relativePoses.size() != _animSkeleton->getNumJoints()) {
// animations haven't fully loaded yet.
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
@@ -1427,9 +1429,10 @@ void Rig::computeAvatarBoundingCapsule(
// call overlay twice: once to verify AnimPoseVec joints and again to do the IK
AnimNode::Triggers triggersOut;
+ AnimContext context(false, glm::mat4());
float dt = 1.0f; // the value of this does not matter
- ikNode.overlay(animVars, dt, triggersOut, _animSkeleton->getRelativeBindPoses());
- AnimPoseVec finalPoses = ikNode.overlay(animVars, dt, triggersOut, _animSkeleton->getRelativeBindPoses());
+ ikNode.overlay(animVars, context, dt, triggersOut, _animSkeleton->getRelativeBindPoses());
+ AnimPoseVec finalPoses = ikNode.overlay(animVars, context, dt, triggersOut, _animSkeleton->getRelativeBindPoses());
// convert relative poses to absolute
_animSkeleton->convertRelativePosesToAbsolute(finalPoses);
diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h
index 41cc5cabc6..ea498e6a69 100644
--- a/libraries/animation/src/Rig.h
+++ b/libraries/animation/src/Rig.h
@@ -219,6 +219,8 @@ public:
const glm::mat4& getGeometryToRigTransform() const { return _geometryToRigTransform; }
+ void setEnableDebugDrawIKTargets(bool enableDebugDrawIKTargets) { _enableDebugDrawIKTargets = enableDebugDrawIKTargets; }
+
signals:
void onLoadComplete();
@@ -324,7 +326,8 @@ protected:
mutable uint32_t _jointNameWarningCount { 0 };
float _maxHipsOffsetLength { 1.0f };
- float _maxErrorOnLastSolve { 0.0f };
+
+ bool _enableDebugDrawIKTargets { false };
private:
QMap _stateHandlers;
diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
index d93e399ab4..509e63cbfe 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
@@ -608,7 +608,6 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons
(void**)&intersectedEntity, lockType, &result.accurate);
if (result.intersects && intersectedEntity) {
result.entityID = intersectedEntity->getEntityItemID();
- result.properties = intersectedEntity->getProperties();
result.intersection = ray.origin + (ray.direction * result.distance);
result.entity = intersectedEntity;
}
@@ -704,7 +703,9 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
if (rayPickResult.intersects) {
//qCDebug(entitiesrenderer) << "mousePressEvent over entity:" << rayPickResult.entityID;
- QString urlString = rayPickResult.properties.getHref();
+ auto entity = getTree()->findEntityByEntityItemID(rayPickResult.entityID);
+ auto properties = entity->getProperties();
+ QString urlString = properties.getHref();
QUrl url = QUrl(urlString, QUrl::StrictMode);
if (url.isValid() && !url.isEmpty()){
DependencyManager::get()->handleLookupString(urlString);
@@ -751,12 +752,6 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) {
if (rayPickResult.intersects) {
//qCDebug(entitiesrenderer) << "mouseDoublePressEvent over entity:" << rayPickResult.entityID;
- QString urlString = rayPickResult.properties.getHref();
- QUrl url = QUrl(urlString, QUrl::StrictMode);
- if (url.isValid() && !url.isEmpty()){
- DependencyManager::get()->handleLookupString(urlString);
- }
-
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
PointerEvent pointerEvent(PointerEvent::Press, MOUSE_POINTER_ID,
pos2D, rayPickResult.intersection,
diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp
index 1ab5438e53..1dded10302 100644
--- a/libraries/entities/src/EntityScriptingInterface.cpp
+++ b/libraries/entities/src/EntityScriptingInterface.cpp
@@ -673,7 +673,6 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorke
(void**)&intersectedEntity, lockType, &result.accurate);
if (result.intersects && intersectedEntity) {
result.entityID = intersectedEntity->getEntityItemID();
- result.properties = intersectedEntity->getProperties();
result.intersection = ray.origin + (ray.direction * result.distance);
}
}
@@ -838,7 +837,6 @@ RayToEntityIntersectionResult::RayToEntityIntersectionResult() :
intersects(false),
accurate(true), // assume it's accurate
entityID(),
- properties(),
distance(0),
face(),
entity(NULL)
@@ -854,9 +852,6 @@ QScriptValue RayToEntityIntersectionResultToScriptValue(QScriptEngine* engine, c
QScriptValue entityItemValue = EntityItemIDtoScriptValue(engine, value.entityID);
obj.setProperty("entityID", entityItemValue);
- QScriptValue propertiesValue = EntityItemPropertiesToScriptValue(engine, value.properties);
- obj.setProperty("properties", propertiesValue);
-
obj.setProperty("distance", value.distance);
QString faceName = "";
@@ -902,10 +897,6 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra
QScriptValue entityIDValue = object.property("entityID");
// EntityItemIDfromScriptValue(entityIDValue, value.entityID);
quuidFromScriptValue(entityIDValue, value.entityID);
- QScriptValue entityPropertiesValue = object.property("properties");
- if (entityPropertiesValue.isValid()) {
- EntityItemPropertiesFromScriptValueHonorReadOnly(entityPropertiesValue, value.properties);
- }
value.distance = object.property("distance").toVariant().toFloat();
QString faceName = object.property("face").toVariant().toString();
diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h
index 63b5771e60..630c55e4e2 100644
--- a/libraries/entities/src/EntityScriptingInterface.h
+++ b/libraries/entities/src/EntityScriptingInterface.h
@@ -58,7 +58,6 @@ public:
bool intersects;
bool accurate;
QUuid entityID;
- EntityItemProperties properties;
float distance;
BoxFace face;
glm::vec3 intersection;
diff --git a/script-archive/example/games/grabHockey.js b/script-archive/example/games/grabHockey.js
index 961a8af6ad..3f2a2fcf91 100644
--- a/script-archive/example/games/grabHockey.js
+++ b/script-archive/example/games/grabHockey.js
@@ -142,7 +142,8 @@ function mousePressEvent(event) {
if (!pickResults.intersects) {
return;
}
- if (pickResults.properties.dynamic) {
+ var isDynamic = Entites.getEntityProperties(pickResults.entityID, "dynamic").dynamic;
+ if (isDynamic) {
grabbedEntity = pickResults.entityID;
var props = Entities.getEntityProperties(grabbedEntity)
originalGravity = props.gravity;
diff --git a/script-archive/example/games/hydraGrabHockey.js b/script-archive/example/games/hydraGrabHockey.js
index e7d6746309..e357735fe5 100644
--- a/script-archive/example/games/hydraGrabHockey.js
+++ b/script-archive/example/games/hydraGrabHockey.js
@@ -190,7 +190,10 @@ function controller(side) {
direction: Vec3.normalize(Vec3.subtract(this.tipPosition, this.palmPosition))
};
var intersection = getRayIntersection(pickRay, true);
- if (intersection.intersects && intersection.properties.dynamic) {
+
+ var isDynamic = Entites.getEntityProperties(intersection.entityID, "dynamic").dynamic;
+
+ if (intersection.intersects && isDynamic) {
this.laserWasHovered = true;
if (this.triggerHeld && !this.grabbing) {
this.grab(intersection.entityID);
diff --git a/script-archive/example/scripts/rayPickExample.js b/script-archive/example/scripts/rayPickExample.js
index d85138211e..3687176af1 100644
--- a/script-archive/example/scripts/rayPickExample.js
+++ b/script-archive/example/scripts/rayPickExample.js
@@ -38,7 +38,6 @@ function mouseMoveEvent(event) {
if (intersection.intersects) {
print("intersection entityID=" + intersection.entityID);
- print("intersection properties.modelURL=" + intersection.properties.modelURL);
print("intersection face=" + intersection.face);
print("intersection distance=" + intersection.distance);
print("intersection intersection.x/y/z=" + intersection.intersection.x + ", "
diff --git a/script-archive/painting/whiteboard/whiteboardEntityScript.js b/script-archive/painting/whiteboard/whiteboardEntityScript.js
index 181932c7cb..01497b406d 100644
--- a/script-archive/painting/whiteboard/whiteboardEntityScript.js
+++ b/script-archive/painting/whiteboard/whiteboardEntityScript.js
@@ -77,6 +77,8 @@
//Comment out above line and uncomment below line to see difference in performance between using a whitelist, and not using one
// this.intersection = Entities.findRayIntersection(pickRay, true);
+ var type = Entites.getEntityProperties(this.intersection.entityID, "type").type;
+
if (this.intersection.intersects) {
var distance = Vec3.distance(handPosition, this.intersection.intersection);
if (distance < MAX_DISTANCE) {
@@ -98,7 +100,7 @@
this.oldPosition = null;
}
}
- } else if (this.intersection.properties.type !== "Unknown") {
+ } else if (type !== "Unknown") {
//Sometimes ray will pick against an invisible object with type unkown... so if type is unknown, ignore
this.stopPainting();
}
diff --git a/script-archive/vrShop/item/shopItemGrab.js b/script-archive/vrShop/item/shopItemGrab.js
index a7226675eb..2b63ca1b53 100644
--- a/script-archive/vrShop/item/shopItemGrab.js
+++ b/script-archive/vrShop/item/shopItemGrab.js
@@ -382,7 +382,10 @@ function MyController(hand) {
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA);
- if (intersection.properties.name == "Grab Debug Entity") {
+ var properties = Entites.getEntityProperties(intersection.entityID, ["locked", "name"]);
+
+
+ if (properties.name == "Grab Debug Entity") {
continue;
}
@@ -399,7 +402,7 @@ function MyController(hand) {
this.grabbedEntity = intersection.entityID;
this.setState(STATE_NEAR_TRIGGER);
return;
- } else if (!intersection.properties.locked) {
+ } else if (!properties.locked) {
var ownerObj = getEntityCustomData('ownerKey', intersection.entityID, null);
if (ownerObj == null || ownerObj.ownerID === MyAvatar.sessionUUID) { //I can only grab new or already mine items
diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js
index 05b2eefeb5..10f477b3af 100644
--- a/scripts/system/controllers/grab.js
+++ b/scripts/system/controllers/grab.js
@@ -343,7 +343,8 @@ Grabber.prototype.pressEvent = function(event) {
return;
}
- if (!pickResults.properties.dynamic) {
+ var isDynamic = Entities.getEntityProperties(pickResults.entityID, "dynamic").dynamic;
+ if (!isDynamic) {
// only grab dynamic objects
return;
}
diff --git a/scripts/tutorials/entity_scripts/pistol.js b/scripts/tutorials/entity_scripts/pistol.js
index 38eb929177..1a570cc80f 100644
--- a/scripts/tutorials/entity_scripts/pistol.js
+++ b/scripts/tutorials/entity_scripts/pistol.js
@@ -151,8 +151,9 @@
});
}, randFloat(10, 200));
}
- if (intersection.properties.dynamic === 1) {
- // Any dynaic entity can be shot
+ var isDynamic = Entities.getEntityProperties(intersection.entityID, "dynamic").dynamic;
+ if (isDynamic === 1) {
+ // Any dynamic entity can be shot
Entities.editEntity(intersection.entityID, {
velocity: Vec3.multiply(this.firingDirection, this.bulletForce)
});
@@ -347,7 +348,7 @@
this.laser = Overlays.addOverlay("line3d", {
start: ZERO_VECTOR,
end: ZERO_VECTOR,
- color: COLORS.RED,
+ color: { red: 255, green: 0, blue: 0},
alpha: 1,
visible: true,
lineWidth: 2