Ignore:
Timestamp:
07/23/14 20:36:44 (11 years ago)
Author:
epyon
Message:
  • merged md5 animation loader into md5_loader
  • all animation now handled through the node system
  • much cleanups
File:
1 edited

Legend:

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

    r287 r289  
    1414using namespace nv;
    1515
    16 // based on http://tfc.duke.free.fr/coding/md5-specs-en.html
    17 
    1816static void next_line( std::istream& stream )
    1917{
     
    2927}
    3028
    31 
    3229static void remove_quotes( std::string& str )
    3330{
     
    4441bool md5_loader::load( stream& source )
    4542{
     43        reset();
    4644        std_stream sstream( &source );
    4745        std::string command;
     46        mesh_node_data* nodes = nullptr;
     47        size_t num_joints = 0;
     48
     49        // MESH data
    4850        dynamic_array< md5_weight > weights;
    4951        dynamic_array< md5_weight_info > weight_info;
     52        size_t num_meshes = 0;
     53
     54        // MESH data
     55        std::vector<md5_joint_info> joint_infos;
     56        std::vector<transform>      base_frames;
     57        size_t num_animated_components = 0;
     58        size_t frame_rate = 0;
     59        size_t num_frames = 0;
    5060
    5161        sstream >> command;
     
    6373                else if ( command == "numJoints" )
    6474                {
    65                         sstream >> m_num_joints;
    66                         m_joints.resize( m_num_joints );
     75                        sstream >> num_joints;
     76                        next_line( sstream );
    6777                }
    6878                else if ( command == "numMeshes" )
    6979                {
    70                         sstream >> m_num_meshes;
    71                         m_meshes.resize( m_num_meshes );
    72                         m_num_meshes = 0;
     80                        assert( m_type == UNKNOWN );
     81                        m_type = MESH;
     82                        sstream >> num_meshes;
     83                        m_meshes.resize( num_meshes );
     84                        num_meshes = 0;
     85                }
     86                else if ( command == "numFrames" )
     87                {
     88                        assert( m_type == UNKNOWN || m_type == ANIMATION );
     89                        m_type = ANIMATION;
     90                        sstream >> num_frames;
     91                        next_line( sstream );
     92                }
     93                else if ( command == "frameRate" )
     94                {
     95                        assert( m_type == UNKNOWN || m_type == ANIMATION );
     96                        m_type = ANIMATION;
     97                        sstream >> frame_rate;
     98                        next_line( sstream );
     99                }
     100                else if ( command == "numAnimatedComponents" )
     101                {
     102                        assert( m_type == UNKNOWN || m_type == ANIMATION );
     103                        m_type = ANIMATION;
     104                        sstream >> num_animated_components;
     105                        next_line( sstream );
    73106                }
    74107                else if ( command == "joints" )
    75108                {
     109                        assert( m_type == MESH );
     110                        assert( m_nodes == nullptr );
     111                        nodes = new mesh_node_data[ num_joints ];
     112                        m_nodes = new mesh_nodes_data( "md5_bones", num_joints, nodes );
    76113                        discard( sstream, "{" );
    77                         md5_joint joint;
    78                         for ( size_t i = 0; i < m_num_joints; ++i )
    79                         {
    80                                 int parent_id;
    81                                 sstream >> joint.name >> parent_id;
     114                        for ( size_t i = 0; i < m_nodes->get_count(); ++i )
     115                        {
     116                                sstream >> nodes[i].name >> nodes[i].parent_id;
     117                                vec3 pos;
     118                                quat orient;
    82119                                discard( sstream, "(" );
    83                                 sstream >> joint.pos.x >> joint.pos.y >> joint.pos.z;
     120                                sstream >> pos.x >> pos.y >> pos.z;
    84121                                discard( sstream, ")" );
    85122                                discard( sstream, "(" );
    86                                 sstream >> joint.orient.x >> joint.orient.y >> joint.orient.z;
    87                                 remove_quotes( joint.name );
    88                                 unit_quat_w( joint.orient );
    89                                 m_joints[i] = joint;
     123                                sstream >> orient.x >> orient.y >> orient.z;
     124                                unit_quat_w( orient );
     125                                remove_quotes( nodes[i].name );
     126                                nodes[i].target_id       = -1;
     127                                nodes[i].parent_id       = -1;
     128                                nodes[i].transform       = transform( pos, orient ).inverse().extract();
     129                                nodes[i].data            = nullptr;
    90130                                next_line( sstream );
    91131                        }
     
    94134                else if ( command == "mesh" )
    95135                {
     136                        assert( m_type == MESH );
    96137                        mesh_data* mesh = new mesh_data("md5_mesh");
    97138
     
    192233                        }
    193234
    194                         prepare_mesh( weight_info.size(), mesh, weights.data(), weight_info.data() );
    195 
    196                         m_meshes[ m_num_meshes ] = mesh;
    197                         m_num_meshes++;
    198                 }
     235                        prepare_mesh( nodes, weight_info.size(), mesh, weights.data(), weight_info.data() );
     236
     237                        m_meshes[ num_meshes ] = mesh;
     238                        num_meshes++;
     239                } // mesh
     240                else if ( command == "hierarchy" )
     241                {
     242                        assert( m_type == ANIMATION );
     243                        assert( nodes == nullptr );
     244                        nodes = new mesh_node_data[ num_joints ];
     245                        m_nodes = new mesh_nodes_data( "md5_animation", num_joints, nodes, (nv::uint16)frame_rate, (float)num_frames, true );
     246                        joint_infos.resize( num_joints );
     247
     248                        discard( sstream, "{" );
     249                        for ( size_t i = 0; i < m_nodes->get_count(); ++i )
     250                        {
     251                                std::string    name;
     252                                sstream >> nodes[i].name >> nodes[i].parent_id >> joint_infos[i].flags >> joint_infos[i].start_index;
     253                                remove_quotes( name );
     254                                nodes[i].transform = mat4();
     255                                nodes[i].target_id = -1;
     256                                nodes[i].data      = new key_data;
     257                                nodes[i].data->add_channel( key_raw_channel::create< md5_key_t >( num_frames ) );
     258                                next_line( sstream );
     259                        }
     260                        discard( sstream, "}" );
     261                }
     262                else if ( command == "bounds" )
     263                {
     264                        assert( m_type == ANIMATION );
     265                        discard( sstream, "{" );
     266                        next_line( sstream );
     267                        for ( size_t i = 0; i < num_frames; ++i )
     268                        {
     269                                //                              vec3 min;
     270                                //                              vec3 max;
     271                                //                              discard( sstream, "(" );
     272                                //                              sstream >> min.x >> min.y >> min.z;
     273                                //                              discard( sstream, ")" );
     274                                //                              discard( sstream, "(" );
     275                                //                              sstream >> max.x >> max.y >> max.z;
     276                                //                              m_bounds.push_back( bound );
     277                                next_line( sstream );
     278                        }
     279
     280                        discard( sstream, "}" );
     281                        next_line( sstream );
     282                }
     283                else if ( command == "baseframe" )
     284                {
     285                        assert( m_type == ANIMATION );
     286                        discard( sstream, "{" );
     287                        next_line( sstream );
     288
     289                        for ( size_t i = 0; i < m_nodes->get_count(); ++i )
     290                        {
     291                                transform base_frame;
     292                                vec3 pos;
     293                                quat orient;
     294                                discard( sstream, "(" );
     295                                sstream >> pos.x >> pos.y >> pos.z;
     296                                discard( sstream, ")" );
     297                                discard( sstream, "(" );
     298                                sstream >> orient.x >> orient.y >> orient.z;
     299                                next_line( sstream );
     300
     301                                base_frames.emplace_back( pos, orient );
     302                        }
     303                        discard( sstream, "}" );
     304                        next_line( sstream );
     305                }
     306                else if ( command == "frame" )
     307                {
     308                        std::vector<float> frame;
     309                        uint32 frame_id;
     310                        sstream >> frame_id;
     311                        discard( sstream, "{" );
     312                        next_line( sstream );
     313
     314                        frame.reserve( num_animated_components );
     315                        char buf[50];
     316                        for ( size_t i = 0; i < num_animated_components; ++i )
     317                        {
     318                                sstream >> buf;
     319                                frame.push_back((float)atof(buf));
     320                        }
     321
     322                        build_frame_skeleton( nodes, frame_id, joint_infos, base_frames, frame );
     323
     324                        discard( sstream, "}" );
     325                        next_line( sstream );
     326                }
     327
    199328                sstream >> command;
    200329        }
     
    203332}
    204333
    205 bool md5_loader::prepare_mesh( uint32 vtx_count, mesh_data* mdata, md5_weight* weights, md5_weight_info* weight_info )
    206 {
     334bool md5_loader::prepare_mesh( mesh_node_data* nodes, uint32 vtx_count, mesh_data* mdata, md5_weight* weights, md5_weight_info* weight_info )
     335{
     336        assert( m_type == MESH );
    207337        md5_vtx_pnt* vtcs = (md5_vtx_pnt*)mdata->get_channel< md5_vtx_pnt >()->data;
    208338        md5_vtx_pntiw* vtx_data = (md5_vtx_pntiw*)mdata->get_channel< md5_vtx_pntiw >()->data;
     
    254384                        if ( j < weight_count )
    255385                        {
    256                                 md5_weight& weight = weights[start_weight + j];
    257                                 md5_joint&  joint  = m_joints[weight.joint_id];
    258                                 glm::vec3 rot_pos = joint.orient * weight.pos;
    259 
    260                                 vtc.position += ( joint.pos + rot_pos ) * weight.bias;
     386                                md5_weight& weight           = weights[start_weight + j];
     387                                const mesh_node_data&  joint = nodes[weight.joint_id];
     388                                const transform tr = transform( joint.transform ).inverse();
     389                                glm::vec3 rot_pos = tr.get_orientation() * weight.pos;
     390
     391                                vtc.position += ( tr.get_position() + rot_pos ) * weight.bias;
    261392                        }
    262393                }
     
    317448                for ( size_t j = 0; j < 4; ++j )
    318449                {
    319                         const md5_joint&  joint  = m_joints[vdata.boneindex[j]];
    320                         vdata.normal  += ( normal  * joint.orient ) * vdata.boneweight[j];
    321                         vdata.tangent += ( tangent * joint.orient ) * vdata.boneweight[j];
     450                        const mesh_node_data&  joint = nodes[vdata.boneindex[j]];
     451                        const transform tr = transform( joint.transform ).inverse();
     452                        vdata.normal  += ( normal  * tr.get_orientation() ) * vdata.boneweight[j];
     453                        vdata.tangent += ( tangent * tr.get_orientation() ) * vdata.boneweight[j];
    322454                }
    323455        }
     
    326458}
    327459
    328 
    329 md5_animation::md5_animation()
    330         : m_md5_version( 0 )
    331         , m_num_frames( 0 )
    332         , m_num_joints( 0 )
    333         , m_frame_rate( 0 )
    334         , m_num_animated_components( 0 )
    335         , m_anim_duration( 0 )
    336         , m_frame_duration( 0 )
    337 {
    338 
    339 }
    340 
    341 md5_animation::~md5_animation()
    342 {
    343 
    344 }
    345 
    346 bool md5_animation::load_animation( stream& source )
    347 {
    348         std::vector<md5_joint_info> joint_infos;
    349         std::vector<transform>      base_frames;
    350         m_num_frames = 0;
    351 
    352         std_stream sstream( &source );
    353         std::string command;
    354 
    355         sstream >> command;
    356         while ( !sstream.eof() )
    357         {
    358                 if ( command == "MD5Version" )
    359                 {
    360                         sstream >> m_md5_version;
    361                         assert( m_md5_version == 10 );
    362                 }
    363                 else if ( command == "commandline" )
    364                 {
    365                         next_line( sstream );
    366                 }
    367                 else if ( command == "numFrames" )
    368                 {
    369                         sstream >> m_num_frames;
    370                         next_line( sstream );
    371                 }
    372                 else if ( command == "numJoints" )
    373                 {
    374                         sstream >> m_num_joints;
    375                         m_joints.reserve( m_num_joints );
    376                         next_line( sstream );
    377                 }
    378                 else if ( command == "frameRate" )
    379                 {
    380                         sstream >> m_frame_rate;
    381                         next_line( sstream );
    382                 }
    383                 else if ( command == "numAnimatedComponents" )
    384                 {
    385                         sstream >> m_num_animated_components;
    386                         next_line( sstream );
    387                 }
    388                 else if ( command == "hierarchy" )
    389                 {
    390                         discard( sstream, "{" );
    391                         for ( size_t i = 0; i < m_num_joints; ++i )
    392                         {
    393                                 md5_joint_info joint;
    394                                 sstream >> joint.name >> joint.parent_id >> joint.flags >> joint.start_index;
    395                                 remove_quotes( joint.name );
    396                                 joint_infos.push_back( joint );
    397                                 m_joints.emplace_back( joint.parent_id );
    398                                 next_line( sstream );
    399                         }
    400                         discard( sstream, "}" );
    401                 }
    402                 else if ( command == "bounds" )
    403                 {
    404                         discard( sstream, "{" );
    405                         next_line( sstream );
    406                         for ( size_t i = 0; i < m_num_frames; ++i )
    407                         {
    408 //                              vec3 min;
    409 //                              vec3 max;
    410 //                              discard( sstream, "(" );
    411 //                              sstream >> min.x >> min.y >> min.z;
    412 //                              discard( sstream, ")" );
    413 //                              discard( sstream, "(" );
    414 //                              sstream >> max.x >> max.y >> max.z;
    415 //                              m_bounds.push_back( bound );
    416                                 next_line( sstream );
    417                         }
    418 
    419                         discard( sstream, "}" );
    420                         next_line( sstream );
    421                 }
    422                 else if ( command == "baseframe" )
    423                 {
    424                         discard( sstream, "{" );
    425                         next_line( sstream );
    426 
    427                         for ( size_t i = 0; i < m_num_joints; ++i )
    428                         {
    429                                 transform base_frame;
    430                                 vec3 pos;
    431                                 quat orient;
    432                                 discard( sstream, "(" );
    433                                 sstream >> pos.x >> pos.y >> pos.z;
    434                                 discard( sstream, ")" );
    435                                 discard( sstream, "(" );
    436                                 sstream >> orient.x >> orient.y >> orient.z;
    437                                 next_line( sstream );
    438 
    439                                 base_frames.emplace_back( pos, orient );
    440                         }
    441                         discard( sstream, "}" );
    442                         next_line( sstream );
    443                 }
    444                 else if ( command == "frame" )
    445                 {
    446                         std::vector<float> frame;
    447                         int frame_id;
    448                         sstream >> frame_id;
    449                         discard( sstream, "{" );
    450                         next_line( sstream );
    451 
    452                         frame.reserve( m_num_animated_components );
    453                         char buf[50];
    454                         for ( size_t i = 0; i < m_num_animated_components; ++i )
    455                         {
    456                                 sstream >> buf;
    457                                 frame.push_back((float)atof(buf));
    458                         }
    459 
    460                         build_frame_skeleton( joint_infos, base_frames, frame );
    461 
    462                         discard( sstream, "}" );
    463                         next_line( sstream );
    464                 }
    465 
    466                 sstream >> command;
    467         }
    468 
    469 
    470         m_frame_duration = 1.0f / (float)m_frame_rate;
    471         m_anim_duration = ( m_frame_duration * (float)m_num_frames );
    472 
    473         return true;
    474 }
    475 
    476 
    477 void nv::md5_animation::update_skeleton( transform* skeleton, float anim_time ) const
    478 {
    479         anim_time = glm::clamp( anim_time, 0.0f, m_anim_duration );
    480         float frame_num = anim_time * (float)m_frame_rate;
    481         size_t frame0 = (size_t)floorf( frame_num );
    482         size_t frame1 = (size_t)ceilf( frame_num );
    483         frame0 = frame0 % m_num_frames;
    484         frame1 = frame1 % m_num_frames;
    485 
    486         float interpolation = fmodf( anim_time, m_frame_duration ) / m_frame_duration;
    487 
    488         for ( size_t i = 0; i < m_num_joints; ++i )
    489         {
    490                 const std::vector< transform >& keys = m_joints[i].keys;
    491                 skeleton[i] = interpolate( keys[frame0], keys[frame1], interpolation );
    492         }
    493 }
    494 
    495 void md5_animation::build_frame_skeleton( const std::vector<md5_joint_info>& joint_infos, const std::vector<transform>& base_frames, const std::vector<float>& frame_data )
    496 {
    497         size_t index = m_joints[0].keys.size();
     460void md5_loader::build_frame_skeleton( mesh_node_data* nodes, uint32 index, const std::vector<md5_joint_info>& joint_infos, const std::vector<transform>& base_frames, const std::vector<float>& frame_data )
     461{
     462        assert( m_type == ANIMATION );
    498463        for ( unsigned int i = 0; i < joint_infos.size(); ++i )
    499464        {
     
    501466
    502467                const md5_joint_info& jinfo = joint_infos[i];
    503 
    504 
    505                 int parent_id = jinfo.parent_id;
     468                mesh_node_data& joint = nodes[i];
     469                int parent_id         = joint.parent_id;
    506470
    507471                vec3 pos    = base_frames[i].get_position();
     
    517481                if ( parent_id >= 0 ) // Has a parent joint
    518482                {
    519                         const std::vector< transform >& ptv = m_joints[ size_t( parent_id ) ].keys;
     483                        const mesh_node_data& pjoint = nodes[parent_id];
     484                        const transform* ptv = (const transform*)pjoint.data->get_channel(0)->data;
    520485                        transform ptr;
    521                         if ( ptv.size() > index ) ptr = ptv[ index ];
     486                        if ( pjoint.data->get_channel(0)->count > index ) ptr = ptv[ index ];
    522487                        glm::vec3 rot_pos = ptr.get_orientation() * pos;
    523488
     
    528493                }
    529494
    530                 m_joints[i].keys.push_back( transform( pos, orient ) );
     495                ((transform*)joint.data->get_channel(0)->data)[index] = transform( pos, orient );
    531496        }
    532497}
     
    541506mesh_nodes_data* nv::md5_loader::release_mesh_nodes_data()
    542507{
    543         mesh_node_data* nodes = new mesh_node_data[ m_num_joints ];
    544         for ( uint32 i = 0; i < m_num_joints; ++i )
    545         {
    546                 mesh_node_data& node = nodes[i];
    547                 node.name      = m_joints[i].name;
    548                 node.target_id = -1;
    549                 node.parent_id = -1;
    550                 node.transform = transform( m_joints[i].pos, m_joints[i].orient ).inverse().extract();
    551                 node.data      = nullptr;
    552         }
    553         return new mesh_nodes_data( "nodes", m_num_joints, nodes );
     508        mesh_nodes_data* nodes = m_nodes;
     509        m_nodes = nullptr;
     510        return nodes;
    554511}
    555512
     
    570527nv::md5_loader::~md5_loader()
    571528{
     529        reset();
     530}
     531
     532void nv::md5_loader::reset()
     533{
     534        if ( m_nodes ) delete m_nodes;
    572535        for ( auto m : m_meshes ) { if (m) delete m; }
    573 }
    574 
     536        m_meshes.resize(0);
     537        m_nodes = nullptr;
     538}
     539
Note: See TracChangeset for help on using the changeset viewer.