Changeset 475
- Timestamp:
- 10/09/15 14:08:44 (10 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/gfx/skeletal_mesh.hh
r470 r475 11 11 #include <nv/interface/context.hh> 12 12 #include <nv/interface/animated_mesh.hh> 13 #include <nv/formats/nmd_loader.hh>14 13 #include <nv/stl/array.hh> 14 #include <nv/gfx/skeleton_instance.hh> 15 15 16 16 namespace nv … … 19 19 class skeletal_animation_entry : public animation_entry 20 20 { 21 22 21 public: 22 skeletal_animation_entry( shash64 name, const mesh_nodes_data* anim, bool a_looping ) 23 23 : animation_entry( name, a_looping, anim->get_fps(), 0, anim->get_frame_count() ) 24 , m_ node_data( anim )24 , m_data( anim ) 25 25 { 26 initialize();27 26 } 28 27 29 28 skeletal_animation_entry( shash64 name, const mesh_nodes_data* anim, uint32 time_start, uint32 time_end, bool a_looping ) 30 29 : animation_entry( name, a_looping, anim->get_fps(), time_start, time_end ) 31 , m_node_data( anim ) 30 , m_data( anim ) 31 32 32 { 33 initialize();34 33 } 35 34 36 35 void prepare( const mesh_nodes_data* bones ); 37 36 void update_skeleton( mat4* tr, uint32 a_ms_time ) const; 38 ~skeletal_animation_entry(); 39 40 protected: 41 void initialize(); 42 void animate_rec( mat4* data, float time, uint32 node_id, const mat4& parent_mat ) const; 43 37 44 38 protected: 45 const mesh_nodes_data* m_node_data; 46 vector< uint32 >* m_children; 47 sint16* m_bone_ids; 48 mat4* m_offsets; 49 uint32 m_root; 50 bool m_prepared; 51 data_descriptor m_interpolation_key; 39 skeleton_instance m_data; 52 40 }; 53 41 … … 63 51 } 64 52 virtual void update( program a_program ); 65 virtual void update_animation( animation_entry* a_anim, uint32 66 a_anim_time ); 53 virtual void update_animation( animation_entry* a_anim, uint32 a_anim_time ); 67 54 virtual transform get_node_transform( uint32 node_id ) const; 68 55 virtual mat4 get_node_matrix( uint32 node_id ) const; -
trunk/nv/interface/mesh_data.hh
r470 r475 26 26 class mesh_nodes_data 27 27 { 28 29 static constexpr size_t MAX_CHILDREN = 7; 30 class child_list : noncopyable 31 { 32 33 public: 34 child_list() : m_size( 0 ) 35 { 36 nv::raw_fill_n( m_data, MAX_CHILDREN, 0 ); 37 } 38 void push( uint8 id ) 39 { 40 NV_ASSERT( m_size < MAX_CHILDREN, "Range error" ); 41 m_data[m_size++] = id; 42 } 43 const uint8* begin() const { return m_data; } 44 const uint8* end() const { return m_data + m_size; } 45 private: 46 uint8 m_size; 47 uint8 m_data[MAX_CHILDREN]; 48 }; 49 static_assert( sizeof( child_list ) == 8, "Align/Padding fail for child_list" ); 50 28 51 friend class mesh_creator; 29 52 friend class mesh_nodes_creator; … … 42 65 } 43 66 44 void push_back( data_channel_set* set )67 void append( data_channel_set* set ) 45 68 { 46 69 m_data.push_back( set ); 70 } 71 72 void initialize() 73 { 74 m_children.resize( m_data.size() ); 75 for ( uint8 n = 0; n < uint8( m_data.size() ); ++n ) 76 { 77 const data_channel_set* node = m_data[n]; 78 if ( node->get_parent_id() != -1 ) 79 { 80 m_children[node->get_parent_id()].push( n ); 81 } 82 } 83 } 84 85 const child_list& children( size_t i ) const 86 { 87 return m_children[i]; 47 88 } 48 89 … … 95 136 private: 96 137 vector< data_channel_set* > m_data; 138 vector< child_list > m_children; 97 139 shash64 m_name; 98 140 uint16 m_frame_rate; -
trunk/src/formats/assimp_loader.cc
r471 r475 307 307 NV_ASSERT( result->size() < MAX_BONES, "Too many bones to merge!" ); 308 308 uint16 index = uint16( result->size() ); 309 result-> push_back( bone );309 result->append( bone ); 310 310 names[ bone->get_name() ] = index; 311 311 translate[b] = index; … … 334 334 } 335 335 } 336 result->initialize(); 336 337 337 338 return result; … … 360 361 for ( auto set : temp_ref ) 361 362 { 362 result->push_back( set ); 363 } 363 result->append( set ); 364 } 365 result->initialize(); 364 366 delete temp; 365 367 return result; -
trunk/src/formats/md3_loader.cc
r471 r475 429 429 access.set_name( make_name( name ) ); 430 430 load_tags( access.add_channel<md3_key>( uint32( md3->header.num_frames ) ).channel(), name ); 431 result->push_back( set ); 432 } 431 result->append( set ); 432 } 433 result->initialize(); 433 434 return result; 434 435 } -
trunk/src/formats/nmd_loader.cc
r470 r475 107 107 data_channel_set* set = data_channel_set_creator::create_set( element_header.children ); 108 108 load_channel_set( source, set, element_header ); 109 m_node_data->push_back( set ); 110 } 109 m_node_data->append( set ); 110 } 111 m_node_data->initialize(); 111 112 return true; 112 113 } -
trunk/src/gfx/skeletal_mesh.cc
r471 r475 11 11 #include "nv/stl/unordered_map.hh" 12 12 13 void nv::skeletal_animation_entry::initialize() 14 { 15 m_root = uint32(-1); 16 m_prepared = false; 17 m_children = nullptr; 18 m_offsets = nullptr; 19 m_bone_ids = new sint16[m_node_data->size()]; 20 21 NV_ASSERT( m_node_data, "node data empty!" ); 22 23 if ( !m_node_data->is_flat() ) 24 { 25 m_children = new vector< uint32 >[m_node_data->size()]; 26 for ( uint32 n = 0; n < m_node_data->size(); ++n ) 27 { 28 const data_channel_set* node = (*m_node_data)[n]; 29 if ( node->get_parent_id() != -1 ) 30 { 31 m_children[ node->get_parent_id()].push_back( n ); 32 } 33 else 34 { 35 if ( m_root >= 0 ) 36 { 37 m_root = uint32( -2 ); 38 } 39 else 40 m_root = n; 41 } 42 } 43 NV_ASSERT( m_root != uint32( -1 ), "Animation without root!" ); 44 } 45 } 13 #include "nv/core/logging.hh" 46 14 47 15 void nv::skeletal_animation_entry::update_skeleton( mat4* data, uint32 a_ms_time ) const … … 70 38 } 71 39 72 if ( !m_node_data->is_flat() ) 73 { 74 if ( m_root == uint32( -2 ) ) // multi-root 75 { 76 for ( uint32 n = 0; n < m_node_data->size(); ++n ) 77 if ( ( *m_node_data )[n]->get_parent_id() == -1 ) 78 animate_rec( data, fframe, n, mat4() ); 79 } 80 else 81 animate_rec( data, fframe, m_root, mat4() ); 82 return; 83 } 84 85 for ( uint32 n = 0; n < m_node_data->size(); ++n ) 86 if ( m_bone_ids[n] >= 0 ) 87 { 88 const data_channel_set* node = (*m_node_data)[n]; 89 nv::mat4 node_mat( node->get_transform() ); 90 91 if ( node->size() > 0 ) 92 { 93 raw_channel_interpolator interpolator( node, m_interpolation_key ); 94 node_mat = interpolator.get< mat4 >( fframe ); 95 } 96 97 sint16 bone_id = m_bone_ids[n]; 98 data[ bone_id ] = node_mat * m_offsets[ bone_id ]; 99 } 40 m_data.animate( data, fframe ); 100 41 } 101 42 102 43 void nv::skeletal_animation_entry::prepare( const mesh_nodes_data* bones ) 103 44 { 104 if ( m_prepared ) return; 105 nv::hash_store< shash64, uint16 > bone_names; 106 m_offsets = new mat4[ bones->size() ]; 107 for ( nv::uint16 bi = 0; bi < bones->size(); ++bi ) 108 { 109 const data_channel_set* bone = (*bones)[ bi ]; 110 bone_names[ bone->get_name() ] = bi; 111 m_offsets[bi] = bone->get_transform(); 112 } 113 114 for ( uint32 n = 0; n < m_node_data->size(); ++n ) 115 { 116 const data_channel_set* node = (*m_node_data)[ n ]; 117 sint16 bone_id = -1; 118 119 auto bi = bone_names.find( node->get_name() ); 120 if ( bi != bone_names.end() ) 121 { 122 bone_id = sint16( bi->second ); 123 } 124 m_bone_ids[n] = bone_id; 125 126 if ( m_interpolation_key.size() == 0 && node->size() > 0 ) 127 m_interpolation_key = node->get_interpolation_key(); 128 129 } 130 m_prepared = true; 131 } 132 133 void nv::skeletal_animation_entry::animate_rec( mat4* data, float time, uint32 node_id, const mat4& parent_mat ) const 134 { 135 // TODO: fix transforms, which are now embedded, 136 // see note in assimp_loader.cc:load_node 137 const data_channel_set* node = ( *m_node_data )[ node_id ]; 138 mat4 node_mat( node->get_transform() ); 139 140 if ( node->size() > 0 ) 141 { 142 raw_channel_interpolator interpolator( node, m_interpolation_key ); 143 node_mat = interpolator.get< mat4 >( time ); 144 } 145 146 mat4 global_mat = parent_mat * node_mat; 147 148 sint16 bone_id = m_bone_ids[ node_id ]; 149 if ( bone_id >= 0 ) 150 { 151 data[ bone_id ] = global_mat * m_offsets[ bone_id ]; 152 } 153 154 for ( auto child : m_children[ node_id ] ) 155 { 156 animate_rec( data, time, child, global_mat ); 157 } 158 } 159 160 nv::skeletal_animation_entry::~skeletal_animation_entry() 161 { 162 delete[] m_offsets; 163 delete[] m_children; 164 delete[] m_bone_ids; 45 m_data.prepare( bones ); 165 46 } 166 47 … … 198 79 nv::transform nv::skeletal_mesh::get_node_transform( uint32 node_id ) const 199 80 { 200 if ( node_id == 0 ) return transform();201 if ( node_id == uint32(-1) ) return transform( m_transform[0] );202 81 return transform( m_transform[ node_id ] ); 203 82 }
Note: See TracChangeset
for help on using the changeset viewer.