# Unity Exporting MAYA skinning mesh and boneoffset matrix problems

This topic is 3064 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've gone though almost all the tutors on web like RobTheBloke and florian.loitsch's gpExport. And I already sucessfully export a static mesh and render it in my engine. But I still failed to render an exported skinned mesh. I had the exp about render a .X file animation so I know the formula for skinning: vertex pos = vertexbindpos * boneoffset * jointworldtranform * bindweight I tried to extract the boneoffset like the following (a mix of RobTheBloke and gpExport and Chad Vernon's cvxport) but I got a distorted result and hope someone can tell me where the problem is.
BoneIT it = g_Bones.begin();
for( ; it != g_Bones.end(); ++it ){
MFnTransform fnX(bone.path);

//---------------------Get BindPoseMatrix using the function in gpExport---------------------
MFnIkJoint joint(bone.path.node());
MMatrix bindPoseMatrix = getBindPoseMatrix(joint);
bindPoseMatrix = bindPoseMatrix.inverse();

//---------------------Get Joint's Transform matrix---------------------
MMatrix mat = fnX.transformation().asMatrix();
while(true){
MStatus s = bone.path.pop();
if(s == MS::kSuccess){
MFnTransform fnXP(bone.path.node());
mat *= fnXP.transformationMatrix();
}
else break;
}
mat = mat.inverse();
MMatrix boneoffset = bindPoseMatrix * mat;
}


But obviously this is not boneoffset, what I saw were all pure rotations, its weird that there's no translation, and the rotations are incorrect either. I just wonder that the joint's transform matrix, Using while(true) to accumulate the transform of all its ancestors. Actually I modified it(Chad's cvxporter in python) to C++, but I'm not sure if I've done it in a correct way. The bindpose matrix I used that from gpExport http://florian.loitsch.com/gpExport/index-4.html#Extraction It's like
MMatrix getBindPoseMatrix(MFnIkJoint joint)
{
// get bindPose-plug on joint
MPlug tempBindPosePlug = joint.findPlug("bindPose");

MPlugArray mapConnections;
tempBindPosePlug.connectedTo(mapConnections, false, true);

if (mapConnections.length() != 1)
{
//cout << "returning currentMatrix" << endl;
// certainly not the most correct way of dealing with the problem...
return joint.transformation().asMatrix();
}

// find the other end. actually we shouldn't call it "bindPosePlug",
// but worldTransformPlug (as that's where it enters).

// theoretically someone could bind the bindPose to other nodes,
// than the bindPose-node. in this case there's a problem.
MPlug bindPosePlug = mapConnections[0];

// this node should be a "dagPose"-node (in case you want to look it
// up in the help)
MFnDependencyNode bindPoseNode(bindPosePlug.node());

// and as such, has the "xformMatrix"-attribute.
MObject xformMatrixAttribute = bindPoseNode.attribute("xformMatrix");

MPlug localTransformPlug(bindPosePlug.node(), xformMatrixAttribute);
// xformMatrix is an array. to get our localmatrix we need to select
// the same index, as our bindPosePlug (logicalIndex()).
localTransformPlug.selectAncestorLogicalIndex(bindPosePlug.logicalIndex(), xformMatrixAttribute);

MObject localMatrixObject;
localTransformPlug.getValue(localMatrixObject);
// extract the matrix out of the object.
return MFnMatrixData(localMatrixObject).matrix();
}


BTW, I'm confused about the transforms in MAYA, http://www.gamedev.net/community/forums/topic.asp?topic_id=517946 And I've tried Rotation = RO * R * JO That's Rotation = Rotate Orient * Rotation * Joint Orient
BoneIT it = g_Bones.begin();
for( ; it != g_Bones.end(); ++it ){
MMatrix test;
MQuaternion JO(0,0,0,1);
MQuaternion RO(0,0,0,1);
MQuaternion Rcomb;
MMatrix RcombMat;

fnX.getScale(Scale);
// Rotation
fnX.getRotation(R);

if( fnX.object().hasFn(MFn::kJoint) )
{
// Joint Orientation
MFnIkJoint fnJ(fnX.object());
fnJ.getOrientation(JO);
}
// Rotate Orientation
RO = fnX.rotateOrientation(MSpace::kObject);

// Test Rotate = [RO] * [R] * [JO]
RcombMat = RO.asMatrix() * R.asMatrix();
RcombMat = RcombMat * JO.asMatrix();
Rcomb = RcombMat;

MVector trans = fnX.translation(MSpace::kTransform);
// Test Transform = [S] * [RO] * [R] * [JO] * [IS] * [T]
MMatrix translationMat; translationMat.setToIdentity();
translationMat(3,0) = trans.x;
translationMat(3,1) = trans.y;
translationMat(3,2) = trans.z;

test = RcombMat * translationMat;
}


I think this should be the jointworldtranform that transform the origin to joint position, but it's not, I was wrong. Really hope someone can help me. I've spent a lot time on it but still can't work out. Any idea is appreciated. [Edited by - Quaid Tseng on March 4, 2010 7:44:22 PM]

1. 1
2. 2
3. 3
Rutin
22
4. 4
JoeJ
16
5. 5

• 14
• 29
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631774
• Total Posts
3002290
×