From 2ed895f54fed8fedd4bb0582c56f8b0fc76fc05f Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 12 Oct 2004 19:05:14 +0000 Subject: [PATCH] finally got the skinning matrix right --- pandatool/src/xfileegg/xFileMaker.cxx | 58 +++++++++++++++++++++++++++ pandatool/src/xfileegg/xFileMesh.cxx | 43 +++++++++++++++++--- 2 files changed, 96 insertions(+), 5 deletions(-) diff --git a/pandatool/src/xfileegg/xFileMaker.cxx b/pandatool/src/xfileegg/xFileMaker.cxx index cf243a55c3..f3f1a5f1b2 100644 --- a/pandatool/src/xfileegg/xFileMaker.cxx +++ b/pandatool/src/xfileegg/xFileMaker.cxx @@ -109,6 +109,64 @@ open(const Filename &filename) { &TID_D3DRMMeshMaterialList, &TID_D3DRMFrameTransformMatrix, &TID_D3DRMFrame, + + /* + This is the complete list I extracted out of the Windows header + files. + + &TID_D3DRMInfo, + &TID_D3DRMMesh, + &TID_D3DRMVector, + &TID_D3DRMMeshFace, + &TID_D3DRMMaterial, + &TID_D3DRMMaterialArray, + &TID_D3DRMFrame, + &TID_D3DRMFrameTransformMatrix, + &TID_D3DRMMeshMaterialList, + &TID_D3DRMMeshTextureCoords, + &TID_D3DRMMeshNormals, + &TID_D3DRMCoords2d, + &TID_D3DRMMatrix4x4, + &TID_D3DRMAnimation, + &TID_D3DRMAnimationSet, + &TID_D3DRMAnimationKey, + &TID_D3DRMFloatKeys, + &TID_D3DRMMaterialAmbientColor, + &TID_D3DRMMaterialDiffuseColor, + &TID_D3DRMMaterialSpecularColor, + &TID_D3DRMMaterialEmissiveColor, + &TID_D3DRMMaterialPower, + &TID_D3DRMColorRGBA, + &TID_D3DRMColorRGB, + &TID_D3DRMGuid, + &TID_D3DRMTextureFilename, + &TID_D3DRMTextureReference, + &TID_D3DRMIndexedColor, + &TID_D3DRMMeshVertexColors, + &TID_D3DRMMaterialWrap, + &TID_D3DRMBoolean, + &TID_D3DRMMeshFaceWraps, + &TID_D3DRMBoolean2d, + &TID_D3DRMTimedFloatKeys, + &TID_D3DRMAnimationOptions, + &TID_D3DRMFramePosition, + &TID_D3DRMFrameVelocity, + &TID_D3DRMFrameRotation, + &TID_D3DRMLight, + &TID_D3DRMCamera, + &TID_D3DRMAppData, + &TID_D3DRMLightUmbra, + &TID_D3DRMLightRange, + &TID_D3DRMLightPenumbra, + &TID_D3DRMLightAttenuation, + &TID_D3DRMInlineData, + &TID_D3DRMUrl, + &TID_D3DRMProgressiveMesh, + &TID_D3DRMExternalVisual, + &TID_D3DRMStringProperty, + &TID_D3DRMPropertyBag, + &TID_D3DRMRightHanded, + */ }; static const int num_temps = sizeof(temps) / sizeof(temps[0]); hr = _dx_file_save->SaveTemplates(num_temps, temps); diff --git a/pandatool/src/xfileegg/xFileMesh.cxx b/pandatool/src/xfileegg/xFileMesh.cxx index b0f3bac73a..dd9afe2100 100644 --- a/pandatool/src/xfileegg/xFileMesh.cxx +++ b/pandatool/src/xfileegg/xFileMesh.cxx @@ -324,9 +324,43 @@ create_polygons(XFileToEggConverter *converter) { temp_vtx.set_normal(LCAST(double, normal->_normal)); } - // Transform the vertex into the appropriate (global) coordinate - // space. - temp_vtx.transform(_egg_parent->get_node_to_vertex()); + // We are given the vertex in local space; we need to transform + // it into global space. If the vertex has been skinned, that + // means the global space of all of its joints (modified by the + // matrix_offset provided in the skinning data). + double net_weight = 0.0; + LMatrix4d weighted_transform(0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0); + SkinWeights::const_iterator swi; + for (swi = _skin_weights.begin(); swi != _skin_weights.end(); ++swi) { + const SkinWeightsData &data = (*swi); + WeightMap::const_iterator wmi = data._weight_map.find(vertex_index); + if (wmi != data._weight_map.end()) { + EggGroup *joint = converter->find_joint(data._joint_name); + if (joint != (EggGroup *)NULL) { + double weight = (*wmi).second; + LMatrix4d mat = LCAST(double, data._matrix_offset); + mat *= joint->get_node_to_vertex(); + weighted_transform += mat * weight; + net_weight += weight; + } + } + } + + if (net_weight == 0.0) { + // The vertex had no joint membership. Transform it into the + // appropriate (global) space based on its parent. + temp_vtx.transform(_egg_parent->get_node_to_vertex()); + + } else { + // The vertex was skinned into one or more joints. Therefore, + // transform it according to the blended matrix_offset from + // the skinning data. + weighted_transform /= net_weight; + temp_vtx.transform(weighted_transform); + } // Now get a real EggVertex matching our template. EggVertex *egg_vtx = vpool->create_unique_vertex(temp_vtx); @@ -352,8 +386,7 @@ create_polygons(XFileToEggConverter *converter) { const SkinWeightsData &data = (*swi); WeightMap::const_iterator wmi = data._weight_map.find(vertex_index); if (wmi != data._weight_map.end()) { - EggGroup *joint = converter->find_joint(data._joint_name, - data._matrix_offset); + EggGroup *joint = converter->find_joint(data._joint_name); if (joint != (EggGroup *)NULL) { double weight = (*wmi).second; joint->ref_vertex(egg_vtx, weight);