bool dagPoseInfo::findDagPose(MObject& jointNode) // // Description: // Given a joint, check for connected dag pose nodes. // For each pose found, write out the pose info. // Return: // If one or more poses is found, return true, else return false. // { bool rtn = 0; // return 1 if we find a pose MStatus status; MFnDependencyNode fnJoint(jointNode); MObject aBindPose = fnJoint.attribute("bindPose",&status); if (MS::kSuccess == status) { unsigned connLength = 0; MPlugArray connPlugs; MPlug pBindPose(jointNode,aBindPose); pBindPose.connectedTo(connPlugs,false,true); connLength = connPlugs.length(); for (unsigned ii = 0; ii < connLength; ++ii) { if (connPlugs[ii].node().apiType() == MFn::kDagPose) { MObject aMember = connPlugs[ii].attribute(); MFnAttribute fnAttr(aMember); if (fnAttr.name() == "worldMatrix") { unsigned jointIndex = connPlugs[ii].logicalIndex(); fprintf(file,"%s\n",fnJoint.name().asChar()); MObject jointObject = connPlugs[ii].node(); printDagPoseInfo(jointObject,jointIndex); rtn = 1; } } } } return rtn; }
MStatus exportJointClusterData::doIt( const MArgList& args ) // // Process the command // 1. parse the args // 2. find the jointClusters in the scene // 3. iterate over their members, writing their weight data out to file // { // parse args to get the file name from the command-line // MStatus stat = parseArgs(args); if (stat != MS::kSuccess) { return stat; } // count the processed jointClusters // unsigned int jcCount = 0; // Iterate through graph and search for jointCluster nodes // MItDependencyNodes iter( MFn::kJointCluster); for ( ; !iter.isDone(); iter.next() ) { MObject object = iter.item(); MFnWeightGeometryFilter jointCluster(object); // get the joint driving this cluster // MObject joint = jointForCluster(object); if (joint.isNull()) { displayError("Joint is not attached to cluster."); continue; } MObject deformSet = jointCluster.deformerSet(&stat); CheckError(stat,"Error getting deformer set."); MFnSet setFn(deformSet, &stat); //need the fn to get the members CheckError(stat,"Error getting deformer set fn."); MSelectionList clusterSetList; //get all the members // stat = setFn.getMembers(clusterSetList, true); CheckError(stat,"Could not make member list with getMembers."); // print out the name of joint and the number of associated skins // MFnDependencyNode fnJoint(joint); fprintf(file,"%s %u\n",fnJoint.name().asChar(), clusterSetList.length()); for (unsigned int kk = 0; kk < clusterSetList.length(); ++kk) { MDagPath skinpath; MObject components; MFloatArray weights; clusterSetList.getDagPath(kk,skinpath,components); jointCluster.getWeights(skinpath,components,weights); // print out the path name of the skin & the weight count // fprintf(file, "%s %u\n",skinpath.partialPathName().asChar(), weights.length()); // loop through the components and print their index and weight // unsigned counter =0; MItGeometry gIter(skinpath,components); for (/* nothing */ ; !gIter.isDone() && counter < weights.length(); gIter.next()) { fprintf(file,"%d %f\n",gIter.index(),weights[counter]); counter++; } } jcCount++; } fclose(file); if (0 == jcCount) { displayError("No jointClusters found in this scene."); return MS::kFailure; } return MS::kSuccess; }
void DMPDSExporter::fillBones( DMPSkeletonData::SubSkeletonStruct* subSkel, string parent, DMPParameters* param, MDagPath& jointDag ) { MStatus status; if (jointDag.apiType() != MFn::kJoint) { return; // early out. } DMPSkeletonData::BoneStruct newBone; newBone.boneHandle = (unsigned int)subSkel->bones.size(); newBone.name = jointDag.partialPathName().asUTF8(); newBone.parentName = parent; MFnIkJoint fnJoint(jointDag, &status); // matrix = [S] * [RO] * [R] * [JO] * [IS] * [T] /* These matrices are defined as follows: •[S] : scale •[RO] : rotateOrient (attribute name is rotateAxis) •[R] : rotate •[JO] : jointOrient •[IS] : parentScaleInverse •[T] : translate The methods to get the value of these matrices are: •[S] : getScale •[RO] : getScaleOrientation •[R] : getRotation •[JO] : getOrientation •[IS] : (the inverse of the getScale on the parent transformation matrix) •[T] : translation */ MVector trans = fnJoint.getTranslation(MSpace::kTransform); double scale[3]; fnJoint.getScale(scale); MQuaternion R, RO, JO; fnJoint.getScaleOrientation(RO); fnJoint.getRotation(R); fnJoint.getOrientation(JO); MQuaternion rot = RO * R * JO; newBone.translate[0] = trans.x * param->lum; newBone.translate[1] = trans.y * param->lum; newBone.translate[2] = trans.z * param->lum; newBone.orientation[0] = rot.w; newBone.orientation[1] = rot.x; newBone.orientation[2] = rot.y; newBone.orientation[3] = rot.z; newBone.scale[0] = scale[0]; newBone.scale[1] = scale[1]; newBone.scale[2] = scale[2]; subSkel->bones.push_back(newBone); // Load child joints for (unsigned int i=0; i<jointDag.childCount();i++) { MObject child; child = jointDag.child(i); MDagPath childDag = jointDag; childDag.push(child); fillBones(subSkel, newBone.name, param, childDag); } // now go for animations if (param->bExportSkelAnimation) { for (unsigned int i = 0; i < subSkel->animations.size(); ++i) { DMPSkeletonData::TransformAnimation& anim = subSkel->animations[i]; DMPSkeletonData::TransformTrack subTrack; subTrack.targetBone = newBone.name; MPlug plugT; // translate MPlug plugR; // R MPlug plugRO; // RO MPlug plugJO; // JO MPlug plugS; // scale double dataT[3]; double dataR[3]; double dataRO[3]; double dataJO[3]; double dataS[3]; MFnDependencyNode fnDependNode( jointDag.node(), &status ); plugT = fnDependNode.findPlug("translate", false, &status); plugR = fnDependNode.findPlug("rotate", false, &status); plugRO = fnDependNode.findPlug("rotateAxis", false, &status); plugJO = fnDependNode.findPlug("jointOrient", false, &status); plugS = fnDependNode.findPlug("scale", false, &status); float timeStep = param->samplerRate; if (param->animSampleType == DMPParameters::AST_Frame) { timeStep /= param->fps; } for (float curTime = anim.startTime; curTime <= anim.endTime; curTime += timeStep) { MTime mayaTime; DMPSkeletonData::TransformKeyFrame keyframe; keyframe.time = curTime - anim.startTime; mayaTime.setUnit(MTime::kSeconds); mayaTime.setValue(curTime); // Get its value at the specified Time. plugT.child(0).getValue(dataT[0], MDGContext(mayaTime)); plugT.child(1).getValue(dataT[1], MDGContext(mayaTime)); plugT.child(2).getValue(dataT[2], MDGContext(mayaTime)); plugR.child(0).getValue(dataR[0], MDGContext(mayaTime)); plugR.child(1).getValue(dataR[1], MDGContext(mayaTime)); plugR.child(2).getValue(dataR[2], MDGContext(mayaTime)); plugRO.child(0).getValue(dataRO[0], MDGContext(mayaTime)); plugRO.child(1).getValue(dataRO[1], MDGContext(mayaTime)); plugRO.child(2).getValue(dataRO[2], MDGContext(mayaTime)); plugJO.child(0).getValue(dataJO[0], MDGContext(mayaTime)); plugJO.child(1).getValue(dataJO[1], MDGContext(mayaTime)); plugJO.child(2).getValue(dataJO[2], MDGContext(mayaTime)); plugS.child(0).getValue(dataS[0], MDGContext(mayaTime)); plugS.child(1).getValue(dataS[1], MDGContext(mayaTime)); plugS.child(2).getValue(dataS[2], MDGContext(mayaTime)); // fill the frame. keyframe.translate[0] = dataT[0] * param->lum; keyframe.translate[1] = dataT[1] * param->lum; keyframe.translate[2] = dataT[2] * param->lum; // calculate quaternion. MEulerRotation rotR(dataR[0], dataR[1], dataR[2]); MEulerRotation rotRO(dataRO[0], dataRO[1], dataRO[2]); MEulerRotation rotJO(dataJO[0], dataJO[1], dataJO[2]); MQuaternion finalRot = rotRO.asQuaternion()*rotR.asQuaternion()*rotJO.asQuaternion(); keyframe.orientation[0] = finalRot.w; keyframe.orientation[1] = finalRot.x; keyframe.orientation[2] = finalRot.y; keyframe.orientation[3] = finalRot.z; keyframe.scale[0] = dataS[0]; keyframe.scale[1] = dataS[1]; keyframe.scale[2] = dataS[2]; subTrack.frames.push_back(keyframe); } anim.tracks.push_back(subTrack); } } }