Changeset 191 for trunk/src/formats
- Timestamp:
- 08/05/13 09:17:23 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/md5_loader.cc
r190 r191 15 15 using namespace nv; 16 16 17 // based on http://tfc.duke.free.fr/coding/md5-specs-en.html 18 17 19 static void next_line( std::istream& stream ) 18 20 { … … 71 73 discard( sstream, "{" ); 72 74 md5_joint joint; 73 for ( int i = 0; i < m_num_joints; ++i )75 for ( size_t i = 0; i < m_num_joints; ++i ) 74 76 { 75 77 sstream >> joint.name >> joint.parent_id; … … 286 288 return m; 287 289 } 290 291 md5_animation::md5_animation() 292 : m_md5_version( 0 ) 293 , m_num_frames( 0 ) 294 , m_num_joints( 0 ) 295 , m_frame_rate( 0 ) 296 , m_num_animated_components( 0 ) 297 , m_anim_duration( 0 ) 298 , m_frame_duration( 0 ) 299 , m_anim_time( 0 ) 300 { 301 302 } 303 304 md5_animation::~md5_animation() 305 { 306 307 } 308 309 bool md5_animation::load_animation( stream& source ) 310 { 311 m_joint_infos.clear(); 312 m_bounds.clear(); 313 m_base_frames.clear(); 314 m_frames.clear(); 315 m_animated_skeleton.joints.clear(); 316 m_num_frames = 0; 317 318 std_stream sstream( &source ); 319 std::string command; 320 321 sstream >> command; 322 while ( !sstream.eof() ) 323 { 324 if ( command == "MD5Version" ) 325 { 326 sstream >> m_md5_version; 327 assert( m_md5_version == 10 ); 328 } 329 else if ( command == "commandline" ) 330 { 331 next_line( sstream ); 332 } 333 else if ( command == "numFrames" ) 334 { 335 sstream >> m_num_frames; 336 next_line( sstream ); 337 } 338 else if ( command == "numJoints" ) 339 { 340 sstream >> m_num_joints; 341 next_line( sstream ); 342 } 343 else if ( command == "frameRate" ) 344 { 345 sstream >> m_frame_rate; 346 next_line( sstream ); 347 } 348 else if ( command == "numAnimatedComponents" ) 349 { 350 sstream >> m_num_animated_components; 351 next_line( sstream ); 352 } 353 else if ( command == "hierarchy" ) 354 { 355 discard( sstream, "{" ); 356 for ( int i = 0; i < m_num_joints; ++i ) 357 { 358 md5_joint_info joint; 359 sstream >> joint.name >> joint.parent_id >> joint.flags >> joint.start_index; 360 remove_quotes( joint.name ); 361 m_joint_infos.push_back( joint ); 362 next_line( sstream ); 363 } 364 discard( sstream, "}" ); 365 } 366 else if ( command == "bounds" ) 367 { 368 discard( sstream, "{" ); 369 next_line( sstream ); 370 for ( int i = 0; i < m_num_frames; ++i ) 371 { 372 md5_bound bound; 373 discard( sstream, "(" ); 374 sstream >> bound.min.x >> bound.min.y >> bound.min.z; 375 discard( sstream, ")" ); 376 discard( sstream, "(" ); 377 sstream >> bound.max.x >> bound.max.y >> bound.max.z; 378 379 m_bounds.push_back( bound ); 380 381 next_line( sstream ); 382 } 383 384 discard( sstream, "}" ); 385 next_line( sstream ); 386 } 387 else if ( command == "baseframe" ) 388 { 389 discard( sstream, "{" ); 390 next_line( sstream ); 391 392 for ( int i = 0; i < m_num_joints; ++i ) 393 { 394 md5_base_frame base_frame; 395 discard( sstream, "(" ); 396 sstream >> base_frame.pos.x >> base_frame.pos.y >> base_frame.pos.z; 397 discard( sstream, ")" ); 398 discard( sstream, "(" ); 399 sstream >> base_frame.orient.x >> base_frame.orient.y >> base_frame.orient.z; 400 next_line( sstream ); 401 402 m_base_frames.push_back( base_frame ); 403 } 404 discard( sstream, "}" ); 405 next_line( sstream ); 406 } 407 else if ( command == "frame" ) 408 { 409 md5_frame_data frame; 410 sstream >> frame.frame_id; 411 discard( sstream, "{" ); 412 next_line( sstream ); 413 414 for ( int i = 0; i < m_num_animated_components; ++i ) 415 { 416 float frameData; 417 sstream >> frameData; 418 frame.frame_data.push_back(frameData); 419 } 420 421 m_frames.push_back(frame); 422 423 build_frame_skeleton( m_skeletons, m_joint_infos, m_base_frames, frame ); 424 425 discard( sstream, "}" ); 426 next_line( sstream ); 427 } 428 429 sstream >> command; 430 } 431 432 m_animated_skeleton.joints.assign( m_num_joints, md5_skeleton_joint() ); 433 434 m_frame_duration = 1.0f / (float)m_frame_rate; 435 m_anim_duration = ( m_frame_duration * (float)m_num_frames ); 436 m_anim_time = 0.0f; 437 438 assert( m_joint_infos.size() == (size_t)m_num_joints ); 439 assert( m_bounds.size() == (size_t)m_num_frames ); 440 assert( m_base_frames.size() == (size_t)m_num_joints ); 441 assert( m_frames.size() == (size_t)m_num_frames ); 442 assert( m_skeletons.size() == (size_t)m_num_frames ); 443 444 return true; 445 } 446 447 void md5_animation::update( float delta_time ) 448 { 449 if ( m_num_frames < 1 ) return; 450 451 m_anim_time += delta_time; 452 453 while ( m_anim_time > m_anim_duration ) m_anim_time -= m_anim_duration; 454 while ( m_anim_time < 0.0f ) m_anim_time += m_anim_duration; 455 456 float frame_num = m_anim_time * (float)m_frame_rate; 457 int frame0 = (int)floorf( frame_num ); 458 int frame1 = (int)ceilf( frame_num ); 459 frame0 = frame0 % m_num_frames; 460 frame1 = frame1 % m_num_frames; 461 462 float interpolate = fmodf( m_anim_time, m_frame_duration ) / m_frame_duration; 463 464 interpolate_skeletons( m_animated_skeleton, m_skeletons[frame0], m_skeletons[frame1], interpolate ); 465 } 466 467 void md5_animation::build_frame_skeleton( md5_frame_skeleton_list& skeletons, const md5_joint_info_list& joint_infos, const md5_base_frame_list& base_frames, const md5_frame_data& frame_data ) 468 { 469 md5_frame_skeleton skeleton; 470 471 for ( unsigned int i = 0; i < joint_infos.size(); ++i ) 472 { 473 unsigned int j = 0; 474 475 const md5_joint_info& jinfo = joint_infos[i]; 476 md5_skeleton_joint animated_joint = base_frames[i]; 477 478 animated_joint.parent = jinfo.parent_id; 479 480 if ( jinfo.flags & 1 ) animated_joint.pos.x = frame_data.frame_data[ jinfo.start_index + j++ ]; 481 if ( jinfo.flags & 2 ) animated_joint.pos.y = frame_data.frame_data[ jinfo.start_index + j++ ]; 482 if ( jinfo.flags & 4 ) animated_joint.pos.z = frame_data.frame_data[ jinfo.start_index + j++ ]; 483 if ( jinfo.flags & 8 ) animated_joint.orient.x = frame_data.frame_data[ jinfo.start_index + j++ ]; 484 if ( jinfo.flags & 16 ) animated_joint.orient.y = frame_data.frame_data[ jinfo.start_index + j++ ]; 485 if ( jinfo.flags & 32 ) animated_joint.orient.z = frame_data.frame_data[ jinfo.start_index + j++ ]; 486 487 unit_quat_w( animated_joint.orient ); 488 489 if ( animated_joint.parent >= 0 ) // Has a parent joint 490 { 491 md5_skeleton_joint& pjoint = skeleton.joints[animated_joint.parent]; 492 glm::vec3 rot_pos = pjoint.orient * animated_joint.pos; 493 494 animated_joint.pos = pjoint.pos + rot_pos; 495 animated_joint.orient = pjoint.orient * animated_joint.orient; 496 497 animated_joint.orient = glm::normalize( animated_joint.orient ); 498 } 499 500 skeleton.joints.push_back( animated_joint ); 501 } 502 503 skeletons.push_back( skeleton ); 504 } 505 506 void md5_animation::interpolate_skeletons( md5_frame_skeleton& final_skeleton, const md5_frame_skeleton& skeleton0, const md5_frame_skeleton& skeleton1, float interpolate ) 507 { 508 for ( int i = 0; i < m_num_joints; ++i ) 509 { 510 md5_skeleton_joint& final_joint = final_skeleton.joints[i]; 511 const md5_skeleton_joint& joint0 = skeleton0.joints[i]; 512 const md5_skeleton_joint& joint1 = skeleton1.joints[i]; 513 514 final_joint.parent = joint0.parent; 515 516 final_joint.pos = glm::mix( joint0.pos, joint1.pos, interpolate ); 517 final_joint.orient = glm::mix( joint0.orient, joint1.orient, interpolate ); 518 } 519 } 520 521 bool md5_loader::check_animation( const md5_animation& animation ) const 522 { 523 if ( m_num_joints != animation.get_num_joints() ) 524 { 525 return false; 526 } 527 528 for ( uint32 i = 0; i < m_joints.size(); ++i ) 529 { 530 const md5_joint& mjoint = m_joints[i]; 531 const md5_animation::md5_joint_info& ajoint = animation.get_joint_info( i ); 532 533 if ( mjoint.name != ajoint.name || mjoint.parent_id != ajoint.parent_id ) 534 { 535 return false; 536 } 537 } 538 539 return true; 540 } 541 542 bool md5_loader::prepare_animated_mesh( md5_mesh& mesh, const md5_animation::md5_frame_skeleton& skel ) 543 { 544 for ( unsigned int i = 0; i < mesh.verts.size(); ++i ) 545 { 546 const md5_vertex& vert = mesh.verts[i]; 547 glm::vec3& pos = mesh.position_buffer[i]; 548 glm::vec3& normal = mesh.normal_buffer[i]; 549 glm::vec3& tangent = mesh.tangent_buffer[i]; 550 551 pos = glm::vec3(0); 552 normal = glm::vec3(0); 553 tangent = glm::vec3(0); 554 555 for ( int j = 0; j < vert.weight_count; ++j ) 556 { 557 const md5_weight& weight = mesh.weights[vert.start_weight + j]; 558 const md5_animation::md5_skeleton_joint& joint = skel.joints[weight.joint_id]; 559 560 glm::vec3 rot_pos = joint.orient * weight.pos; 561 pos += ( joint.pos + rot_pos ) * weight.bias; 562 563 normal += ( joint.orient * vert.normal ) * weight.bias; 564 tangent += ( joint.orient * vert.tangent ) * weight.bias; 565 } 566 } 567 return true; 568 } 569 570 void md5_loader::apply( const md5_animation& animation ) 571 { 572 const md5_animation::md5_frame_skeleton& skeleton = animation.get_skeleton(); 573 574 for ( unsigned int i = 0; i < m_meshes.size(); ++i ) 575 { 576 prepare_animated_mesh( m_meshes[i], skeleton ); 577 } 578 } 579 580 size_t nv::md5_loader::get_size() 581 { 582 return m_size; 583 }
Note: See TracChangeset
for help on using the changeset viewer.