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

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