Changeset 485 for trunk/src/formats/assimp_loader.cc
- Timestamp:
- 01/26/16 18:59:46 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/assimp_loader.cc
r482 r485 12 12 13 13 using namespace nv; 14 15 namespace nv { 16 17 struct assimp_data 18 { 19 const aiScene* scene; 20 vector< const aiBone* > bones; 21 vector< const aiNode* > nodes; 22 vector< const aiMesh* > meshes; 23 vector< const aiNode* > skeletons; 24 25 hash_store< shash64, const aiBone* > bone_by_name; 26 hash_store< shash64, const aiNode* > node_by_name; 27 }; 28 29 } 14 30 15 31 const unsigned MAX_BONES = 64; … … 58 74 59 75 nv::assimp_loader::assimp_loader( string_table* strings, const string_view& a_ext, uint32 a_assimp_flags /*= 0 */ ) 60 : mesh_loader( strings ), m_ scene( nullptr ), m_mesh_count(0)76 : mesh_loader( strings ), m_mesh_count(0) 61 77 { 62 78 m_ext = a_ext; … … 76 92 aiProcess_SortByPType | 77 93 aiProcess_FindDegenerates | 78 aiProcess_Find InvalidData |94 aiProcess_FindDegenerates | 79 95 0 ); 80 96 } 97 m_data = new assimp_data; 98 m_data->scene = nullptr; 81 99 } 82 100 … … 85 103 { 86 104 load_assimp_library(); 87 if ( m_ scene != nullptr ) aiReleaseImport( reinterpret_cast<const aiScene*>( m_scene ));88 m_ scene = nullptr;105 if ( m_data->scene != nullptr ) aiReleaseImport( m_data->scene ); 106 m_data->scene = nullptr; 89 107 m_mesh_count = 0; 90 108 NV_LOG_NOTICE( "AssImp loading file..." ); … … 99 117 return false; 100 118 } 101 m_ scene= scene;102 m_mesh_count = scene->mNumMeshes;119 m_data->scene = scene; 120 m_mesh_count = scene->mNumMeshes; 103 121 NV_LOG_NOTICE( "Loading successfull" ); 122 123 scan_nodes( scene->mRootNode ); 124 125 for ( unsigned i = 0; i < scene->mRootNode->mNumChildren; ++i ) 126 { 127 const aiNode* node = scene->mRootNode->mChildren[i]; 128 if ( node->mNumMeshes == 0 ) 129 m_data->skeletons.push_back( node ); 130 } 131 132 for ( nv::uint32 i = 0; i < m_mesh_count; i++ ) 133 { 134 data_node_info info; 135 data_channel_set* data = data_channel_set_creator::create_set( 2 ); 136 load_mesh_data( data, i, info ); 137 m_meshes.push_back( data ); 138 m_mesh_info.push_back( info ); 139 } 140 141 scene_report(); 104 142 return true; 105 143 } … … 108 146 { 109 147 if ( index >= m_mesh_count ) return nullptr; 110 data_channel_set* result = data_channel_set_creator::create_set( 2 ); 111 load_mesh_data( result, index, info ); 112 return result; 148 info = m_mesh_info[index]; 149 return m_meshes[index]; 113 150 } 114 151 void nv::assimp_loader::load_mesh_data( data_channel_set* data, size_t index, data_node_info& info ) 115 152 { 116 const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene ); 117 const aiMesh* mesh = scene->mMeshes[ index ]; 153 const aiMesh* mesh = m_data->scene->mMeshes[ index ]; 118 154 119 155 bool skinned = mesh->mNumBones > 0; … … 125 161 desc.initialize< assimp_plain_vtx >(); 126 162 data_channel_set_creator maccess( data ); 127 const char* name = mesh->mName.data; 163 string64 name( mesh->mName.data, mesh->mName.length ); 164 if ( mesh->mName.length == 0 ) 165 { 166 for ( auto node : m_data->nodes ) 167 { 168 if ( node->mMeshes ) 169 for ( uint32 i = 0; i < node->mNumMeshes; ++i ) 170 if ( node->mMeshes[i] == index ) 171 { 172 name.assign( node->mName.data, node->mName.length ); 173 if ( i != 0 ) 174 { 175 name.append( "#0" ); 176 name.append( i ); 177 } 178 } 179 180 } 181 } 128 182 info.name = make_name( name ); 129 183 info.parent_id = -1; 184 int hack_for_node_anim; 185 if ( is_node_animated() ) 186 info.parent_id = index; 187 188 130 189 uint8* cdata = maccess.add_channel( desc, mesh->mNumVertices ).raw_data(); 131 190 uint16* indices = reinterpret_cast<uint16*>( maccess.add_channel< index_u16 >( mesh->mNumFaces * 3 ).raw_data() ); … … 188 247 nv::assimp_loader::~assimp_loader() 189 248 { 190 if ( m_scene != nullptr ) aiReleaseImport( reinterpret_cast<const aiScene*>( m_scene ) ); 191 } 192 193 bool nv::assimp_loader::load_bones( size_t index, array_ref< data_node_info > bones ) 194 { 195 if ( m_scene == nullptr ) return false; 196 const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene ); 197 const aiMesh* mesh = scene->mMeshes[ index ]; 198 199 for (unsigned int m=0; m<mesh->mNumBones; m++) 200 { 201 aiBone* bone = mesh->mBones[m]; 202 mat4 offset = assimp_mat4_cast( bone->mOffsetMatrix ); 203 const char* name = bone->mName.data; 204 bones[m].name = make_name( name ); 205 bones[m].transform = offset; 206 } 207 return true; 249 if ( m_data->scene != nullptr ) aiReleaseImport( m_data->scene ); 250 delete m_data; 208 251 } 209 252 210 253 void nv::assimp_loader::scene_report() const 211 254 { 212 const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene ); 213 if ( scene == nullptr ) return; 255 if ( m_data->scene == nullptr ) return; 214 256 215 257 NV_LOG_NOTICE( "------------------------" ); 216 NV_LOG_NOTICE( "Texture count - ", scene->mNumTextures );217 NV_LOG_NOTICE( "Animation count - ", scene->mNumAnimations );218 NV_LOG_NOTICE( "Material count - ", scene->mNumMaterials );219 NV_LOG_NOTICE( "Meshes count - ", scene->mNumMeshes );258 NV_LOG_NOTICE( "Texture count - ", m_data->scene->mNumTextures ); 259 NV_LOG_NOTICE( "Animation count - ", m_data->scene->mNumAnimations ); 260 NV_LOG_NOTICE( "Material count - ", m_data->scene->mNumMaterials ); 261 NV_LOG_NOTICE( "Meshes count - ", m_data->scene->mNumMeshes ); 220 262 NV_LOG_NOTICE( "------------------------" ); 221 263 222 aiNode* root = scene->mRootNode;264 aiNode* root = m_data->scene->mRootNode; 223 265 if (root) 224 266 { … … 233 275 NV_LOG_NOTICE( "------------------------" ); 234 276 235 if ( scene->mNumMeshes > 0 )236 { 237 for ( nv::uint32 mc = 0; mc < scene->mNumMeshes; mc++ )238 { 239 aiMesh* mesh = scene->mMeshes[mc];240 241 NV_LOG_NOTICE( "Mesh #", mc, " - ", string_view( static_cast<char*>( mesh->mName.data ) ) );277 if ( m_data->scene->mNumMeshes > 0 ) 278 { 279 for ( nv::uint32 mc = 0; mc < m_data->scene->mNumMeshes; mc++ ) 280 { 281 aiMesh* mesh = m_data->scene->mMeshes[mc]; 282 283 NV_LOG_NOTICE( "Mesh #", mc, " - ", string_view( static_cast<char*>( mesh->mName.data ), mesh->mName.length ) ); 242 284 NV_LOG_NOTICE( " bones - ", mesh->mNumBones ); 243 285 NV_LOG_NOTICE( " uvs - ", mesh->mNumUVComponents[0] ); … … 259 301 NV_LOG_NOTICE( "------------------------" ); 260 302 303 for ( auto node : m_data->nodes ) 304 { 305 NV_LOG_NOTICE( "Node : ", string_view( node->mName.data, node->mName.length ) ); 306 } 307 308 for ( auto skeleton : m_data->skeletons ) 309 { 310 NV_LOG_NOTICE( "Skeleton : ", string_view( skeleton->mName.data, skeleton->mName.length ) ); 311 } 261 312 262 313 // if ( scene->mNumMaterials > 0 ) … … 283 334 } 284 335 285 data_node_list* nv::assimp_loader::release_merged_bones( data_channel_set* meshes ) 286 { 287 const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene ); 288 data_node_list* result = new data_node_list( make_name( "bones" ) ); 289 hash_store< shash64, uint16 > names; 336 bool nv::assimp_loader::is_node_animated() 337 { 338 return is_animated() && m_data->skeletons.empty(); 339 } 340 341 void nv::assimp_loader::build_skeleton( vector< data_node_info >& skeleton, const void* node, int parent_id ) 342 { 343 const aiNode* ainode = reinterpret_cast<const aiNode*>( node ); 344 345 if ( ainode->mNumMeshes > 0 ) 346 { 347 int error; 348 int bug_this_works_only_if_before_releasing_meshes; 349 350 nv::uint32 mid = ainode->mMeshes[0]; 351 m_mesh_info[mid].parent_id = parent_id; 352 return; 353 } 354 355 string_view name( ainode->mName.data, ainode->mName.length ); 356 if ( name.starts_with( '_' ) ) return; 357 358 data_node_info info; 359 info.name = make_name( name ); 360 info.parent_id = parent_id; 361 362 int this_id = skeleton.size(); 363 skeleton.push_back( info ); 364 for ( unsigned i = 0; i < ainode->mNumChildren; ++i ) 365 { 366 build_skeleton( skeleton, ainode->mChildren[i], this_id ); 367 } 368 } 369 370 data_node_list* nv::assimp_loader::release_merged_bones() 371 { 372 if ( m_data->skeletons.empty() ) return nullptr; 373 vector< data_node_info > bone_data; 374 hash_store< shash64, uint16 > bone_map; 375 376 { 377 const aiNode* skeleton = m_data->skeletons[0]; 378 build_skeleton( bone_data, skeleton, -1 ); 379 380 for ( uint32 i = 0; i < bone_data.size(); ++i ) 381 { 382 bone_map[bone_data[i].name] = uint16(i); 383 } 384 } 385 290 386 for ( unsigned int m = 0; m < m_mesh_count; ++m ) 291 387 { 292 388 uint16 translate[MAX_BONES]; 293 389 vector< data_node_info > bones; 294 const aiMesh* mesh = scene->mMeshes[ m];390 const aiMesh* mesh = m_data->scene->mMeshes[m]; 295 391 if ( mesh->mNumBones != 0 ) 296 392 { 297 bones.resize( mesh->mNumBones ); 298 NV_ASSERT( false, "parent ids for bones are not loaded!" ); 299 load_bones( m, bones ); 300 for ( unsigned int b = 0; b < mesh->mNumBones; ++b ) 393 for ( unsigned int b = 0; b < mesh->mNumBones; b++ ) 301 394 { 302 303 data_node_info bone = bones[b]; 304 auto iname = names.find( bone.name ); 305 if ( iname == names.end() ) 395 aiBone* bone = mesh->mBones[b]; 396 mat4 offset = assimp_mat4_cast( bone->mOffsetMatrix ); 397 shash64 bone_name( bone->mName.data ); 398 399 int remove_this; 400 401 NV_ASSERT( bone_map.find( shash64( bone->mName.data ) ) != bone_map.end(), "BONE NOT FOUND!" ); 402 uint16 index = bone_map[bone_name]; 403 bone_data[index].transform = offset; 404 translate[b] = index; 405 } 406 407 data_channel_access< assimp_skinned_vtx > channel( const_cast<raw_data_channel*>( m_meshes[m]->get_channel( 0 ) ) ); 408 for ( unsigned v = 0; v < channel.size(); ++v ) 409 { 410 assimp_skinned_vtx& vertex = channel.data()[v]; 411 for ( int i = 0; i < 4; ++i ) 306 412 { 307 NV_ASSERT( result->size() < MAX_BONES, "Too many bones to merge!" ); 308 uint16 index = uint16( result->size() ); 309 result->append( bone ); 310 names[ bone.name ] = index; 311 translate[b] = index; 312 } 313 else 314 { 315 translate[b] = iname->second; 316 } 317 } 318 if ( m > 0 && bones.size() > 0 ) 319 { 320 data_channel_access< assimp_skinned_vtx > channel( const_cast< raw_data_channel* >( meshes[m].get_channel(0) ) ); 321 for ( unsigned v = 0; v < channel.size(); ++v ) 322 { 323 assimp_skinned_vtx& vertex = channel.data()[v]; 324 325 for ( int i = 0 ; i < 4; ++i) 413 if ( vertex.boneweight[i] > 0.0f ) 326 414 { 327 if ( vertex.boneweight[i] > 0.0f ) 328 { 329 vertex.boneindex[i] = int( translate[vertex.boneindex[i]] ); 330 } 415 vertex.boneindex[i] = int( translate[vertex.boneindex[i]] ); 331 416 } 332 417 } 333 418 } 334 } 335 } 336 //result->initialize(); 337 338 return result; 419 420 } 421 } 422 423 for ( uint32 i = 0; i < bone_data.size(); ++i ) 424 { 425 int error; // not really, just 426 int check_this_shit; 427 if ( bone_data[i].transform == mat4() ) 428 { 429 mat4 tr = nv::math::inverse( assimp_mat4_cast( m_data->node_by_name[bone_data[i].name]->mTransformation ) ); 430 bone_data[i].transform = tr * bone_data[bone_data[i].parent_id].transform; 431 } 432 // list->append( bone_data[i] ); 433 } 434 435 436 data_node_list* list = new data_node_list( make_name( "bones" ) ); 437 for ( uint32 i = 0; i < bone_data.size(); ++i ) 438 { 439 list->append( bone_data[i] ); 440 } 441 442 return list; 339 443 } 340 444 341 445 mesh_nodes_data* nv::assimp_loader::release_mesh_nodes_data( size_t index /*= 0*/ ) 342 446 { 343 if ( m_ scene == nullptr ) return nullptr;344 const aiScene* scene = reinterpret_cast<const aiScene*>( m_ scene );447 if ( m_data->scene == nullptr ) return nullptr; 448 const aiScene* scene = reinterpret_cast<const aiScene*>( m_data->scene ); 345 449 if ( scene->mRootNode == nullptr || scene->mAnimations == nullptr || scene->mAnimations[index] == nullptr) return nullptr; 346 450 … … 349 453 350 454 uint32 count = count_nodes( scene->mRootNode ); 455 count = count - 1; 351 456 352 457 uint16 frame_rate = static_cast<uint16>( anim->mTicksPerSecond ); 353 uint16 duration = static_cast<uint16>( anim->mDuration ) ;458 uint16 duration = static_cast<uint16>( anim->mDuration )+1; 354 459 355 460 data_channel_set** temp = new data_channel_set*[ count ]; 356 data_node_info* temp2 = new data_node_info[count ];461 data_node_info* temp2 = new data_node_info[count ]; 357 462 array_ref< data_channel_set* > temp_ref( temp, count ); 358 463 array_ref< data_node_info > temp2_ref( temp2, count ); 359 load_node( index, temp_ref, temp2_ref, root, 0, -1 ); 464 465 nv::sint16 next = 0; 466 for ( unsigned i = 0; i < scene->mRootNode->mNumChildren; ++i ) 467 { 468 next = load_node( index, temp_ref, temp2_ref, scene->mRootNode->mChildren[i], next, -1 ); 469 } 470 // load_node( index, temp_ref, temp2_ref, scene->mRootNode, 0, -1 ); 360 471 361 472 mesh_nodes_data* result = new mesh_nodes_data( make_name( static_cast<const char*>( anim->mName.data ) ), frame_rate, duration ); … … 372 483 data_node_list* nv::assimp_loader::release_data_node_list( size_t index /*= 0 */ ) 373 484 { 485 return release_merged_bones(); 486 } 487 488 bool nv::assimp_loader::is_animated( size_t /*= 0 */ ) 489 { 374 490 int this_is_incorrect; 375 NV_ASSERT( false, "unimplemented!" ); 376 // mesh_nodes_data* half_result = release_mesh_nodes_data( index ); 377 // data_node_list* result = new data_node_list( half_result->get_name() ); 378 // for ( auto node : *half_result ) 379 // result->append( node->get_info() ); 380 // delete half_result; 381 // return result; 382 return nullptr; 383 } 384 385 bool nv::assimp_loader::is_animated( size_t /*= 0 */ ) 386 { 387 int this_is_incorrect; 388 return false; 491 return m_mesh_count == 0 || m_data->scene->mNumAnimations > 0 && m_data->skeletons.size() == 0; 492 } 493 494 int indent = 0; 495 496 void nv::assimp_loader::scan_nodes( const void* node ) const 497 { 498 const aiNode* ainode = reinterpret_cast<const aiNode*>( node ); 499 m_data->nodes.push_back( ainode ); 500 m_data->node_by_name[shash64(ainode->mName.data)] = ainode; 501 502 for ( unsigned i = 0; i < ainode->mNumChildren; ++i ) 503 { 504 scan_nodes( ainode->mChildren[i] ); 505 } 389 506 } 390 507 … … 402 519 nv::sint16 nv::assimp_loader::load_node( uint32 anim_id, array_ref< data_channel_set* > nodes, array_ref< data_node_info > infos, const void* vnode, sint16 this_id, sint16 parent_id ) 403 520 { 404 const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );405 521 const aiNode* node = reinterpret_cast<const aiNode*>( vnode ); 406 522 string_view name( static_cast< const char* >( node->mName.data ) ); 407 const aiAnimation* anim = scene->mAnimations[anim_id];523 const aiAnimation* anim = m_data->scene->mAnimations[anim_id]; 408 524 const aiNodeAnim* anode = nullptr; 409 525 … … 415 531 } 416 532 417 nodes[ this_id ] = anode ? create_keys( anode ) : data_channel_set_creator::create_set( 0 ); 533 534 transform t = nv::transform( nv::assimp_mat4_cast( node->mTransformation ) ); 535 536 nodes[ this_id ] = anode ? create_keys( anode, t ) : data_channel_set_creator::create_set( 0 ); 418 537 419 538 infos[this_id].name = make_name( name ); … … 424 543 // node's without keys 425 544 // TODO: this can probably be deleted 426 infos[this_id].transform = nv::assimp_mat4_cast( node->mTransformation ); 427 if ( this_id == 0 ) infos[this_id].transform = mat4(); 545 // infos[this_id].transform = nv::assimp_mat4_cast( node->mTransformation ); 546 // if ( this_id == 0 ) infos[this_id].transform = mat4(); 547 428 548 429 549 nv::sint16 next = this_id + 1; … … 436 556 } 437 557 438 data_channel_set* nv::assimp_loader::create_keys( const void* vnode )439 { 440 const aiNodeAnim* node = reinterpret_cast< const aiNodeAnim* >( vnode );558 data_channel_set* nv::assimp_loader::create_keys( const void* vnode, const transform& tr ) 559 { 560 const aiNodeAnim* node = reinterpret_cast< const aiNodeAnim* >( vnode ); 441 561 if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 ) 442 562 { 443 563 return data_channel_set_creator::create_set( 0 ); 444 564 } 445 565 566 /* OLD 446 567 data_channel_set* set = data_channel_set_creator::create_set( 2 ); 447 568 data_channel_set_creator key_set( set ); … … 461 582 rchannel[np].rotation = assimp_quat_cast(node->mRotationKeys[np].mValue ); 462 583 } 584 */ 585 data_channel_set* set = data_channel_set_creator::create_set( 1 ); 586 data_channel_set_creator key_set( set ); 587 588 assimp_key_tr* channel = key_set.add_channel< assimp_key_tr >( node->mNumPositionKeys ).data(); 589 for ( unsigned np = 0; np < node->mNumPositionKeys; ++np ) 590 { 591 channel[np].tform.set_position( assimp_vec3_cast( node->mPositionKeys[np].mValue ) ); 592 channel[np].tform.set_orientation( assimp_quat_cast( node->mRotationKeys[np].mValue ) ); 593 if ( is_node_animated() ) 594 channel[np].tform = tr.inverse() * channel[np].tform ; 595 } 596 463 597 // if ( node->mNumScalingKeys > 0 ) 464 598 // { … … 503 637 nv::size_t nv::assimp_loader::get_nodes_data_count() const 504 638 { 505 if ( m_scene == nullptr ) return 0; 506 const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene ); 507 return scene->mNumAnimations; 508 } 509 510 639 if ( m_data->scene == nullptr ) return 0; 640 return m_data->scene->mNumAnimations; 641 } 642 643
Note: See TracChangeset
for help on using the changeset viewer.