Changeset 287 for trunk/src/formats/nmd_loader.cc
- Timestamp:
- 07/23/14 15:24:03 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/nmd_loader.cc
r285 r287 7 7 #include "nv/formats/nmd_loader.hh" 8 8 #include "nv/io/std_stream.hh" 9 #include "nv/string.hh" 9 10 10 11 using namespace nv; … … 24 25 case nmd_type::MESH : load_mesh( source, element_header ); break; 25 26 case nmd_type::ANIMATION : load_animation( source, element_header ); break; 26 case nmd_type::BONE_ARRAY : load_bones( source, element_header ); break;27 27 case nmd_type::STRING_TABLE : load_strings( source ); break; 28 28 default: NV_ASSERT( false, "UNKNOWN NMD ELEMENT!" ); break; … … 47 47 mesh->add_channel( channel ); 48 48 } 49 m_mesh_names.push_back( e.name ); 49 50 m_meshes.push_back( mesh ); 50 51 return true; … … 54 55 { 55 56 mesh_data* result = m_meshes[ index ]; 57 if ( m_strings ) result->set_name( m_strings->get( m_mesh_names[ index ] ) ); 56 58 m_meshes[ index ] = nullptr; 57 59 return result; 60 } 61 62 mesh_data_pack* nv::nmd_loader::release_mesh_data_pack() 63 { 64 uint32 size = m_meshes.size(); 65 mesh_data* meshes = new mesh_data[ size ]; 66 for ( uint32 i = 0; i < size; ++i ) 67 { 68 m_meshes[i]->move_to( meshes[i] ); 69 delete m_meshes[i]; 70 } 71 m_meshes.clear(); 72 return new mesh_data_pack( size, meshes, release_mesh_nodes_data() ); 58 73 } 59 74 … … 61 76 { 62 77 for ( auto mesh : m_meshes ) if ( mesh ) delete mesh; 63 if ( m_animation ) delete m_animation;64 78 if ( m_strings ) delete m_strings; 65 if ( m_ bone_data ) delete m_bone_data;79 if ( m_node_data ) delete m_node_data; 66 80 m_meshes.clear(); 67 m_animation = nullptr; 68 m_bone_data = nullptr; 69 m_strings = nullptr; 81 m_mesh_names.clear(); 82 m_node_names.clear(); 83 84 m_node_data = nullptr; 85 m_node_array = nullptr; 86 m_strings = nullptr; 70 87 } 71 88 … … 82 99 } 83 100 84 bool nv::nmd_loader::load_bones( stream& source, const nmd_element_header& e )85 {86 NV_ASSERT( m_bone_data == nullptr, "MULTIPLE BONE ENTRIES!" );87 m_bone_data = new nmd_bone_data;88 m_bone_data->bones = new nmd_bone[ e.children ];89 m_bone_data->count = (uint16)e.children;90 source.read( m_bone_data->bones, sizeof( nmd_bone ), e.children );91 return true;92 }93 94 nmd_animation* nv::nmd_loader::release_animation()95 {96 nmd_animation* result = m_animation;97 m_animation = nullptr;98 return result;99 }100 101 nmd_bone_data* nv::nmd_loader::release_bone_data()102 {103 nmd_bone_data* result = m_bone_data;104 m_bone_data = nullptr;105 return result;106 }107 108 string_table* nv::nmd_loader::release_string_table()109 {110 string_table* result = m_strings;111 m_strings = nullptr;112 return result;113 }114 115 116 101 bool nv::nmd_loader::load_animation( stream& source, const nmd_element_header& e ) 117 102 { 118 NV_ASSERT( m_animation == nullptr, "MULTIPLE ANIMATION ENTRIES!" ); 119 nmd_animation_header header; 120 source.read( &header, sizeof( header ), 1 ); 121 m_animation = new nmd_animation; 122 m_animation->fps = header.fps; 123 m_animation->duration = header.duration; 124 m_animation->flat = header.flat; 125 m_animation->node_count = (uint16)e.children; 126 m_animation->nodes = new nmd_node[ e.children ]; 103 NV_ASSERT( m_node_data == nullptr, "MULTIPLE NODE ENTRIES!" ); 104 nmd_animation_header animation_header; 105 source.read( &animation_header, sizeof( animation_header ), 1 ); 106 m_node_array = new mesh_node_data[ e.children ]; 127 107 for ( uint32 i = 0; i < e.children; ++i ) 128 108 { 129 109 nmd_element_header element_header; 130 110 source.read( &element_header, sizeof( element_header ), 1 ); 131 NV_ASSERT( element_header.type == nmd_type::ANIMATION_NODE, "ANIMATION_NODE expected!" ); 132 m_animation->nodes[i].name = element_header.name; 133 111 NV_ASSERT( element_header.type == nmd_type::NODE, "NODE expected!" ); 112 m_node_names.push_back( element_header.name ); 134 113 uint16 ch_count = element_header.children; 135 114 136 nmd_ animation_node_header node_header;115 nmd_node_header node_header; 137 116 source.read( &node_header, sizeof( node_header ), 1 ); 138 m_ animation->nodes[i].parent_id = node_header.parent_id;139 m_ animation->nodes[i].transform = node_header.transform;140 m_ animation->nodes[i].data = nullptr;117 m_node_array[i].parent_id = node_header.parent_id; 118 m_node_array[i].transform = node_header.transform; 119 m_node_array[i].data = nullptr; 141 120 if ( ch_count > 0 ) 142 121 { 143 122 key_data* kdata = new key_data; 144 m_ animation->nodes[i].data = kdata;123 m_node_array[i].data = kdata; 145 124 for ( uint32 c = 0; c < ch_count; ++c ) 146 125 { 147 126 source.read( &element_header, sizeof( element_header ), 1 ); 148 NV_ASSERT( element_header.type == nmd_type:: ANIMATION_CHANNEL, "ANIMATION_CHANNEL expected!" );149 nv::nmd_ animation_channel_header cheader;127 NV_ASSERT( element_header.type == nmd_type::KEY_CHANNEL, "CHANNEL expected!" ); 128 nv::nmd_key_channel_header cheader; 150 129 source.read( &cheader, sizeof( cheader ), 1 ); 151 130 key_raw_channel* channel = key_raw_channel::create( cheader.format, cheader.count ); … … 155 134 } 156 135 } 136 m_node_data = new mesh_nodes_data( "animation", e.children, m_node_array, animation_header.frame_rate, animation_header.duration, animation_header.flat ); 157 137 return true; 158 138 } 159 139 140 mesh_nodes_data* nv::nmd_loader::release_mesh_nodes_data() 141 { 142 if ( m_node_data ) 143 { 144 if ( m_strings ) 145 { 146 for ( uint32 i = 0; i < m_node_data->get_count(); ++i ) 147 { 148 m_node_array[i].name = m_strings->get( m_node_names[i] ); 149 } 150 } 151 mesh_nodes_data* result = m_node_data; 152 m_node_data = nullptr; 153 m_node_array = nullptr; 154 return result; 155 } 156 return nullptr; 157 } 160 158 161 159 // TEMPORARY 162 nv::nmd_temp_animation::nmd_temp_animation( nmd_loader* loader )163 {164 m_animation = loader->release_animation();165 m_strings = loader->release_string_table();166 160 167 for ( uint32 n = 0; n < m_animation->node_count; ++n ) 168 { 169 nmd_node& node = m_animation->nodes[n]; 170 m_data.push_back( node.data ); 171 node.data = nullptr; 172 } 173 174 if ( !m_animation->flat ) 175 { 176 m_children.resize( m_animation->node_count ); 177 for ( nv::uint32 n = 0; n < m_animation->node_count; ++n ) 178 { 179 const nmd_node& node = m_animation->nodes[n]; 180 if ( node.parent_id != -1 ) 181 { 182 m_children[ node.parent_id ].push_back( n ); 183 } 184 } 185 } 186 187 m_bone_ids.resize( m_animation->node_count ); 188 } 189 190 nv::nmd_temp_animation::~nmd_temp_animation() 191 { 192 for ( auto node : m_data ) delete node; 193 delete m_animation; 194 delete m_strings; 195 } 196 197 void nv::nmd_temp_animation::prepare( const nmd_temp_model* model ) 198 { 199 m_offsets = model->m_bone_offsets.data(); 200 for ( uint32 n = 0; n < m_animation->node_count; ++n ) 201 { 202 const nmd_node& node = m_animation->nodes[n]; 203 sint16 bone_id = -1; 204 205 auto bi = model->m_bone_names.find( m_strings->get( node.name ) ); 206 if ( bi != model->m_bone_names.end() ) 207 { 208 bone_id = bi->second; 209 } 210 m_bone_ids[n] = bone_id; 211 } 212 } 213 214 void nv::nmd_temp_animation::animate( mat4* data, uint32 time ) 215 { 216 float tick_time = ( time / 1000.0f ) * m_animation->fps; 217 float anim_time = fmodf( tick_time, m_animation->duration ); 218 219 if ( !m_animation->flat ) 220 { 221 animate_rec( data, anim_time, 0, mat4() ); 222 return; 223 } 224 225 for ( uint32 n = 0; n < m_animation->node_count; ++n ) 226 if ( m_bone_ids[n] >= 0 ) 227 { 228 const nmd_node* node = &m_animation->nodes[ n ]; 229 nv::mat4 node_mat( node->transform ); 230 231 if ( m_data[n] ) 232 { 233 node_mat = m_data[n]->get_matrix( anim_time ); 234 } 235 236 sint16 bone_id = m_bone_ids[n]; 237 data[ bone_id ] = node_mat * m_offsets[ bone_id ]; 238 } 239 240 } 241 242 void nv::nmd_temp_animation::animate_rec( mat4* data, float time, uint32 node_id, const mat4& parent_mat ) 243 { 244 // TODO: fix transforms, which are now embedded, 245 // see note in assimp_loader.cc:load_node 246 const nmd_node* node = &m_animation->nodes[ node_id ]; 247 mat4 node_mat( node->transform ); 248 249 if ( m_data[ node_id ] ) 250 { 251 node_mat = m_data[ node_id ]->get_matrix( time ); 252 } 253 254 mat4 global_mat = parent_mat * node_mat; 255 256 sint16 bone_id = m_bone_ids[ node_id ]; 257 if ( bone_id >= 0 ) 258 { 259 data[ bone_id ] = global_mat * m_offsets[ bone_id ]; 260 } 261 262 for ( auto child : m_children[ node_id ] ) 263 { 264 animate_rec( data, time, child, global_mat ); 265 } 266 } 267 268 nv::nmd_temp_model::nmd_temp_model( nmd_loader* loader ) 161 nv::nmd_temp_model_data::nmd_temp_model_data( nmd_loader* loader ) 269 162 { 270 163 for ( unsigned m = 0; m < loader->get_mesh_count(); ++m ) … … 272 165 m_mesh_data.push_back(loader->release_mesh_data(m)); 273 166 } 274 nmd_bone_data* bone_data = loader->release_bone_data(); 275 string_table* strings = loader->release_string_table(); 276 277 for ( nv::uint16 bi = 0; bi < bone_data->count; ++bi ) 278 { 279 m_bone_names[ strings->get( bone_data->bones[bi].name ) ] = bi; 280 m_bone_offsets.push_back( bone_data->bones[bi].offset ); 281 } 282 283 delete bone_data; 284 delete strings; 167 m_node_data = loader->release_mesh_nodes_data(); 285 168 } 286 169 287 nv::nmd_temp_model ::~nmd_temp_model()170 nv::nmd_temp_model_data::~nmd_temp_model_data() 288 171 { 289 172 for ( unsigned m = 0; m < m_mesh_data.size(); ++m ) … … 291 174 delete m_mesh_data[m]; 292 175 } 176 delete m_node_data; 293 177 }
Note: See TracChangeset
for help on using the changeset viewer.