#include <maya/MIOStream.h>
#include <maya/MPxNode.h>
#include <maya/MPxLocatorNode.h>
#include <maya/MString.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/MFnUnitAttribute.h>
#include <maya/MFn.h>
#include <maya/MPxNode.h>
#include <maya/MPxManipContainer.h>
#include <maya/MFnDistanceManip.h>
#include <maya/MPxContext.h>
#include <maya/MPxSelectionContext.h>
#include <maya/MFnNumericData.h>
#include <maya/MManipData.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 footPrintLocatorManip : public MPxManipContainer
{
public:
footPrintLocatorManip();
virtual ~footPrintLocatorManip();
static void * creator();
static MStatus initialize();
virtual MStatus createChildren();
virtual MStatus connectToDependNode(const MObject & node);
virtual void draw(M3dView & view,
const MDagPath & path,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status);
MManipData startPointCallback(unsigned index) const;
MVector nodeTranslation() const;
MDagPath fDistanceManip;
MDagPath fNodePath;
public:
static MTypeId id;
};
MManipData footPrintLocatorManip::startPointCallback(unsigned index)
const
{
MFnNumericData numData;
MObject numDataObj = numData.create(MFnNumericData::k3Double);
MVector vec = nodeTranslation();
numData.setData(vec.x, vec.y, vec.z);
return MManipData(numDataObj);
}
MVector footPrintLocatorManip::nodeTranslation() const
{
MFnDagNode dagFn(fNodePath);
MDagPath path;
dagFn.getPath(path);
path.pop();
MFnTransform transformFn(path);
return transformFn.translation(MSpace::kWorld);
}
MTypeId footPrintLocatorManip::id( 0x8001b );
footPrintLocatorManip::footPrintLocatorManip()
{
}
footPrintLocatorManip::~footPrintLocatorManip()
{
}
void* footPrintLocatorManip::creator()
{
return new footPrintLocatorManip();
}
MStatus footPrintLocatorManip::initialize()
{
MStatus stat;
stat = MPxManipContainer::initialize();
return stat;
}
MStatus footPrintLocatorManip::createChildren()
{
MStatus stat = MStatus::kSuccess;
MString manipName("distanceManip");
MString distanceName("distance");
MPoint startPoint(0.0, 0.0, 0.0);
MVector direction(0.0, 1.0, 0.0);
fDistanceManip = addDistanceManip(manipName,
distanceName);
MFnDistanceManip distanceManipFn(fDistanceManip);
distanceManipFn.setStartPoint(startPoint);
distanceManipFn.setDirection(direction);
return stat;
}
MStatus footPrintLocatorManip::connectToDependNode(const MObject &node)
{
MStatus stat;
MFnDagNode dagNodeFn(node);
dagNodeFn.getPath(fNodePath);
MFnDistanceManip distanceManipFn(fDistanceManip);
MFnDependencyNode nodeFn(node);
MPlug sizePlug = nodeFn.findPlug("size", &stat);
if (MStatus::kFailure != stat) {
distanceManipFn.connectToDistancePlug(sizePlug);
unsigned startPointIndex = distanceManipFn.startPointIndex();
addPlugToManipConversionCallback(startPointIndex,
(plugToManipConversionCallback)
&footPrintLocatorManip::startPointCallback);
finishAddingManips();
MPxManipContainer::connectToDependNode(node);
}
return stat;
}
void footPrintLocatorManip::draw(M3dView & view,
const MDagPath &path,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status)
{
MPxManipContainer::draw(view, path, style, status);
view.beginGL();
MPoint textPos = nodeTranslation();
char str[100];
sprintf(str, "Stretch Me!");
MString distanceText(str);
view.drawText(distanceText, textPos, M3dView::kLeft);
view.endGL();
}
class footPrintLocator : public MPxLocatorNode
{
public:
footPrintLocator();
virtual ~footPrintLocator();
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;
};
MTypeId footPrintLocator::id( 0x8001c );
MObject footPrintLocator::size;
footPrintLocator::footPrintLocator()
{}
footPrintLocator::~footPrintLocator()
{}
MStatus footPrintLocator::compute(const MPlug &plug, MDataBlock &data)
{
return MS::kUnknownParameter;
}
void footPrintLocator::draw(M3dView &view, const MDagPath &path,
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 footPrintLocator::isBounded() const
{
return true;
}
MBoundingBox footPrintLocator::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* footPrintLocator::creator()
{
return new footPrintLocator();
}
MStatus footPrintLocator::initialize()
{
MFnUnitAttribute unitFn;
MStatus stat;
size = unitFn.create("size", "sz", MFnUnitAttribute::kDistance);
unitFn.setDefault(10.0);
unitFn.setStorable(true);
unitFn.setWritable(true);
stat = addAttribute(size);
if (!stat) {
stat.perror("addAttribute");
return stat;
}
MPxManipContainer::addToManipConnectTable(id);
return MS::kSuccess;
}
MStatus initializePlugin(MObject obj)
{
MStatus status;
MFnPlugin plugin(obj, PLUGIN_COMPANY, "3.0", "Any");
status = plugin.registerNode("footPrintLocator",
footPrintLocator::id,
&footPrintLocator::creator,
&footPrintLocator::initialize,
MPxNode::kLocatorNode);
if (!status) {
status.perror("registerNode");
return status;
}
status = plugin.registerNode("footPrintLocatorManip",
footPrintLocatorManip::id,
&footPrintLocatorManip::creator,
&footPrintLocatorManip::initialize,
MPxNode::kManipContainer);
if (!status) {
status.perror("registerNode");
return status;
}
return status;
}
MStatus uninitializePlugin(MObject obj)
{
MStatus status;
MFnPlugin plugin(obj);
status = plugin.deregisterNode(footPrintLocator::id);
if (!status) {
status.perror("deregisterNode");
return status;
}
status = plugin.deregisterNode(footPrintLocatorManip::id);
if (!status) {
status.perror("deregisterNode");
return status;
}
return status;
}