Beispiel #1
0
void EntityInstanceNode::Flatten()
{
    EntityNode& instanceClassNode = EntityNode::Get( m_Entity->GetEntity()->GetPath() );

    if( instanceClassNode == EntityNode::Null )
        return;

    MFnDagNode instanceFn( thisMObject() );

    MFnDagNode nodeFn( instanceClassNode.thisMObject() );
    u32 len = nodeFn.childCount();

    MDagPath path;
    MFnTransform newTransformFn;
    MObject newTransform = newTransformFn.create();

    MTransformationMatrix matrix = instanceFn.transformationMatrix();
    newTransformFn.set( matrix );
    newTransformFn.getPath( path );

    for( u32 i = 0; i < len; ++i )
    {
        MFnDagNode nodeFn( nodeFn.child( i ) );

        MDagPath child;
        nodeFn.getPath( child );
        MDagPath result;

        Maya::duplicate( child, path, result, false, false );
    }

    Maya::LockHierarchy( thisMObject(), false );
}
Beispiel #2
0
//
// This callback gets called for the PostToolChanged and SelectionChanged events.
// It checks to see if the current context is the dragAttrContext, which is the context
// applied by default when a custom numeric attribute is selected in the channel box.
// In this case, the customAttrManip context is set.
// 
static void eventCB(void * data)
{
	// This check prevents recursion from happening when overriding the manip.
	if (isSetting)
		return;

	MSelectionList selList;
	MGlobal::getActiveSelectionList(selList);

	MString curCtx = "";
	MGlobal::executeCommand("currentCtx", curCtx);

	MDagPath path;
	MObject dependNode;
	for (unsigned int i=0; i<selList.length(); i++)
	{
        if ((selList.getDependNode(i, dependNode)) == MStatus::kSuccess)
		{
			MFnTransform node;
			if (node.hasObj(dependNode))
				node.setObject(dependNode);
			else
				continue;

			if (node.typeId() == rockingTransformNode::id)
			{
				// If the current context is the dragAttrContext, check to see
				// if the custom channel box attributes are selected.  If so,
				// attach the custom manipulator.
				if ((curCtx == "dragAttrContext") || (curCtx == ""))
				{
					// Make sure that the correct channel box attributes are selected
					// before setting the tool context.
					unsigned int c;
					MStringArray cboxAttrs;
					MGlobal::executeCommand(
							"channelBox -q -selectedMainAttributes $gChannelBoxName", cboxAttrs);
					for (c=0; c<cboxAttrs.length(); c++)
					{
						if (cboxAttrs[c] == customAttributeString)
						{
							isSetting = true;
							MGlobal::executeCommand("setToolTo myCustomAttrContext");
							isSetting = false;
							return;
						}
					}
				}
				if ((curCtx == "moveSuperContext") || (curCtx == "manipMoveContext") ||
					(curCtx == ""))
				{
					isSetting = true;
					MGlobal::executeCommand("setToolTo myCustomTriadContext");
					isSetting = false;
					return;
				}
			}
		}
	}
}
MStatus lrutils::makeHomeNull(MObject obj, MFnTransform& transformFn, MObject& groupObj) {
    MStatus status = MS::kFailure;
    
    status = transformFn.setObject(obj);
    MyCheckStatusReturn(status, "invalid MObject provided for MFnTransform.setObject()");

    if( status == MS::kSuccess ) {
        MDagModifier dagMod;
        groupObj = dagMod.createNode( "transform", MObject::kNullObj, &status );
        MyCheckStatusReturn(status, "MDagModifier.createNode() failed");
        dagMod.doIt();

        MFnTransform groupFn;
        groupFn.setObject(groupObj);
        groupFn.set(transformFn.transformation());
        groupFn.addChild(obj);
        
        MString groupName = transformFn.name();
        groupName = groupName.substring(0, groupName.numChars() - 4);
        groupName += "GRP";
        groupFn.setName(groupName);
        
    }

    return status;
}
Beispiel #4
0
MObject HesperisTransformCreator::create(BaseTransform * data, MObject & parentObj,
                       const std::string & nodeName)
{
    MObject otm = MObject::kNullObj;
    if(!HesperisIO::FindNamedChild(otm, nodeName, parentObj)) {
        MFnTransform ftransform;
        otm = ftransform.create(parentObj);

        std::string validName(nodeName);
        SHelper::noColon(validName);
        ftransform.setName(validName.c_str()); 
    }
    // MGlobal::displayInfo(MString("todo transform in ")+nodeName.c_str()); 
    return otm;
}
Beispiel #5
0
void GDExporter::GetUniqueRenderContexts( MFnTransform& transform, std::list<GDRenderContext>& uniqueContexts )
{
	for(unsigned int i = 0; i < transform.childCount(); ++i)
	{
		if( transform.child(i).apiType() == MFn::kMesh )
		{
			MFnMesh childMesh( transform.child(i) );

			if( childMesh.isIntermediateObject() )
				continue;

			MDagPath meshPath;
			childMesh.getPath(meshPath);
			MFnDependencyNode depNode(meshPath.node());
			MStatus fpResult;
			MPlug gdRenderContextPlug = childMesh.findPlug("GDRenderContext", &fpResult);

			if( fpResult != MS::kSuccess )
				continue;

			GDRenderContext newContext(gdRenderContextPlug);

			bool bFound = false;
			std::list<GDRenderContext>::iterator uniqueIter = uniqueContexts.begin();
			for(; uniqueIter != uniqueContexts.end(); ++uniqueIter )
			{
				if( (*uniqueIter) == newContext )
				{
					bFound = true;
					break;
				}
			}

			if( bFound == false )
				uniqueContexts.push_back( newContext );
			else
				gdRenderContextPlug.child(0).setValue( (*uniqueIter).name.c_str() );
		}
		else if( transform.child(i).apiType() == MFn::kTransform )
		{
			MFnTransform childTransform( transform.child(i) );
			GetUniqueRenderContexts( childTransform, uniqueContexts );
		}
	}
}
MStatus lrutils::makeGroup(MObject & obj, MString name) {
    MStatus status = MS::kFailure;

    MDagModifier dagMod;
    MObject groupObj = dagMod.createNode( "transform", MObject::kNullObj, &status );
    MyCheckStatusReturn(status, "MDagModifier.createNode() failed");
    dagMod.doIt();

    MFnTransform groupFn;
    groupFn.setObject(groupObj);
    MString groupName = name;
    groupName += "_GRP";
    groupFn.setName(groupName);

    obj = groupObj;

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

};
MStatus lrutils::setParentConstraintOffset(MObject constraintObj, MTransformationMatrix transform) {
    MStatus status = MS::kFailure;

    MFnTransform constraintFn;
    status = constraintFn.setObject( constraintObj );
    MyCheckStatusReturn(status, "invalid MObject provided for MFnTransform.setObject()");
    MString constraintName = constraintFn.name();

    if ( status = MS::kSuccess ) {
        MVector vTranslation = transform.getTranslation(MSpace::kTransform);
        MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetTranslateX\" "+vTranslation.x+";");
        MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetTranslateY\" "+vTranslation.y+";");
        MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetTranslateZ\" "+vTranslation.z+";");
        double* rotation = new double[3];
        MTransformationMatrix::RotationOrder rotOrder = MTransformationMatrix::kXYZ;
        transform.getRotation(rotation,rotOrder);
        MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetRotateX\" "+rotation[0]+";");
        MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetRotateY\" "+rotation[1]+";");
        MGlobal::executeCommand( "setAttr \""+constraintName+".target[0].targetOffsetRotateZ\" "+rotation[2]+";");
    }

    return status;
}
Beispiel #9
0
bool HesperisIO::ReadTransforms(HBase * parent, MObject &target)
{
    std::vector<std::string > tmNames;
    parent->lsTypedChild<HTransform>(tmNames);
	std::vector<std::string>::const_iterator it = tmNames.begin();
	
    for(;it!=tmNames.end();++it) {
        std::string nodeName = *it;
        SHelper::behead(nodeName, parent->pathToObject());
        SHelper::behead(nodeName, "/");
        HBase child(*it);
        MObject otm = MObject::kNullObj;
        if(!FindNamedChild(otm, nodeName, target)) {
            MFnTransform ftransform;
            otm = ftransform.create(target);
            SHelper::noColon(nodeName);
            ftransform.setName(nodeName.c_str()); 
        }
        ReadTransforms(&child, otm);
        ReadCurves(&child, otm);
        child.close();
	}
    return true;
}
Beispiel #10
0
double splineSolverNode::getJointsTotalLenght()
{
    double totalLength = 0;
    MPoint pBaseJoint, pEndJoint;
    for (int i = 0; i < joints.size(); i++)
    {
        MFnIkJoint j( joints[i]);
        pBaseJoint = j.rotatePivot(MSpace::kWorld);
        if( i == joints.size() - 1)
            //Effector Position
            pEndJoint = tran.rotatePivot(MSpace::kWorld);
        else
        {
            //get position of next joint
            MFnIkJoint j2( joints[i + 1]);
            pEndJoint = j2.rotatePivot(MSpace::kWorld);
        }
        MVector vBaseJoint(pBaseJoint[0]-pEndJoint[0], pBaseJoint[1]-pEndJoint[1], pBaseJoint[2]-pEndJoint[2]);
        totalLength += vBaseJoint.length();
    }
    return totalLength;
}
MStatus lrutils::setLocation(MObject obj, MVectorArray location, MFnTransform& transformFn, bool translate, bool rotation, bool scale) {
    MStatus status = MS::kFailure;

    status = transformFn.setObject(obj);
    MyCheckStatusReturn(status, "invalid MObject provided for MFnTransform.setObject()");

    if( status == MS::kSuccess ) {
        if(translate) {
            MVector vTranslation = location[0] ;
            //stringstream text; text << "(" << vTranslation.x << ", " << vTranslation.y << ", " << vTranslation.z << ")";
            //MGlobal::displayInfo( text.str().c_str() );
            status = transformFn.setTranslation(vTranslation, MSpace::kTransform);
            stringstream text; text << "MFnTransform.setTranslation() failed, status code [" << status.errorString().asChar() << "]";
            MyCheckStatusReturn(status, text.str().c_str() ); 
            vTranslation = transformFn.getTranslation(MSpace::kWorld);
            //text.clear(); text << "(" << vTranslation.x << ", " << vTranslation.y << ", " << vTranslation.z << ")";
            //MGlobal::displayInfo( text.str().c_str() );
        }
        if(rotation) {
            MVector vRotation = location[1]*3.141592/180.0;
            MEulerRotation eRotation = MEulerRotation(vRotation);
            status = transformFn.setRotation(eRotation);
        }
        if(scale) {
            MVector vScale = location[2];
            double* scale = new double[3];
            vScale.get(scale);
            transformFn.setScale(scale);
            //make the scale of the controller the identity
            MGlobal::executeCommand("select -r "+transformFn.name()+";");
            MGlobal::executeCommand("makeIdentity -s true -apply true;");
        }
    }

    return status;
}
Beispiel #12
0
MStatus simulateBoids::doIt( const MArgList& args )
{
	
	//	Description: implements the MEL boids command
	//	Arguments: args - the argument list that was passes to the command from MEL

	MStatus status = MS::kSuccess;

	
    /****************************************
	*	building thread/dll data structure  *
	****************************************/

	InfoCache infoCache;
	SimulationParameters simParams;
	RulesParameters *applyingRules;
	double progressBar=0;
	double aov=pi/3;
	int i,numberOfDesires=0;
	
	// params retrievement
	MSelectionList sel;
	MObject node;
	MFnDependencyNode nodeFn;
	MFnTransform locatorFn;
	MPlug plug;

	// simulation params
	int simulationLengthValue;		// [int] in seconds
	int framesPerSecondValue;		// [int]
	int startFrameValue;			// [int]
	int boidsNumberValue;			// [int]
	// export params
	MString logFilePathValue;		// [char *]
	MString logFileNameValue;		// [char *]
	int logFileTypeValue;			// 0 = nCache; 1 = log file; 2 = XML; 
	// locomotion params
	int locomotionModeValue;		// [int]
	double maxSpeedValue;			// [double]
	double maxForceValue;			// [double]

	// double mass=1;				// [double]

	MTime currentTime, maxTime;
	MPlug plugX, plugY, plugZ;
	double tx, ty, tz;
	int frameLength ;
	Vector * leader = NULL;

	MStatus leaderFound=MStatus::kFailure;

	MGlobal::getActiveSelectionList(sel);
	for ( MItSelectionList listIter(sel); !listIter.isDone(); listIter.next() )
	{
		listIter.getDependNode(node);
		switch(node.apiType())
		{
			case MFn::kTransform:
				// get locator transform to follow
				leaderFound=locatorFn.setObject(node);
				cout << locatorFn.name().asChar() << " is selected as locator" << endl;
				break;
			case MFn::kPluginDependNode:
				nodeFn.setObject(node);
				cout << nodeFn.name().asChar() << " is selected as brain" << endl;
				break;
			default:
				break;
		}
		cout<< node.apiTypeStr()<<endl;
	}

	// rules params
	setRuleVariables(alignment);
	setRuleVariables(cohesion);
	setRuleVariables(separation);
	setRuleVariables(follow);

	getPlugValue(simulationLength);
	getPlugValue(framesPerSecond);
	getPlugValue(startFrame);
	getPlugValue(boidsNumber);
	getPlugValue(logFileType);
	getRulePlugValue(alignment);
	getRulePlugValue(cohesion);
	getRulePlugValue(separation);
	getRulePlugValue(follow);
	getPlugValue(locomotionMode);
	getPlugValue(maxSpeed);
	getPlugValue(maxForce);
	getTypePlugValue(logFilePath);
	getTypePlugValue(logFileName);
		// counting active rules number
	if(alignmentActiveValue)
		numberOfDesires++;
	if(cohesionActiveValue)
		numberOfDesires++;
	if(separationActiveValue)
		numberOfDesires++;
	if(followActiveValue)
		numberOfDesires++;


	currentTime = MTime((double)startFrameValue);														// MAnimControl::minTime();
	maxTime = MTime((double)(startFrameValue + (simulationLengthValue * framesPerSecondValue)));		// MAnimControl::maxTime();
	cout << "time unit enum (6 is 24 fps): " << currentTime.unit() << endl;	
	plugX = locatorFn.findPlug( MString( "translateX" ), &status );
	plugY = locatorFn.findPlug( MString( "translateY" ), &status );
	plugZ = locatorFn.findPlug( MString( "translateZ" ), &status );
	frameLength = simulationLengthValue * framesPerSecondValue;
	
	if(leaderFound==MS::kSuccess)
	{
		leader = new Vector[frameLength];	
		while ( currentTime < maxTime )
		{
			{
				int index = (int)currentTime.value() - startFrameValue;
				/*
				MGlobal::viewFrame(currentTime);
				pos = locatorFn.getTranslation(MSpace::kWorld);
				cout << "pos: " << pos.x << " " << pos.y << " " << pos.z << endl;
				*/
				status = plugX.getValue( tx, MDGContext(currentTime) );
				status = plugY.getValue( ty, MDGContext(currentTime) );
				status = plugZ.getValue( tz, MDGContext(currentTime) );

				leader[index].x = tx;
				leader[index].y = ty;
				leader[index].z = tz;
				//cout << "pos at time " << currentTime.value() << " has x: " << tx << " y: " << ty << " z: " << tz << endl;
				currentTime++;
			}	
		}
	}

	simParams.fps=framesPerSecondValue;
	simParams.lenght=simulationLengthValue;
	simParams.numberOfBoids=boidsNumberValue;
	simParams.maxAcceleration=maxForceValue;
	simParams.maxVelocity=maxSpeedValue;
	simParams.simplifiedLocomotion=TRUE;


	
	
	applyingRules=new RulesParameters[numberOfDesires];
	

	// cache settings
	MString saveString;
	saveString = logFilePathValue+"/"+logFileNameValue;
	infoCache.fileName=new char[saveString.length()+1];
	memcpy(infoCache.fileName,saveString.asChar(),sizeof(char)*(saveString.length()+1));
	infoCache.cacheFormat=ONEFILE;
	infoCache.fps=framesPerSecondValue;
	infoCache.start=startFrameValue/framesPerSecondValue;
	infoCache.end=simulationLengthValue+infoCache.start;	
	infoCache.loging=FALSE;
	infoCache.option=POSITIONVELOCITY;
	infoCache.particleSysName="BoidsNParticles";
	infoCache.saveMethod=MAYANCACHE;

	for(i=0;i<numberOfDesires;i++)
	{
		applyingRules[i].enabled=TRUE;
		applyingRules[i].precedence=1;
		applyingRules[i].aov=aov;
		applyingRules[i].visibilityOption=FALSE;
	}	

	if(cohesionActiveValue==0)
		applyingRules[COHESIONRULE].enabled=FALSE;
	else
	{
		applyingRules[COHESIONRULE].ruleName=COHESIONRULE;
		applyingRules[COHESIONRULE].ruleFactor=cohesionFactorValue;
		applyingRules[COHESIONRULE].ruleRadius=cohesionRadiusValue;
		applyingRules[COHESIONRULE].ruleWeight=cohesionWeightValue;
	}

	if(separationActiveValue==0)
		applyingRules[SEPARATIONRULE].enabled=FALSE;
	else
	{
		applyingRules[SEPARATIONRULE].ruleName=SEPARATIONRULE;
		applyingRules[SEPARATIONRULE].ruleFactor=separationFactorValue;
		applyingRules[SEPARATIONRULE].ruleRadius=separationRadiusValue;
		applyingRules[SEPARATIONRULE].ruleWeight=separationWeightValue;
	}

	if(alignmentActiveValue==0)
		applyingRules[ALIGNMENTRULE].enabled=FALSE;
	else
	{
		applyingRules[ALIGNMENTRULE].ruleName=ALIGNMENTRULE;
		applyingRules[ALIGNMENTRULE].ruleFactor=alignmentFactorValue;
		applyingRules[ALIGNMENTRULE].ruleRadius=alignmentRadiusValue;
		applyingRules[ALIGNMENTRULE].ruleWeight=alignmentWeightValue;
	}
	
	if(followActiveValue==0)
		applyingRules[FOLLOWRULE].enabled=FALSE;
	else
	{
		applyingRules[FOLLOWRULE].ruleName=FOLLOWRULE;
		applyingRules[FOLLOWRULE].ruleRadius=followRadiusValue;
		applyingRules[FOLLOWRULE].ruleFactor=followFactorValue;
		applyingRules[FOLLOWRULE].ruleWeight=followWeightValue;
	}
	

	// initializing simulation parameters
	boidInit(numberOfDesires, applyingRules, simParams , infoCache, leader);

	DLLData datadll;
	// preparing threads pool
	status = MThreadPool::init();
	
	if (status==MStatus::kSuccess)
	{
		MThreadPool::newParallelRegion(ThreadsCreator, &datadll);
		setResult( "Command executed!\n" );
		CHECK_MSTATUS(MProgressWindow::endProgress());
		MThreadPool::release();
	}

	switch(datadll.result)
	{
	case 0:
		status=MS::kSuccess;
		break;

	default:
		status=MS::kFailure;
	}

	MThreadPool::release();
	return status;
}
Beispiel #13
0
MStatus splineSolverNode::doSimpleSolver()
//
// Solve single joint in the x-y plane
//
// - first it calculates the angle between the handle and the end-effector.
// - then it determines which way to rotate the joint.
//
{
    //Do Real Solve
    //
    MStatus stat;
    float curCurveLength = curveFn.length();
    MPlug crvLengPlug = fnHandle.findPlug("cvLen");
    double initCurveLength = crvLengPlug.asDouble();
    //Twist
    MPlug twistRamp = fnHandle.findPlug("twistRamp");
    MRampAttribute curveAttribute( twistRamp, &stat );
    MPlug startTwistPlug = fnHandle.findPlug("strtw");
    double startTwist = startTwistPlug.asDouble();
    MPlug endTwistPlug = fnHandle.findPlug("endtw");
    double endTwist = endTwistPlug.asDouble();
    //Scale Ramp
    MPlug scaleRamp = fnHandle.findPlug("scaleRamp");
    MRampAttribute curveScaleAttribute( scaleRamp, &stat );
    //Roll
    MPlug rollPlug = fnHandle.findPlug("roll");
    double roll = rollPlug.asDouble();
    MPlug strPlug = fnHandle.findPlug("str");
    float stretchRatio = strPlug.asDouble();
    float normCrvLength = curCurveLength / initCurveLength;
    double scale[3] = {1 +stretchRatio*(normCrvLength -1), 1, 1};
    //Get Anchor Position
    MPlug ancPosPlug = fnHandle.findPlug("ancp");
    double anchorPos = ancPosPlug.asDouble();
    MPlug jointsTotLengthPlug = fnHandle.findPlug("jsLen");
    double jointsTotalLength = jointsTotLengthPlug.asDouble();
    double difLengthCurveJoints = curCurveLength - (jointsTotalLength * scale[0]);
    float startLength = 0.0 + anchorPos*( difLengthCurveJoints );
    float parm = curveFn.findParamFromLength( startLength );
    MPoint pBaseJoint, pEndJoint;
    curveFn.getPointAtParam( parm, pBaseJoint );
    //get Init normal
    MPlug initNormalPlug = fnHandle.findPlug("norm");
    double nx = initNormalPlug.child(0).asDouble();
    double ny = initNormalPlug.child(1).asDouble();
    double nz = initNormalPlug.child(2).asDouble();
    MVector eyeUp( nx, ny, nz );
    //get Init Tangent
    MPlug initTangentPlug = fnHandle.findPlug("tang");
    double tx = initTangentPlug.child(0).asDouble();
    double ty = initTangentPlug.child(1).asDouble();
    double tz = initTangentPlug.child(2).asDouble();
    MVector eyeV( tx, ty, tz );

    MFnIkJoint j( joints[0] );
    j.setTranslation( MVector( pBaseJoint ), MSpace::kWorld );
    float jointRotPercent = 1.0/joints.size();
    float currJointRot = 0;
    float prevTwist = 0;
    double angle;
    //j.setScale(scale);
    for (int i = 0; i < joints.size(); i++)
    {
        MFnIkJoint j( joints[i]);
        pBaseJoint = j.rotatePivot(MSpace::kWorld);
        //Calculate Scale
        float scaleValue;
        curveScaleAttribute.getValueAtPosition(currJointRot, scaleValue, &stat);
        //if ( scale[0] >= 1 ) // Stretch
        scale[1] = 1 + scaleValue * ( 1 - scale[0] );
        /*
        else //Squash
        	scale[1] = 1 + scaleValue * ( 1.0 - scale[0] );
        */
        if (scale[1] < 0)
            scale[1] = 0;
        scale[2] = scale[1];
        j.setScale(scale);
        //j.setRotation( rot, j.rotationOrder()  );
        if( i == joints.size() - 1)
            //Effector Position
            pEndJoint = tran.rotatePivot(MSpace::kWorld);
        else
        {
            //get position of next joint
            MFnIkJoint j2( joints[i + 1]);
            pEndJoint = j2.rotatePivot(MSpace::kWorld);
        }
        MVector vBaseJoint(pBaseJoint[0]-pEndJoint[0], pBaseJoint[1]-pEndJoint[1], pBaseJoint[2]-pEndJoint[2]);
        startLength += vBaseJoint.length();
        MVector eyeAim(1.0,0.0,0.0);
        MPoint pFinalPos;
        float parm = curveFn.findParamFromLength( startLength );
        //Aim to final Pos
        curveFn.getPointAtParam( parm, pFinalPos, MSpace::kWorld );
        MVector eyeU(pBaseJoint[0]-pFinalPos[0], pBaseJoint[1]-pFinalPos[1], pBaseJoint[2]-pFinalPos[2]);
        eyeU.normalize();
        MVector eyeW( eyeU ^ eyeV );
        eyeW.normalize();
        eyeV = eyeW ^ eyeU;
        MQuaternion qU( -eyeAim, eyeU );

        MVector upRotated( eyeUp.rotateBy( qU ));
        angle = acos( upRotated*eyeV );

        //Calculate Twist
        {
            float twistValue;
            curveAttribute.getValueAtPosition(currJointRot, twistValue, &stat);
            double rotVal = (1-twistValue)*startTwist + twistValue*endTwist;
            angle += MAngle(rotVal, MAngle::kDegrees).asRadians();
            currJointRot += jointRotPercent;
        }
        //Calculate Roll
        angle += roll;

        MQuaternion qV(angle, eyeU);

        MQuaternion q(qU*qV);

        j.setRotation( q, MSpace::kWorld );
    }

    return MS::kSuccess;
}
Beispiel #14
0
	/********************************************************************************************************
	*                           Method to translate a single camera                                        *
	********************************************************************************************************/
	MStatus OgreExporter::writeCamera(MFnCamera& camera)
	{
		MPlug plug;
		MPlugArray srcplugarray;
		double dist;
		MAngle angle;
		MFnTransform* cameraTransform = NULL;
		MFnAnimCurve* animCurve = NULL;
		// get camera transform
		for (int i=0; i<camera.parentCount(); i++)
		{
			if (camera.parent(i).hasFn(MFn::kTransform))
			{
				cameraTransform = new MFnTransform(camera.parent(i));
				continue;
			}
		}
		// start camera description
		m_params.outCameras << "camera " << cameraTransform->partialPathName().asChar() << "\n";
		m_params.outCameras << "{\n";

		//write camera type
		m_params.outCameras << "\ttype ";
		if (camera.isOrtho())
			m_params.outCameras << "ortho\n";
		else
			m_params.outCameras << "persp\n";

		// write translation data
		m_params.outCameras << "\ttranslation\n";
		m_params.outCameras << "\t{\n";
		//translateX
		m_params.outCameras << "\t\tx ";
		plug = cameraTransform->findPlug("translateX");
		if (plug.isConnected() && m_params.exportCamerasAnim)
		{
			plug.connectedTo(srcplugarray,true,false,&stat);
			for (int i=0; i < srcplugarray.length(); i++)
			{
				if (srcplugarray[i].node().hasFn(MFn::kAnimCurve))
				{
					if (animCurve)
						delete animCurve;
					animCurve = new MFnAnimCurve(srcplugarray[i].node());
					continue;
				}
				else if (i == srcplugarray.length()-1)
				{
					std::cout << "Invalid link to translateX attribute\n";
					return MS::kFailure;
				}
			}
			m_params.outCameras << "anim " << animCurve->name().asChar() << "\n";
		}
		else
		{
			plug.getValue(dist);
			m_params.outCameras << "= " << dist << "\n";
		}
		//translateY
		m_params.outCameras << "\t\ty ";
		plug = cameraTransform->findPlug("translateY");
		if (plug.isConnected() && m_params.exportCamerasAnim)
		{
			plug.connectedTo(srcplugarray,true,false,&stat);
			for (int i=0; i< srcplugarray.length(); i++)
			{
				if (srcplugarray[i].node().hasFn(MFn::kAnimCurve))
				{
					if (animCurve)
						delete animCurve;
					animCurve = new MFnAnimCurve(srcplugarray[i].node());
					continue;
				}
				else if (i == srcplugarray.length()-1)
				{
					std::cout << "Invalid link to translateY attribute\n";
					return MS::kFailure;
				}
			}
			m_params.outCameras << "anim " << animCurve->name().asChar() << "\n";
		}
		else
		{
			plug.getValue(dist);
			m_params.outCameras << "= " << dist << "\n";
		}
		//translateZ
		m_params.outCameras << "\t\tz ";
		plug = cameraTransform->findPlug("translateZ");
		if (plug.isConnected() && m_params.exportCamerasAnim)
		{
			plug.connectedTo(srcplugarray,true,false,&stat);
			for (int i=0; i< srcplugarray.length(); i++)
			{
				if (srcplugarray[i].node().hasFn(MFn::kAnimCurve))
				{
					if (animCurve)
						delete animCurve;
					animCurve = new MFnAnimCurve(srcplugarray[i].node());
					continue;
				}
				else if (i == srcplugarray.length()-1)
				{
					std::cout << "Invalid link to translateZ attribute\n";
					return MS::kFailure;
				}
			}
			m_params.outCameras << "anim " << animCurve->name().asChar() << "\n";
		}
		else
		{
			plug.getValue(dist);
			m_params.outCameras << "= " << dist << "\n";
		}
		m_params.outCameras << "\t}\n";

		// write rotation data
		m_params.outCameras << "\trotation\n";
		m_params.outCameras << "\t{\n";
		m_params.outCameras << "\t\tx ";
		//rotateX
		plug = cameraTransform->findPlug("rotateX");
		if (plug.isConnected() && m_params.exportCamerasAnim)
		{
			plug.connectedTo(srcplugarray,true,false,&stat);
			for (int i=0; i< srcplugarray.length(); i++)
			{
				if (srcplugarray[i].node().hasFn(MFn::kAnimCurve))
				{
					if (animCurve)
						delete animCurve;
					animCurve = new MFnAnimCurve(srcplugarray[i].node());
					continue;
				}
				else if (i == srcplugarray.length()-1)
				{
					std::cout << "Invalid link to rotateX attribute\n";
					return MS::kFailure;
				}
			}
			m_params.outCameras << "anim " << animCurve->name().asChar() << "\n";
		}
		else
		{
			plug.getValue(angle);
			m_params.outCameras << "= " << angle.asDegrees() << "\n";
		}
		//rotateY
		m_params.outCameras << "\t\ty ";
		plug = cameraTransform->findPlug("rotateY");
		if (plug.isConnected() && m_params.exportCamerasAnim)
		{
			plug.connectedTo(srcplugarray,true,false,&stat);
			for (int i=0; i< srcplugarray.length(); i++)
			{
				if (srcplugarray[i].node().hasFn(MFn::kAnimCurve))
				{
					if (animCurve)
						delete animCurve;
					animCurve = new MFnAnimCurve(srcplugarray[i].node());
					continue;
				}
				else if (i == srcplugarray.length()-1)
				{
					std::cout << "Invalid link to rotateY attribute\n";
					return MS::kFailure;
				}
			}
			m_params.outCameras << "anim " << animCurve->name().asChar() << "\n";
		}
		else
		{
			plug.getValue(angle);
			m_params.outCameras << "= " << angle.asDegrees() << "\n";
		}
		//rotateZ
		m_params.outCameras << "\t\tz ";
		plug = cameraTransform->findPlug("rotateZ");
		if (plug.isConnected() && m_params.exportCamerasAnim)
		{
			plug.connectedTo(srcplugarray,true,false,&stat);
			for (int i=0; i< srcplugarray.length(); i++)
			{
				if (srcplugarray[i].node().hasFn(MFn::kAnimCurve))
				{
					if (animCurve)
						delete animCurve;
					animCurve = new MFnAnimCurve(srcplugarray[i].node());
					continue;
				}
				else if (i == srcplugarray.length()-1)
				{
					std::cout << "Invalid link to rotateZ attribute\n";
					return MS::kFailure;
				}
			}
			m_params.outCameras << "anim " << animCurve->name().asChar() << "\n";
		}
		else
		{
			plug.getValue(angle);
			m_params.outCameras << "= " << angle.asDegrees() << "\n";
		}
		m_params.outCameras << "\t}\n";

		// end camera description
		m_params.outCameras << "}\n\n";
		if (cameraTransform != NULL)
			delete cameraTransform;
		if (animCurve != NULL)
			delete animCurve;
		return MS::kSuccess;
	}
