#include <math.h>
#include <dynExprField.h>
#include <maya/MIOStream.h>
#include <maya/MTime.h>
#include <maya/MFloatVector.h>
#include <maya/MVectorArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MString.h>
#include <maya/MMatrix.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnCompoundAttribute.h>
#include <maya/MFnUnitAttribute.h>
#include <maya/MFnVectorArrayData.h>
#include <maya/MFnDoubleArrayData.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnArrayAttrsData.h>
MObject dynExprField::mDirection;
MTypeId dynExprField::id( 0x00107340 );
void *dynExprField::creator()
{
return new dynExprField;
}
MStatus dynExprField::initialize()
{
MStatus status;
MFnNumericAttribute numAttr;
mDirection = numAttr.createPoint("direction","dir");
numAttr.setDefault( 0.0, 1.0, 0.0 );
numAttr.setKeyable(true);
numAttr.setStorable(true);
numAttr.setReadable(true);
numAttr.setWritable(true);
status = addAttribute( mDirection );
attributeAffects(mDirection, mOutputForce);
return( MS::kSuccess );
}
MStatus dynExprField::compute(const MPlug& plug, MDataBlock& block)
{
MStatus status;
if( !(plug == mOutputForce) )
return( MS::kUnknownParameter );
int multiIndex = plug.logicalIndex( &status );
McheckErr(status, "ERROR in plug.logicalIndex.\n");
MArrayDataHandle hInputArray = block.outputArrayValue( mInputData, &status );
McheckErr(status,"ERROR in hInputArray = block.outputArrayValue().\n");
status = hInputArray.jumpToElement( multiIndex );
McheckErr(status, "ERROR: hInputArray.jumpToElement failed.\n");
MDataHandle hCompond = hInputArray.inputValue( &status );
McheckErr(status, "ERROR in hCompond=hInputArray.inputValue\n");
MDataHandle hPosition = hCompond.child( mInputPositions );
MObject dPosition = hPosition.data();
MFnVectorArrayData fnPosition( dPosition );
MVectorArray points = fnPosition.array( &status );
McheckErr(status, "ERROR in fnPosition.array(), not find points.\n");
MArrayDataHandle mhInputPPData = block.inputArrayValue( mInputPPData, &status );
McheckErr(status,"ERROR in mhInputPPData = block.inputArrayValue().\n");
status = mhInputPPData.jumpToElement( multiIndex );
McheckErr(status, "ERROR: mhInputPPArray.jumpToElement failed.\n");
MDataHandle hInputPPData = mhInputPPData.inputValue( &status );
McheckErr(status, "ERROR in hInputPPData = mhInputPPData.inputValue\n");
MObject dInputPPData = hInputPPData.data();
MFnArrayAttrsData inputPPArray( dInputPPData );
MDataHandle hOwnerPPData = block.inputValue( mOwnerPPData, &status );
McheckErr(status, "ERROR in hOwnerPPData = block.inputValue\n");
MObject dOwnerPPData = hOwnerPPData.data();
MFnArrayAttrsData ownerPPArray( dOwnerPPData );
const MString magString("magnitude");
MFnArrayAttrsData::Type doubleType(MFnArrayAttrsData::kDoubleArray);
bool arrayExist;
MDoubleArray magnitudeArray;
arrayExist = inputPPArray.checkArrayExist(magString, doubleType, &status);
if(arrayExist) {
magnitudeArray = inputPPArray.getDoubleData(magString, &status);
}
MDoubleArray magnitudeOwnerArray;
arrayExist = ownerPPArray.checkArrayExist(magString, doubleType, &status);
if(arrayExist) {
magnitudeOwnerArray = ownerPPArray.getDoubleData(magString, &status);
}
const MString dirString("direction");
MFnArrayAttrsData::Type vectorType(MFnArrayAttrsData::kVectorArray);
arrayExist = inputPPArray.checkArrayExist(dirString, vectorType, &status);
MVectorArray directionArray;
if(arrayExist) {
directionArray = inputPPArray.getVectorData(dirString, &status);
}
arrayExist = ownerPPArray.checkArrayExist(dirString, vectorType, &status);
MVectorArray directionOwnerArray;
if(arrayExist) {
directionOwnerArray = ownerPPArray.getVectorData(dirString, &status);
}
MVectorArray forceArray;
apply( block, points.length(), magnitudeArray, magnitudeOwnerArray,
directionArray, directionOwnerArray, forceArray );
MArrayDataHandle hOutArray = block.outputArrayValue( mOutputForce, &status);
McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n");
MArrayDataBuilder bOutArray = hOutArray.builder( &status );
McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n");
MDataHandle hOut = bOutArray.addElement(multiIndex, &status);
McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n");
MFnVectorArrayData fnOutputForce;
MObject dOutputForce = fnOutputForce.create( forceArray, &status );
McheckErr(status, "ERROR in dOutputForce = fnOutputForce.create\n");
hOut.set( dOutputForce );
block.setClean( plug );
return( MS::kSuccess );
}
MStatus dynExprField::iconSizeAndOrigin(GLuint& width,
GLuint& height,
GLuint& xbo,
GLuint& ybo )
{
width = 32;
height = 32;
xbo = 4;
ybo = 4;
return MS::kSuccess;
}
MStatus dynExprField::iconBitmap(GLubyte* bitmap)
{
bitmap[0] = 0x18;
bitmap[4] = 0x18;
bitmap[8] = 0x18;
bitmap[12] = 0x18;
bitmap[16] = 0x18;
bitmap[20] = 0x5A;
bitmap[24] = 0x3C;
bitmap[28] = 0x18;
return MS::kSuccess;
}
MStatus initializePlugin(MObject obj)
{
MStatus status;
MFnPlugin plugin(obj, PLUGIN_COMPANY, "6.0", "Any");
status = plugin.registerNode( "dynExprField",
dynExprField::id,
&dynExprField::creator,
&dynExprField::initialize,
MPxNode::kFieldNode );
if (!status) {
status.perror("registerNode");
return status;
}
return status;
}
MStatus uninitializePlugin(MObject obj)
{
MStatus status;
MFnPlugin plugin(obj);
status = plugin.deregisterNode( dynExprField::id );
if (!status) {
status.perror("deregisterNode");
return status;
}
return status;
}
double dynExprField::magnitude( MDataBlock& block )
{
MStatus status;
MDataHandle hValue = block.inputValue( mMagnitude, &status );
double value = 0.0;
if( status == MS::kSuccess )
value = hValue.asDouble();
return( value );
}
MVector dynExprField::direction( MDataBlock& block )
{
MFloatVector &fV = block.inputValue(mDirection).asFloatVector();
return( MVector(fV.x, fV.y, fV.z) );
}
void dynExprField::apply(
MDataBlock &block,
int receptorSize,
const MDoubleArray &magnitudeArray,
const MDoubleArray &magnitudeOwnerArray,
const MVectorArray &directionArray,
const MVectorArray &directionOwnerArray,
MVectorArray &outputForce
)
{
MVector defaultDir = direction(block);
double defaultMag = magnitude(block);
int magArraySize = magnitudeArray.length();
int dirArraySize = directionArray.length();
int magOwnerArraySize = magnitudeOwnerArray.length();
int dirOwnerArraySize = directionOwnerArray.length();
int numOfOwner = magOwnerArraySize;
if( dirOwnerArraySize > numOfOwner )
numOfOwner = dirOwnerArraySize;
double magnitude = defaultMag;
MVector direction = defaultDir;
for (int ptIndex = 0; ptIndex < receptorSize; ptIndex ++ ) {
if(receptorSize == magArraySize)
magnitude = magnitudeArray[ptIndex];
if(receptorSize == dirArraySize)
direction = directionArray[ptIndex];
if( numOfOwner > 0) {
for( int nthOwner = 0; nthOwner < numOfOwner; nthOwner++ ) {
if(magOwnerArraySize == numOfOwner)
magnitude = magnitudeOwnerArray[nthOwner];
if(dirOwnerArraySize == numOfOwner)
direction = directionOwnerArray[nthOwner];
outputForce.append( direction * magnitude );
}
} else {
outputForce.append( direction * magnitude );
}
}
}