- Timestamp:
- 08/05/13 09:17:23 (12 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/formats/md5_loader.hh
r190 r191 21 21 namespace nv 22 22 { 23 24 class md5_animation 25 { 26 protected: 27 friend class md5_loader; 28 struct md5_joint_info 29 { 30 std::string name; 31 int parent_id; 32 int flags; 33 int start_index; 34 }; 35 typedef std::vector<md5_joint_info> md5_joint_info_list; 36 37 struct md5_bound 38 { 39 glm::vec3 min; 40 glm::vec3 max; 41 }; 42 typedef std::vector<md5_bound> md5_bound_list; 43 44 struct md5_base_frame 45 { 46 glm::vec3 pos; 47 glm::quat orient; 48 }; 49 typedef std::vector<md5_base_frame> md5_base_frame_list; 50 51 struct md5_frame_data 52 { 53 int frame_id; 54 std::vector<float> frame_data; 55 }; 56 typedef std::vector<md5_frame_data> md5_frame_data_list; 57 58 struct md5_skeleton_joint 59 { 60 md5_skeleton_joint() : parent(-1), pos(0) {} 61 md5_skeleton_joint( const md5_base_frame& copy ) : pos( copy.pos ), orient( copy.orient ) {} 62 63 int parent; 64 glm::vec3 pos; 65 glm::quat orient; 66 }; 67 typedef std::vector<md5_skeleton_joint> md5_skeleton_joint_list; 68 69 struct md5_frame_skeleton 70 { 71 md5_skeleton_joint_list joints; 72 }; 73 typedef std::vector<md5_frame_skeleton> md5_frame_skeleton_list; 74 75 76 public: 77 md5_animation(); 78 virtual ~md5_animation(); 79 80 bool load_animation( stream& source ); 81 void update( float delta_time ); 82 83 const md5_frame_skeleton& get_skeleton() const 84 { 85 return m_animated_skeleton; 86 } 87 88 int get_num_joints() const 89 { 90 return m_num_joints; 91 } 92 93 const md5_joint_info& get_joint_info( uint32 index ) const 94 { 95 assert( index < m_joint_infos.size() ); 96 return m_joint_infos[index]; 97 } 98 99 protected: 100 101 md5_joint_info_list m_joint_infos; 102 md5_bound_list m_bounds; 103 md5_base_frame_list m_base_frames; 104 md5_frame_data_list m_frames; 105 md5_frame_skeleton_list m_skeletons; 106 107 md5_frame_skeleton m_animated_skeleton; 108 109 void build_frame_skeleton( md5_frame_skeleton_list& skeletons, const md5_joint_info_list& joint_info, const md5_base_frame_list& base_frames, const md5_frame_data& frame_data ); 110 void interpolate_skeletons( md5_frame_skeleton& final_skeleton, const md5_frame_skeleton& skeleton0, const md5_frame_skeleton& skeleton1, float interpolate ); 111 112 private: 113 int m_md5_version; 114 int m_num_frames; 115 int m_num_joints; 116 int m_frame_rate; 117 int m_num_animated_components; 118 119 float m_anim_duration; 120 float m_frame_duration; 121 float m_anim_time; 122 }; 123 23 124 24 125 class md5_loader : public mesh_loader … … 28 129 virtual ~md5_loader() {}; 29 130 virtual bool load( stream& source ); 30 virtual size_t get_size() { return m_size; }131 virtual size_t get_size(); 31 132 virtual mesh* release_mesh(); 32 133 virtual mesh* get_frame( sint32 frame ) { return nullptr; } 134 bool check_animation( const md5_animation& animation ) const; 135 void apply( const md5_animation& animation ); 33 136 // virtual const md3_tag* get_tag( const std::string& name ) const; 34 137 // virtual mat4 get_tag( sint32 frame, const std::string& name ) const; … … 40 143 // void load_texcoords( std::vector<vec2>& t ); 41 144 // void load_indicies( std::vector<uint16>& idx ); 42 43 145 protected: 44 146 typedef std::vector<glm::vec3> md5_vec_buffer; … … 95 197 }; 96 198 typedef std::vector<md5_mesh> md5_mesh_list; 199 public: 200 const md5_vec_buffer& get_positions( uint32 mesh_id ) const { return m_meshes[mesh_id].position_buffer; } 201 const md5_vec_buffer& get_normals ( uint32 mesh_id ) const { return m_meshes[mesh_id].normal_buffer; } 202 const md5_vec_buffer& get_tangents ( uint32 mesh_id ) const { return m_meshes[mesh_id].tangent_buffer; } 203 const md5_tc_buffer& get_texcoords( uint32 mesh_id ) const { return m_meshes[mesh_id].texcoord_buffer; } 204 const md5_index_buffer& get_indices ( uint32 mesh_id ) const { return m_meshes[mesh_id].index_buffer; } 205 uint32 get_vertex_count( uint32 mesh_id ) const { return m_meshes[mesh_id].position_buffer.size(); } 206 uint32 get_index_count( uint32 mesh_id ) const { return m_meshes[mesh_id].index_buffer.size(); } 97 207 protected: 98 208 bool prepare_mesh( md5_mesh& mesh ); 99 209 bool prepare_normals( md5_mesh& mesh ); 100 210 bool prepare_animated_mesh( md5_mesh& mesh, const md5_animation::md5_frame_skeleton& skel ); 101 211 protected: 102 212 uint32 m_md5_version; -
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 } -
trunk/src/gl/gl_vertex_buffer.cc
r153 r191 20 20 void gl_vertex_buffer::update( const void* data, size_t offset, size_t size ) 21 21 { 22 // IMPORTANT - THIS DOES NOT BIND, SHOULD IT? 22 23 glBufferSubData( GL_ARRAY_BUFFER, (GLintptr)offset, (GLsizeiptr)size, data ); 23 24 }
Note: See TracChangeset
for help on using the changeset viewer.