Maya API How-To #05 | ||
| ||
How do I "constrain" my custom manipulator so it moves with its parent node?Method #1: For function sets with a .setStartPoint() method (e.g. MFnDistanceManip) First, declare a ‘ We'll also be using a utility function ‘ class myManip : public MPxManipContainer
{
// ...
private:
MDagPath fNodePath;
MPoint nodePos;
MVector nodeTranslation() const;
// ...
};
Within the ‘
MStatus myManip::connectToDependNode(const MObject &node)
{
// ...
// Get the DAG path for this manipulator
MFnDagNode dagNodeFn(node);
dagNodeFn.getPath(fNodePath);
// Set member variable to node position
nodePos = nodeTranslation();
MPlug myPlug = nodeFn.findPlug("myPlug", &stat);
if ( stat != MS::kFailure )
{
MFnDistanceManip distanceManipFn( fDistanceManip );
distanceManipFn.connectToDistancePlug( myPlug );
// Set the "home" pos for this manipulator
distanceManipFn.setStartPoint( startPoint );
}
finishAddingManips();
MPxManipContainer::connectToDependNode(node);
// ...
}
The ‘
MVector myManip::nodeTranslation() const
{
MFnDagNode dagFn(fNodePath);
MDagPath path;
dagFn.getPath(path);
path.pop(); // pop from the shape to the transform
MFnTransform transformFn(path);
return transformFn.translation(MSpace::kWorld);
}
If you are providing any custom GL calls for your manipulator, you can use the stored nodePos value. Add its matrix to any text or GL draw calls. void myManip::draw(M3dView & view,
const MDagPath & path,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status)
{
// ...
view.beginGL();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Move manip to node's position
glTranslated( nodePos.x, nodePos.y, nodePos.z );
// convert to Y-up
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
glBegin( GL_LINE_LOOP );
// Draw a 1.0-unit circle around node/manip
for ( r = 0; r < SEGMENTS; r++ )
{
double angle = ( 2 * PI ) / SEGMENTS * r;
GLdouble radiusX = cos(angle);
GLdouble radiusY = sin(angle);
glVertex2d( radiusX, radiusY );
}
glEnd();
MString manipText( "Pick me!" );
MPoint textPos( 0.0, 0.0, 0.0 );
// offset text by node's position
textPos += nodePos;
view.drawText( manipText, textPos, M3dView::kRight );
glPopMatrix();
view.endGL();
// ...
}
Method #2: For function sets without a .setStartPoint() method (e.g. MFnStateManip) This technique is almost identical to the one above -- we just have to use a The declaration of your manipulator will still include a MDagPath object and nodeTranslation() method, and also the callback (as exemplified in footPrintManip.cpp in the DevKit): class myManip : public MPxManipContainer
{
// ...
private:
MDagPath fNodePath;
MManipData startPointCallback( unsigned index ) const;
MVector nodeTranslation() const;
// ...
};
The ‘
MManipData containerManip::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 myManip::nodeTranslation() const
{
MFnDagNode dagFn(fNodePath);
MDagPath path;
dagFn.getPath(path);
path.pop(); // pop from the shape to the transform
MFnTransform transformFn(path);
return transformFn.translation(MSpace::kWorld);
}
Within the ‘
MStatus myManip::connectToDependNode(const MObject &node)
{
// ...
// Get the DAG path for this manipulator
MFnDagNode dagNodeFn(node);
dagNodeFn.getPath(fNodePath);
MFnStateManip containerStateManipFn( fContainerStateManip );
positionIndex = containerStateManipFn.positionIndex();
// Use the callback to set the startPoint for this manipulator
addPlugToManipConversionCallback(positionIndex, (plugToManipConversionCallback) startPointCallback);
// ...
finishAddingManips();
MPxManipContainer::connectToDependNode(node);
// ...
}
Note: I've had problems (read: Maya crashes) initiating multiple startPointCallbacks for multiple manipulators in the same MPxManipContainer. I know it's possible, because A|w does so in their examples. I think the crashes were due to the fact that the manipulators were all of the same type (in my case, MFnDistanceManip). This was the reason I started using the "direct" method of using setStartPoint() instead of the callback. Your mileage may vary. Related How-To's | ||
| Copyright ©2005 by Bryan Ewert, maya@ewertb.com Maya is a Registered Trademark of Alias |