I'm new to Maya API/C++ in general and I'm trying to write a simple plugin. I have the relevant code pasted below but I have also attached dropbox link to a .zip if you'd prefer to download it as a package.
https://dl.dropboxusercontent.com/u/40345020/inverseMatrixNode03.zip
This code in particular is sampled from a .pdf I got off Autodesk Developer Network although I have tried other methods, including ones provided in "Complete Maya Programming" (David Gould). The files compile without error and so I believe I erred somewhere in my method. Anyway, onto the code.
Synopsis of the file:
-- END --
.h header, named "inverseMatrixNode.h"
#include <maya/MPxNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MMatrix.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MTransformationMatrix.h>
#include <maya/MVector.h>
#include <math.h>
#include <iostream>
#include <maya/MFnPlugin.h>
class matrixInverseNode : public MPxNode
{
public:
matrixInverseNode();
virtual ~matrixInverseNode();
static void* creator();
virtual MStatus compute( const MPlug &plug, MDataBlock& data);
static MStatus initialize();
static MTypeId id;
//input
static MObject aInMatrix;
//output
static MObject aOutInvMatrix;
static MObject aOutTrans;
static MObject aOutTransX;
static MObject aOutTransY;
static MObject aOutTransZ;
static MObject aOutInvTrans;
static MObject aOutInvTransX;
static MObject aOutInvTransY;
static MObject aOutInvTransZ;
};
and the .cpp
#include "inverseMatrixNode.h"
MTypeId matrixInverseNode::id( 0x00000233 );
MObject matrixInverseNode::aInMatrix;
MObject matrixInverseNode::aOutTrans;
MObject matrixInverseNode::aOutTransX;
MObject matrixInverseNode::aOutTransY;
MObject matrixInverseNode::aOutTransZ;
MObject matrixInverseNode::aOutInvTrans;
MObject matrixInverseNode::aOutInvTransX;
MObject matrixInverseNode::aOutInvTransY;
MObject matrixInverseNode::aOutInvTransZ;
matrixInverseNode::matrixInverseNode()
{
}
matrixInverseNode::~matrixInverseNode()
{
}
MStatus matrixInverseNode::compute( const MPlug& plug, MDataBlock& data )
{
MStatus status;
//create matrix handle
MTransformationMatrix inMatrix = data.inputValue( aInMatrix, &status ).asMatrix();
CHECK_MSTATUS_AND_RETURN_IT( status );
// Get Translate as vector then assign vector components to individual values
MVector transInMatrix = inMatrix.getTranslation( MSpace::kWorld );
double transInMatrixX = transInMatrix.x;
double transInMatrixY = transInMatrix.y;
double transInMatrixZ = transInMatrix.z;
// And again for the inverseMatrix
MTransformationMatrix invInMatrix = inMatrix.asMatrixInverse();
MVector transInvInMatrix = invInMatrix.getTranslation( MSpace::kWorld );
double transInvInMatrixX = transInvInMatrix.x;
double transInvInMatrixY = transInvInMatrix.y;
double transInvInMatrixZ = transInvInMatrix.z;
//create handles for outTrans and its inverse
MDataHandle hOutTransX = data.outputValue( aOutTransX, &status );
CHECK_MSTATUS_AND_RETURN_IT( status );
MDataHandle hOutTransY = data.outputValue( aOutTransY, &status );
CHECK_MSTATUS_AND_RETURN_IT( status );
MDataHandle hOutTransZ = data.outputValue( aOutTransZ, &status );
CHECK_MSTATUS_AND_RETURN_IT( status );
MDataHandle hOutInvTransX = data.outputValue( aOutInvTransX, &status );
CHECK_MSTATUS_AND_RETURN_IT( status );
MDataHandle hOutInvTransY = data.outputValue( aOutInvTransY, &status );
CHECK_MSTATUS_AND_RETURN_IT( status );
MDataHandle hOutInvTransZ = data.outputValue( aOutInvTransZ, &status );
CHECK_MSTATUS_AND_RETURN_IT( status );
// set value to handle and then set clean
hOutTransX.set( transInMatrixX );
hOutTransX.setClean();
hOutTransY.set( transInMatrixY );
hOutTransY.setClean();
hOutTransZ.set( transInMatrixZ );
hOutTransZ.setClean();
hOutInvTransX.set( transInvInMatrixX );
hOutInvTransX.setClean();
hOutInvTransY.set( transInvInMatrixY );
hOutInvTransY.setClean();
hOutInvTransZ.set( transInvInMatrixZ );
hOutInvTransZ.setClean();
return MS::kSuccess;
}
void* matrixInverseNode::creator()
{
return new matrixInverseNode();
}
MStatus matrixInverseNode::initialize()
{
MStatus status;
MFnNumericAttribute nAttr;
aOutTransX = nAttr.create( "outTranslateX", "oTx", MFnNumericData::kFloat, 0.0 );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutTransX );
aOutTransY = nAttr.create( "outTranslateY", "oTy", MFnNumericData::kFloat, 0.0 );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutTransY );
aOutTransZ = nAttr.create( "outTranslateZ", "oTz", MFnNumericData::kFloat, 0.0 );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutTransZ );
aOutTrans = nAttr.create( "outTranslate", "oT", aOutTransX, aOutTransY, aOutTransZ );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutTrans );
aOutInvTransX = nAttr.create( "outInverseTranslateX", "oITx", MFnNumericData::kFloat, 0.0 );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutInvTransX );
aOutInvTransY = nAttr.create( "outInverseTranslateY", "oITy", MFnNumericData::kFloat, 0.0 );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutInvTransY );
aOutInvTransZ = nAttr.create( "outInverseTranslateZ", "oITz", MFnNumericData::kFloat, 0.0 );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutInvTransZ );
aOutInvTrans = nAttr.create( "outInverseTranslate", "oIT", aOutInvTransX, aOutInvTransY, aOutInvTransZ );
nAttr.setKeyable( false );
nAttr.setStorable( false );
nAttr.setReadable( true );
nAttr.setWritable( false );
nAttr.setCached( false );
addAttribute( aOutInvTrans );
MFnMatrixAttribute mAttr;
aInMatrix = mAttr.create( "inMatrix", "inM", MFnMatrixAttribute::kDouble );
mAttr.setStorable( true );
mAttr.setKeyable( false );
mAttr.setReadable( true );
mAttr.setWritable( true );
mAttr.setCached( false );
addAttribute( aInMatrix );
attributeAffects( aInMatrix, aOutTransX );
attributeAffects( aInMatrix, aOutTransY );
attributeAffects( aInMatrix, aOutTransZ );
attributeAffects( aInMatrix, aOutTrans );
attributeAffects( aInMatrix, aOutInvTransX );
attributeAffects( aInMatrix, aOutInvTransY );
attributeAffects( aInMatrix, aOutInvTransZ );
attributeAffects( aInMatrix, aOutInvTrans );
return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin fnPlugin( obj, "Colin Kennedy", "1.0", "Any" );
status = fnPlugin.registerNode( "matrixInverse",
matrixInverseNode::id,
matrixInverseNode::creator,
matrixInverseNode::initialize );
CHECK_MSTATUS_AND_RETURN_IT( status );
return MS::kSuccess;
}
MStatus uninitializePlugin( MObject obj )
{
MStatus status;
MFnPlugin fnPlugin( obj );
status = fnPlugin.deregisterNode( matrixInverseNode::id );
CHECK_MSTATUS_AND_RETURN_IT( status );
return MS::kSuccess;
}
Despite this being simple, I'm getting no results once the plugin is loaded inside Maya. My files compile without warning/error but when I actually try to grab a .worldMatrix from a transform in Maya, both the original matrix and its inverse translate values read (0,0,0).
If someone could shed some light on the error in my implementation or suggest a better way to get translate/rotate from a matrix, I'd appreciate it. The project is made using Maya Plugin Wizard in VS2010. The node is named matrixInverse as to not conflict with the native inverseMatrix node in Maya. Oh, also, if there's any egregious, noobish errors in my code, I'd love to know about those, too. Thank you.
It won't calculate unless you plug the outputs into something usually, but you haven't given it an if statement to have it not compute. My guess is that your doing this:
// set value to handle and then set clean
hOutTransX.set( transInMatrixX );
hOutTransX.setClean();
hOutTransY.set( transInMatrixY );
hOutTransY.setClean();
hOutTransZ.set( transInMatrixZ );
hOutTransZ.setClean();
Instead of:
hOutTransX.setFloat(transInMatrixX);
hOutTransY.setFloat(transInMatrixY);
hOutTransZ.setFloat(transInMatrixZ);
data.setClean(plug);
You have to specify what you're setting and just set the plug clean not the attribute. Since the output attributes are floats just do a setFloat to set the value.I would also make sure to instead of declaring the variable as a double declare it as float:
float transInvInMatrixX = transInvInMatrix.x;
Instead of:
double transInvInMatrixX = transInvInMatrix.x;
If you want to use doubles just change the variable in the init to MFnNumericData::kDouble instead of float.
Here's my simple node example that could help as well: http://goo.gl/PNcPW5
Hope that helps!
User contributions licensed under CC BY-SA 3.0