Changeset 191 for trunk/src


Ignore:
Timestamp:
08/05/13 09:17:23 (12 years ago)
Author:
epyon
Message:
  • formats - md3_animation works!
Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/formats/md5_loader.cc

    r190 r191  
    1515using namespace nv;
    1616
     17// based on http://tfc.duke.free.fr/coding/md5-specs-en.html
     18
    1719static void next_line( std::istream& stream )
    1820{
     
    7173                        discard( sstream, "{" );
    7274                        md5_joint joint;
    73                         for ( int i = 0; i < m_num_joints; ++i )
     75                        for ( size_t i = 0; i < m_num_joints; ++i )
    7476                        {
    7577                                sstream >> joint.name >> joint.parent_id;
     
    286288        return m;
    287289}
     290
     291md5_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
     304md5_animation::~md5_animation()
     305{
     306
     307}
     308
     309bool 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
     447void 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
     467void 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
     506void 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
     521bool 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
     542bool 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
     570void 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
     580size_t nv::md5_loader::get_size()
     581{
     582        return m_size;
     583}
  • trunk/src/gl/gl_vertex_buffer.cc

    r153 r191  
    2020void gl_vertex_buffer::update( const void* data, size_t offset, size_t size )
    2121{
     22        // IMPORTANT - THIS DOES NOT BIND, SHOULD IT?
    2223        glBufferSubData( GL_ARRAY_BUFFER, (GLintptr)offset, (GLsizeiptr)size, data );
    2324}
Note: See TracChangeset for help on using the changeset viewer.