torusField.h
#include <maya/MIOStream.h>
#include <maya/MVector.h>
#include <maya/MObject.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MFnPlugin.h>
#include <maya/MPxFieldNode.h>
#if defined(OSMac_MachO_)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#define McheckErr(stat, msg)            \
        if ( MS::kSuccess != stat )             \
        {                                                               \
                cerr << msg;                            \
                return MS::kFailure;            \
        }
class torusField: public MPxFieldNode
{
public:
        torusField() {};
        virtual ~torusField() {};
        static void             *creator();
        static MStatus  initialize();
        
        
        virtual MStatus compute( const MPlug& plug, MDataBlock& block );
        virtual void    draw (  M3dView  & view, const  MDagPath  & path,  M3dView::DisplayStyle  style, M3dView:: DisplayStatus );
    virtual MStatus getForceAtPoint(const MVectorArray& point,
                            const MVectorArray& velocity,
                            const MDoubleArray& mass,
                            MVectorArray& force,
                            double deltaTime);
        virtual MStatus iconSizeAndOrigin(      GLuint& width,
                                                GLuint& height,
                                                GLuint& xbo,
                                                GLuint& ybo   );
        virtual MStatus iconBitmap(GLubyte* bitmap);
        
        
        
        
        
        static MObject  aMinDistance;
        
        
        static MObject  aAttractDistance;
        
        
        static MObject  aRepelDistance;
        
        
        static MObject  aDrag;
        
        
        static MObject  aSwarmAmplitude;
        
        
        static MObject  aSwarmFrequency;
        
        
        static MObject  aSwarmPhase;
        
        
        static MTypeId  id;
private:
        
        
        void    applyNoMaxDist( MDataBlock& block,
                                                        const MVectorArray &points,
                                                        const MVectorArray &velocities,
                                                        const MDoubleArray &masses,
                                                        MVectorArray &outputForce );
        void    applyMaxDist( MDataBlock& block,
                                                        const MVectorArray &points,
                                                        const MVectorArray &velocities,
                                                        const MDoubleArray &masses,
                                                        MVectorArray &outputForce );
        void    ownerPosition( MDataBlock& block, MVectorArray &vArray );
        MStatus getWorldPosition( MVector &vector );
        MStatus getWorldPosition( MDataBlock& block, MVector &vector );
        void    noiseFunction( double *inputNoise, double *out );
        
        
        double  magnitudeValue( MDataBlock& block );
        double  attenuationValue( MDataBlock& block );
        double  maxDistanceValue( MDataBlock& block );
        bool    useMaxDistanceValue( MDataBlock& block );
        bool    applyPerVertexValue( MDataBlock& block );
        
        
        double  minDistanceValue( MDataBlock& block );
        double  attractDistanceValue( MDataBlock& block );
        double  repelDistanceValue( MDataBlock& block );
        double  dragValue( MDataBlock& block );
        double  swarmAmplitudeValue( MDataBlock& block );
        double  swarmFrequencyValue( MDataBlock& block );
        double  swarmPhaseValue( MDataBlock& block );
        MStatus ownerCentroidValue( MDataBlock& block, MVector &vector );
};
inline double torusField::magnitudeValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( mMagnitude, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::attenuationValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( mAttenuation, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::maxDistanceValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( mMaxDistance, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline bool torusField::useMaxDistanceValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( mUseMaxDistance, &status );
        bool value = false;
        if( status == MS::kSuccess )
                value = hValue.asBool();
        return( value );
}
inline bool torusField::applyPerVertexValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( mApplyPerVertex, &status );
        bool value = false;
        if( status == MS::kSuccess )
                value = hValue.asBool();
        return( value );
}
inline double torusField::minDistanceValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( aMinDistance, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::attractDistanceValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( aAttractDistance, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::repelDistanceValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( aRepelDistance, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::dragValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( aDrag, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::swarmAmplitudeValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( aSwarmAmplitude, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::swarmFrequencyValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( aSwarmFrequency, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline double torusField::swarmPhaseValue( MDataBlock& block )
{
        MStatus status;
        MDataHandle hValue = block.inputValue( aSwarmPhase, &status );
        double value = 0.0;
        if( status == MS::kSuccess )
                value = hValue.asDouble();
        return( value );
}
inline MStatus torusField::ownerCentroidValue(MDataBlock& block,MVector &vector)
{
        MStatus status;
        MDataHandle hValueX = block.inputValue( mOwnerCentroidX, &status );
        MDataHandle hValueY = block.inputValue( mOwnerCentroidY, &status );
        MDataHandle hValueZ = block.inputValue( mOwnerCentroidZ, &status );
        if( status == MS::kSuccess )
        {
                vector[0] = hValueX.asDouble();
                vector[1] = hValueY.asDouble();
                vector[2] = hValueZ.asDouble();
        }
        return( status );
}