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