11 #ifndef hifi_AnimChain
12 #define hifi_AnimChain
15 #include <glm/glm.hpp>
16 #include <glm/gtc/quaternion.hpp>
18 #include <DebugDraw.h>
26 AnimChainT(
const AnimChainT& orig) {
28 for (
int i = 0; i < _top; i++) {
29 _chain[i] = orig._chain[i];
33 AnimChainT& operator=(
const AnimChainT& orig) {
35 for (
int i = 0; i < _top; i++) {
36 _chain[i] = orig._chain[i];
41 bool buildFromRelativePoses(
const AnimSkeleton::ConstPointer& skeleton,
const AnimPoseVec& relativePoses,
int tipIndex) {
44 for (
int jointIndex = tipIndex; jointIndex != -1; jointIndex = skeleton->getParentIndex(jointIndex)) {
50 _chain[_top].relativePose = relativePoses[jointIndex];
51 _chain[_top].jointIndex = jointIndex;
52 _chain[_top].dirty =
true;
56 buildDirtyAbsolutePoses();
61 const AnimPose& getAbsolutePoseFromJointIndex(
int jointIndex)
const {
62 for (
int i = 0; i < _top; i++) {
63 if (_chain[i].jointIndex == jointIndex) {
64 return _chain[i].absolutePose;
67 return AnimPose::identity;
70 bool setRelativePoseAtJointIndex(
int jointIndex,
const AnimPose& relativePose) {
71 bool foundIndex =
false;
72 for (
int i = _top - 1; i >= 0; i--) {
73 if (_chain[i].jointIndex == jointIndex) {
74 _chain[i].relativePose = relativePose;
79 _chain[i].dirty =
true;
85 void buildDirtyAbsolutePoses() {
87 _chain[_top - 1].absolutePose = _chain[_top - 1].relativePose;
88 _chain[_top - 1].dirty =
false;
91 for (
int i = _top - 1; i > 0; i--) {
92 AnimChainElem& parent = _chain[i];
93 AnimChainElem& child = _chain[i - 1];
96 child.absolutePose = parent.absolutePose * child.relativePose;
102 void blend(
const AnimChainT& srcChain,
float alpha) {
104 assert(srcChain._top == _top);
105 if (srcChain._top != _top) {
110 for (
int i = 0; i < _top; i++) {
111 _chain[i].relativePose.blend(srcChain._chain[i].relativePose, alpha);
112 _chain[i].dirty =
true;
120 void outputRelativePoses(AnimPoseVec& relativePoses) {
121 for (
int i = 0; i < _top; i++) {
122 relativePoses[_chain[i].jointIndex] = _chain[i].relativePose;
126 void debugDraw(
const glm::mat4& geomToWorldMat,
const glm::vec4& color)
const {
127 for (
int i = 1; i < _top; i++) {
128 glm::vec3 start = transformPoint(geomToWorldMat, _chain[i - 1].absolutePose.trans());
129 glm::vec3 end = transformPoint(geomToWorldMat, _chain[i].absolutePose.trans());
130 DebugDraw::getInstance().drawRay(start, end, color);
135 for (
int i = 0; i < _top; i++) {
136 qWarning() <<
"AJT: AnimPoseElem[" << i <<
"]";
137 qWarning() <<
"AJT: relPose =" << _chain[i].relativePose;
138 qWarning() <<
"AJT: absPose =" << _chain[i].absolutePose;
139 qWarning() <<
"AJT: jointIndex =" << _chain[i].jointIndex;
140 qWarning() <<
"AJT: dirty =" << _chain[i].dirty;
146 struct AnimChainElem {
147 AnimPose relativePose;
148 AnimPose absolutePose;
149 int jointIndex { -1 };
153 AnimChainElem _chain[N];
157 using AnimChain = AnimChainT<10>;