rockingTransform.cpp
#include <maya/MPxTransform.h>
#include <maya/MPxTransformationMatrix.h>
#include <maya/MGlobal.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MTransformationMatrix.h>
#include <maya/MIOStream.h>
#include "rockingTransform.h"
#ifndef M_PI
#include <math.h>
#endif
MObject rockingTransformNode::aRockInX;
MTypeId rockingTransformNode::id(kRockingTransformNodeID);
MTypeId rockingTransformMatrix::id(kRockingTransformMatrixID);
rockingTransformMatrix::rockingTransformMatrix()
{
rockXValue = 0.0;
}
void *rockingTransformMatrix::creator()
{
return new rockingTransformMatrix();
}
double rockingTransformMatrix::getRockInX() const
{
return rockXValue;
}
void rockingTransformMatrix::setRockInX( double rock )
{
rockXValue = rock;
}
MMatrix rockingTransformMatrix::asMatrix() const
{
MMatrix m = ParentClass::asMatrix();
MTransformationMatrix tm( m );
MQuaternion quat = rotation();
DegreeRadianConverter conv;
double newTheta = conv.degreesToRadians( getRockInX() );
quat.setToXAxis( newTheta );
tm.addRotationQuaternion( quat.x, quat.y, quat.z, quat.w, MSpace::kTransform );
return tm.asMatrix();
}
MMatrix rockingTransformMatrix::asMatrix(double percent) const
{
MPxTransformationMatrix m(*this);
MVector trans = m.translation();
trans *= percent;
m.translateTo( trans );
MPoint rotatePivotTrans = m.rotatePivot();
rotatePivotTrans = rotatePivotTrans * percent;
m.setRotatePivot( rotatePivotTrans );
MPoint scalePivotTrans = m.scalePivotTranslation();
scalePivotTrans = scalePivotTrans * percent;
m.setScalePivotTranslation( scalePivotTrans );
MQuaternion quat = rotation();
DegreeRadianConverter conv;
double newTheta = conv.degreesToRadians( getRockInX() );
quat.setToXAxis( newTheta );
m.rotateBy( quat );
MEulerRotation eulRotate = m.eulerRotation();
m.rotateTo( eulRotate * percent, MSpace::kTransform);
MVector s(scale(MSpace::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::kTransform);
return m.asMatrix();
}
MMatrix rockingTransformMatrix::asRotateMatrix() const
{
return ParentClass::asRotateMatrix();
}
rockingTransformNode::rockingTransformNode()
: ParentClass()
{
rockXValue = 0.0;
}
rockingTransformNode::rockingTransformNode(MPxTransformationMatrix *tm)
: ParentClass(tm)
{
rockXValue = 0.0;
}
void rockingTransformNode::postConstructor()
{
ParentClass::postConstructor();
if (NULL == baseTransformationMatrix) {
MGlobal::displayWarning("NULL baseTransformationMatrix found!");
baseTransformationMatrix = new MPxTransformationMatrix();
}
MPlug aRockInXPlug(thisMObject(), aRockInX);
}
rockingTransformNode::~rockingTransformNode()
{
}
MPxTransformationMatrix *rockingTransformNode::createTransformationMatrix()
{
return new rockingTransformMatrix();
}
void *rockingTransformNode::creator()
{
return new rockingTransformNode();
}
MStatus rockingTransformNode::initialize()
{
MFnNumericAttribute numFn;
aRockInX = numFn.create("RockInX", "rockx", MFnNumericData::kDouble, 0.0);
numFn.setKeyable(true);
numFn.setAffectsWorldSpace(true);
addAttribute(aRockInX);
mustCallValidateAndSet(aRockInX);
return MS::kSuccess;
}
const char* rockingTransformNode::className()
{
return "rockingTransformNode";
}
void rockingTransformNode::resetTransformation (const MMatrix &matrix)
{
ParentClass::resetTransformation( matrix );
}
void rockingTransformNode::resetTransformation (MPxTransformationMatrix *resetMatrix )
{
ParentClass::resetTransformation( resetMatrix );
}
MStatus rockingTransformNode::validateAndSetValue(const MPlug& plug,
const MDataHandle& handle,
const MDGContext& context)
{
MStatus status = MS::kSuccess;
if (plug.isNull())
return MS::kFailure;
MDataBlock block = forceCache(*(MDGContext *)&context);
MDataHandle blockHandle = block.outputValue(plug, &status);
ReturnOnError(status);
if ( plug == aRockInX )
{
double rockInX = handle.asDouble();
blockHandle.set(rockInX);
rockXValue = rockInX;
rockingTransformMatrix *ltm = getRockingTransformMatrix();
if (ltm)
ltm->setRockInX(rockXValue);
else
MGlobal::displayError("Failed to get rock transform matrix");
blockHandle.setClean();
dirtyMatrix();
}
return ParentClass::validateAndSetValue(plug, handle, context);
}
rockingTransformMatrix *rockingTransformNode::getRockingTransformMatrix()
{
rockingTransformMatrix *ltm = (rockingTransformMatrix *) baseTransformationMatrix;
return ltm;
}
double DegreeRadianConverter::degreesToRadians( double degrees )
{
return degrees * ( M_PI/ 180.0 );
}
double DegreeRadianConverter::radiansToDegrees( double radians )
{
return radians * (180.0/M_PI);
}