- Timestamp:
- 06/15/14 17:26:35 (11 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/formats/md5_loader.hh
r241 r259 36 36 struct md5_vtx_data 37 37 { 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; 49 43 }; 50 44 … … 108 102 md5_mesh_instance( const md5_mesh_data* a_data ); 109 103 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; 114 109 }; 115 110 … … 125 120 md5_vtx_pnt* m_pntdata; 126 121 std::string m_shader; 122 std::vector< transform > m_bone_offset; 127 123 std::vector< md5_vtx_data > m_vtx_data; 128 std::vector< md5_weight > m_weights;129 124 }; 130 125 … … 139 134 virtual size_t get_mesh_count() const { return m_meshes.size(); } 140 135 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 }; 141 148 142 149 struct md5_joint … … 147 154 }; 148 155 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 ); 150 157 protected: 151 158 uint32 m_md5_version; -
trunk/nv/transform.hh
r241 r259 57 57 return result; 58 58 } 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 } 59 77 private: 60 78 vec3 m_position; 61 79 quat m_orientation; 62 80 }; 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 63 94 64 95 template<> -
trunk/src/formats/md5_loader.cc
r258 r259 47 47 std_stream sstream( &source ); 48 48 std::string command; 49 std::vector< md5_weight > weights; 50 std::vector< md5_weight_info > weight_info; 49 51 50 52 sstream >> command; … … 120 122 } 121 123 mesh->m_vtx_data.resize( num_verts ); 124 weight_info.resize( num_verts ); 122 125 123 126 next_line( sstream ); … … 125 128 for ( int i = 0; i < num_verts; ++i ) 126 129 { 127 md5_vtx_data& vdata = mesh->m_vtx_data[i];128 130 size_t weight_count; 129 131 size_t start_weight; … … 132 134 std::getline( sstream, line ); 133 135 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; 136 138 mesh->m_tdata[i].texcoord = texcoord; 137 139 } … … 166 168 { 167 169 sstream >> num_weights; 168 mesh->m_weights.reserve( num_weights );170 weights.reserve( num_weights ); 169 171 next_line( sstream ); 170 172 std::string line; … … 175 177 std::getline( sstream, line ); 176 178 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); 178 180 } 179 181 } … … 186 188 } 187 189 188 prepare_mesh( mesh );190 prepare_mesh( mesh, weights, weight_info ); 189 191 190 192 m_meshes.push_back(mesh); … … 198 200 } 199 201 200 bool md5_loader::prepare_mesh( md5_mesh_data* mdata )202 bool md5_loader::prepare_mesh( md5_mesh_data* mdata, std::vector< md5_weight >& weights, std::vector< md5_weight_info >& weight_info ) 201 203 { 202 204 uint32 vtx_count = mdata->m_vtx_data.size(); 203 205 md5_vtx_pnt* vtcs = mdata->m_pntdata; 204 206 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 205 213 for ( uint32 i = 0; i < vtx_count; ++i ) 206 214 { 215 size_t start_weight = weight_info[i].start_weight; 216 size_t weight_count = weight_info[i].weight_count; 207 217 md5_vtx_data& vdata = mdata->m_vtx_data[i]; 208 218 md5_vtx_pnt& vtc = vtcs[i]; … … 212 222 vtc.tangent = glm::vec3(0); 213 223 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 ) 217 227 { 218 228 float sum = 0.0f; 219 229 for ( size_t j = 0; j < 4; ++j ) 220 230 { 221 sum += mdata->m_weights[vdata.start_weight + j].bias;231 sum += weights[start_weight + j].bias; 222 232 } 223 233 float ratio = 1.0f / sum; 224 234 for ( size_t j = 0; j < 4; ++j ) 225 235 { 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 } 240 265 } 241 266 } … … 286 311 vtcs[i].tangent = tangent; 287 312 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); 290 316 291 for ( size_t j = 0; j < vdata.weight_count; ++j )317 for ( size_t j = 0; j < 4; ++j ) 292 318 { 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]; 297 322 } 298 323 } … … 537 562 { 538 563 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 539 570 char* fill_ptr = (char*)&(m_pntdata[0]); 540 571 std::fill( fill_ptr, fill_ptr + m_size * ( sizeof( md5_vtx_pnt ) ), 0 ); … … 544 575 md5_vtx_pnt& result = m_pntdata[i]; 545 576 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.