1 #include <Core/Animation/Skeleton.hpp>
2 #include <Core/Math/LinearAlgebra.hpp>
23 static_assert( std::is_same<
bool,
typename std::underlying_type<SpaceType>::type>::value,
24 "SpaceType is not a boolean" );
25 if ( MODE == SpaceType::LOCAL )
return m_pose;
30 CORE_ASSERT( (
size() == pose.size() ),
"Size mismatching" );
31 static_assert( std::is_same<
bool,
typename std::underlying_type<SpaceType>::type>::value,
32 "SpaceType is not a boolean" );
33 if ( MODE == SpaceType::LOCAL ) {
38 for (
const auto& child :
m_graph.children()[i] ) {
48 for (
const auto& child :
m_graph.children()[i] ) {
56 CORE_ASSERT( ( i <
size() ),
"Index i out of bounds" );
57 static_assert( std::is_same<
bool,
typename std::underlying_type<SpaceType>::type>::value,
58 "SpaceType is not a boolean" );
59 if ( MODE == SpaceType::LOCAL )
return m_pose[i];
64 CORE_ASSERT( ( i <
size() ),
"Index i out of bounds" );
65 static_assert( std::is_same<
bool,
typename std::underlying_type<SpaceType>::type>::value,
66 "SpaceType is not a boolean" );
71 if ( MODE == SpaceType::LOCAL )
78 if ( MODE == SpaceType::LOCAL ) modelT = (
m_modelSpace[i] *
m_pose[i].inverse() * T );
80 const int pBoneIdx =
m_graph.parents()[i];
81 if ( pBoneIdx != -1 &&
m_graph.children()[pBoneIdx].size() == 1 ) {
88 B_ = modelT.translation();
89 auto q = Ra::Core::Quaternion::FromTwoVectors( ( B - A ), ( B_ - A ) );
90 Ra::Core::Transform R( q );
107 std::stack<uint> stack;
109 while ( !stack.empty() ) {
110 uint parent = stack.top();
112 for (
const auto& child :
m_graph.children()[parent] ) {
126 std::stack<uint> stack;
128 while ( !stack.empty() ) {
129 uint parent = stack.top();
131 for (
const auto& child :
m_graph.children()[parent] ) {
149 const Label label ) {
150 static_assert( std::is_same<
bool,
typename std::underlying_type<SpaceType>::type>::value,
151 "SpaceType is not a boolean" );
152 if ( MODE == SpaceType::LOCAL ) {
166 CORE_ASSERT( i <
m_modelSpace.size(),
"invalid bone index" );
172 const auto& children =
m_graph.children()[i];
173 CORE_ASSERT( children.size() > 0,
"non-leaf bone has no children." );
175 endOut = Vector3::Zero();
176 for (
auto child : children ) {
179 endOut *= ( 1_ra / children.size() );
187 auto op = pos - start;
188 auto dir = ( end - start );
190 const Scalar length_sq = dir.squaredNorm();
191 CORE_ASSERT( length_sq != 0.f,
"bone has lenght 0, cannot project." );
194 const Scalar t = std::clamp( op.dot( dir ) / length_sq, Scalar( 0 ), Scalar( 1 ) );
195 return start + ( t * dir );
198 std::ostream& operator<<( std::ostream& os,
const Skeleton& skeleton ) {
199 for ( uint i = 0; i < skeleton.
size(); ++i ) {
201 const std::string name = skeleton.
getLabel( i );
202 const std::string type = skeleton.
m_graph.
isRoot( i ) ?
"ROOT"
207 const int pid = skeleton.
m_graph.parents()[i];
208 const std::string pname =
209 ( pid == -1 ) ?
"" : (
"(" + std::to_string( pid ) +
") " + skeleton.
getLabel( pid ) );
211 const auto& children = skeleton.
m_graph.children()[i];
213 os <<
"Bone " <<
id <<
"\t: " << name << std::endl;
214 os <<
"Type\t: " << type << std::endl;
215 os <<
"Parent\t: " << pname << std::endl;
216 os <<
"Children#\t: " << children.size() << std::endl;
217 os <<
"Children\t: ";
218 for (
const auto& cid : children ) {
219 const std::string cname = skeleton.
getLabel( cid );
220 os <<
"(" << cid <<
") " << cname <<
" | ";
223 os <<
" " << std::endl;
224 os <<
" " << std::endl;
void clear()
Clear the vectors.
uint size() const
Return the number of nodes in the graph.
uint addRoot()
Return the index of the added root.
bool isJoint(const uint i) const
Return true if the node is a joint node. ( |child| == 1 )
bool isLeaf(const uint i) const
Return true if the node is a leaf node.
bool isBranch(const uint i) const
Return true if the node is a branch node. ( |child| > 1 )
bool isRoot(const uint i) const
Return true if a node is a root node.
uint addNode(const uint parent)
Return the index of the added leaf.
Label getLabel(const uint i) const
std::vector< Label > m_label
void setModelTransform(uint i, const Transform &T)
ModelPose m_modelSpace
Skeleton pose in MODEL space.
uint addRoot(const Transform &T=Transform::Identity(), const Label label="")
@ FORWARD
Standard edition scheme: rotation and / or translation of one bone.
@ PSEUDO_IK
Advanced edition scheme: translation of a bone means parent's rotation.
Vector3 projectOnBone(uint boneIdx, const Vector3 &pos) const
Projects point pos, given in Model Space, onto the bone with index boneIdx.
void setTransform(const uint i, const Transform &T, const SpaceType MODE) override
uint size() const override
void setLocalTransform(uint i, const Transform &T)
void setPose(const Pose &pose, const SpaceType MODE) override
AdjacencyList m_graph
The Joint hierarchy.
void getBonePoints(uint i, Vector3 &startOut, Vector3 &endOut) const
uint addBone(const uint parent, const Transform &T=Transform::Identity(), const SpaceType MODE=SpaceType::LOCAL, const Label label="")
Manipulation m_manipulation
The manipulation scheme.
const Pose & getPose(const SpaceType MODE) const override
const Transform & getTransform(const uint i, const SpaceType MODE) const override