#include <maya/MIOStream.h>
#include <math.h>
#include <stdlib.h>
#include "ownerEmitter.h"
#include <maya/MVectorArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MIntArray.h>
#include <maya/MMatrix.h>
#include <maya/MArrayDataBuilder.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnUnitAttribute.h>
#include <maya/MFnVectorArrayData.h>
#include <maya/MFnDoubleArrayData.h>
#include <maya/MFnArrayAttrsData.h>
#include <maya/MFnMatrixData.h>
MTypeId ownerEmitter::id( 0x80015 );
ownerEmitter::ownerEmitter()
: lastWorldPoint(0, 0, 0, 1)
{
}
ownerEmitter::~ownerEmitter()
{
}
void *ownerEmitter::creator()
{
return new ownerEmitter;
}
{
return( MS::kSuccess );
}
{
if( !(plug == mOutput) )
return( MS::kUnknownParameter );
McheckErr(status, "ERROR in plug.logicalIndex.\n");
McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n");
McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n");
McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n");
McheckErr(status, "ERROR in fnOutput.create.\n");
bool beenFull = isFullValue( multiIndex, block );
if( beenFull )
{
return( MS::kSuccess );
}
ownerPosition( block, inPosAry );
ownerVelocity( multiIndex, block, inVelAry );
unsigned inPosLength = inPosAry.
length();
if( (inPosLength == 0) || (inPosLength != inVelAry.
length()) )
{
return( MS::kFailure );
}
MTime cT = currentTimeValue( block );
MTime sT = startTimeValue( multiIndex, block );
MTime dT = deltaTimeValue( multiIndex, block );
if( (cT <= sT) || (dT <= 0.0) )
{
return( MS::kSuccess );
}
status = emitCountPerPoint( plug, block, inPosLength, emitCountPP );
double speed = speedValue( block );
MVector dirV = directionVector( block );
double inheritFactor = inheritFactorValue( multiIndex, block );
MVector rotatedV = useRotation ( dirV );
emit( inPosAry, inVelAry, emitCountPP,
dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel );
return( MS::kSuccess );
}
void ownerEmitter::emit
(
double dt,
double speed,
double inheritFactor,
)
{
int posLength = inPosAry.
length();
int velLength = inVelAry.
length();
int countLength = emitCountPP.
length();
if( (posLength != velLength) || (posLength != countLength) )
return;
int index;
int totalCount = 0;
for( index = 0; index < countLength; index ++ )
totalCount += emitCountPP[index];
if( totalCount <= 0 )
return;
int emitCount;
for( index = 0; index < posLength; index++ )
{
emitCount = emitCountPP[index];
if( emitCount <= 0 )
continue;
sPos = inPosAry[index];
sVel = inVelAry[index];
prePos = sPos - sVel * dt;
for( int i = 0; i < emitCount; i++ )
{
double alpha = ( (double)i + drand48() ) / (double)emitCount;
newPos = (1 - alpha) * prePos + alpha * sPos;
newVel = dirV * speed;
newPos += newVel * ( dt * (1 - alpha) );
newVel += sVel * inheritFactor;
}
}
}
void ownerEmitter::ownerPosition
(
)
{
bool hasOwner = false;
if( status == MS::kSuccess )
{
if( status == MS::kSuccess )
{
for(
unsigned int i = 0; i < posArray.
length(); i ++ )
ownerPosArray.
append( posArray[i] );
hasOwner = true;
}
}
if( !hasOwner )
{
MPoint worldPos(0.0, 0.0, 0.0);
status = getWorldPosition( worldPos );
worldV[0] = worldPos[0];
worldV[1] = worldPos[1];
worldV[2] = worldPos[2];
ownerPosArray.
append( worldV );
}
}
void ownerEmitter::ownerVelocity
(
int plugIndex,
)
{
bool hasOwner = false;
if( status == MS::kSuccess )
{
if( status == MS::kSuccess )
{
for(
unsigned int i = 0; i < velArray.
length(); i ++ )
ownerVelArray.
append( velArray[i] );
hasOwner = true;
}
}
if( !hasOwner )
{
MPoint worldPos(0.0, 0.0, 0.0);
status = getWorldPosition( worldPos );
MTime dT = deltaTimeValue( plugIndex, block );
if( dt > 0.0 )
velV = (worldPos - lastWorldPoint) / dt;
lastWorldPoint = worldPos;
}
}
{
MObject worldMatrixAttr = fnThisNode.attribute(
"worldMatrix" );
MPlug matrixPlug( thisNode, worldMatrixAttr );
matrixPlug = matrixPlug.elementByLogicalIndex( 0 );
status = matrixPlug.getValue( matrixObject );
if( !status )
{
status.
perror(
"ownerEmitter::getWorldPosition: get matrixObject");
return( status );
}
if( !status )
{
status.
perror(
"ownerEmitter::getWorldPosition: get worldMatrixData");
return( status );
}
if( !status )
{
status.
perror(
"ownerEmitter::getWorldPosition: get worldMatrix");
return( status );
}
point[0] = worldMatrix( 3, 0 );
point[1] = worldMatrix( 3, 1 );
point[2] = worldMatrix( 3, 2 );
return( status );
}
{
MObject worldMatrixAttr = fnThisNode.attribute(
"worldMatrix" );
MPlug matrixPlug( thisNode, worldMatrixAttr );
matrixPlug = matrixPlug.elementByLogicalIndex( 0 );
McheckErr(status, "ERROR getting hWMatrix from dataBlock.\n");
if( status == MS::kSuccess )
{
point[0] = wMatrix(3, 0);
point[1] = wMatrix(3, 1);
point[2] = wMatrix(3, 2);
}
return( status );
}
{
MObject worldMatrixAttr = fnThisNode.attribute(
"worldMatrix" );
MPlug matrixPlug( thisNode, worldMatrixAttr );
matrixPlug = matrixPlug.elementByLogicalIndex( 0 );
status = matrixPlug.getValue( matrixObject );
if( !status )
{
status.
perror(
"ownerEmitter::getWorldPosition: get matrixObject");
return ( direction );
}
if( !status )
{
status.
perror(
"ownerEmitter::getWorldPosition: get worldMatrixData");
return( direction );
}
if( !status )
{
status.
perror(
"ownerEmitter::getWorldPosition: get worldMatrix");
return( direction );
}
rotatedVector = direction * worldMatrix;
return( rotatedVector );
}
MStatus ownerEmitter::emitCountPerPoint
(
int length,
)
{
McheckErr(status, "ERROR in emitCountPerPoint: when plug.logicalIndex.\n");
double rate = rateValue( block );
MTime dt = deltaTimeValue( plugIndex, block );
int intCount = (int)dblCount;
for( int i = 0; i < length; i++ )
{
emitCountPP.
append( intCount );
}
return( MS::kSuccess );
}
{
MFnPlugin plugin(obj, PLUGIN_COMPANY,
"3.0",
"Any");
status = plugin.registerNode( "ownerEmitter", ownerEmitter::id,
&ownerEmitter::creator, &ownerEmitter::initialize,
if (!status) {
status.
perror(
"registerNode");
return status;
}
return status;
}
{
status = plugin.deregisterNode( ownerEmitter::id );
if (!status) {
status.
perror(
"deregisterNode");
return status;
}
return status;
}