Changeset 259 for trunk/src


Ignore:
Timestamp:
06/15/14 17:26:35 (11 years ago)
Author:
epyon
Message:
  • severly cleaned up the md5 loader, uses now the same scheme as the assimp loader (but different structures)
  • transform utulity operators/functions added
File:
1 edited

Legend:

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

    r258 r259  
    4747        std_stream sstream( &source );
    4848        std::string command;
     49        std::vector< md5_weight > weights;
     50        std::vector< md5_weight_info > weight_info;
    4951
    5052        sstream >> command;
     
    120122                                        }
    121123                                        mesh->m_vtx_data.resize( num_verts );
     124                                        weight_info.resize( num_verts );
    122125
    123126                                        next_line( sstream );
     
    125128                                        for ( int i = 0; i < num_verts; ++i )
    126129                                        {
    127                                                 md5_vtx_data& vdata = mesh->m_vtx_data[i];
    128130                                                size_t weight_count;
    129131                                                size_t start_weight;
     
    132134                                                std::getline( sstream, line );
    133135                                                sscanf( line.c_str(), "%*s %*u ( %f %f ) %u %u", &(texcoord.x), &(texcoord.y), &(start_weight), &(weight_count) );
    134                                                 vdata.start_weight = start_weight;
    135                                                 vdata.weight_count = weight_count;
     136                                                weight_info[i].start_weight = start_weight;
     137                                                weight_info[i].weight_count = weight_count;
    136138                                                mesh->m_tdata[i].texcoord = texcoord;
    137139                                        } 
     
    166168                                {
    167169                                        sstream >> num_weights;
    168                                         mesh->m_weights.reserve( num_weights );
     170                                        weights.reserve( num_weights );
    169171                                        next_line( sstream );
    170172                                        std::string line;
     
    175177                                                std::getline( sstream, line );
    176178                                                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));
    177                                                 mesh->m_weights.push_back(weight);
     179                                                weights.push_back(weight);
    178180                                        }
    179181                                }
     
    186188                        }
    187189
    188                         prepare_mesh( mesh );
     190                        prepare_mesh( mesh, weights, weight_info );
    189191
    190192                        m_meshes.push_back(mesh);
     
    198200}
    199201
    200 bool md5_loader::prepare_mesh( md5_mesh_data* mdata )
     202bool md5_loader::prepare_mesh( md5_mesh_data* mdata, std::vector< md5_weight >& weights, std::vector< md5_weight_info >& weight_info )
    201203{
    202204        uint32 vtx_count = mdata->m_vtx_data.size();
    203205        md5_vtx_pnt* vtcs = mdata->m_pntdata;
    204206
     207        for ( auto joint : m_joints )
     208        {
     209                transform j( joint.pos, joint.orient );
     210                mdata->m_bone_offset.push_back(j.inverse());
     211        }
     212
    205213        for ( uint32 i = 0; i < vtx_count; ++i )
    206214        {
     215                size_t start_weight = weight_info[i].start_weight;
     216                size_t weight_count = weight_info[i].weight_count;
    207217                md5_vtx_data& vdata = mdata->m_vtx_data[i];
    208218                md5_vtx_pnt& vtc = vtcs[i];
     
    212222                vtc.tangent  = glm::vec3(0);
    213223
    214                 std::sort( mdata->m_weights.begin() + vdata.start_weight, mdata->m_weights.begin() + vdata.start_weight + vdata.weight_count, [](const md5_weight& a, const md5_weight& b) -> bool { return a.bias > b.bias; } );
    215 
    216                 if ( vdata.weight_count > 4 )
     224                std::sort( weights.begin() + start_weight, weights.begin() + start_weight + weight_count, [](const md5_weight& a, const md5_weight& b) -> bool { return a.bias > b.bias; } );
     225
     226                if ( weight_count > 4 )
    217227                {
    218228                        float sum = 0.0f;
    219229                        for ( size_t j = 0; j < 4; ++j )
    220230                        {
    221                                 sum += mdata->m_weights[vdata.start_weight + j].bias;
     231                                sum += weights[start_weight + j].bias;
    222232                        }
    223233                        float ratio = 1.0f / sum;
    224234                        for ( size_t j = 0; j < 4; ++j )
    225235                        {
    226                                 mdata->m_weights[vdata.start_weight + j].bias =
    227                                         ratio * mdata->m_weights[vdata.start_weight + j].bias;
    228                         }
    229                         vdata.weight_count = 4;
    230                 }
    231 
    232                 for ( size_t j = 0; j < vdata.weight_count; ++j )
    233                 {
    234                         md5_weight& weight = mdata->m_weights[vdata.start_weight + j];
    235                         md5_joint&  joint  = m_joints[weight.joint_id];
    236 
    237                         glm::vec3 rot_pos = joint.orient * weight.pos;
    238 
    239                         vtc.position += ( joint.pos + rot_pos ) * weight.bias;
     236                                weights[start_weight + j].bias = ratio * weights[start_weight + j].bias;
     237                        }
     238                        weight_count = 4;
     239                }
     240
     241                for ( size_t j = 0; j < 4; ++j )
     242                {
     243                        if ( j < weight_count )
     244                        {
     245                                vdata.boneindex[j]  = weights[start_weight + j].joint_id;
     246                                vdata.boneweight[j] = weights[start_weight + j].bias;
     247                        }
     248                        else
     249                        {
     250                                vdata.boneindex[j]  = 0;
     251                                vdata.boneweight[j] = 0.0f;
     252                        }
     253                }
     254
     255                for ( size_t j = 0; j < 4; ++j )
     256                {
     257                        if ( j < weight_count )
     258                        {
     259                                md5_weight& weight = weights[start_weight + j];
     260                                md5_joint&  joint  = m_joints[weight.joint_id];
     261                                glm::vec3 rot_pos = joint.orient * weight.pos;
     262
     263                                vtc.position += ( joint.pos + rot_pos ) * weight.bias;
     264                        }
    240265                }
    241266        }
     
    286311                vtcs[i].tangent  = tangent;
    287312
    288                 vdata.normal  = glm::vec3(0);
    289                 vdata.tangent = glm::vec3(0);
     313                vdata.position = vtcs[i].position;
     314                vdata.normal   = glm::vec3(0);
     315                vdata.tangent  = glm::vec3(0);
    290316 
    291                 for ( size_t j = 0; j < vdata.weight_count; ++j )
     317                for ( size_t j = 0; j < 4; ++j )
    292318                {
    293                         const md5_weight& weight = mdata->m_weights[vdata.start_weight + j];
    294                         const md5_joint&  joint  = m_joints[weight.joint_id];
    295                         vdata.normal  += ( normal  * joint.orient ) * weight.bias;
    296                         vdata.tangent += ( tangent * joint.orient ) * weight.bias;
     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];
    297322                }
    298323        }
     
    537562{
    538563        NV_PROFILE("md5::apply");
     564        m_pos_offset.resize( skeleton.size() );
     565        for ( unsigned int i = 0; i < skeleton.size(); ++i )
     566        {
     567                m_pos_offset[i] = skeleton[i] * m_data->m_bone_offset[i];
     568        }
     569
    539570        char* fill_ptr = (char*)&(m_pntdata[0]);
    540571        std::fill( fill_ptr, fill_ptr + m_size * ( sizeof( md5_vtx_pnt ) ), 0 );
     
    544575                md5_vtx_pnt& result = m_pntdata[i];
    545576
    546                 for ( size_t j = 0; j < vert.weight_count; ++j )
    547                 {
    548                         const md5_weight& weight = m_data->m_weights[vert.start_weight + j];
    549                         const transform& joint = skeleton[weight.joint_id];
    550 
    551                         glm::vec3 rot_pos = joint.get_orientation() * weight.pos;
    552                         result.position += ( joint.get_position() + rot_pos ) * weight.bias;
    553 
    554                         result.normal  += ( joint.get_orientation() * vert.normal  ) * weight.bias;
    555                         result.tangent += ( joint.get_orientation() * vert.tangent ) * weight.bias;
    556                 }
    557         }
    558 }
     577                for ( size_t j = 0; j < 4; ++j )
     578                {
     579                        int   index  = vert.boneindex[j];
     580                        float weight = vert.boneweight[j];
     581                        transform joint  = skeleton[index];
     582                        transform offset = m_pos_offset[index];
     583                        result.position += offset.transformed( vert.position )        * weight;
     584                        result.normal   += ( joint.get_orientation() * vert.normal  ) * weight;
     585                        result.tangent  += ( joint.get_orientation() * vert.tangent ) * weight;
     586                }
     587        }
     588}
Note: See TracChangeset for help on using the changeset viewer.