#include <maya/MPxLocatorNode.h>
#include <maya/MString.h>
#include <maya/MDagPath.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MVector.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MColor.h>
#include <maya/M3dView.h>
#include <maya/MFnPlugin.h>
#include <maya/MDistance.h>
#include <maya/MFloatMatrix.h>
#include <maya/MFnUnitAttribute.h>
#include <maya/MDrawRegistry.h>
#include <maya/MPxDrawOverride.h>
#include <maya/MUserData.h>
#include <maya/MDrawContext.h>
#include <maya/MGlobal.h>
#include <maya/MSelectionList.h>
static float sole[][3] = { { 0.00f, 0.0f, -0.70f },
{ 0.04f, 0.0f, -0.69f },
{ 0.09f, 0.0f, -0.65f },
{ 0.13f, 0.0f, -0.61f },
{ 0.16f, 0.0f, -0.54f },
{ 0.17f, 0.0f, -0.46f },
{ 0.17f, 0.0f, -0.35f },
{ 0.16f, 0.0f, -0.25f },
{ 0.15f, 0.0f, -0.14f },
{ 0.13f, 0.0f, 0.00f },
{ 0.00f, 0.0f, 0.00f },
{ -0.13f, 0.0f, 0.00f },
{ -0.15f, 0.0f, -0.14f },
{ -0.16f, 0.0f, -0.25f },
{ -0.17f, 0.0f, -0.35f },
{ -0.17f, 0.0f, -0.46f },
{ -0.16f, 0.0f, -0.54f },
{ -0.13f, 0.0f, -0.61f },
{ -0.09f, 0.0f, -0.65f },
{ -0.04f, 0.0f, -0.69f },
{ -0.00f, 0.0f, -0.70f } };
static float heel[][3] = { { 0.00f, 0.0f, 0.06f },
{ 0.13f, 0.0f, 0.06f },
{ 0.14f, 0.0f, 0.15f },
{ 0.14f, 0.0f, 0.21f },
{ 0.13f, 0.0f, 0.25f },
{ 0.11f, 0.0f, 0.28f },
{ 0.09f, 0.0f, 0.29f },
{ 0.04f, 0.0f, 0.30f },
{ 0.00f, 0.0f, 0.30f },
{ -0.04f, 0.0f, 0.30f },
{ -0.09f, 0.0f, 0.29f },
{ -0.11f, 0.0f, 0.28f },
{ -0.13f, 0.0f, 0.25f },
{ -0.14f, 0.0f, 0.21f },
{ -0.14f, 0.0f, 0.15f },
{ -0.13f, 0.0f, 0.06f },
{ -0.00f, 0.0f, 0.06f } };
static int heelCount = 17;
static int soleCount = 21;
class footPrint : public MPxLocatorNode
{
public:
footPrint();
virtual ~footPrint();
virtual MStatus compute( const MPlug& plug, MDataBlock& data );
virtual void draw( M3dView & view, const MDagPath & path,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status );
virtual bool isBounded() const;
virtual MBoundingBox boundingBox() const;
static void * creator();
static MStatus initialize();
static MObject size;
public:
static MTypeId id;
static MString drawDbClassification;
static MString drawRegistrantId;
};
MObject footPrint::size;
MTypeId footPrint::id( 0x80007 );
MString footPrint::drawDbClassification("drawdb/geometry/footPrint");
MString footPrint::drawRegistrantId("FootprintNodePlugin");
footPrint::footPrint() {}
footPrint::~footPrint() {}
MStatus footPrint::compute( const MPlug& , MDataBlock& )
{
return MS::kUnknownParameter;
}
void footPrint::draw( M3dView & view, const MDagPath & ,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status )
{
MObject thisNode = thisMObject();
MPlug plug( thisNode, size );
MDistance sizeVal;
plug.getValue( sizeVal );
float multiplier = (float) sizeVal.asCentimeters();
view.beginGL();
if ( ( style == M3dView::kFlatShaded ) ||
( style == M3dView::kGouraudShaded ) )
{
glPushAttrib( GL_CURRENT_BIT );
if ( status == M3dView::kActive ) {
view.setDrawColor( 13, M3dView::kActiveColors );
} else {
view.setDrawColor( 13, M3dView::kDormantColors );
}
glBegin( GL_TRIANGLE_FAN );
int i;
int last = soleCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( sole[i][0] * multiplier,
sole[i][1] * multiplier,
sole[i][2] * multiplier );
}
glEnd();
glBegin( GL_TRIANGLE_FAN );
last = heelCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( heel[i][0] * multiplier,
heel[i][1] * multiplier,
heel[i][2] * multiplier );
}
glEnd();
glPopAttrib();
}
glBegin( GL_LINES );
int i;
int last = soleCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( sole[i][0] * multiplier,
sole[i][1] * multiplier,
sole[i][2] * multiplier );
glVertex3f( sole[i+1][0] * multiplier,
sole[i+1][1] * multiplier,
sole[i+1][2] * multiplier );
}
last = heelCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( heel[i][0] * multiplier,
heel[i][1] * multiplier,
heel[i][2] * multiplier );
glVertex3f( heel[i+1][0] * multiplier,
heel[i+1][1] * multiplier,
heel[i+1][2] * multiplier );
}
glEnd();
view.endGL();
}
bool footPrint::isBounded() const
{
return true;
}
MBoundingBox footPrint::boundingBox() const
{
MObject thisNode = thisMObject();
MPlug plug( thisNode, size );
MDistance sizeVal;
plug.getValue( sizeVal );
double multiplier = sizeVal.asCentimeters();
MPoint corner1( -0.17, 0.0, -0.7 );
MPoint corner2( 0.17, 0.0, 0.3 );
corner1 = corner1 * multiplier;
corner2 = corner2 * multiplier;
return MBoundingBox( corner1, corner2 );
}
void* footPrint::creator()
{
return new footPrint();
}
class FootPrintData : public MUserData
{
public:
FootPrintData() : MUserData(false) {}
virtual ~FootPrintData() {}
float fMultiplier;
bool fIsSelected;
};
class FootPrintDrawOverride : public MHWRender::MPxDrawOverride
{
public:
static MHWRender::MPxDrawOverride* Creator(const MObject& obj)
{
return new FootPrintDrawOverride(obj);
}
virtual ~FootPrintDrawOverride();
virtual MBoundingBox boundingBox(
const MDagPath& objPath,
const MDagPath& cameraPath) const;
virtual MUserData* prepareForDraw(
const MDagPath& objPath,
const MDagPath& cameraPath,
MUserData* oldData);
static void draw(const MHWRender::MDrawContext& context, const MUserData* data);
private:
FootPrintDrawOverride(const MObject& obj);
float getMultiplier(const MDagPath& objPath) const;
bool getSelectionStatus(const MDagPath& objPath) const;
};
FootPrintDrawOverride::FootPrintDrawOverride(const MObject& obj)
: MHWRender::MPxDrawOverride(obj, FootPrintDrawOverride::draw)
{
}
FootPrintDrawOverride::~FootPrintDrawOverride()
{
}
float FootPrintDrawOverride::getMultiplier(const MDagPath& objPath) const
{
MStatus status;
MObject footprintNode = objPath.node(&status);
if (status)
{
MPlug plug(footprintNode, footPrint::size);
if (!plug.isNull())
{
MDistance sizeVal;
if (plug.getValue(sizeVal))
{
return (float)sizeVal.asCentimeters();
}
}
}
return 1.0f;
}
bool FootPrintDrawOverride::getSelectionStatus(const MDagPath& objPath) const
{
MStatus status;
MSelectionList selectedList;
status = MGlobal::getActiveSelectionList(selectedList);
if(!status)
return false;
MDagPath pathCopy = objPath;
do
{
if(selectedList.hasItem(pathCopy))
return true;
status = pathCopy.pop();
}while(status);
return false;
}
MBoundingBox FootPrintDrawOverride::boundingBox(
const MDagPath& objPath,
const MDagPath& cameraPath) const
{
MPoint corner1( -0.17, 0.0, -0.7 );
MPoint corner2( 0.17, 0.0, 0.3 );
float multiplier = getMultiplier(objPath);
corner1 = corner1 * multiplier;
corner2 = corner2 * multiplier;
return MBoundingBox(corner1, corner2);
}
MUserData* FootPrintDrawOverride::prepareForDraw(
const MDagPath& objPath,
const MDagPath& cameraPath,
MUserData* oldData)
{
FootPrintData* data = dynamic_cast<FootPrintData*>(oldData);
if (!data)
{
data = new FootPrintData();
}
data->fMultiplier = getMultiplier(objPath);
data->fIsSelected = getSelectionStatus(objPath);
return data;
}
void FootPrintDrawOverride::draw(const MHWRender::MDrawContext& context, const MUserData* data)
{
float multiplier = 1.0f;
bool isSelected = false;
const FootPrintData* footData = dynamic_cast<const FootPrintData*>(data);
if (footData)
{
multiplier = footData->fMultiplier;
isSelected = footData->fIsSelected;
}
static const float colorData[] = {1.0f, 0.0f, 0.0f};
static const float selectedColorData[] = {0.0f, 1.0f, 0.0f};
if(isSelected)
glColor3fv(selectedColorData);
else
glColor3fv(colorData);
MStatus status;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
MFloatMatrix transform =
context.getMatrix(MHWRender::MDrawContext::kWorldViewMtx, &status);
if (status)
{
glLoadMatrixf(transform.matrix[0]);
}
glMatrixMode(GL_PROJECTION);
glPushMatrix();
MFloatMatrix projection =
context.getMatrix(MHWRender::MDrawContext::kProjectionMtx, &status);
if (status)
{
glLoadMatrixf(projection.matrix[0]);
}
const int displayStyle = context.getDisplayStyle();
if(displayStyle & MHWRender::MDrawContext::kGouraudShaded)
{
glPushAttrib( GL_CURRENT_BIT );
glBegin( GL_TRIANGLE_FAN );
int i;
int last = soleCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( sole[i][0] * multiplier,
sole[i][1] * multiplier,
sole[i][2] * multiplier );
}
glEnd();
glBegin( GL_TRIANGLE_FAN );
last = heelCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( heel[i][0] * multiplier,
heel[i][1] * multiplier,
heel[i][2] * multiplier );
}
glEnd();
glPopAttrib();
}
if(displayStyle & MHWRender::MDrawContext::kWireFrame)
{
glBegin( GL_LINES );
int i;
int last = soleCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( sole[i][0] * multiplier,
sole[i][1] * multiplier,
sole[i][2] * multiplier );
glVertex3f( sole[i+1][0] * multiplier,
sole[i+1][1] * multiplier,
sole[i+1][2] * multiplier );
}
last = heelCount - 1;
for ( i = 0; i < last; ++i ) {
glVertex3f( heel[i][0] * multiplier,
heel[i][1] * multiplier,
heel[i][2] * multiplier );
glVertex3f( heel[i+1][0] * multiplier,
heel[i+1][1] * multiplier,
heel[i+1][2] * multiplier );
}
glEnd();
}
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
MStatus footPrint::initialize()
{
MFnUnitAttribute unitFn;
MStatus stat;
size = unitFn.create( "size", "sz", MFnUnitAttribute::kDistance );
unitFn.setDefault( 1.0 );
stat = addAttribute( size );
if (!stat) {
stat.perror("addAttribute");
return stat;
}
return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
status = plugin.registerNode(
"footPrint",
footPrint::id,
&footPrint::creator,
&footPrint::initialize,
MPxNode::kLocatorNode,
&footPrint::drawDbClassification);
if (!status) {
status.perror("registerNode");
return status;
}
status = MHWRender::MDrawRegistry::registerDrawOverrideCreator(
footPrint::drawDbClassification,
footPrint::drawRegistrantId,
FootPrintDrawOverride::Creator);
if (!status) {
status.perror("registerDrawOverrideCreator");
return status;
}
return status;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status;
MFnPlugin plugin( obj );
status = MHWRender::MDrawRegistry::deregisterDrawOverrideCreator(
footPrint::drawDbClassification,
footPrint::drawRegistrantId);
if (!status) {
status.perror("deregisterDrawOverrideCreator");
return status;
}
status = plugin.deregisterNode( footPrint::id );
if (!status) {
status.perror("deregisterNode");
return status;
}
return status;
}