Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
HandleToSkeleton.cpp
1 #include <Core/Asset/HandleToSkeleton.hpp>
2 
3 #include <set>
4 
5 #include <Core/Animation/Skeleton.hpp>
6 #include <Core/Asset/HandleData.hpp>
7 #include <Core/Utils/Log.hpp>
8 
9 using namespace Ra::Core::Utils;
10 
11 namespace Ra {
12 namespace Core {
13 namespace Asset {
14 
15 namespace {
16 // Recursive function to add bones
17 void addBone( const uint parent, // index of parent bone
18  const uint dataID, // index in map
19  const Ra::Core::Asset::HandleData& data, // handle data
20  const Ra::Core::AlignedStdVector<Ra::Core::Vector2ui>& edgeList, // list of edges
21  std::vector<bool>& processed, // which ids have been processed
22  Core::Animation::Skeleton& skelOut ) // correspondance between bone name and bone idx
23 {
24  if ( !processed[dataID] ) {
25  processed[dataID] = true;
26  const auto& dd = data.getComponentData()[dataID];
27  uint index = skelOut.addBone(
28  parent, dd.m_frame, Ra::Core::Animation::HandleArray::SpaceType::MODEL, dd.m_name );
29  for ( const auto& edge : edgeList ) {
30  if ( edge[0] == dataID ) {
31  addBone( index, edge[1], data, edgeList, processed, skelOut );
32  }
33  }
34  }
35 }
36 // function to add bones from a given root
37 void addRoot( const uint dataID, // index in map
38  const Ra::Core::Asset::HandleData& data, // handle data
39  const Ra::Core::AlignedStdVector<Ra::Core::Vector2ui>& edgeList, // list of edges
40  std::vector<bool>& processed, // which ids have been processed
41  Core::Animation::Skeleton& skelOut ) // correspondance between bone name and bone idx
42 {
43  if ( !processed[dataID] ) {
44  processed[dataID] = true;
45  const auto& dd = data.getComponentData()[dataID];
46  uint index = skelOut.addRoot( dd.m_frame, dd.m_name );
47  for ( const auto& edge : edgeList ) {
48  if ( edge[0] == dataID ) {
49  addBone( index, edge[1], data, edgeList, processed, skelOut );
50  }
51  }
52  }
53 }
54 } // namespace
55 
56 void createSkeleton( const Ra::Core::Asset::HandleData& data, Core::Animation::Skeleton& skelOut ) {
57  const uint size = data.getComponentDataSize();
58  auto component = data.getComponentData();
59 
60  std::set<uint> root;
61  for ( uint i = 0; i < size; ++i ) {
62  root.insert( i );
63  }
64  std::set<uint> leaves = root;
65 
66  auto edgeList = data.getEdgeData();
67  for ( const auto& edge : edgeList ) {
68  root.erase( edge[1] );
69  leaves.erase( edge[0] );
70  }
71 
72  std::vector<bool> processed( size, false );
73  for ( const auto& r : root ) {
74  addRoot( r, data, edgeList, processed, skelOut );
75  }
76 
77  if ( data.needsEndNodes() ) {
78  std::map<std::string, uint> boneNameMap;
79  for ( uint i = 0; i < skelOut.size(); ++i ) {
80  boneNameMap[skelOut.getLabel( i )] = i;
81  }
82  for ( const auto& l : leaves ) {
83  const auto& dd = component[l];
84  if ( dd.m_weights.size() ) {
85  LOG( logDEBUG ) << "Adding end-bone at " << dd.m_name << ".";
86  skelOut.addBone( boneNameMap[dd.m_name],
87  data.getFrame().inverse() * dd.m_frame,
88  Ra::Core::Animation::HandleArray::SpaceType::MODEL,
89  dd.m_name + "_Ra_endBone" );
90  }
91  }
92  }
93 }
94 } // namespace Asset
95 } // namespace Core
96 } // namespace Ra
uint getComponentDataSize() const
Definition: HandleData.hpp:296
const Core::AlignedStdVector< HandleComponentData > & getComponentData() const
Definition: HandleData.hpp:300
const Core::AlignedStdVector< Core::Vector2ui > & getEdgeData() const
Definition: HandleData.hpp:328
Core::Transform getFrame() const
Definition: HandleData.hpp:277
Definition: Cage.cpp:3