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

Last change on this file since 476 was 475, checked in by epyon, 10 years ago
  • skeletal_mesh updates
File size: 2.5 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
9void nv::skeleton_instance::prepare( const mesh_nodes_data* bones )
10{
11        if ( m_offsets || m_indices ) return;
12        hash_store< shash64, uint16 > bone_names;
13        m_offsets = new mat4[bones->size()];
14        m_indices = new sint16[m_data->size()];
15
16        for ( nv::uint16 bi = 0; bi < bones->size(); ++bi )
17        {
18                const data_channel_set* bone = ( *bones )[bi];
19                bone_names[bone->get_name()] = bi;
20                m_offsets[bi] = bone->get_transform();
21        }
22
23        for ( uint32 n = 0; n < m_data->size(); ++n )
24        {
25                const data_channel_set* node = ( *m_data )[n];
26                sint16 bone_id = -1;
27
28                auto bi = bone_names.find( node->get_name() );
29                if ( bi != bone_names.end() )
30                {
31                        bone_id = sint16( bi->second );
32                }
33                m_indices[n] = bone_id;
34
35                if ( m_key.size() == 0 && node->size() > 0 )
36                        m_key = node->get_interpolation_key();
37        }
38}
39
40void nv::skeleton_instance::animate( mat4* data, float frame ) const
41{
42        if ( m_data->is_flat() )
43        {
44                animate_flat( data, frame );
45        }
46        else
47        {
48                for ( uint32 n = 0; n < m_data->size(); ++n )
49                        if ( ( *m_data )[n]->get_parent_id() == -1 )
50                                animate_rec( data, frame, n, mat4() );
51        }
52}
53
54void nv::skeleton_instance::animate_flat( mat4* data, float frame ) const
55{
56        for ( uint32 n = 0; n < m_data->size(); ++n )
57                if ( m_indices[n] >= 0 )
58                {
59                        const data_channel_set* node = ( *m_data )[n];
60                        nv::mat4 node_mat( node->get_transform() );
61
62                        if ( node->size() > 0 )
63                        {
64                                raw_channel_interpolator interpolator( node, m_key );
65                                node_mat = interpolator.get< mat4 >( frame );
66                        }
67
68                        sint16 bone_id = m_indices[n];
69                        data[bone_id] = node_mat * m_offsets[bone_id];
70                }
71}
72
73void nv::skeleton_instance::animate_rec( mat4* data, float frame, uint32 id, const mat4& parent ) const
74{
75        // TODO: fix transforms, which are now embedded,
76        //       see note in assimp_loader.cc:load_node
77        const data_channel_set* node = ( *m_data )[id];
78        mat4 node_mat( node->get_transform() );
79
80        if ( node->size() > 0 )
81        {
82                raw_channel_interpolator interpolator( node, m_key );
83                node_mat = interpolator.get< mat4 >( frame );
84        }
85
86        mat4 global_mat = parent * node_mat;
87
88        sint16 bone_id = m_indices[id];
89        if ( bone_id >= 0 )
90        {
91                data[bone_id] = global_mat * m_offsets[bone_id];
92        }
93
94        for ( auto child : m_data->children( id ) )
95        {
96                animate_rec( data, frame, child, global_mat );
97        }
98}
Note: See TracBrowser for help on using the repository browser.