!XT (Code) Update copyright headers in Code/Sandbox.
[CRYENGINE.git] / Code / Sandbox / Plugins / MeshImporter / SkeletonPoser / SkeletonPoser.cpp
blob6d0da396b054e892dd203c0b5d34e82f68f15c8b
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "SkeletonPoser.h"
6 CSkeletonPoseModifier::SJoint::SJoint()
7 : m_crc(0)
8 , m_transform(IDENTITY)
9 , m_id(-1)
12 CSkeletonPoseModifier::SJoint::SJoint(const string& name, const QuatT& transform)
13 : m_name(name)
14 , m_transform(transform)
15 , m_id(-1)
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;
25 });
26 if (it != m_posedJoints.end())
28 it->m_transform = transform;
30 else
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)
42 if (joint.m_id == -1)
44 joint.m_id = skeleton.GetJointIDByCRC32(joint.m_crc);
48 return true;
51 void ComputeAbsolutJointTransformationsRecursive(int joint, const IDefaultSkeleton& skel, IAnimationPoseData* pPoseData)
53 const int parent = skel.GetJointParentIDByID(joint);
54 if (parent > -1)
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;
85 });
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])
101 continue;
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])
110 if (dirty[pathIt])
112 dirtyRoot = pathIt;
114 visited[pathIt] = true;
115 pathIt = skel.GetJointParentIDByID(pathIt);
117 if (pathIt == -1)
119 dirtyRoots.push_back(dirtyRoot);
123 ComputeAbsolutJointTransformations(dirtyRoots, skel, pPoseData);
125 return true;
128 CRYREGISTER_CLASS(CSkeletonPoseModifier)