From 4e298d815ddbb5ebcf7c81391454dffb1a33c13c Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 24 Jul 2015 14:07:32 -0700 Subject: [PATCH] Add the joint mapping necessary for playing animations in the rig. --- libraries/animation/src/AnimationHandle.cpp | 11 ++++++++++- libraries/animation/src/AnimationHandle.h | 4 ++-- libraries/animation/src/Rig.cpp | 11 +++++++++++ libraries/animation/src/Rig.h | 11 ++++++++++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index 51e8cb62d2..e8ac6e0a10 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -103,6 +103,15 @@ void AnimationHandle::setJointMappings(QVector jointMappings) { _jointMappings = jointMappings; } +QVector AnimationHandle::getJointMappings() { + if (_jointMappings.isEmpty()) { + QVector animationJoints = _animation->getGeometry().joints; + for (int i = 0; i < animationJoints.count(); i++) { + _jointMappings.append(_rig->indexOfJoint(animationJoints.at(i).name)); + } + } + return _jointMappings; +} void AnimationHandle::simulate(float deltaTime) { if (!_animation || !_animation->isLoaded()) { @@ -111,7 +120,7 @@ void AnimationHandle::simulate(float deltaTime) { _animationLoop.simulate(deltaTime); - if (_jointMappings.isEmpty()) { + if (getJointMappings().isEmpty()) { qDebug() << "AnimationHandle::simulate -- _jointMappings.isEmpty()"; return; } diff --git a/libraries/animation/src/AnimationHandle.h b/libraries/animation/src/AnimationHandle.h index 9075118f43..5d39682a0a 100644 --- a/libraries/animation/src/AnimationHandle.h +++ b/libraries/animation/src/AnimationHandle.h @@ -45,7 +45,7 @@ inline uint qHash(const std::weak_ptr& a, uint seed) { -/// Represents a handle to a model animation. +/// Represents a handle to a model animation. I.e., an Animation in use by a given Rig. class AnimationHandle : public QObject, public std::enable_shared_from_this { Q_OBJECT @@ -96,6 +96,7 @@ public: void setAnimationDetails(const AnimationDetails& details); void setJointMappings(QVector jointMappings); + QVector getJointMappings(); // computing if necessary void simulate(float deltaTime); void applyFrame(float frameIndex); void replaceMatchingPriorities(float newPriority); @@ -125,7 +126,6 @@ private: AnimationLoop _animationLoop; static QHash, QVector> _jointMappingsCache; - static QVector getJointMappings(const AnimationPointer& animation); }; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index e0b1625813..8f4047bc71 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -73,6 +73,17 @@ float Rig::initJointStates(QVector states, glm::mat4 parentTransform return radius; } +// We could build and cache a dictionary, too.... +// Should we be using .fst mapping instead/also? +int Rig::indexOfJoint(const QString& jointName) { + for (int i = 0; i < _jointStates.count(); i++) { + if (_jointStates[i].getFBXJoint().name == jointName) { + return i; + } + } + return -1; +} + void Rig::initJointTransforms(glm::mat4 parentTransform) { // compute model transforms diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 20110813fc..0af4073c96 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -10,7 +10,15 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* TBD: +/* + Things we want to be able to do, that I think we cannot do now: + * Stop an animation at a given time so that it can be examined visually or in a test harness. (I think we can already stop animation and set frame to a computed float? But does that move the bones?) + * Play two animations, blending between them. (Current structure just has one, under script control.) + * Fade in an animation over another. + * Apply IK, lean, head pointing or other overrides relative to previous position. + All of this depends on coordinated state. + + TBD: - What are responsibilities of Animation/AnimationPointer/AnimationCache/AnimationDetails/AnimationObject/AnimationLoop? Is there common/copied code (e.g., ScriptableAvatar::update)? - How do attachments interact with the physics of the attached entity? E.g., do hand joints need to reflect held object @@ -58,6 +66,7 @@ public: float initJointStates(QVector states, glm::mat4 parentTransform, int neckJointIndex); bool jointStatesEmpty() { return _jointStates.isEmpty(); }; int getJointStateCount() const { return _jointStates.size(); } + int indexOfJoint(const QString& jointName) ; void initJointTransforms(glm::mat4 parentTransform); void clearJointTransformTranslation(int jointIndex);