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

Last change on this file since 483 was 483, checked in by epyon, 10 years ago
  • skeleton updates
File size: 6.1 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 data_node_list& 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                        bone_names[bone_data[bi].name] = bi;
21
22                for ( uint32 n = 0; n < node_data->size(); ++n )
23                {
24                        sint16 bone_id = -1;
25                        auto bi = bone_names.find( node_data->get_info( n ).name );
26                        if ( bi != bone_names.end() )
27                        {
28                                bone_id = sint16( bi->second );
29                        }
30                        m_indices[n] = bone_id;
31
32                }
33                m_bone_count = bone_data.size();
34        }
35
36        if ( m_key.size() == 0 )
37        {
38                for ( uint32 n = 0; n < node_data->size(); ++n )
39                        if ( ( *node_data )[n]->size() > 0 )
40                        {
41                                m_key = ( *node_data )[n]->get_interpolation_key();
42                                break;
43                        }
44        }
45}
46
47void nv::skeleton_instance::assign( const skeleton_transforms& skeleton, const bone_transforms& bones )
48{
49        if ( bones.size() != m_matrix.size() )
50                m_matrix.resize( bones.size() );
51        const transform* transforms = skeleton.transforms();
52        for ( uint32 n = 0; n < skeleton.size(); ++n )
53        {
54                m_matrix[n] = transforms[n].extract() * bones.m_offsets[n];
55        }
56}
57
58void nv::skeleton_instance::assign( const bone_transforms& bones )
59{
60        if ( bones.size() != m_matrix.size() )
61                m_matrix.resize( bones.size() );
62}
63
64void nv::skeleton_transforms::assign( const data_node_list* node_data )
65{
66        NV_ASSERT( node_data, "!!!" );
67        if ( m_transforms.size() != node_data->size() )
68                m_transforms.resize( node_data->size() );
69        for ( uint32 n = 0; n < node_data->size(); ++n )
70        {
71                const data_node_info& info = (*node_data)[ n ];
72                m_transforms[n] = transform( info.transform );
73        }
74}
75
76void nv::skeleton_transforms::interpolate( const skeleton_transforms& a, const skeleton_transforms& b, float t )
77{
78        NV_ASSERT( a.size() == b.size(), "!!!" );
79        if ( m_transforms.size() != a.size() )
80                m_transforms.resize( a.size() );
81        for ( uint32 n = 0; n < a.size(); ++n )
82        {
83                m_transforms[n] = nv::interpolate( a.m_transforms[n], b.m_transforms[n], t );
84        }
85}
86
87void nv::skeleton_transforms::assign( const skeleton_transforms& other )
88{
89        m_transforms.assign( other.m_transforms );
90}
91
92void nv::skeleton_transforms::animate_local( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame )
93{
94        if ( m_transforms.size() != binding.skeleton_size() )
95                m_transforms.resize( binding.skeleton_size() );
96        for ( uint32 n = 0; n < node_data->size(); ++n )
97        {
98                const data_channel_set* node = ( *node_data )[n];
99                sint16 bone_id = binding.m_indices[n];
100                if ( bone_id >= 0 )
101                {
102                        if ( node->size() > 0 )
103                                m_transforms[bone_id] = raw_channel_interpolator( node, binding.m_key ).get< transform >( frame );
104                        int confirm_that_not_needed;
105//                      else
106//                              m_transforms[bone_id] = transform( node->get_transform() );
107                }
108        }
109}
110
111void nv::skeleton_transforms::blend_local( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame, float blend )
112{
113        if ( m_transforms.size() != binding.skeleton_size() )
114                m_transforms.resize( binding.skeleton_size() );
115        for ( uint32 n = 0; n < node_data->size(); ++n )
116        {
117                const data_channel_set* node = ( *node_data )[n];
118                sint16 bone_id = binding.m_indices[n];
119                if ( bone_id >= 0 )
120                {
121                       
122                        transform tr = node->size() > 0 ? raw_channel_interpolator( node, binding.m_key ).get< transform >( frame ) : transform( /*node->get_transform()*/ ); int confirm_that_not_needed;
123                        m_transforms[bone_id] = nv::interpolate( m_transforms[bone_id], tr, blend );
124                }
125        }
126}
127
128void nv::skeleton_transforms::delocalize_rec( const data_node_tree& node_data, const skeleton_binding& binding, uint32 id, const transform& parent )
129{
130        sint16 bone_id = binding.m_indices[id];
131        transform global_mat = parent;
132        if ( bone_id >= 0 )
133        {
134                global_mat *= m_transforms[bone_id];
135                m_transforms[bone_id] = global_mat;
136        }
137        for ( auto child : node_data.children( id ) )
138        {
139                delocalize_rec( node_data, binding, child, global_mat );
140        }
141}
142
143void nv::skeleton_transforms::animate_rec( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame, uint32 id, const transform& parent, bool local )
144{
145        const data_channel_set* node = ( *node_data )[id];
146        transform node_mat;
147
148        if ( node->size() > 0 )
149                node_mat = raw_channel_interpolator( node, binding.m_key ).get< transform >( frame );
150        int confirm_that_not_needed;
151        //      else
152//              node_mat = transform( node->get_transform() );
153        sint16 bone_id = binding.m_indices[id];
154        transform global_mat = parent * node_mat;
155        if ( bone_id >= 0 )
156        {
157                m_transforms[bone_id] = local ? node_mat : global_mat;
158        }
159        for ( auto child : node_data->children( id ) )
160        {
161                animate_rec( node_data, binding, frame, child, global_mat, local );
162        }
163}
164
165void nv::skeleton_transforms::blend_rec( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame, uint32 id, const transform& parent, bool local, float blend )
166{
167        const data_channel_set* node = ( *node_data )[id];
168        int confirm_that_not_needed;
169        transform node_mat/*( node->get_transform() )*/;
170
171        if ( node->size() > 0 )
172        {
173                raw_channel_interpolator interpolator( node, binding.m_key );
174                node_mat = interpolator.get< transform >( frame );
175        }
176        sint16 bone_id = binding.m_indices[id];
177        transform global_mat = parent * node_mat;
178        if ( bone_id >= 0 )
179        {
180                m_transforms[bone_id] = nv::interpolate( m_transforms[bone_id], local ? node_mat : global_mat, blend );
181        }
182        for ( auto child : node_data->children( id ) )
183        {
184                blend_rec( node_data, binding, frame, child, global_mat, local, blend );
185        }
186}
187
188
189void nv::bone_transforms::prepare( const data_node_list& bone_data )
190{
191        if ( m_offsets.empty() )
192        {
193                m_offsets.resize( bone_data.size() );
194
195                for ( nv::uint16 bi = 0; bi < bone_data.size(); ++bi )
196                        m_offsets[bi] = bone_data[bi].transform;
197        }
198}
Note: See TracBrowser for help on using the repository browser.