finally got the skinning matrix right

This commit is contained in:
David Rose 2004-10-12 19:05:14 +00:00
parent 62c3a5bf1d
commit 2ed895f54f
2 changed files with 96 additions and 5 deletions

View File

@ -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);

View File

@ -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);