Changeset 259


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
Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/formats/md5_loader.hh

    r241 r259  
    3636        struct md5_vtx_data
    3737        {
    38                 glm::vec3 normal;
    39                 glm::vec3 tangent;
    40                 size_t    start_weight;
    41                 size_t    weight_count;
    42         };
    43 
    44         struct md5_weight
    45         {
    46                 size_t    joint_id;
    47                 float     bias;
    48                 glm::vec3 pos;
     38                vec3  position;
     39                vec3  normal;
     40                vec3  tangent;
     41                ivec4 boneindex;
     42                vec4  boneweight;
    4943        };
    5044
     
    108102                md5_mesh_instance( const md5_mesh_data* a_data );
    109103
    110                 uint32               m_size;
    111                 uint32               m_indices;
    112                 md5_vtx_pnt*         m_pntdata;
    113                 const md5_mesh_data* m_data;
     104                uint32                   m_size;
     105                uint32                   m_indices;
     106                md5_vtx_pnt*             m_pntdata;
     107                std::vector< transform > m_pos_offset;
     108                const md5_mesh_data*     m_data;
    114109        };
    115110
     
    125120                md5_vtx_pnt*                m_pntdata;
    126121                std::string                 m_shader;
     122                std::vector< transform >    m_bone_offset;
    127123                std::vector< md5_vtx_data > m_vtx_data;
    128                 std::vector< md5_weight   > m_weights;
    129124        };
    130125
     
    139134                virtual size_t get_mesh_count() const { return m_meshes.size(); }
    140135        protected:
     136                struct md5_weight
     137                {
     138                        size_t    joint_id;
     139                        float     bias;
     140                        glm::vec3 pos;
     141                };
     142
     143                struct md5_weight_info
     144                {
     145                        size_t     start_weight;
     146                        size_t     weight_count;
     147                };
    141148
    142149                struct md5_joint
     
    147154                };
    148155        protected:
    149                 bool prepare_mesh( md5_mesh_data* mdata );
     156                bool prepare_mesh( md5_mesh_data* mdata, std::vector< md5_weight >& weights, std::vector< md5_weight_info >& weight_info );
    150157        protected:
    151158                uint32 m_md5_version;
  • trunk/nv/transform.hh

    r241 r259  
    5757                        return result;
    5858                }
     59                transform inverse() const
     60                {
     61                        quat new_orient( glm::inverse( m_orientation ) );
     62                        // TODO: simplify
     63                        return transform( -glm::mat3_cast(new_orient) * m_position, new_orient );
     64                }
     65
     66                transform& operator*=(const transform& rhs)
     67                {
     68                        m_position = m_position + m_orientation * rhs.m_position;
     69                        m_orientation = m_orientation * rhs.m_orientation;
     70                        return *this;
     71                }
     72
     73                vec3 transformed( const vec3 v ) const
     74                {
     75                        return m_orientation * v + m_position;
     76                }
    5977        private:
    6078                vec3 m_position;
    6179                quat m_orientation;
    6280        };
     81
     82        inline transform operator*(transform lhs, const transform& rhs)
     83        {
     84                lhs *= rhs;
     85                return lhs;
     86        }
     87
     88        inline vec3 operator*(const vec3 lhs, const transform& rhs)
     89        {
     90                return rhs.transformed( lhs );
     91        }
     92
     93
    6394
    6495        template<>
  • 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.