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
RevLine 
[475]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
[480]9#include "nv/core/profiler.hh"
10
[477]11void nv::skeleton_binding::prepare( const mesh_nodes_data* node_data, const mesh_nodes_data* bone_data )
[475]12{
[481]13        if ( m_indices.empty() )
[475]14        {
[477]15                // TODO: either fixed size struct or static allocator
16                hash_store< shash64, uint16 > bone_names;
[481]17                m_indices.resize( node_data->size() );
18               
[477]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                }
[475]24
[477]25                for ( uint32 n = 0; n < node_data->size(); ++n )
[475]26                {
[477]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
[475]37                }
[481]38                m_bone_count = bone_data->size();
[475]39        }
40
[477]41        if ( m_key.size() == 0 )
[475]42        {
[477]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                        }
[475]49        }
[477]50
[481]51
[475]52}
53
[481]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 )
[475]117{
[481]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];
[475]123}
124
[481]125void nv::skeleton_instance::assign( const bone_transforms& bones )
[475]126{
[481]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{
[477]133        const data_channel_set* node = ( *node_data )[id];
[480]134        transform node_mat( node->get_transform() );
[475]135
136        if ( node->size() > 0 )
137        {
[477]138                raw_channel_interpolator interpolator( node, binding.m_key );
[480]139                node_mat = interpolator.get< transform >( frame );
[475]140        }
[481]141        sint16 bone_id = binding.m_indices[id];
[480]142        transform global_mat = parent * node_mat;
[475]143        if ( bone_id >= 0 )
144        {
[481]145                m_transforms[bone_id] = global_mat;
[475]146        }
[477]147        for ( auto child : node_data->children( id ) )
[475]148        {
[477]149                animate_rec( node_data, binding, frame, child, global_mat );
[475]150        }
151}
[477]152
[481]153void nv::bone_transforms::prepare( const mesh_nodes_data* bone_data )
[477]154{
[481]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 )
[477]160                {
[481]161                        const data_channel_set* bone = ( *bone_data )[bi];
162                        m_offsets[bi] = bone->get_transform();
[477]163                }
[481]164        }
[477]165}
Note: See TracBrowser for help on using the repository browser.