void Exporter::RecursiveJointExtraction(MFnTransform& joint, int parentIndex){

	Bone output;
	output.parent = parentIndex;

	output.invBindPose = joint.transformation().asMatrixInverse().matrix;

	MItDependencyNodes matIt(MFn::kAnimCurve);
	while (!matIt.isDone())
	{
		MFnAnimCurve animCurve(matIt.item());

		if (!strcmp(animCurve.name().substring(0, joint.name().length() - 1).asChar(), joint.name().asChar())){

			cout << animCurve.name().asChar() << endl;
			std::string type = animCurve.name().substring(joint.name().length(), animCurve.name().length()).asChar();
			output.frames.resize(animCurve.time(animCurve.numKeys() - 1).value());
			for (int i = 0; i < output.frames.size(); i++)
			{
				MTime time;
				time.setValue(i);
				output.frames[i].time = time.value();
				if (!strcmp(type.c_str(), "_translateX")){
					cout << animCurve.evaluate(time) << endl;
					output.frames[i].trans.x = animCurve.evaluate(time);
				}
				if (!strcmp(type.c_str(), "_translateY")){
					cout << animCurve.evaluate(time) << endl;
					output.frames[i].trans.y = animCurve.evaluate(time);
				}
				if (!strcmp(type.c_str(), "_translateZ")){
					cout << animCurve.evaluate(time) << endl;
					output.frames[i].trans.z = animCurve.evaluate(time);
				}
				if (!strcmp(type.c_str(), "_rotateX")){
					cout << animCurve.evaluate(time) << endl;
					output.frames[i].rot.x = animCurve.evaluate(time);
				}
				if (!strcmp(type.c_str(), "_rotateY")){
					cout << animCurve.evaluate(time) << endl;
					output.frames[i].rot.y = animCurve.evaluate(time);
				}
				if (!strcmp(type.c_str(), "_rotateZ")){
					cout << animCurve.evaluate(time) << endl;
					output.frames[i].rot.z = animCurve.evaluate(time);
				}
			}
		}
		matIt.next();
	}


	scene_.skeleton.push_back(output);
	int children = joint.childCount();
	int parent = scene_.skeleton.size() - 1;
	for (int i = 0; i < children; i++)
		RecursiveJointExtraction(MFnTransform(joint.child(i)), parent);

};
 // -------------------------------------------
 MTime AnimationHelper::animationEndTime()
 {
     MTime time ( MAnimControl::currentTime() );
     double result;
     MGlobal::executeCommand ( "playbackOptions -q -" TEND, result );
     time.setValue ( result );
     return time;
 }
Example #3
0
MStatus
XmlCacheFormat::readTime( MTime& time )
{
	MStringArray timeValue;
	readXmlTagValue(timeTag, timeValue);
	time.setValue( strtod( timeValue[0].asChar(), NULL ) );

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