MVector swissArmyLocatorManip::nodeTranslation() const { MFnDagNode dagFn(fNodePath); MDagPath path; dagFn.getPath(path); path.pop(); // pop from the shape to the transform MFnTransform transformFn(path); return transformFn.translation(MSpace::kWorld); }
MVector customAttrManip::nodeTranslation() const // // Description // Query and return the translation values for the attached transform node. // { MFnDagNode dagFn(fNodePath); MDagPath path; dagFn.getPath(path); MFnTransform transformFn(path); return transformFn.translation(MSpace::kWorld); }
MQuaternion customAttrManip::nodeRotation() const // // Description // Query and return the rotation values for the attached transform node. // { MFnDagNode dagFn(fNodePath); MDagPath path; dagFn.getPath(path); MFnTransform transformFn(path); MQuaternion q; transformFn.getRotation( q, MSpace::kWorld ); return q; }
MStatus geometrySurfaceConstraintCommand::connectObjectAndConstraint( MDGModifier& modifier ) { MObject transform = transformObject(); if ( transform.isNull() ) { MGlobal::displayError("Failed to get transformObject()"); return MS::kFailure; } MStatus status; MFnTransform transformFn( transform ); MVector translate = transformFn.getTranslation(MSpace::kTransform,&status); if (!status) { status.perror(" transformFn.getTranslation"); return status;} MPlug translatePlug = transformFn.findPlug( "translate", &status ); if (!status) { status.perror(" transformFn.findPlug"); return status;} if ( MPlug::kFreeToChange == translatePlug.isFreeToChange() ) { MFnNumericData nd; MObject translateData = nd.create( MFnNumericData::k3Double, &status ); status = nd.setData3Double( translate.x,translate.y,translate.z); if (!status) { status.perror("nd.setData3Double"); return status;} status = modifier.newPlugValue( translatePlug, translateData ); if (!status) { status.perror("modifier.newPlugValue"); return status;} status = connectObjectAttribute( MPxTransform::geometry, geometrySurfaceConstraint::constraintGeometry, false ); if (!status) { status.perror("connectObjectAttribute"); return status;} } status = connectObjectAttribute( MPxTransform::parentInverseMatrix, geometrySurfaceConstraint::constraintParentInverseMatrix, true, true ); if (!status) { status.perror("connectObjectAttribute"); return status;} return MS::kSuccess; }
// In order for the new animation curve positions to match the controller's previous global position, // first we need to get the controller's global transform matrix. The new local position of the controller // will be the controller's global transform matrix multiplied by the inverse of the new parent group's // global transform matrix. // So if: // [A] = controller's global transformation matrix // [B] = parent group's global transformation matrix // [X] = controller's new local transformation matrix // Then: // [X] = [A]inverse([B]) // // The controller's new local transformation matrix needs to be calculated per keyframe, which is why // a map of world position matrices for the controller are passed in as a parameter. The key for the map // is the time at which the associated world matrix was stored. MStatus lrutils::updateAnimCurves(MObject transformObj, std::map<double, MMatrix> ctlWorldMatrices, MMatrix ctlGroupMatrix) { MStatus status = MS::kFailure; MFnTransform transformFn( transformObj, &status ); MyCheckStatusReturn(status, status.errorString() ); //get all of the connections from the transform node MPlugArray transformConnections; status = transformFn.getConnections( transformConnections ); MyCheckStatusReturn(status, status.errorString() ); for(unsigned int i = 0; i < transformConnections.length(); i++) { //get all of the plugs this plug is connected to as a destination MPlugArray connectedPlugs; transformConnections[i].connectedTo(connectedPlugs,true,false,&status); MyCheckStatusReturn(status, status.errorString() ); MString plugName = transformConnections[i].partialName(false,false,false,false,false,true); for(unsigned int j = 0; j < connectedPlugs.length(); j++) { MObject connectedObj = connectedPlugs[j].node(); MFn::Type animType = connectedObj.apiType(); //if the connected object is an animCurveT[L,A], then transform it if( (animType == MFn::kAnimCurveTimeToDistance) || (animType == MFn::kAnimCurveTimeToAngular) ) { MFnAnimCurve animCurve(connectedObj, &status); MyCheckStatusReturn(status, status.errorString() ); //iterate through every key in the curve for(unsigned int k = 0; k < animCurve.numKeys(); k++) { double keyTime = animCurve.time(k, &status).value(); MyCheckStatusReturn( status, status.errorString() ); double keyVal = animCurve.value(k, &status); MyCheckStatusReturn( status, status.errorString() ); float tangentX, tangentY; status = animCurve.getTangent(k, tangentX, tangentY, false); MyCheckStatusReturn(status, status.errorString() ); //stringstream tmp; //tmp << "out tangent = (" << tangentX << "," << tangentY << ")"; //MGlobal::displayInfo(tmp.str().c_str()); //calculate the controller's local transformation matrix //first retrieve the corresponding world matrix for this key time MMatrix ctlWorldMatrix = ctlWorldMatrices[keyTime]; //if the transformation matrices are the same, don't update the curve //if( ctlWorldMatrix == ctlGroupMatrix) { // continue; //} MTransformationMatrix ctlGroupTransMatrix(ctlGroupMatrix); MMatrix ctlGroupMatrixInverse = ctlGroupTransMatrix.asMatrixInverse(); MMatrix newCtlLocalMatrix = ctlWorldMatrix * ctlGroupMatrixInverse; MTransformationMatrix newCtlLocalTransMatrix(newCtlLocalMatrix); //determine if the curve is for translation data if(animType == MFn::kAnimCurveTimeToDistance) { MVector vTransform = newCtlLocalTransMatrix.translation(MSpace::kTransform); if( plugName.indexW( MString("X") ) != -1 ) { keyVal = vTransform.x; } else if ( plugName.indexW( MString("Y") ) != -1 ) { keyVal = vTransform.y; } else if ( plugName.indexW( MString("Z") ) != -1 ) { keyVal = vTransform.z; } //if the curve is for rotation data } else if (animType == MFn::kAnimCurveTimeToAngular) { double* rotation = new double[3]; MTransformationMatrix::RotationOrder rotOrder = MTransformationMatrix::kXYZ; newCtlLocalTransMatrix.getRotation(rotation,rotOrder); if( plugName.indexW( MString("X") ) != -1 ) { keyVal = rotation[0]; } else if ( plugName.indexW( MString("Y") ) != -1 ) { keyVal = rotation[1]; } else if ( plugName.indexW( MString("Z") ) != -1 ) { keyVal = rotation[2]; } } animCurve.setValue(k, keyVal); status = MS::kSuccess; } } } } return status; }