#include <maya/MFnPlugin.h>
#include <maya/MPxNode.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFloatVector.h>
#define PERRORfail(stat,msg) \
if (!(stat)) { stat.perror((msg)); return (stat); }
class shiftNode;
class shiftNode : public MPxNode
{
public:
shiftNode();
virtual ~shiftNode();
virtual MStatus compute( const MPlug&, MDataBlock& );
static void * creator();
static MStatus initialize();
static MTypeId id;
private:
float ox, oy, oz;
int initID, doneID;
static bool firstTime;
static MObject aShift;
static MObject aDist;
static MObject aColor;
static MObject aRefPointCamera;
static MObject aUv;
static MObject aOutColor;
};
MTypeId shiftNode::id( 0x8001a );
MObject shiftNode::aShift;
MObject shiftNode::aDist;
MObject shiftNode::aColor;
MObject shiftNode::aRefPointCamera;
MObject shiftNode::aUv;
MObject shiftNode::aOutColor;
shiftNode::shiftNode()
{
}
shiftNode::~shiftNode()
{
}
void * shiftNode::creator()
{
return new shiftNode();
}
MStatus shiftNode::initialize()
{
MStatus stat;
MFnNumericAttribute nAttr;
aShift = nAttr.create( "shift", "sh",
MFnNumericData::kBoolean, false );
stat = addAttribute( aShift );
PERRORfail( stat, "addAttribute shift" );
aDist = nAttr.create( "distance", "dis",
MFnNumericData::kFloat, 0.0 );
stat = addAttribute( aDist );
PERRORfail( stat, "addAttribute dist" );
aColor = nAttr.createColor( "color", "c" );
nAttr.setStorable(false);
stat = addAttribute( aColor );
PERRORfail( stat, "addAttribute inColor" );
aRefPointCamera = nAttr.createPoint( "refPointCamera", "rpc" );
nAttr.setStorable(false);
nAttr.setWritable(true);
nAttr.setRenderSource(true);
nAttr.setHidden(true);
stat = addAttribute( aRefPointCamera );
PERRORfail( stat, "addAttribute refPointCamera" );
MObject u = nAttr.create( "uCoord", "u", MFnNumericData::kFloat, 0.0 );
MObject v = nAttr.create( "vCoord", "v", MFnNumericData::kFloat, 0.0 );
aUv = nAttr.create( "uvCoord", "uv", u, v );
nAttr.setStorable(false);
nAttr.setWritable(true);
nAttr.setRenderSource(true);
nAttr.setHidden(true);
stat = addAttribute( aUv );
PERRORfail( stat, "addAttribute uv" );
aOutColor = nAttr.createColor( "outColor", "oc" );
PERRORfail(stat, "initialize create outColor attribute");
nAttr.setReadable( true );
nAttr.setWritable( false );
stat = addAttribute( aOutColor );
PERRORfail(stat, "addAttribute(outColor)");
attributeAffects ( aShift, aOutColor );
attributeAffects ( aDist, aOutColor );
attributeAffects ( aColor, aOutColor );
attributeAffects ( aRefPointCamera, aOutColor );
attributeAffects ( aUv, aOutColor );
attributeAffects ( aUv, aUv );
attributeAffects ( aRefPointCamera, aRefPointCamera );
return MS::kSuccess;
}
MStatus shiftNode::compute( const MPlug& plug, MDataBlock& data )
{
MStatus stat;
if ((plug != aOutColor) && (plug.parent() != aOutColor))
return MS::kUnknownParameter;
MDataHandle colorH;
MFloatVector color;
MDataHandle shiftH = data.inputValue( aShift, &stat);
PERRORfail(stat, "compute getting shift attr");
bool shiftIt = shiftH.asBool();
MDataHandle distH = data.inputValue( aDist, &stat);
PERRORfail(stat, "compute getting distance attr");
float distance = distH.asFloat();
MFloatVector clr;
if ( shiftIt && distance != 0.0 )
{
clr = data.inputValue( aColor ).asFloatVector();
MDataHandle refPointCamH = data.inputValue( aRefPointCamera, &stat);
PERRORfail(stat, "compute getting refPointCamera attr");
MFloatVector refPC = refPointCamH.asFloatVector();
const float2 & oldUV = data.inputValue(aUv).asFloat2();
MDataHandle outUV = data.outputValue( aUv );
MDataHandle outPC = data.outputValue( aRefPointCamera );
outUV.set( oldUV[0]-distance, oldUV[1] );
outPC.set( refPC.x + distance, refPC.y + distance, refPC.z + distance);
colorH = data.inputValue( aColor, &stat);
color = colorH.asFloatVector();
clr += color;
outUV.set( oldUV[0]+distance, oldUV[1] );
outPC.set( refPC.x - distance, refPC.y + distance, refPC.z + distance);
colorH = data.inputValue( aColor, &stat);
color = colorH.asFloatVector();
clr += color;
outUV.set( oldUV[0], oldUV[1]-distance );
outPC.set( refPC.x + distance, refPC.y - distance, refPC.z + distance);
colorH = data.inputValue( aColor, &stat);
color = colorH.asFloatVector();
clr += color;
outUV.set( oldUV[0], oldUV[1]+distance );
outPC.set( refPC.x - distance, refPC.y - distance, refPC.z + distance);
colorH = data.inputValue( aColor, &stat);
color = colorH.asFloatVector();
clr += color;
clr /= 5.0;
outUV.set( oldUV[0], oldUV[1] );
outPC.set( refPC.x, refPC.y, refPC.z );
}
else
{
colorH = data.inputValue( aColor, &stat);
clr = colorH.asFloatVector();
}
MDataHandle outColorHandle = data.outputValue( aOutColor );
MFloatVector& oclr = outColorHandle.asFloatVector();
oclr = clr;
outColorHandle.setClean();
return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
const MString UserClassify( "utility/general" );
MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5", "Any");
plugin.registerNode( "shiftNode", shiftNode::id,
shiftNode::creator, shiftNode::initialize,
MPxNode::kDependNode, &UserClassify );
return MS::kSuccess;
}
MStatus uninitializePlugin( MObject obj )
{
MFnPlugin plugin( obj );
plugin.deregisterNode( shiftNode::id );
return MS::kSuccess;
}