Я новичок в Maya API / C ++ в целом, и я пытаюсь написать простой плагин. У меня есть соответствующий код, вставленный ниже, но я также прикрепил ссылку на Dropbox к ZIP-архиву, если вы хотите загрузить его в виде пакета.
https://dl.dropboxusercontent.com/u/40345020/inverseMatrixNode03.zip
Этот код, в частности, взят из файла .pdf, который я получил от Autodesk Developer Network, хотя я пробовал другие методы, в том числе те, которые приведены в «Полном программировании на Maya» (Дэвид Гулд). Файлы компилируются без ошибок, и поэтому я считаю, что где-то в моем методе произошла ошибка. Во всяком случае, на код.
Синопсис файла:
— КОНЕЦ —
.заголовок h с именем «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;};
и .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;
}
Несмотря на то, что это просто, я не получаю результатов, когда плагин загружен в Maya. Мои файлы компилируются без предупреждения / ошибки, но когда я на самом деле пытаюсь получить .worldMatrix из преобразования в Maya, исходная матрица и ее значения обратного преобразования читаются (0,0,0).
Если бы кто-то мог пролить свет на ошибку в моей реализации или предложить лучший способ получить перевод / вращение из матрицы, я был бы признателен. Проект выполнен с использованием Maya Plugin Wizard в VS2010. Узел называется matrixInverse, чтобы не конфликтовать с собственным узлом inverseMatrix в Maya. О, также, если в моем коде есть какие-то вопиющие, нудистские ошибки, я бы тоже хотел узнать о них. Спасибо.
Он не будет вычисляться, если вы обычно не подключаете выходные данные к чему-либо, но вы не дали ему оператор if, чтобы он не вычислялся. Я думаю, что вы делаете это:
// set value to handle and then set clean
hOutTransX.set( transInMatrixX );
hOutTransX.setClean();
hOutTransY.set( transInMatrixY );
hOutTransY.setClean();
hOutTransZ.set( transInMatrixZ );
hOutTransZ.setClean();
Вместо:
hOutTransX.setFloat(transInMatrixX);
hOutTransY.setFloat(transInMatrixY);
hOutTransZ.setFloat(transInMatrixZ);
data.setClean(plug);
Вы должны указать, что вы устанавливаете, и просто установить чистую заглушку, а не атрибут. Поскольку выходные атрибуты являются числами с плавающей запятой, просто сделайте setFloat для установки значения. Я бы также вместо объявления переменной как двойного объявил ее как float:
float transInvInMatrixX = transInvInMatrix.x;
Вместо:
double transInvInMatrixX = transInvInMatrix.x;
Если вы хотите использовать double, просто измените переменную в init на MFnNumericData :: kDouble вместо float.
Вот мой простой пример узла, который также может помочь:
http://goo.gl/PNcPW5
Надеюсь, это поможет!