Beispiel #15
0
// Creates an AnimChannel from a Maya compound attribute if there is meaningful
// data.  This means we found data that is non-identity.
//
// returns true if we extracted an AnimChannel and false otherwise (e.g., the
// data was identity). 
static bool 
_GatherAnimChannel(
        XFormOpType opType, 
        const MFnTransform& iTrans, 
        MString parentName, 
        MString xName, MString yName, MString zName, 
        std::vector<AnimChannel>* oAnimChanList, 
        bool isWritingAnimation,
        bool setOpName)
{
    AnimChannel chan;
    chan.opType = opType;
    chan.isInverse = false;
    if (setOpName) {
        chan.opName = parentName.asChar();
    }

    // We default to single precision (later we set the main translate op and
    // shear to double)
    chan.precision = UsdGeomXformOp::PrecisionFloat;
    
    unsigned int validComponents = 0;
    
    // this is to handle the case where there is a connection to the parent
    // plug but not to the child plugs, if the connection is there and you are
    // not forcing static, then all of the children are considered animated
    int parentSample = PxrUsdMayaUtil::getSampledType(iTrans.findPlug(parentName),false);
    
    // Determine what plug are needed based on default value & being
    // connected/animated
    MStringArray channels;
    channels.append(parentName+xName);
    channels.append(parentName+yName);
    channels.append(parentName+zName);

    GfVec3d nullValue(opType == SCALE ? 1.0 : 0.0);
    for (unsigned int i = 0; i<3; i++) {
        // Find the plug and retrieve the data as the channel default value. It
        // won't be updated if the channel is NOT ANIMATED
        chan.plug[i] = iTrans.findPlug(channels[i]);
        double plugValue = chan.plug[i].asDouble();
        chan.defValue[i] = opType == ROTATE ? GfRadiansToDegrees(plugValue) : plugValue;
        chan.sampleType[i] = NO_XFORM;
        // If we allow animation and either the parentsample or local sample is
        // not 0 then we havea ANIMATED sample else we have a scale and the
        // value is NOT 1 or if the value is NOT 0 then we have a static xform
        if ((parentSample != 0 || PxrUsdMayaUtil::getSampledType(chan.plug[i], true) != 0) && 
             isWritingAnimation) {
            chan.sampleType[i] = ANIMATED; 
            validComponents++;
        } 
        else if (!GfIsClose(chan.defValue[i], nullValue[i], 1e-7)) {
            chan.sampleType[i] = STATIC; 
            validComponents++;
        }
    }

    // If there are valid component, then we will add the animation channel.
    // Rotates with 1 component will be optimized to single axis rotation
    if (validComponents>0) {
        if (opType == SCALE) {
            chan.usdOpType = UsdGeomXformOp::TypeScale;
        } else if (opType == TRANSLATE) {
            chan.usdOpType = UsdGeomXformOp::TypeTranslate;
            // The main translate is set to double precision
            if (parentName == "translate") {
                chan.precision = UsdGeomXformOp::PrecisionDouble;
            }
        } else if (opType == ROTATE) {
            chan.usdOpType = UsdGeomXformOp::TypeRotateXYZ;
            if (validComponents == 1) {
                if (chan.sampleType[0] != NO_XFORM) chan.usdOpType = UsdGeomXformOp::TypeRotateX;
                if (chan.sampleType[1] != NO_XFORM) chan.usdOpType = UsdGeomXformOp::TypeRotateY;
                if (chan.sampleType[2] != NO_XFORM) chan.usdOpType = UsdGeomXformOp::TypeRotateZ;
            } 
            else {
                // Rotation Order ONLY applies to the "rotate" attribute
                if (parentName == "rotate") {
                    switch (iTrans.rotationOrder()) {
                        case MTransformationMatrix::kYZX:
                            chan.usdOpType = UsdGeomXformOp::TypeRotateYZX;
                        break;
                        case MTransformationMatrix::kZXY:
                            chan.usdOpType = UsdGeomXformOp::TypeRotateZXY;
                        break;
                        case MTransformationMatrix::kXZY:
                            chan.usdOpType = UsdGeomXformOp::TypeRotateXZY;
                        break;
                        case MTransformationMatrix::kYXZ:
                            chan.usdOpType = UsdGeomXformOp::TypeRotateYXZ;
                        break;
                        case MTransformationMatrix::kZYX:
                            chan.usdOpType = UsdGeomXformOp::TypeRotateZYX;
                        break;
                        default: break;
                    }
                }
            }
        } 
        else if (opType == SHEAR) {
            chan.usdOpType = UsdGeomXformOp::TypeTransform;
            chan.precision = UsdGeomXformOp::PrecisionDouble;
        } 
        else {
            return false;
        }
        oAnimChanList->push_back(chan);
        return true;
    }
    return false;
}
MStatus lrutils::loadGeoReference(MString geoFilePath, MString geoName, MString & name, MObject & geoObj) {
    MStatus status = MS::kFailure;

    MString projPath = MGlobal::executeCommandStringResult(MString("workspace -q -rd;"),false,false);
    MString relativePath = geoFilePath.substring(2,geoFilePath.numChars() - 1);

    //assemble the full file path of the geometry file
    MString fullGeoPath = projPath + relativePath;

    //load the geometry file as a reference into the current scene
    //check to see if the referenced file has already been used
    MStringArray refNodeList;
    status = MFileIO::getReferences(refNodeList, true);
    MyCheckStatus(status, "getReferences failed");
    int numReferences = 0;
    for(unsigned int i = 0; i < refNodeList.length(); i++) {
        MString tmp = refNodeList[i];
        string tmp1 = tmp.asChar();
        string tmp2 = fullGeoPath.asChar();
        if(std::string::npos != tmp1.find(tmp2))
            numReferences++;
    }
    string str (geoFilePath.asChar());
    string key ("/");
    size_t found = str.rfind(key);
    string fileName = str.substr(found+1,str.length()-found-4);
    string fileNamespace;
    if(numReferences > 0) {
        stringstream tmp;
        tmp << fileName << (numReferences+1);
        fileNamespace = tmp.str();
    } else { fileNamespace = fileName; }

    {
        stringstream tmp;
        tmp << "file -r -type \"mayaAscii\" -gl -loadReferenceDepth \"all\" -namespace \"" << fileNamespace.c_str() << "\" -options \"v=0\" \"" << fullGeoPath.asChar() << "\";";
        MString referenceCommand = MString(tmp.str().c_str());
        MGlobal::executeCommand(referenceCommand);
    }
    
    //get the referenced geometry transform node and add the metaParent
    //attribute to it
    MSelectionList selection;
    if(numReferences > 0) {
        name += (boost::lexical_cast<string>(numReferences+1)).c_str();
    }
    stringstream geoRefName;
    geoRefName << fileNamespace << ":" << geoName;
    MString mGeoRefName = MString(geoRefName.str().c_str());
    status = selection.add( mGeoRefName, true );
    MyCheckStatusReturn(status, "add geoRefName "+mGeoRefName+" to selection failed.");

    if(selection.length() )
        selection.getDependNode(0, geoObj);

    MFnTransform transformFn;
    transformFn.setObject(geoObj);
    MFnMessageAttribute mAttr;
    MObject transformAttr = mAttr.create("metaParent", "metaParent");
    transformFn.addAttribute(transformAttr);

    if( !geoObj.isNull() )
        status = MS::kSuccess;

    return status;
}
void MayaTransformWriter::pushTransformStack(const MFnTransform & iTrans,
	bool iForceStatic)
{

	// inspect the translate
	addTranslate(iTrans, "translate", "translateX", "translateY", "translateZ",
		Alembic::AbcGeom::kTranslateHint, false, iForceStatic, false, mSample,
		mAnimChanList);


	// inspect the rotate pivot translate
	addTranslate(iTrans, "rotatePivotTranslate", "rotatePivotTranslateX",
		"rotatePivotTranslateY", "rotatePivotTranslateZ",
		Alembic::AbcGeom::kRotatePivotTranslationHint, false,
			iForceStatic, false, mSample, mAnimChanList);

	// inspect the rotate pivot
	addTranslate(iTrans, "rotatePivot", "rotatePivotX", "rotatePivotY",
		"rotatePivotZ",  Alembic::AbcGeom::kRotatePivotPointHint,
		false, iForceStatic, false, mSample, mAnimChanList);

	// inspect rotate names
	MString rotateNames[3];
	rotateNames[0] = "rotateX";
	rotateNames[1] = "rotateY";
	rotateNames[2] = "rotateZ";

	unsigned int rotOrder[3];

	// if this returns false then the rotation order was kInvalid or kLast
	MTransformationMatrix::RotationOrder eRotOrder(iTrans.rotationOrder());
	if (util::getRotOrder(eRotOrder, rotOrder[0], rotOrder[1],
		rotOrder[2]))
	{
		addRotate(iTrans, "rotate", rotateNames, rotOrder,
			Alembic::AbcGeom::kRotateHint, iForceStatic, false,
			mSample, mAnimChanList, mRotateOpIndex);
	}

	// now look at the rotation orientation, aka rotate axis
	rotateNames[0] = "rotateAxisX";
	rotateNames[1] = "rotateAxisY";
	rotateNames[2] = "rotateAxisZ";
	rotOrder[0] = 0;
	rotOrder[1] = 1;
	rotOrder[2] = 2;
	addRotate(iTrans, "rotateAxis", rotateNames, rotOrder,
		Alembic::AbcGeom::kRotateOrientationHint, iForceStatic, false,
		mSample, mAnimChanList, mRotateAxisOpIndex);

	// invert the rotate pivot if necessary
	addTranslate(iTrans, "rotatePivot", "rotatePivotX", "rotatePivotY",
		"rotatePivotZ", Alembic::AbcGeom::kRotatePivotPointHint,
		true, iForceStatic, false, mSample, mAnimChanList);

	// inspect the scale pivot translation
	addTranslate(iTrans, "scalePivotTranslate", "scalePivotTranslateX",
		"scalePivotTranslateY", "scalePivotTranslateZ",
		Alembic::AbcGeom::kScalePivotTranslationHint, false, iForceStatic,
		false, mSample, mAnimChanList);

	// inspect the scale pivot point
	addTranslate(iTrans, "scalePivot", "scalePivotX", "scalePivotY",
		"scalePivotZ", Alembic::AbcGeom::kScalePivotPointHint, false,
		iForceStatic, false, mSample, mAnimChanList);

	// inspect the shear
	addShear(iTrans, iForceStatic, mSample, mAnimChanList);

	// add the scale
	addScale(iTrans, "scale", "scaleX", "scaleY", "scaleZ", false,
		iForceStatic, false, mSample, mAnimChanList);

	// inverse the scale pivot point if necessary
	addTranslate(iTrans, "scalePivot", "scalePivotX", "scalePivotY",
		"scalePivotZ", Alembic::AbcGeom::kScalePivotPointHint, true,
		iForceStatic, false, mSample, mAnimChanList);

	// remember current rotation
	if (mFilterEulerRotations)
	{
		double xx(0), yy(0), zz(0);

		// there are 2 rotation order enum definitions:
		//	 MEulerRotation::RotationOrder = MTransformationMatrix::RotationOrder-1
		if (getSampledRotation( mSample, mRotateOpIndex, xx, yy, zz ))
		{
			mPrevRotateSolution.setValue(xx, yy, zz, (MEulerRotation::RotationOrder)(eRotOrder-1));
		}

		if (getSampledRotation( mSample, mRotateAxisOpIndex, xx, yy, zz ))
		{
			mPrevRotateAxisSolution.setValue(xx, yy, zz, MEulerRotation::kXYZ);
		}
	}

}
Beispiel #18
0
MStatus splineSolverNode::preSolve()
{

    MStatus stat;
    setRotatePlane(false);
    setSingleChainOnly(true);
    setPositionOnly(false);
    //Get Handle
    MIkHandleGroup * handle_group = handleGroup();
    if (NULL == handle_group) {
        return MS::kFailure;
    }
    MObject handle = handle_group->handle( 0 );
    MDagPath handlePath = MDagPath::getAPathTo( handle );
    fnHandle.setObject( handlePath );
    //Get Curve
    MPlug inCurvePlug = fnHandle.findPlug( "inCurve" );
    MDataHandle curveHandle = inCurvePlug.asMDataHandle();
    MObject inputCurveObject = curveHandle.asNurbsCurveTransformed();
    curveFn.setObject( inputCurveObject );
    float initCurveLength = curveFn.length();
    MVector initNormal = curveFn.normal(0);
    MVector initTangent = curveFn.tangent(0);
    float stretchRatio = 1;
    // Get the position of the end_effector
    //
    MDagPath effectorPath;
    fnHandle.getEffector(effectorPath);
    tran.setObject( effectorPath );
    // Get the start joint position
    //
    MDagPath startJointPath;
    fnHandle.getStartJoint( startJointPath );
    joints.clear();
    //Get Joints
    while (true)
    {
        effectorPath.pop();
        joints.push_back( effectorPath );
        if (effectorPath == startJointPath)
            break;
    }
    std::reverse(joints.begin(), joints.end());
    if (!fnHandle.hasAttribute("str"))
    {
        //Add Custom Attributes to Handle
        MFnNumericAttribute fnAttr;
        MObject attr = fnAttr.create("stretchRatio", "str", MFnNumericData::kDouble, stretchRatio);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setMin(0);
        fnAttr.setMax(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("anchorPosition", "ancp", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setMin(0);
        fnAttr.setMax(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("curveLength", "cvLen", MFnNumericData::kDouble, initCurveLength);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("initNormal", "norm", MFnNumericData::k3Double);
        fnAttr.setDefault(initNormal.x, initNormal.y, initNormal.z);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("initTangent", "tang", MFnNumericData::k3Double);
        fnAttr.setDefault(initTangent.x, initTangent.y, initTangent.z);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("jointsLength", "jsLen", MFnNumericData::kDouble, getJointsTotalLenght());
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("startTwist", "strtw", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("endTwist", "endtw", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        MObject twistRamp = MRampAttribute::createCurveRamp("twistRamp", "twr");
        fnHandle.addAttribute(twistRamp, MFnDependencyNode::kLocalDynamicAttr);
        MObject scaleRamp = MRampAttribute::createCurveRamp("scaleRamp", "scr");
        fnHandle.addAttribute(scaleRamp, MFnDependencyNode::kLocalDynamicAttr);
    } else
    {
        MPlug strPlug = fnHandle.findPlug("str");
        stretchRatio = strPlug.asDouble();
    }

    return MS::kSuccess;
}
Beispiel #19
0
// Populate the AnimationChannel vector with various ops based on the Maya
// transformation logic If scale and/or rotate pivot are declared, create
// inverse ops in the appropriate order
void MayaTransformWriter::pushTransformStack(
        const MFnTransform& iTrans, 
        const UsdGeomXformable& usdXformable, 
        bool writeAnim)
{   
    // NOTE: I think this logic and the logic in MayaTransformReader
    // should be merged so the concept of "CommonAPI" stays centralized.
    //
    // By default we assume that the xform conforms to the common API
    // (xlate,pivot,rotate,scale,pivotINVERTED) As soon as we encounter any
    // additional xform (compensation translates for pivots, rotateAxis or
    // shear) we are not conforming anymore 
    bool conformsToCommonAPI = true;

    // Keep track of where we have rotate and scale Pivots and their inverse so
    // that we can combine them later if possible
    unsigned int rotPivotIdx = -1, rotPivotINVIdx = -1, scalePivotIdx = -1, scalePivotINVIdx = -1;
    
    // Check if the Maya prim inheritTransform
    MPlug inheritPlug = iTrans.findPlug("inheritsTransform");
    if (!inheritPlug.isNull()) {
        if(!inheritPlug.asBool()) {
            usdXformable.SetResetXformStack(true);
        }
    }
            
    // inspect the translate, no suffix to be closer compatibility with common API
    _GatherAnimChannel(TRANSLATE, iTrans, "translate", "X", "Y", "Z", &mAnimChanList, writeAnim, false);

    // inspect the rotate pivot translate
    if (_GatherAnimChannel(TRANSLATE, iTrans, "rotatePivotTranslate", "X", "Y", "Z", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // inspect the rotate pivot
    bool hasRotatePivot = _GatherAnimChannel(TRANSLATE, iTrans, "rotatePivot", "X", "Y", "Z", &mAnimChanList, writeAnim, true);
    if (hasRotatePivot) {
        rotPivotIdx = mAnimChanList.size()-1;
    }

    // inspect the rotate, no suffix to be closer compatibility with common API
    _GatherAnimChannel(ROTATE, iTrans, "rotate", "X", "Y", "Z", &mAnimChanList, writeAnim, false);

    // inspect the rotateAxis/orientation
    if (_GatherAnimChannel(ROTATE, iTrans, "rotateAxis", "X", "Y", "Z", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // invert the rotate pivot
    if (hasRotatePivot) {
        AnimChannel chan;
        chan.usdOpType = UsdGeomXformOp::TypeTranslate;
        chan.precision = UsdGeomXformOp::PrecisionFloat;
        chan.opName = "rotatePivot";
        chan.isInverse = true;
        mAnimChanList.push_back(chan);
        rotPivotINVIdx = mAnimChanList.size()-1;
    }

    // inspect the scale pivot translation
    if (_GatherAnimChannel(TRANSLATE, iTrans, "scalePivotTranslate", "X", "Y", "Z", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // inspect the scale pivot point
    bool hasScalePivot = _GatherAnimChannel(TRANSLATE, iTrans, "scalePivot", "X", "Y", "Z", &mAnimChanList, writeAnim, true);
    if (hasScalePivot) {
        scalePivotIdx = mAnimChanList.size()-1;
    }

    // inspect the shear. Even if we have one xform on the xform list, it represents a share so we should name it
    if (_GatherAnimChannel(SHEAR, iTrans, "shear", "XY", "XZ", "YZ", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // add the scale. no suffix to be closer compatibility with common API
    _GatherAnimChannel(SCALE, iTrans, "scale", "X", "Y", "Z", &mAnimChanList, writeAnim, false);

    // inverse the scale pivot point
    if (hasScalePivot) {
        AnimChannel chan;
        chan.usdOpType = UsdGeomXformOp::TypeTranslate;
        chan.precision = UsdGeomXformOp::PrecisionFloat;
        chan.opName = "scalePivot";
        chan.isInverse = true;
        mAnimChanList.push_back(chan);
        scalePivotINVIdx = mAnimChanList.size()-1;
    }
    
    // If still potential common API, check if the pivots are the same and NOT animated/connected
    if (hasRotatePivot != hasScalePivot) {
        conformsToCommonAPI = false;
    }

    if (conformsToCommonAPI && hasRotatePivot && hasScalePivot) {
        AnimChannel rotPivChan, scalePivChan;
        rotPivChan = mAnimChanList[rotPivotIdx];
        scalePivChan = mAnimChanList[scalePivotIdx];
        // If they have different sampleType or are ANIMATED, does not conformsToCommonAPI anymore
        for (unsigned int i = 0;i<3;i++) {
            if (rotPivChan.sampleType[i] != scalePivChan.sampleType[i] ||
                    rotPivChan.sampleType[i] == ANIMATED) {
                conformsToCommonAPI = false;
            }
        }

        // If The defaultValue is not the same, does not conformsToCommonAPI anymore
        if (!GfIsClose(rotPivChan.defValue, scalePivChan.defValue, 1e-9)) {
            conformsToCommonAPI = false;
        }

        // If opType, usdType or precision are not the same, does not conformsToCommonAPI anymore
        if (rotPivChan.opType != scalePivChan.opType           || 
                rotPivChan.usdOpType != scalePivChan.usdOpType || 
                rotPivChan.precision != scalePivChan.precision) {
            conformsToCommonAPI = false;
        }

        if (conformsToCommonAPI) {
            // To Merge, we first rename rotatePivot and the scalePivot inverse
            // to pivot. Then we remove the scalePivot and the inverse of the
            // rotatePivot.
            //
            // This means that pivot and its inverse will wrap rotate and scale
            // since no other ops have been found
            //
            // NOTE: scalePivotIdx > rotPivotINVIdx
            mAnimChanList[rotPivotIdx].opName = "pivot";
            mAnimChanList[scalePivotINVIdx].opName = "pivot";
            mAnimChanList.erase(mAnimChanList.begin()+scalePivotIdx);
            mAnimChanList.erase(mAnimChanList.begin()+rotPivotINVIdx);
        }
    }
    
    // Loop over anim channel vector and create corresponding XFormOps
    // including the inverse ones if needed
    TF_FOR_ALL(iter, mAnimChanList) {
        AnimChannel& animChan = *iter;
        animChan.op = usdXformable.AddXformOp(
            animChan.usdOpType, animChan.precision,
            TfToken(animChan.opName),
            animChan.isInverse);
    }
void MayaTransformWriter::pushTransformStack(double iFrame,
    const MFnTransform & iTrans)
{
    bool forceStatic = (iFrame == DBL_MAX);

    // inspect the translate
    addTranslate(iTrans, "translate", "translateX", "translateY", "translateZ",
        Alembic::AbcGeom::kTranslateHint, false, forceStatic, mSample,
        mAnimChanList);


    // inspect the rotate pivot translate
    addTranslate(iTrans, "rotatePivotTranslate", "rotatePivotTranslateX",
        "rotatePivotTranslateY", "rotatePivotTranslateZ",
        Alembic::AbcGeom::kRotatePivotTranslationHint, false,
            forceStatic, mSample, mAnimChanList);

    // inspect the rotate pivot
    addTranslate(iTrans, "rotatePivot", "rotatePivotX", "rotatePivotY",
        "rotatePivotZ",  Alembic::AbcGeom::kRotatePivotPointHint,
        false, forceStatic, mSample, mAnimChanList);

    // inspect rotate names
    MString rotateNames[3];
    rotateNames[0] = "rotateX";
    rotateNames[1] = "rotateY";
    rotateNames[2] = "rotateZ";

    unsigned int rotOrder[3];

    // if this returns false then the rotation order was kInvalid or kLast
    if (util::getRotOrder(iTrans.rotationOrder(), rotOrder[0], rotOrder[1],
        rotOrder[2]))
    {
        addRotate(iTrans, "rotate", rotateNames, rotOrder,
            Alembic::AbcGeom::kRotateHint, forceStatic, false,
            mSample, mAnimChanList);
    }

    // now look at the rotation orientation, aka rotate axis
    rotateNames[0] = "rotateAxisX";
    rotateNames[1] = "rotateAxisY";
    rotateNames[2] = "rotateAxisZ";
    rotOrder[0] = 0;
    rotOrder[1] = 1;
    rotOrder[2] = 2;
    addRotate(iTrans, "rotateAxis", rotateNames, rotOrder,
        Alembic::AbcGeom::kRotateOrientationHint, forceStatic, false,
        mSample, mAnimChanList);

    // invert the rotate pivot if necessary
    addTranslate(iTrans, "rotatePivot", "rotatePivotX", "rotatePivotY",
        "rotatePivotZ", Alembic::AbcGeom::kRotatePivotPointHint,
        true, forceStatic, mSample, mAnimChanList);

    // inspect the scale pivot translation
    addTranslate(iTrans, "scalePivotTranslate", "scalePivotTranslateX",
        "scalePivotTranslateY", "scalePivotTranslateZ",
        Alembic::AbcGeom::kScalePivotTranslationHint, false, forceStatic,
        mSample, mAnimChanList);

    // inspect the scale pivot point
    addTranslate(iTrans, "scalePivot", "scalePivotX", "scalePivotY",
        "scalePivotZ", Alembic::AbcGeom::kScalePivotPointHint, false,
        forceStatic, mSample, mAnimChanList);

    // inspect the shear
    addShear(iTrans, forceStatic, mSample, mAnimChanList);

    // add the scale
    addScale(iTrans, "scale", "scaleX", "scaleY", "scaleZ", forceStatic,
        mSample, mAnimChanList);

    // inverse the scale pivot point if necessary
    addTranslate(iTrans, "scalePivot", "scalePivotX", "scalePivotY",
        "scalePivotZ", Alembic::AbcGeom::kScalePivotPointHint, true,
        forceStatic, mSample, mAnimChanList);
}