Radium Engine  1.5.20
Loading...
Searching...
No Matches
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
9using namespace Ra::Core::Utils;
10
11namespace Ra {
12namespace Core {
13namespace Asset {
14
15namespace {
16// Recursive function to add bones
17void 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
37void 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
56void 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() ) {
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
Label getLabel(const uint i) const
uint addRoot(const Transform &T=Transform::Identity(), const Label label="")
Definition Skeleton.cpp:142
uint size() const override
Definition Skeleton.hpp:40
uint addBone(const uint parent, const Transform &T=Transform::Identity(), const SpaceType MODE=SpaceType::LOCAL, const Label label="")
Definition Skeleton.cpp:149
const Core::AlignedStdVector< HandleComponentData > & getComponentData() const
const Core::AlignedStdVector< Core::Vector2ui > & getEdgeData() const
Core::Transform getFrame() const
T erase(T... args)
T insert(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3