public static MDagPath AddParentCircle(MDagPath targetDagPath, bool createParallelGrp) { string ctlName = "ctl_" + targetDagPath.partialPathName; MDagPath ctlDagPath = BasicFunc.CreateCircle(ctlName); ctlName = ctlDagPath.fullPathName; MFnTransform targetTrans = new MFnTransform(targetDagPath); if (createParallelGrp) { MFnTransform parellelGrpTrans = new MFnTransform(AddEmptyGroup(new MFnTransform(targetTrans.parent(0)))); parellelGrpTrans.setTranslation(targetTrans.getTranslation(MSpace.Space.kTransform), MSpace.Space.kTransform); //Debug.Log("finalLocalPos:"+BasicFunc.ToCMDSParamStr(parellelGrpTrans.getTranslation(MSpace.kTransform))); MEulerRotation rot = new MEulerRotation(); targetTrans.getRotation(rot); parellelGrpTrans.setRotation(rot); SetTransformParent(ctlName, parellelGrpTrans.fullPathName); } MFnTransform circleTransform = new MFnTransform(ctlDagPath); circleTransform.setTranslation(new MVector(0, 0, 0), MSpace.Space.kTransform); circleTransform.setRotation(new MEulerRotation(0, 90 / ConstantValue.DPR, 0)); FreezeTransform(circleTransform); return(ctlDagPath); }
public override void connectToDependNode(MObject node) { // Find the rotate and rotatePivot plugs on the node. These plugs will // be attached either directly or indirectly to the manip values on the // rotate manip. // MFnDependencyNode nodeFn = new MFnDependencyNode(node); MPlug rPlug = nodeFn.findPlug("rotate"); MPlug rcPlug = nodeFn.findPlug("rotatePivot"); // If the translate pivot exists, it will be used to move the state manip // to a convenient location. // MPlug tPlug = nodeFn.findPlug("translate"); // To avoid having the object jump back to the default rotation when the // manipulator is first used, extract the existing rotation from the node // and set it as the initial rotation on the manipulator. // MEulerRotation existingRotation = new MEulerRotation(vectorPlugValue(rPlug)); MVector existingTranslation = new MVector(vectorPlugValue(tPlug)); // // The following code configures default settings for the rotate // manipulator. // MFnRotateManip rotateManip = new MFnRotateManip(fRotateManip); rotateManip.setInitialRotation(existingRotation); rotateManip.setRotateMode(MFnRotateManip.RotateMode.kObjectSpace); rotateManip.displayWithNode(node); // Add a callback function to be called when the rotation value changes // //rotatePlugIndex = addManipToPlugConversionCallback( rPlug, (manipToPlugConversionCallback)&exampleRotateManip::rotationChangedCallback ); ManipToPlugConverion[rPlug] = rotationChangedCallback; // get the index of plug rotatePlugIndex = this[rPlug]; // Create a direct (1-1) connection to the rotation center plug // rotateManip.connectToRotationCenterPlug(rcPlug); // Place the state manip at a distance of 2.0 units away from the object // along the X-axis. // MFnStateManip stateManip = new MFnStateManip(fStateManip); MVector delta = new MVector(2, 0, 0); stateManip.setTranslation(existingTranslation + delta, MSpace.Space.kTransform); finishAddingManips(); base.connectToDependNode(node); }
protected override MEulerRotation applyRotationLimits(MEulerRotation unlimitedRotation, MDataBlock block) { // // For demonstration purposes we limit the rotation to 60 // degrees and bypass the rotation limit attributes // DegreeRadianConverter conv = new DegreeRadianConverter(); double degrees = conv.radiansToDegrees(unlimitedRotation.x); if (degrees < 60) { return(unlimitedRotation); } MEulerRotation euler = new MEulerRotation(); euler.x = conv.degreesToRadians(60.0); return(euler); }
public static void ClearHierachyJointsRotation(MSelectionList selectionList = null) { if (selectionList == null || selectionList.length == 0) { selectionList = BasicFunc.GetSelectedList(); } foreach (MDagPath dag in selectionList.DagPaths()) { List <MFnTransform> transList = BasicFunc.GetHierachyAllTrans(dag, MFn.Type.kJoint); foreach (MFnTransform trans in transList) { //Debug.Log("trans:" + trans.fullPathName); trans.setRotation(new MEulerRotation(0, 0, 0)); MEulerRotation result = new MEulerRotation(); trans.getRotation(result); //Debug.LogEuler(result, "value"); } } }
internal static CoordinateSystem mLocatorFromName(string dagName, string space) { MDagPath dagPath = DMInterop.getDagNode(dagName); MSpace.Space mspace = MSpace.Space.kWorld; Enum.TryParse(space, out mspace); // MObject obj = DMInterop.getDependNode(dagName); MMatrix worldPos = dagPath.inclusiveMatrix; double x = worldPos[3, 0]; double y = worldPos[3, 1]; double z = worldPos[3, 2]; MEulerRotation rot = new MEulerRotation(); double xr = worldPos[3, 0]; double yr = worldPos[3, 1]; double zr = worldPos[3, 2]; //MFnTransform loc = new MFnTransform(dagShape.node); //var vec = loc.transformation.getTranslation(mspace); //return Point.ByCoordinates(vec.x, vec.y, vec.z); ; CoordinateSystem cs; if (MGlobal.isZAxisUp) { cs = CoordinateSystem.ByOrigin(x, y, z); cs.Rotate(cs.Origin, Vector.XAxis(), x); cs.Rotate(cs.Origin, Vector.YAxis(), y); cs.Rotate(cs.Origin, Vector.ZAxis(), z); return(cs); } else { cs = CoordinateSystem.ByOrigin(x, -z, y); cs.Rotate(cs.Origin, Vector.XAxis(), x); cs.Rotate(cs.Origin, Vector.YAxis(), y); cs.Rotate(cs.Origin, Vector.ZAxis(), z); return(cs); } }
public override MMatrix asMatrix(double percent) { MPxTransformationMatrix m = new MPxTransformationMatrix(this); // Apply the percentage to the matrix components MVector trans = m.translation(); trans *= percent; m.translateTo(trans); MPoint rotatePivotTrans = m.rotatePivot(); rotatePivotTrans = rotatePivotTrans * percent; m.setRotatePivot(rotatePivotTrans); MPoint scalePivotTrans = new MPoint(m.scalePivotTranslation()); scalePivotTrans = scalePivotTrans * percent; m.setScalePivotTranslation(new MVector(scalePivotTrans)); // Apply the percentage to the rotate value. Same // as above + the percentage gets applied MQuaternion quat = rotation(); DegreeRadianConverter conv = new DegreeRadianConverter(); double newTheta = conv.degreesToRadians(getRockInX()); quat.setToXAxis(newTheta); m.rotateBy(quat); MEulerRotation eulRotate = m.eulerRotation(); m.rotateTo(eulRotate.multiply(percent), MSpace.Space.kTransform); // Apply the percentage to the scale MVector s = new MVector(scale(MSpace.Space.kTransform)); s.x = 1.0 + (s.x - 1.0) * percent; s.y = 1.0 + (s.y - 1.0) * percent; s.z = 1.0 + (s.z - 1.0) * percent; m.scaleTo(s, MSpace.Space.kTransform); return(m.asMatrix()); }
private void OrientFix(object sender, RoutedEventArgs e) { if (joints == null && joints.Count == 0) { return; } if (joints.Count == 1) { //set for the one } MVector lastJointWorldPos = joints[joints.Count - 1].getTranslation(MSpace.Space.kWorld); MVector firstJointWorldPos = joints[0].getTranslation(MSpace.Space.kWorld); //string[] lines = System.IO.File.ReadAllLines("D:\temp\testValue.txt"); //float valueX = float.Parse(text_x.Text); //float valueY = float.Parse(text_y.Text); //float valueZ = float.Parse(text_z.Text); //MVector direction = (lastJointWorldPos - firstJointWorldPos).normal; //MVector yzDirect = direction; //yzDirect.x = 0; //yzDirect.normalize(); for (int i = 0; i < joints.Count - 1; i++) { //MEulerRotation //MVector originOrient = joints[i].getOrientation() MQuaternion mq = new MQuaternion(new MVector(1, 0, 0), lastJointWorldPos - firstJointWorldPos); MEulerRotation euler = mq.asEulerRotation; joints[i].setOrientation(mq); //text_x.Text = euler.x + ""; //text_y.Text = euler.y + ""; //text_z.Text = euler.z + ""; //joints[i].setOrientation(new MEulerRotation(valueX, valueY, valueZ)); } }
// // Calls applyRotationLocks && applyRotationLimits // This method verifies that the passed value can be set on the // rotate plugs. In the base class, limits as well as locking are // checked by this method. // // The compute, validateAndSetValue, and rotateTo functions // all use this method. // protected override void checkAndSetRotation(MDataBlock block, MPlug plug, MEulerRotation newRotation, MSpace.Space space) { MDGContext context = block.context; updateMatrixAttrs(context); MEulerRotation outRotation = newRotation; if (context.isNormal) { // For easy reading. // MPxTransformationMatrix xformMat = baseTransformationMatrix; // Get the current translation in transform space for // clamping and locking. // MEulerRotation savedRotation = xformMat.eulerRotation(MSpace.Space.kTransform); // Translate to transform space, since the limit test needs the // values in transform space. The locking test needs the values // in the same space as the savedR value - which is transform // space as well. // baseTransformationMatrix.rotateTo(newRotation, space); outRotation = xformMat.eulerRotation(MSpace.Space.kTransform); // Now that everything is in the same space, apply limits // and change the value to adhere to plug locking. // outRotation = applyRotationLimits(outRotation, block); outRotation = applyRotationLocks(outRotation, savedRotation); // The value that remain is in transform space. // xformMat.rotateTo(outRotation, MSpace.Space.kTransform); // Get the value that was just set. It needs to be in transform // space since it is used to set the datablock values at the // end of this method. Getting the vaolue right before setting // ensures that the transformation matrix and data block will // be synchronized. // outRotation = xformMat.eulerRotation(MSpace.Space.kTransform); } else { // Get the rotation for clamping and locking. This will get the // rotate value in transform space. // double[] s3 = block.inputValue(rotate).Double3; MEulerRotation savedRotation = new MEulerRotation(s3[0], s3[1], s3[2]); // Create a local transformation matrix for non-normal context // calculations. // MPxTransformationMatrix local = createTransformationMatrix(); if (null == local) { throw new InvalidOperationException("rockingTransformCheck::checkAndSetRotation internal error"); } // Fill the newly created transformation matrix. // computeLocalTransformation(local, block); // Translate the values to transform space. This will allow the // limit and locking tests to work properly. // local.rotateTo(newRotation, space); outRotation = local.eulerRotation(MSpace.Space.kTransform); // Apply limits // outRotation = applyRotationLimits(outRotation, block); outRotation = applyRotationLocks(outRotation, savedRotation); local.rotateTo(outRotation, MSpace.Space.kTransform); // Get the rotate value in transform space for placement in the // data block. // outRotation = local.eulerRotation(MSpace.Space.kTransform); local.Dispose(); } MDataHandle handle = block.outputValue(plug); if (plug.equalEqual(rotate)) { handle.set(outRotation.x, outRotation.y, outRotation.z); } else if (plug.equalEqual(rotateX)) { handle.set(outRotation.x); } else if (plug.equalEqual(rotateY)) { handle.set(outRotation.y); } else { handle.set(outRotation.z); } return; }
protected override MEulerRotation applyRotationLocks(MEulerRotation toTest, MEulerRotation savedRotation) { return toTest; }
protected override MEulerRotation applyRotationLimits(MEulerRotation unlimitedRotation, MDataBlock block) { // // For demonstration purposes we limit the rotation to 60 // degrees and bypass the rotation limit attributes // DegreeRadianConverter conv = new DegreeRadianConverter(); double degrees = conv.radiansToDegrees( unlimitedRotation.x ); if ( degrees < 60 ) return unlimitedRotation; MEulerRotation euler = new MEulerRotation(); euler.x = conv.degreesToRadians( 60.0 ); return euler; }
// Callback function MManipData rotationChangedCallback(object sender, ManipConversionArgs args) { MObject obj = MObject.kNullObj; // If we entered the callback with an invalid index, print an error and // return. Since we registered the callback only for one plug, all // invocations of the callback should be for that plug. // MFnNumericData numericData = new MFnNumericData(); if (args.ManipIndex != rotatePlugIndex) { MGlobal.displayError("Invalid index in rotation changed callback!"); // For invalid indices, return vector of 0's obj = numericData.create(MFnNumericData.Type.k3Double); numericData.setData(0.0, 0.0, 0.0); return new MManipData(obj); } // Assign function sets to the manipulators // MFnStateManip stateManip = new MFnStateManip(fStateManip); MFnRotateManip rotateManip = new MFnRotateManip(fRotateManip); // Adjust settings on the rotate manip based on the state of the state // manip. // uint mode = stateManip.state; if (mode != 3) { rotateManip.setRotateMode((MFnRotateManip.RotateMode)stateManip.state); rotateManip.setSnapMode(false); } else { // State 3 enables snapping for an object space manip. In this case, // we snap every 15.0 degrees. // rotateManip.setRotateMode(MFnRotateManip.RotateMode.kObjectSpace); rotateManip.setSnapMode(true); rotateManip.snapIncrement = 15.0; } // The following code creates a data object to be returned in the // MManipData. In this case, the plug to be computed must be a 3-component // vector, so create data as MFnNumericData::k3Double // obj = numericData.create(MFnNumericData.Type.k3Double); // Retrieve the value for the rotation from the manipulator and return it // directly without modification. If the manipulator should eg. slow down // rotation, this method would need to do some math with the value before // returning it. // MEulerRotation manipRotation = new MEulerRotation(); try { getConverterManipValue(rotateManip.rotationIndex, manipRotation); numericData.setData(manipRotation.x, manipRotation.y, manipRotation.z); } catch (System.Exception) { MGlobal.displayError("Error retrieving manip value"); numericData.setData(0.0, 0.0, 0.0); } return new MManipData(obj); }
public static void LogEuler(MEulerRotation euler, string tag) { Log(string.Format("{0}:({1},{2},{3})", tag, euler.x, euler.y, euler.z)); }
protected override MEulerRotation applyRotationLocks(MEulerRotation toTest, MEulerRotation savedRotation) { return(toTest); }
// Callback function MManipData rotationChangedCallback(object sender, ManipConversionArgs args) { MObject obj = MObject.kNullObj; // If we entered the callback with an invalid index, print an error and // return. Since we registered the callback only for one plug, all // invocations of the callback should be for that plug. // MFnNumericData numericData = new MFnNumericData(); if (args.ManipIndex != rotatePlugIndex) { MGlobal.displayError("Invalid index in rotation changed callback!"); // For invalid indices, return vector of 0's obj = numericData.create(MFnNumericData.Type.k3Double); numericData.setData(0.0, 0.0, 0.0); return(new MManipData(obj)); } // Assign function sets to the manipulators // MFnStateManip stateManip = new MFnStateManip(fStateManip); MFnRotateManip rotateManip = new MFnRotateManip(fRotateManip); // Adjust settings on the rotate manip based on the state of the state // manip. // uint mode = stateManip.state; if (mode != 3) { rotateManip.setRotateMode((MFnRotateManip.RotateMode)stateManip.state); rotateManip.setSnapMode(false); } else { // State 3 enables snapping for an object space manip. In this case, // we snap every 15.0 degrees. // rotateManip.setRotateMode(MFnRotateManip.RotateMode.kObjectSpace); rotateManip.setSnapMode(true); rotateManip.snapIncrement = 15.0; } // The following code creates a data object to be returned in the // MManipData. In this case, the plug to be computed must be a 3-component // vector, so create data as MFnNumericData::k3Double // obj = numericData.create(MFnNumericData.Type.k3Double); // Retrieve the value for the rotation from the manipulator and return it // directly without modification. If the manipulator should eg. slow down // rotation, this method would need to do some math with the value before // returning it. // MEulerRotation manipRotation = new MEulerRotation(); try { getConverterManipValue(rotateManip.rotationIndex, manipRotation); numericData.setData(manipRotation.x, manipRotation.y, manipRotation.z); } catch (System.Exception) { MGlobal.displayError("Error retrieving manip value"); numericData.setData(0.0, 0.0, 0.0); } return(new MManipData(obj)); }