1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "SkeletonPoser.h"
6 CSkeletonPoseModifier::SJoint::SJoint()
8 , m_transform(IDENTITY
)
12 CSkeletonPoseModifier::SJoint::SJoint(const string
& name
, const QuatT
& transform
)
14 , m_transform(transform
)
17 m_crc
= m_name
.length() ? CCrc32::ComputeLowercase(m_name
.c_str()) : 0;
20 void CSkeletonPoseModifier::PoseJoint(const string
& name
, const QuatT
& transform
)
22 auto it
= std::find_if(m_posedJoints
.begin(), m_posedJoints
.end(), [name
](const SJoint
& joint
)
24 return joint
.m_name
== name
;
26 if (it
!= m_posedJoints
.end())
28 it
->m_transform
= transform
;
32 m_posedJoints
.emplace_back(name
, transform
);
36 bool CSkeletonPoseModifier::Prepare(const SAnimationPoseModifierParams
& params
)
38 const IDefaultSkeleton
& skeleton
= params
.GetIDefaultSkeleton();
40 for (auto& joint
: m_posedJoints
)
44 joint
.m_id
= skeleton
.GetJointIDByCRC32(joint
.m_crc
);
51 void ComputeAbsolutJointTransformationsRecursive(int joint
, const IDefaultSkeleton
& skel
, IAnimationPoseData
* pPoseData
)
53 const int parent
= skel
.GetJointParentIDByID(joint
);
56 pPoseData
->SetJointAbsolute(joint
, pPoseData
->GetJointAbsolute(parent
) * pPoseData
->GetJointRelative(joint
));
59 for (int i
= 0, N
= skel
.GetJointChildrenCountByID(joint
); i
< N
; ++i
)
61 ComputeAbsolutJointTransformationsRecursive(skel
.GetJointChildIDAtIndexByID(joint
, i
), skel
, pPoseData
);
65 void ComputeAbsolutJointTransformations(const std::vector
<int>& dirtyRoots
, const IDefaultSkeleton
& skel
, IAnimationPoseData
* pPoseData
)
67 for (int dirtyRoot
: dirtyRoots
)
69 ComputeAbsolutJointTransformationsRecursive(dirtyRoot
, skel
, pPoseData
);
73 bool CSkeletonPoseModifier::Execute(const SAnimationPoseModifierParams
& params
)
75 IAnimationPoseData
* const pPoseData
= params
.pPoseData
;
77 const IDefaultSkeleton
& skel
= params
.GetIDefaultSkeleton();
79 const int jointCount
= skel
.GetJointCount();
81 std::vector
<SJoint
> validPosedJoints
;
82 std::copy_if(m_posedJoints
.begin(), m_posedJoints
.end(), std::back_inserter(validPosedJoints
), [jointCount
](const SJoint
& joint
)
84 return joint
.m_id
> -1 && joint
.m_id
< jointCount
;
87 std::vector
<bool> dirty(jointCount
, false);
88 for (auto& joint
: validPosedJoints
)
90 const QuatT rel
= pPoseData
->GetJointRelative(joint
.m_id
);
91 pPoseData
->SetJointRelative(joint
.m_id
, rel
* joint
.m_transform
);
92 dirty
[joint
.m_id
] = true;
95 std::vector
<bool> visited(jointCount
, false);
96 std::vector
<int> dirtyRoots
;
97 for (auto& joint
: validPosedJoints
)
99 if (visited
[joint
.m_id
])
104 visited
[joint
.m_id
] = true;
106 int dirtyRoot
= joint
.m_id
;
107 int pathIt
= skel
.GetJointParentIDByID(joint
.m_id
);
108 while (pathIt
> -1 && !visited
[pathIt
])
114 visited
[pathIt
] = true;
115 pathIt
= skel
.GetJointParentIDByID(pathIt
);
119 dirtyRoots
.push_back(dirtyRoot
);
123 ComputeAbsolutJointTransformations(dirtyRoots
, skel
, pPoseData
);
128 CRYREGISTER_CLASS(CSkeletonPoseModifier
)