1#include <Core/Animation/Skeleton.hpp>
2#include <Core/Math/LinearAlgebra.hpp>
24 "SpaceType is not a boolean" );
25 if ( MODE == SpaceType::LOCAL )
return m_pose;
30 CORE_ASSERT( (
size() == pose.
size() ),
"Size mismatching" );
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" );
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" );
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 );
112 while ( !stack.
empty() ) {
113 uint parent = stack.
top();
115 for (
const auto& child :
m_graph.children()[parent] ) {
131 while ( !stack.
empty() ) {
132 uint parent = stack.
top();
134 for (
const auto& child :
m_graph.children()[parent] ) {
152 const Label label ) {
154 "SpaceType is not a boolean" );
155 if ( MODE == SpaceType::LOCAL ) {
175 const auto& children =
m_graph.children()[i];
176 CORE_ASSERT( children.size() > 0,
"non-leaf bone has no children." );
178 endOut = Vector3::Zero();
179 for (
auto child : children ) {
182 endOut *= ( 1_ra / children.size() );
190 auto op = pos - start;
191 auto dir = ( end - start );
193 const Scalar length_sq = dir.squaredNorm();
194 CORE_ASSERT( length_sq != 0.f,
"bone has lenght 0, cannot project." );
197 const Scalar t = std::clamp( op.dot( dir ) / length_sq, Scalar( 0 ), Scalar( 1 ) );
198 return start + ( t * dir );
202 for ( uint i = 0; i < skeleton.
size(); ++i ) {
210 const int pid = skeleton.
m_graph.parents()[i];
214 const auto& children = skeleton.
m_graph.children()[i];
216 os <<
"Bone " <<
id <<
"\t: " << name <<
std::endl;
218 os <<
"Parent\t: " << pname <<
std::endl;
219 os <<
"Children#\t: " << children.size() <<
std::endl;
220 os <<
"Children\t: ";
221 for (
const auto& cid : children ) {
223 os <<
"(" << cid <<
") " << cname <<
" | ";
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 editing scheme: rotation and / or translation of one bone.
@ PSEUDO_IK
Advanced editing 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
hepler function to manage enum as underlying types in VariableSet