MStatus MannequinMoveManipulator::connectToDependNode(const MObject &dependNode) { MStatus status; MFnDependencyNode nodeFn(dependNode, &status); if (!status) return MS::kFailure; MPlug translatePlug = nodeFn.findPlug("translate", &status); if (!status) return MS::kFailure; int plugIndex = 0; status = connectPlugToValue(translatePlug, _translateIndex, plugIndex); if (!status) return MS::kFailure; MFnDagNode dagNodeFn(dependNode); MDagPath nodePath; dagNodeFn.getPath(nodePath); MTransformationMatrix m(nodePath.exclusiveMatrix()); _parentXform = m; MTransformationMatrix n(nodePath.inclusiveMatrix()); _childXform = n; finishAddingManips(); return MPxManipulatorNode::connectToDependNode(dependNode); }
MStatus ik2Bsolver::doSolve() // // This is the doSolve method which calls solveIK. // { MStatus stat; // Handle Group // MIkHandleGroup * handle_group = handleGroup(); if (NULL == handle_group) { return MS::kFailure; } // Handle // // For single chain types of solvers, get the 0th handle. // Single chain solvers are solvers which act on one handle only, // i.e. the handle group for a single chain solver // has only one handle // MObject handle = handle_group->handle(0); MDagPath handlePath = MDagPath::getAPathTo(handle); MFnIkHandle handleFn(handlePath, &stat); // Effector // MDagPath effectorPath; handleFn.getEffector(effectorPath); MFnIkEffector effectorFn(effectorPath); // Mid Joint // effectorPath.pop(); MFnIkJoint midJointFn(effectorPath); // Start Joint // MDagPath startJointPath; handleFn.getStartJoint(startJointPath); MFnIkJoint startJointFn(startJointPath); // Preferred angles // double startJointPrefAngle[3]; double midJointPrefAngle[3]; startJointFn.getPreferedAngle(startJointPrefAngle); midJointFn.getPreferedAngle(midJointPrefAngle); // Set to preferred angles // startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder()); midJointFn.setRotation(midJointPrefAngle, midJointFn.rotationOrder()); AwPoint handlePos = handleFn.rotatePivot(MSpace::kWorld); AwPoint effectorPos = effectorFn.rotatePivot(MSpace::kWorld); AwPoint midJointPos = midJointFn.rotatePivot(MSpace::kWorld); AwPoint startJointPos = startJointFn.rotatePivot(MSpace::kWorld); AwVector poleVector = poleVectorFromHandle(handlePath); poleVector *= handlePath.exclusiveMatrix(); double twistValue = twistFromHandle(handlePath); AwQuaternion qStart, qMid; solveIK(startJointPos, midJointPos, effectorPos, handlePos, poleVector, twistValue, qStart, qMid); midJointFn.rotateBy(qMid, MSpace::kWorld); startJointFn.rotateBy(qStart, MSpace::kWorld); return MS::kSuccess; }
MBoundingBox AbcWriteJob::getBoundingBox(double iFrame, const MMatrix & eMInvMat) { MStatus status; MBoundingBox curBBox; if (iFrame == mFirstFrame) { // Set up bbox shape map in the first frame. // If we have a lot of transforms and shapes, we don't need to // iterate them for each frame. MItDag dagIter; for (dagIter.reset(mCurDag); !dagIter.isDone(); dagIter.next()) { MObject object = dagIter.currentItem(); MDagPath path; dagIter.getPath(path); // short-circuit if the selection flag is on but this node is not in the // active selection // MGlobal::isSelected(ob) doesn't work, because DG node and DAG node is // not the same even if they refer to the same MObject if (mArgs.useSelectionList && !mSList.hasItem(path)) { dagIter.prune(); continue; } MFnDagNode dagNode(path, &status); if (status == MS::kSuccess) { // check for riCurves flag for flattening all curve object to // one curve group MPlug riCurvesPlug = dagNode.findPlug("riCurves", &status); if ( status == MS::kSuccess && riCurvesPlug.asBool() == true) { MBoundingBox box = dagNode.boundingBox(); box.transformUsing(path.exclusiveMatrix()*eMInvMat); curBBox.expand(box); // Prune this curve group dagIter.prune(); // Save children paths std::map< MDagPath, util::ShapeSet, util::cmpDag >::iterator iter = mBBoxShapeMap.insert(std::make_pair(mCurDag, util::ShapeSet())).first; if (iter != mBBoxShapeMap.end()) (*iter).second.insert(path); } else if (object.hasFn(MFn::kParticle) || object.hasFn(MFn::kMesh) || object.hasFn(MFn::kNurbsCurve) || object.hasFn(MFn::kNurbsSurface) ) { if (util::isIntermediate(object)) continue; MBoundingBox box = dagNode.boundingBox(); box.transformUsing(path.exclusiveMatrix()*eMInvMat); curBBox.expand(box); // Save children paths std::map< MDagPath, util::ShapeSet, util::cmpDag >::iterator iter = mBBoxShapeMap.insert(std::make_pair(mCurDag, util::ShapeSet())).first; if (iter != mBBoxShapeMap.end()) (*iter).second.insert(path); } } } } else { // We have already find out all the shapes for the dag path. std::map< MDagPath, util::ShapeSet, util::cmpDag >::iterator iter = mBBoxShapeMap.find(mCurDag); if (iter != mBBoxShapeMap.end()) { // Iterate through the saved paths to calculate the box. util::ShapeSet& paths = (*iter).second; for (util::ShapeSet::iterator pathIter = paths.begin(); pathIter != paths.end(); pathIter++) { MFnDagNode dagNode(*pathIter, &status); if (status == MS::kSuccess) { MBoundingBox box = dagNode.boundingBox(); box.transformUsing((*pathIter).exclusiveMatrix()*eMInvMat); curBBox.expand(box); } } } } return curBBox; }
/** * Insert a new node into the hash table. */ int liqRibHT::insert( MDagPath &path, double /*lframe*/, int sample, ObjectType objType, int CountID, MMatrix *matrix, const MString instanceStr, int particleId ) { CM_TRACE_FUNC("liqRibHT::insert("<<path.fullPathName().asChar()<<",lframe," <<sample<<","<<objType<<","<<CountID<<",matrix,"<<instanceStr.asChar()<<","<<particleId<<")"); LIQDEBUGPRINTF( "-> inserting node into hash table\n" ); MFnDagNode fnDagNode( path ); MStatus returnStatus; objTypeVec.push_back( objType ); MString nodeName = fnDagNode.fullPathName( &returnStatus ); if ( objType == MRT_RibGen ) nodeName += "RIBGEN"; const char* name( nodeName.asChar() ); ulong hc = hash( name ,CountID ); RibHashVec.push_back( nodeName ); LIQDEBUGPRINTF( "-> hashed node name: %s", name ); LIQDEBUGPRINTF( " ID: %u\n", hc ); liqRibNodePtr node; /*node = find( path.node(), objType );*/ node = find( nodeName, path, objType ); liqRibNodePtr newNode; liqRibNodePtr instance; // If "node" is non-null then there's already a hash table entry at // this point // liqRibNodePtr tail; if( node ) { while( node ) { tail = node; // Break if we've already dealt with this DAG path // (and instance string - by default this is "", which // will match for most objects - allowing us to deal // with particle-instancing). // if ( path == node->path() && instanceStr == node->getInstanceStr() ) { break; } if ( path.node() == node->path().node() ) { // We have found another instance of the object we are object // looking for instance = node; } node = node->next; } if ( ( !node ) && ( instance ) ) { // We have not found a node with a matching path, but we have found // one with a matching object, so we need to insert a new instance newNode = liqRibNodePtr( new liqRibNode( instance, instanceStr ) ); } } if( !newNode ) { // We have to make a new node if ( !node) { node = liqRibNodePtr( new liqRibNode( liqRibNodePtr(), instanceStr) ); if ( tail ) { assert( !tail->next ); tail->next = node; RibNodeMap.insert( RNMAP::value_type( hc, node ) ); } else RibNodeMap.insert( RNMAP::value_type( hc, node ) ); } } else { assert( !node ); // Append new instance node onto tail of linked list node = newNode; if( tail ) { assert( !tail->next ); tail->next = node; RibNodeMap.insert( RNMAP::value_type( hc, node ) ); } else RibNodeMap.insert( RNMAP::value_type( hc, node ) ); } node->set( path, sample, objType, particleId ); // If we were given a specific matrix to use (this only // happens when we've got particle-instancing. // if( matrix != NULL ) { // Calculate the inclusive matrix for the instanced // object (as a product of the original object's // exclusive matrix - see Maya docs - and the given // matrix). // MMatrix inclusiveMatrix = path.exclusiveMatrix() * ( *matrix ); node->object( sample )->setMatrix( 0, inclusiveMatrix ); } // We can NOT support deformation blur on particle instancing, // since there's no way to guarantee that the objects are // topologically identical over the sample range. // if( instanceStr != "" ) node->motion.deformationBlur = false; LIQDEBUGPRINTF( "-> finished inserting node into hash table\n" ); return 0; }
MStatus ik2Bsolver::doSolve() // // This is the doSolve method which calls solveIK. // { MStatus stat; // Handle Group // MIkHandleGroup * handle_group = handleGroup(); if (NULL == handle_group) { return MS::kFailure; } // Handle // // For single chain types of solvers, get the 0th handle. // Single chain solvers are solvers which act on one handle only, // i.e. the handle group for a single chain solver // has only one handle // MObject handle = handle_group->handle(0); MDagPath handlePath = MDagPath::getAPathTo(handle); MFnIkHandle handleFn(handlePath, &stat); // Effector // MDagPath effectorPath; handleFn.getEffector(effectorPath); // MGlobal::displayInfo(effectorPath.fullPathName()); MFnIkEffector effectorFn(effectorPath); // Mid Joint // effectorPath.pop(); MFnIkJoint midJointFn(effectorPath); // End Joint // MDagPath endJointPath; bool hasEndJ = findFirstJointChild(effectorPath, endJointPath); // if(hasEndJ) MGlobal::displayInfo(endJointPath.fullPathName()); MFnIkJoint endJointFn(endJointPath); // Start Joint // MDagPath startJointPath; handleFn.getStartJoint(startJointPath); MFnIkJoint startJointFn(startJointPath); // Preferred angles // double startJointPrefAngle[3]; double midJointPrefAngle[3]; startJointFn.getPreferedAngle(startJointPrefAngle); midJointFn.getPreferedAngle(midJointPrefAngle); // Set to preferred angles // startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder()); midJointFn.setRotation(midJointPrefAngle, midJointFn.rotationOrder()); MPoint handlePos = handleFn.rotatePivot(MSpace::kWorld); MPoint effectorPos = effectorFn.rotatePivot(MSpace::kWorld); MPoint midJointPos = midJointFn.rotatePivot(MSpace::kWorld); MPoint startJointPos = startJointFn.rotatePivot(MSpace::kWorld); MVector poleVector = poleVectorFromHandle(handlePath); poleVector *= handlePath.exclusiveMatrix(); double twistValue = twistFromHandle(handlePath); MObject thisNode = thisMObject(); MVector localEndJointT = endJointFn.getTranslation(MSpace::kTransform); MVector worldEndJointT = endJointFn.rotatePivot(MSpace::kWorld) - midJointPos; double scaling = worldEndJointT.length() / ( localEndJointT.length() + 1e-6); // MGlobal::displayInfo(MString(" scaling ")+scaling); // get rest length // double restL1, restL2; MPlug(thisNode, arestLength1).getValue(restL1); MPlug(thisNode, arestLength2).getValue(restL2); // get soft distance // MPlug plug( thisNode, asoftDistance ); double softD = 0.0; plug.getValue(softD); restL1 *= scaling; restL2 *= scaling; softD *= scaling; // get max stretching double maxStretching = 0.0; MPlug(thisNode, amaxStretching).getValue(maxStretching); MQuaternion qStart, qMid; double stretching = 0.0; solveIK(startJointPos, midJointPos, effectorPos, handlePos, poleVector, twistValue, qStart, qMid, softD, restL1, restL2, stretching); midJointFn.rotateBy(qMid, MSpace::kWorld); startJointFn.rotateBy(qStart, MSpace::kWorld); midJointFn.setTranslation(MVector(restL1 / scaling, 0.0, 0.0), MSpace::kTransform); endJointFn.setTranslation(MVector(restL2 / scaling, 0.0, 0.0), MSpace::kTransform); // if(stretching > maxStretching) stretching = maxStretching; if(maxStretching > 0.0) { MVector vstretch(stretching* 0.5 / scaling, 0.0, 0.0); midJointFn.translateBy(vstretch, MSpace::kTransform); endJointFn.translateBy(vstretch, MSpace::kTransform); } return MS::kSuccess; }