#include "cgfxShaderCommon.h"
#include "cgfxVector.h"
#include <maya/MMatrix.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MPlug.h>
#ifdef _WIN32
MTypeId cgfxVector::sId( 4084862001 );
#else
MTypeId cgfxVector::sId( 0xF37A0C31 );
#endif
MObject cgfxVector::sVector;
MObject cgfxVector::sVectorX;
MObject cgfxVector::sVectorY;
MObject cgfxVector::sVectorZ;
MObject cgfxVector::sIsDirection;
MObject cgfxVector::sMatrix;
MObject cgfxVector::sWorldVector;
MObject cgfxVector::sWorldVectorX;
MObject cgfxVector::sWorldVectorY;
MObject cgfxVector::sWorldVectorZ;
MObject cgfxVector::sWorldVectorW;
cgfxVector::cgfxVector()
{
}
cgfxVector::~cgfxVector()
{
}
#ifdef CGFX_DEBUG
#include <stdarg.h>
#ifdef _WIN32
#endif
#else
static inline void dprintf(char* format, ...)
{
}
#endif
MStatus cgfxVector::compute( const MPlug& plug, MDataBlock& data )
{
MStatus status;
MFnData::Type dataType = MFnData::kInvalid;
if( plug == sWorldVector ||
plug == sWorldVectorX ||
plug == sWorldVectorY ||
plug == sWorldVectorZ ||
plug == sWorldVectorW)
{
MDataHandle dhIsDirection = data.inputValue(sIsDirection, &status);
if (!status)
{
status.perror("cgfxVector: isDirection handle");
return status;
}
dataType = dhIsDirection.type();
MDataHandle dhVector = data.inputValue(sVector, &status);
if (!status)
{
status.perror("cgfxVector: vector handle");
return status;
}
dataType = dhVector.type();
MMatrix matrix;
MPlug matrixPlug(thisMObject(), sMatrix);
if (matrixPlug.isNull())
{
OutputDebugString("matrixPlug is NULL!\n");
}
MObject oMatrix;
matrixPlug.getValue(oMatrix);
MFnMatrixData fndMatrix(oMatrix, &status);
if (!status)
{
status.perror("cgfxVector: matrix data");
}
matrix= fndMatrix.matrix(&status);
if (!status)
{
status.perror("cgfxVector: get matrix");
}
#if 0
MDataHandle dhMatrix = data.inputValue(sMatrix, &status);
if (!status)
{
status.perror("cgfxVector: matrix handle");
}
dataType = dhMatrix.type();
oMatrix = dhMatrix.data();
MFnMatrixData fnMatrix(oMatrix, &status);
if (!status)
{
status.perror("cgfxVector: matrix function set");
}
matrix = fnMatrix.matrix();
#endif
bool isDirection = dhIsDirection.asBool();
double3& vector = dhVector.asDouble3();
double mat[4][4];
matrix.get(mat);
double ix, iy, iz, iw;
float ox, oy, oz, ow;
ix = vector[0];
iy = vector[1];
iz = vector[2];
iw = isDirection ? 0.0 : 1.0;
ox = (float)(mat[0][0] * ix +
mat[1][0] * iy +
mat[2][0] * iz +
mat[3][0] * iw);
oy = (float)(mat[0][1] * ix +
mat[1][1] * iy +
mat[2][1] * iz +
mat[3][1] * iw);
oz = (float)(mat[0][2] * ix +
mat[1][2] * iy +
mat[2][2] * iz +
mat[3][2] * iw);
ow = (float)(mat[0][3] * ix +
mat[1][3] * iy +
mat[2][3] * iz +
mat[3][3] * iw);
MDataHandle dhWVector = data.outputValue(sWorldVector, &status);
if (!status)
{
status.perror("cgfxVector: worldVector handle");
return status;
}
MDataHandle dhWVectorW = data.outputValue(sWorldVectorW, &status);
if (!status)
{
status.perror("cgfxVector: worldVectorW handle");
return status;
}
dhWVector.set(ox, oy, oz);
dhWVectorW.set(ow);
data.setClean(sWorldVector);
data.setClean(sWorldVectorW);
}
else
{
return MS::kUnknownParameter;
}
return MS::kSuccess;
}
void* cgfxVector::creator()
{
return new cgfxVector;
}
MStatus cgfxVector::initialize()
{
MStatus status;
MFnNumericAttribute nAttr;
MFnMatrixAttribute mAttr;
sVectorX = nAttr.create("vectorX", "vx",
MFnNumericData::kDouble, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create vectorX");
return status;
}
nAttr.setKeyable(true);
sVectorY = nAttr.create("vectorY", "vy",
MFnNumericData::kDouble, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create vectorY");
return status;
}
nAttr.setKeyable(true);
sVectorZ = nAttr.create("vectorZ", "vz",
MFnNumericData::kDouble, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create vectorZ");
return status;
}
nAttr.setKeyable(true);
sVector = nAttr.create("vector", "v",
sVectorX, sVectorY, sVectorZ, &status);
if (!status)
{
status.perror("cgfxVector: create vector");
return status;
}
nAttr.setKeyable(true);
sIsDirection = nAttr.create("isDirection", "id",
MFnNumericData::kBoolean, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create isDirection");
return status;
}
nAttr.setKeyable(true);
nAttr.setDefault(false);
sMatrix = mAttr.create("matrix", "m",
MFnMatrixAttribute::kDouble, &status);
if (!status)
{
status.perror("cgfxVector: create matrix");
return status;
}
mAttr.setWritable(true);
mAttr.setStorable(true);
sWorldVectorX = nAttr.create("worldVectorX", "wvx",
MFnNumericData::kFloat, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create worldVectorX");
return status;
}
nAttr.setWritable(false);
nAttr.setStorable(false);
sWorldVectorY = nAttr.create("worldVectorY", "wvy",
MFnNumericData::kFloat, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create worldVectorY");
return status;
}
nAttr.setWritable(false);
nAttr.setStorable(false);
sWorldVectorZ = nAttr.create("worldVectorZ", "wvz",
MFnNumericData::kFloat, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create worldVectorZ");
return status;
}
nAttr.setWritable(false);
nAttr.setStorable(false);
sWorldVectorW = nAttr.create("worldVectorW", "wvw",
MFnNumericData::kFloat, 0.0, &status);
if (!status)
{
status.perror("cgfxVector: create worldVectorW");
return status;
}
nAttr.setWritable(false);
nAttr.setStorable(false);
sWorldVector = nAttr.create("worldVector", "wv",
sWorldVectorX, sWorldVectorY, sWorldVectorZ,
&status);
if( !status )
{
status.perror("cgfxVector: create worldVector");
return status;
}
nAttr.setWritable(false);
nAttr.setStorable(false);
status = addAttribute(sVector);
if (!status)
{
status.perror("cgfxVector: addAttribute vector");
return status;
}
status = addAttribute(sIsDirection);
if (!status)
{
status.perror("cgfxVector: addAttribute isDirection");
return status;
}
status = addAttribute(sMatrix);
if (!status)
{
status.perror("cgfxVector: addAttribute matrix");
return status;
}
status = addAttribute(sWorldVector);
if (!status)
{
status.perror("cgfxVector: addAttribute worldVector");
return status;
}
status = addAttribute(sWorldVectorW);
if (!status)
{
status.perror("cgfxVector: addAttribute worldVectorW");
return status;
}
status = attributeAffects(sVector, sWorldVector);
if (!status)
{
status.perror("cgfxVector: attributeAffects vector -> worldVector");
return status;
}
status = attributeAffects(sIsDirection, sWorldVector);
if (!status)
{
status.perror("cgfxVector: attributeAffects isDirection -> worldVector");
return status;
}
status = attributeAffects(sMatrix, sWorldVector);
if (!status)
{
status.perror("cgfxVector: attributeAffects matrix -> worldVector");
return status;
}
status = attributeAffects(sVector, sWorldVectorW);
if (!status)
{
status.perror("cgfxVector: attributeAffects vector -> worldVectorW");
return status;
}
status = attributeAffects(sIsDirection, sWorldVectorW);
if (!status)
{
status.perror("cgfxVector: attributeAffects isDirection -> worldVectorW");
return status;
}
status = attributeAffects(sMatrix, sWorldVectorW);
if (!status)
{
status.perror("cgfxVector: attributeAffects matrix -> worldVectorW");
return status;
}
return MS::kSuccess;
}