// // 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. // MStatus rockingTransformCheckNode::checkAndSetRotation(MDataBlock &block, const MPlug& plug, const MEulerRotation& newRotation, MSpace::Space space ) { const MDGContext context = block.context(); updateMatrixAttrs(context); MStatus status = MS::kSuccess; 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::kTransform, &status); ReturnOnError(status); // 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. // status = baseTransformationMatrix->rotateTo(newRotation, space); ReturnOnError(status); outRotation = xformMat->eulerRotation(MSpace::kTransform, &status); ReturnOnError(status); // Now that everything is in the same space, apply limits // and change the value to adhere to plug locking. // outRotation = applyRotationLimits(outRotation, block, &status); ReturnOnError(status); outRotation = applyRotationLocks(outRotation, savedRotation, &status); ReturnOnError(status); // The value that remain is in transform space. // status = xformMat->rotateTo(outRotation, MSpace::kTransform); ReturnOnError(status); // 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::kTransform, &status); ReturnOnError(status); } else { // Get the rotation for clamping and locking. This will get the // rotate value in transform space. // double3 &s3 = block.inputValue(rotate).asDouble3(); MEulerRotation savedRotation(s3[0], s3[1], s3[2]); // Create a local transformation matrix for non-normal context // calculations. // MPxTransformationMatrix *local = createTransformationMatrix(); if (NULL == local) { MGlobal::displayError("rockingTransformCheck::checkAndSetRotation internal error"); return status; } // Fill the newly created transformation matrix. // status = computeLocalTransformation(local, block); if ( MS::kSuccess != status) { delete local; return status; } // Translate the values to transform space. This will allow the // limit and locking tests to work properly. // status = local->rotateTo(newRotation, space); if ( MS::kSuccess != status) { delete local; return status; } outRotation = local->eulerRotation(MSpace::kTransform, &status); if ( MS::kSuccess != status) { delete local; return status; } // Apply limits // outRotation = applyRotationLimits(outRotation, block, &status); if ( MS::kSuccess != status) { delete local; return status; } outRotation = applyRotationLocks(outRotation, savedRotation, &status); if ( MS::kSuccess != status) { delete local; return status; } status = local->rotateTo(outRotation, MSpace::kTransform); if ( MS::kSuccess != status) { delete local; return status; } // Get the rotate value in transform space for placement in the // datablock. // outRotation = local->eulerRotation(MSpace::kTransform, &status); if ( MS::kSuccess != status) { delete local; return status; } delete local; } MDataHandle handle = block.outputValue(plug, &status); if ( MS::kSuccess != status) { return status; } if (plug == rotate) { handle.set(outRotation.x, outRotation.y, outRotation.z); } else if (plug == rotateX) { handle.set(outRotation.x); } else if (plug == rotateY) { handle.set(outRotation.y); } else { handle.set(outRotation.z); } return status; }
MStatus dgTransform::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MDataHandle hTranslate = data.inputValue( aTranslate, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hRotate = data.inputValue( aRotate, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hScale = data.inputValue( aScale, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hShear = data.inputValue( aShear, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hJointOrient = data.inputValue( aJointOrient, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hInputTranslate = data.inputValue( aInputTranslate, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hInputRotate = data.inputValue( aInputRotate, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hInputScale = data.inputValue( aInputScale, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MDataHandle hInputShear = data.inputValue( aInputShear, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); MPxTransformationMatrix inputMpxTrMtx; MEulerRotation inputEulerRot( hInputRotate.asVector() ); inputMpxTrMtx.translateTo( hInputTranslate.asVector() ); inputMpxTrMtx.rotateTo( inputEulerRot ); inputMpxTrMtx.scaleTo( hInputScale.asVector() ); inputMpxTrMtx.shearTo( hInputShear.asVector() ); MMatrix parentMatrix = inputMpxTrMtx.asMatrix(); MPxTransformationMatrix mpxTrMtx; MEulerRotation eulerRot( hRotate.asVector() ); MEulerRotation joEulerRot( hJointOrient.asVector() ); mpxTrMtx.translateTo( hTranslate.asVector() ); mpxTrMtx.rotateTo( eulerRot ); mpxTrMtx.rotateBy( joEulerRot ); mpxTrMtx.scaleTo( hScale.asVector() ); mpxTrMtx.shearTo( hShear.asVector() ); if( plug == aMatrix ) { //cout <<"matrix"<<endl; MDataHandle hMatrix = data.outputValue( aMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); hMatrix.setMMatrix( mpxTrMtx.asMatrix() ); } if( plug == aInverseMatrix ) { //cout <<"inverseMatrix"<<endl; MDataHandle hInverseMatrix = data.outputValue( aInverseMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); hInverseMatrix.setMMatrix( mpxTrMtx.asMatrix().inverse() ); } if( plug == aWorldMatrix || plug == aWorldInverseMatrix ) { MMatrix worldMatrix = mpxTrMtx.asMatrix()*parentMatrix; if( plug == aWorldMatrix ) { //cout <<"worldMatrix"<<endl; MDataHandle hWorldMatrix = data.outputValue( aWorldMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); hWorldMatrix.setMMatrix( worldMatrix ); } if( plug == aWorldInverseMatrix ) { //cout <<"worldInverseMatrix"<<endl; MDataHandle hWorldInverseMatrix = data.outputValue( aWorldInverseMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); hWorldInverseMatrix.setMMatrix( worldMatrix.inverse() ); } } if( plug == aParentMatrix ) { //cout <<"parentMatrix"<<endl; MDataHandle hParentMatrix = data.outputValue( aParentMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); hParentMatrix.setMMatrix( parentMatrix ); } if( plug == aParentInverseMatrix ) { //cout <<"parentInverseMatrix"<<endl; MDataHandle hParentInverseMatrix = data.outputValue( aParentInverseMatrix, &status ); CHECK_MSTATUS_AND_RETURN_IT( status ); hParentInverseMatrix.setMMatrix( parentMatrix.inverse() ); } data.setClean( plug ); return status; }