Esempio n. 1
0
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);
		}
	}
}