Ignore:
Timestamp:
05/17/14 02:35:19 (11 years ago)
Author:
epyon
Message:
  • massive update of mesh handling
  • universal mesh handling routines
  • removed a lot of legacy code
  • significantly streamlined MD5 loading
  • all tests updated to new features
File:
1 edited

Legend:

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

    r236 r239  
    9090                else if ( command == "mesh" )
    9191                {
    92                         md5_mesh* mesh = new md5_mesh;
     92                        md5_mesh_data* mesh = new md5_mesh_data();
     93
    9394                        int num_verts, num_tris, num_weights;
    9495
     
    99100                                if ( command == "shader" )
    100101                                {
    101                                         sstream >> mesh->shader;
    102                                         remove_quotes( mesh->shader );
     102                                        sstream >> mesh->m_shader;
     103                                        remove_quotes( mesh->m_shader );
    103104                                        // texturePath.replace_extension( ".tga" );
    104105                                        next_line( sstream );
     
    107108                                {
    108109                                        sstream >> num_verts;
     110
     111                                        {
     112                                                mesh_raw_channel* ch_pnt = mesh_raw_channel::create<md5_vtx_pnt>( num_verts );
     113                                                mesh_raw_channel* ch_t   = mesh_raw_channel::create<md5_vtx_t>( num_verts );
     114                                                mesh->m_pntdata          = (md5_vtx_pnt*)ch_pnt->data;
     115                                                mesh->m_tdata            = (md5_vtx_t*)ch_t->data;
     116                                                mesh->add_channel( ch_pnt );
     117                                                mesh->add_channel( ch_t );
     118                                        }
     119                                        mesh->m_vtx_data.resize( num_verts );
     120
    109121                                        next_line( sstream );
    110122                                        std::string line;
    111123                                        for ( int i = 0; i < num_verts; ++i )
    112124                                        {
    113                                                 md5_vertex vert;
     125                                                md5_vtx_data& vdata = mesh->m_vtx_data[i];
     126                                                size_t weight_count;
     127                                                size_t start_weight;
     128                                                vec2 texcoord;
    114129
    115130                                                std::getline( sstream, line );
    116                                                 sscanf( line.c_str(), "%*s %*u ( %f %f ) %u %u", &(vert.texcoord.x), &(vert.texcoord.y), &(vert.start_weight), &(vert.weight_count) );
    117 
    118 //                                              std::string ignore;
    119 //                                              discard( sstream, "vert" );
    120 //                                              sstream >> ignore;
    121 //                                              discard( sstream, "(" );
    122 //                                              sstream >> vert.texcoord.x >> vert.texcoord.y;
    123 //                                              discard( sstream, ")" );
    124 //                                              sstream >> vert.start_weight >> vert.weight_count;
    125 //                                              next_line( sstream );
    126 
    127                                                 mesh->verts.push_back(vert);
    128                                                 mesh->texcoord_buffer.push_back( vert.texcoord );
     131                                                sscanf( line.c_str(), "%*s %*u ( %f %f ) %u %u", &(texcoord.x), &(texcoord.y), &(start_weight), &(weight_count) );
     132                                                vdata.start_weight = start_weight;
     133                                                vdata.weight_count = weight_count;
     134                                                mesh->m_tdata[i].texcoord = texcoord;
    129135                                        } 
    130136                                }
     
    132138                                {
    133139                                        sstream >> num_tris;
     140
     141                                        mesh_raw_index_channel* ch_i = mesh_raw_index_channel::create<uint32>( num_tris * 3 );
     142                                        uint32* vtx_i                = (uint32*)ch_i->data;
     143                                        mesh->m_idata                = vtx_i;
     144                                        uint32 idx = 0;
     145                                        mesh->set_index_channel( ch_i );
     146
    134147                                        next_line( sstream );
    135148                                        std::string line;
    136149                                        for ( int i = 0; i < num_tris; ++i )
    137150                                        {
    138                                                 md5_triangle tri;
     151                                                size_t ti0;
     152                                                size_t ti1;
     153                                                size_t ti2;
    139154
    140155                                                std::getline( sstream, line );
    141                                                 sscanf( line.c_str(), "%*s %*u %u %u %u )", &(tri.indices[0]), &(tri.indices[1]), &(tri.indices[2]));
    142 
    143 //                                              std::string ignore;
    144 //                                              discard( sstream, "tri" );
    145 //                                              sstream >> ignore >> tri.indices[0] >> tri.indices[1] >> tri.indices[2];
    146 //                                              next_line( sstream );
    147 
    148                                                 mesh->tris.push_back( tri );
    149                                                 mesh->index_buffer.push_back( (uint32)tri.indices[0] );
    150                                                 mesh->index_buffer.push_back( (uint32)tri.indices[1] );
    151                                                 mesh->index_buffer.push_back( (uint32)tri.indices[2] );
     156                                                sscanf( line.c_str(), "%*s %*u %u %u %u )", &(ti0), &(ti1), &(ti2));
     157
     158                                                vtx_i[idx++] = (uint32)ti0;
     159                                                vtx_i[idx++] = (uint32)ti1;
     160                                                vtx_i[idx++] = (uint32)ti2;
    152161                                        }             
    153162                                }
     
    155164                                {
    156165                                        sstream >> num_weights;
    157                                         mesh->weights.reserve( num_weights );
     166                                        mesh->m_weights.reserve( num_weights );
    158167                                        next_line( sstream );
    159168                                        std::string line;
     
    164173                                                std::getline( sstream, line );
    165174                                                sscanf( line.c_str(), "%*s %*u %u %f ( %f %f %f )", &(weight.joint_id), &(weight.bias), &(weight.pos.x), &(weight.pos.y), &(weight.pos.z));
    166 
    167 //                                              std::string ignore;
    168 //                                              discard( sstream, "weight" );
    169 //                                              sstream >> ignore >> weight.joint_id >> weight.bias;
    170 //                                              discard( sstream, "(" );
    171 //                                              sstream >> weight.pos.x >> weight.pos.y >> weight.pos.z;
    172 //                                              discard( sstream, ")" );
    173 //                                              next_line( sstream );
    174                                                 mesh->weights.push_back(weight);
     175                                                mesh->m_weights.push_back(weight);
    175176                                        }
    176177                                }
     
    184185
    185186                        prepare_mesh( mesh );
    186                         prepare_normals( mesh );
    187187
    188188                        m_meshes.push_back(mesh);
     
    196196}
    197197
    198 bool md5_loader::prepare_mesh( md5_mesh* mesh )
    199 {
    200         mesh->position_buffer.clear();
    201         mesh->texcoord_buffer.clear();
    202 
    203         for ( uint32 i = 0; i < mesh->verts.size(); ++i )
    204         {
    205                 md5_vertex& vert = mesh->verts[i];
    206 
    207                 vert.position = glm::vec3(0);
    208                 vert.normal   = glm::vec3(0);
    209                 vert.tangent  = glm::vec3(0);
    210 
    211                 for ( size_t j = 0; j < vert.weight_count; ++j )
    212                 {
    213                         md5_weight& weight = mesh->weights[vert.start_weight + j];
     198bool md5_loader::prepare_mesh( md5_mesh_data* mdata )
     199{
     200        uint32 vtx_count = mdata->m_vtx_data.size();
     201        md5_vtx_pnt* vtcs = mdata->m_pntdata;
     202
     203        for ( uint32 i = 0; i < vtx_count; ++i )
     204        {
     205                md5_vtx_data& vdata = mdata->m_vtx_data[i];
     206                md5_vtx_pnt& vtc = vtcs[i];
     207
     208                vtc.position = glm::vec3(0);
     209                vtc.normal   = glm::vec3(0);
     210                vtc.tangent  = glm::vec3(0);
     211
     212                for ( size_t j = 0; j < vdata.weight_count; ++j )
     213                {
     214                        md5_weight& weight = mdata->m_weights[vdata.start_weight + j];
    214215                        md5_joint&  joint  = m_joints[weight.joint_id];
    215216
    216217                        glm::vec3 rot_pos = joint.orient * weight.pos;
    217218
    218                         vert.position += ( joint.pos + rot_pos ) * weight.bias;
    219                 }
    220 
    221                 mesh->position_buffer.push_back(vert.position);
    222                 mesh->texcoord_buffer.push_back(vert.texcoord);
    223         }
    224 
    225         return true;
    226 }
    227 
    228 bool md5_loader::prepare_normals( md5_mesh* mesh )
    229 {
    230         mesh->normal_buffer.clear();
    231 
    232         for ( unsigned int i = 0; i < mesh->tris.size(); ++i )
    233         {
    234                 const md5_triangle& tri = mesh->tris[i];
    235                 glm::vec3 v1 = mesh->verts[ tri.indices[0] ].position;
    236                 glm::vec3 v2 = mesh->verts[ tri.indices[1] ].position;
    237                 glm::vec3 v3 = mesh->verts[ tri.indices[2] ].position;
     219                        vtc.position += ( joint.pos + rot_pos ) * weight.bias;
     220                }
     221        }
     222
     223        // Prepare normals
     224        uint32 tri_count = mdata->get_count() / 3;
     225        for ( unsigned int i = 0; i < tri_count; ++i )
     226        {
     227                uint32 ti0 = mdata->m_idata[ i * 3 ];
     228                uint32 ti1 = mdata->m_idata[ i * 3 + 1 ];
     229                uint32 ti2 = mdata->m_idata[ i * 3 + 2 ];
     230 
     231                glm::vec3 v1 = vtcs[ ti0 ].position;
     232                glm::vec3 v2 = vtcs[ ti1 ].position;
     233                glm::vec3 v3 = vtcs[ ti2 ].position;
    238234                glm::vec3 xyz1 = v3 - v1;
    239235                glm::vec3 xyz2 = v2 - v1;
     
    241237                glm::vec3 normal = glm::cross( xyz1, xyz2 );
    242238
    243                 mesh->verts[ tri.indices[0] ].normal += normal;
    244                 mesh->verts[ tri.indices[1] ].normal += normal;
    245                 mesh->verts[ tri.indices[2] ].normal += normal;
    246 
    247                 const vec2& w1 = mesh->verts[ tri.indices[0] ].texcoord;
    248                 const vec2& w2 = mesh->verts[ tri.indices[1] ].texcoord;
    249                 const vec2& w3 = mesh->verts[ tri.indices[2] ].texcoord;
     239                vtcs[ ti0 ].normal += normal;
     240                vtcs[ ti1 ].normal += normal;
     241                vtcs[ ti2 ].normal += normal;
     242
     243                const vec2& w1 = mdata->m_tdata[ ti0 ].texcoord;
     244                const vec2& w2 = mdata->m_tdata[ ti1 ].texcoord;
     245                const vec2& w3 = mdata->m_tdata[ ti2 ].texcoord;
    250246
    251247                vec2 st1 = w3 - w1;
     
    256252                vec3 tangent = (( xyz1 * st2.y ) - ( xyz2 * st1.y )) * coef;
    257253
    258                 mesh->verts[ tri.indices[0] ].tangent += tangent;
    259                 mesh->verts[ tri.indices[1] ].tangent += tangent;
    260                 mesh->verts[ tri.indices[2] ].tangent += tangent;
    261         }
    262 
    263         for ( size_t i = 0; i < mesh->verts.size(); ++i )
    264         {
    265                 md5_vertex& vert = mesh->verts[i];
    266 
    267                 glm::vec3 normal  = glm::normalize( vert.normal );
    268                 glm::vec3 tangent = glm::normalize( vert.tangent );
    269                 mesh->normal_buffer.push_back( normal );
    270                 mesh->tangent_buffer.push_back( tangent );
    271 
    272                 vert.normal  = glm::vec3(0);
    273                 vert.tangent = glm::vec3(0);
    274 
    275                 for ( size_t j = 0; j < vert.weight_count; ++j )
    276                 {
    277                         const md5_weight& weight = mesh->weights[vert.start_weight + j];
    278                         const md5_joint&  joint  = m_joints[weight.joint_id];
    279                         vert.normal  += ( normal  * joint.orient ) * weight.bias;
    280                         vert.tangent += ( tangent * joint.orient ) * weight.bias;
    281                 }
     254                vtcs[ ti0 ].tangent += tangent;
     255                vtcs[ ti1 ].tangent += tangent;
     256                vtcs[ ti2 ].tangent += tangent;
     257        }
     258
     259        for ( size_t i = 0; i < vtx_count; ++i )
     260        {
     261                md5_vtx_data& vdata = mdata->m_vtx_data[i];
     262
     263                glm::vec3 normal  = glm::normalize( vtcs[i].normal );
     264                glm::vec3 tangent = glm::normalize( vtcs[i].tangent );
     265                vtcs[i].normal   = normal;
     266                vtcs[i].tangent  = tangent;
     267
     268                vdata.normal  = glm::vec3(0);
     269                vdata.tangent = glm::vec3(0);
     270 
     271                for ( size_t j = 0; j < vdata.weight_count; ++j )
     272                {
     273                        const md5_weight& weight = mdata->m_weights[vdata.start_weight + j];
     274                        const md5_joint&  joint  = m_joints[weight.joint_id];
     275                        vdata.normal  += ( normal  * joint.orient ) * weight.bias;
     276                        vdata.tangent += ( tangent * joint.orient ) * weight.bias;
     277                }
    282278        }
    283279
     
    285281}
    286282
    287 mesh_data_old* nv::md5_loader::release_submesh_data( uint32 mesh_id )
    288 {
    289         mesh_data_creator m;
    290         m.get_positions().assign( m_meshes[mesh_id]->position_buffer.begin(), m_meshes[mesh_id]->position_buffer.begin() );
    291         m.get_normals()  .assign( m_meshes[mesh_id]->normal_buffer.begin(),   m_meshes[mesh_id]->normal_buffer.begin() );
    292         m.get_tangents() .assign( m_meshes[mesh_id]->tangent_buffer.begin(),  m_meshes[mesh_id]->tangent_buffer.begin() );
    293         m.get_texcoords().assign( m_meshes[mesh_id]->texcoord_buffer.begin(), m_meshes[mesh_id]->texcoord_buffer.begin() );
    294         m.get_indices()  .assign( m_meshes[mesh_id]->index_buffer.begin(),    m_meshes[mesh_id]->index_buffer.begin() );
    295 
    296         return m.release();
    297 }
    298 
    299 /*
    300 mesh* md5_loader::release_mesh()
    301 {
    302         mesh* m = new mesh();
    303         auto position = m->add_attribute< vec3 >( "nv_position" );
    304         auto normal   = m->add_attribute< vec3 >( "nv_normal" );
    305         auto texcoord = m->add_attribute< vec2 >( "nv_texcoord" );
    306         auto tangent  = m->add_attribute< vec3 >( "nv_tangent" );
    307         auto indices  = m->add_indices< uint32 >();
    308 
    309         position->get().assign( m_meshes[0].position_buffer.begin(), m_meshes[0].position_buffer.end() );
    310         normal  ->get().assign( m_meshes[0].normal_buffer.begin(),   m_meshes[0].normal_buffer.end() );
    311         texcoord->get().assign( m_meshes[0].texcoord_buffer.begin(), m_meshes[0].texcoord_buffer.end() );
    312         tangent ->get().assign( m_meshes[0].tangent_buffer.begin(),  m_meshes[0].tangent_buffer.end() );
    313         indices ->get().assign( m_meshes[0].index_buffer.begin(),    m_meshes[0].index_buffer.end() );
    314 
    315         m_size = m_meshes[0].index_buffer.size();
    316         return m;
    317 }
    318 */
    319283
    320284md5_animation::md5_animation()
     
    570534}
    571535
    572 bool md5_loader::prepare_animated_mesh( md5_mesh* mesh, const md5_animation::md5_frame_skeleton& skel )
    573 {
    574         for ( unsigned int i = 0; i < mesh->verts.size(); ++i )
    575         {
    576                 const md5_vertex& vert = mesh->verts[i];
    577                 glm::vec3& pos     = mesh->position_buffer[i];
    578                 glm::vec3& normal  = mesh->normal_buffer[i];
    579                 glm::vec3& tangent = mesh->tangent_buffer[i];
    580 
    581                 pos     = glm::vec3(0);
    582                 normal  = glm::vec3(0);
    583                 tangent = glm::vec3(0);
     536mesh_data* nv::md5_loader::release_mesh_data( uint32 mesh )
     537{
     538        mesh_data* result = m_meshes[ mesh ];
     539        m_meshes[ mesh ] = nullptr;
     540        return result;
     541}
     542
     543void nv::md5_mesh_data::apply( const md5_animation& animation )
     544{
     545        const md5_animation::md5_frame_skeleton& skeleton = animation.get_skeleton();
     546
     547        for ( unsigned int i = 0; i < m_vtx_data.size(); ++i )
     548        {
     549                const md5_vtx_data& vert = m_vtx_data[i];
     550                md5_vtx_pnt& result = m_pntdata[i];
     551
     552                result.position = glm::vec3(0);
     553                result.normal   = glm::vec3(0);
     554                result.tangent  = glm::vec3(0);
    584555
    585556                for ( size_t j = 0; j < vert.weight_count; ++j )
    586557                {
    587                         const md5_weight& weight = mesh->weights[vert.start_weight + j];
    588                         const md5_animation::md5_skeleton_joint& joint = skel.joints[weight.joint_id];
     558                        const md5_weight& weight = m_weights[vert.start_weight + j];
     559                        const md5_animation::md5_skeleton_joint& joint = skeleton.joints[weight.joint_id];
    589560
    590561                        glm::vec3 rot_pos = joint.orient * weight.pos;
    591                         pos += ( joint.pos + rot_pos ) * weight.bias;
    592 
    593                         normal  += ( joint.orient * vert.normal  ) * weight.bias;
    594                         tangent += ( joint.orient * vert.tangent ) * weight.bias;
    595                 }
    596         }
    597         return true;
    598 }
    599 
    600 void md5_loader::apply( const md5_animation& animation )
    601 {
    602         const md5_animation::md5_frame_skeleton& skeleton = animation.get_skeleton();
    603 
    604         for ( unsigned int i = 0; i < m_meshes.size(); ++i )
    605         {
    606                 prepare_animated_mesh( m_meshes[i], skeleton );
    607         }
    608 }
    609 
    610 size_t nv::md5_loader::get_size()
    611 {
    612         return m_size;
    613 }
     562                        result.position += ( joint.pos + rot_pos ) * weight.bias;
     563
     564                        result.normal  += ( joint.orient * vert.normal  ) * weight.bias;
     565                        result.tangent += ( joint.orient * vert.tangent ) * weight.bias;
     566                }
     567        }
     568}
     569
     570nv::md5_loader::~md5_loader()
     571{
     572        for ( auto m : m_meshes ) { if (m) delete m; }
     573}
Note: See TracChangeset for help on using the changeset viewer.