source: trunk/src/gfx/skeleton_instance.cc @ 481

Last change on this file since 481 was 481, checked in by epyon, 10 years ago
  • skeleton/resource updates


File size: 4.8 KB
Line 
1// Copyright (C) 2011-2015 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7#include "nv/gfx/skeleton_instance.hh"
8
9#include "nv/core/profiler.hh"
10
11void nv::skeleton_binding::prepare( const mesh_nodes_data* node_data, const mesh_nodes_data* bone_data )
12{
13        if ( m_indices.empty() )
14        {
15                // TODO: either fixed size struct or static allocator
16                hash_store< shash64, uint16 > bone_names;
17                m_indices.resize( node_data->size() );
18               
19                for ( nv::uint16 bi = 0; bi < bone_data->size(); ++bi )
20                {
21                        const data_channel_set* bone = ( *bone_data )[bi];
22                        bone_names[bone->get_name()] = bi;
23                }
24
25                for ( uint32 n = 0; n < node_data->size(); ++n )
26                {
27                        const data_channel_set* node = ( *node_data )[n];
28                        sint16 bone_id = -1;
29
30                        auto bi = bone_names.find( node->get_name() );
31                        if ( bi != bone_names.end() )
32                        {
33                                bone_id = sint16( bi->second );
34                        }
35                        m_indices[n] = bone_id;
36
37                }
38                m_bone_count = bone_data->size();
39        }
40
41        if ( m_key.size() == 0 )
42        {
43                for ( uint32 n = 0; n < node_data->size(); ++n )
44                        if ( ( *node_data )[n]->size() > 0 )
45                        {
46                                m_key = ( *node_data )[n]->get_interpolation_key();
47                                break;
48                        }
49        }
50
51
52}
53
54// void nv::skeleton_instance::animate_( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame )
55// {
56//      if ( m_matrix.size() > 0 )
57//      {
58//              if ( node_data->is_flat() )
59//              {
60//                      animate_flat( node_data, binding, frame );
61//              }
62//              else
63//              {
64//                      for ( uint32 n = 0; n < node_data->size(); ++n )
65//                              if ( ( *node_data )[n]->get_parent_id() == -1 )
66//                                      animate_rec( node_data, binding, frame, n, transform() );
67//              }
68//      }
69// }
70//
71// void nv::skeleton_instance::animate_rec( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame, uint32 id, const transform& parent )
72// {
73//      // TODO: fix transforms, which are now embedded,
74//      //       see note in assimp_loader.cc:load_node
75//      const data_channel_set* node = ( *node_data )[id];
76//      transform node_mat( node->get_transform() );
77//
78//      if ( node->size() > 0 )
79//      {
80//              raw_channel_interpolator interpolator( node, binding.m_key );
81//              node_mat = interpolator.get< transform >( frame );
82//      }
83//
84//      transform global_mat = parent * node_mat;
85//
86//      sint16 bone_id = binding.m_indices[id];
87//      if ( bone_id >= 0 )
88//      {
89//              m_matrix[bone_id] = global_mat.extract() * binding.m_offsets[bone_id];
90//      }
91//
92//      for ( auto child : node_data->children( id ) )
93//      {
94//              animate_rec( node_data, binding, frame, child, global_mat );
95//      }
96// }
97//
98// void nv::skeleton_instance::animate_flat( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame )
99// {
100//      for ( uint32 n = 0; n < node_data->size(); ++n )
101//              if ( binding.m_indices[n] >= 0 )
102//              {
103//                      const data_channel_set* node = ( *node_data )[n];
104//                      nv::mat4 node_mat( node->get_transform() );
105//
106//                      if ( node->size() > 0 )
107//                      {
108//                              raw_channel_interpolator interpolator( node, binding.m_key );
109//                              node_mat = interpolator.get< mat4 >( frame );
110//                      }
111//                      sint16 bone_id = binding.m_indices[n];
112//                      m_matrix[bone_id] = node_mat * binding.m_offsets[bone_id];
113//              }
114// }
115
116void nv::skeleton_instance::assign( const skeleton_transforms& skeleton, const bone_transforms& bones )
117{
118        if ( bones.size() != m_matrix.size() )
119                m_matrix.resize( bones.size() );
120        const transform* transforms = skeleton.transforms();
121        for ( uint32 n = 0; n < skeleton.size(); ++n )
122                m_matrix[n] = transforms[n].extract() * bones.m_offsets[n];
123}
124
125void nv::skeleton_instance::assign( const bone_transforms& bones )
126{
127        if ( bones.size() != m_matrix.size() )
128                m_matrix.resize( bones.size() );
129}
130
131void nv::skeleton_transforms::animate_rec( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame, uint32 id, const transform& parent )
132{
133        const data_channel_set* node = ( *node_data )[id];
134        transform node_mat( node->get_transform() );
135
136        if ( node->size() > 0 )
137        {
138                raw_channel_interpolator interpolator( node, binding.m_key );
139                node_mat = interpolator.get< transform >( frame );
140        }
141        sint16 bone_id = binding.m_indices[id];
142        transform global_mat = parent * node_mat;
143        if ( bone_id >= 0 )
144        {
145                m_transforms[bone_id] = global_mat;
146        }
147        for ( auto child : node_data->children( id ) )
148        {
149                animate_rec( node_data, binding, frame, child, global_mat );
150        }
151}
152
153void nv::bone_transforms::prepare( const mesh_nodes_data* bone_data )
154{
155        if ( m_offsets.empty() )
156        {
157                m_offsets.resize( bone_data->size() );
158
159                for ( nv::uint16 bi = 0; bi < bone_data->size(); ++bi )
160                {
161                        const data_channel_set* bone = ( *bone_data )[bi];
162                        m_offsets[bi] = bone->get_transform();
163                }
164        }
165}
Note: See TracBrowser for help on using the repository browser.