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
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
[482]11void nv::skeleton_binding::prepare( const mesh_nodes_data* node_data, const data_node_list& 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() );
[475]18
[482]19                for ( nv::uint16 bi = 0; bi < bone_data.size(); ++bi )
20                        bone_names[bone_data[bi].name] = bi;
21
[477]22                for ( uint32 n = 0; n < node_data->size(); ++n )
[475]23                {
[477]24                        sint16 bone_id = -1;
[482]25                        auto bi = bone_names.find( node_data->get_info( n ).name );
[477]26                        if ( bi != bone_names.end() )
27                        {
28                                bone_id = sint16( bi->second );
29                        }
30                        m_indices[n] = bone_id;
31
[475]32                }
[482]33                m_bone_count = bone_data.size();
[475]34        }
35
[477]36        if ( m_key.size() == 0 )
[475]37        {
[477]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                        }
[475]44        }
45}
46
[481]47void nv::skeleton_instance::assign( const skeleton_transforms& skeleton, const bone_transforms& bones )
[475]48{
[481]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 )
[482]53        {
[481]54                m_matrix[n] = transforms[n].extract() * bones.m_offsets[n];
[482]55        }
[475]56}
57
[481]58void nv::skeleton_instance::assign( const bone_transforms& bones )
[475]59{
[481]60        if ( bones.size() != m_matrix.size() )
61                m_matrix.resize( bones.size() );
62}
63
[483]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
[482]92void nv::skeleton_transforms::animate_local( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame )
[481]93{
[482]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{
[477]145        const data_channel_set* node = ( *node_data )[id];
[482]146        transform node_mat;
[475]147
148        if ( node->size() > 0 )
[482]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 )
[475]156        {
[482]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        {
[477]173                raw_channel_interpolator interpolator( node, binding.m_key );
[480]174                node_mat = interpolator.get< transform >( frame );
[475]175        }
[481]176        sint16 bone_id = binding.m_indices[id];
[480]177        transform global_mat = parent * node_mat;
[475]178        if ( bone_id >= 0 )
179        {
[482]180                m_transforms[bone_id] = nv::interpolate( m_transforms[bone_id], local ? node_mat : global_mat, blend );
[475]181        }
[477]182        for ( auto child : node_data->children( id ) )
[475]183        {
[482]184                blend_rec( node_data, binding, frame, child, global_mat, local, blend );
[475]185        }
186}
[477]187
[482]188
189void nv::bone_transforms::prepare( const data_node_list& bone_data )
[477]190{
[481]191        if ( m_offsets.empty() )
192        {
[482]193                m_offsets.resize( bone_data.size() );
[481]194
[482]195                for ( nv::uint16 bi = 0; bi < bone_data.size(); ++bi )
196                        m_offsets[bi] = bone_data[bi].transform;
[481]197        }
[477]198}
Note: See TracBrowser for help on using the repository browser.