//---------------------------------------- // System Includes //---------------------------------------- #include //---------------------------------------- // Project Includes //---------------------------------------- #include "intersectioncontext.h" #include "nodes/intersection.h" #include "utility/mext.h" #include "main/trackeditor.h" //---------------------------------------- // Constants, Typedefs and Statics //---------------------------------------- const short OFFSET = 10; const double SCALE_FACTOR = 0.002; const char* IntersectionContext::stringId = "IntersectionContext"; //============================================================================== // IntersectionContextCmd::IntersectionContextCmd //============================================================================== // Description: Comment // // Parameters: () // // Return: IntersectionContextCmd // //============================================================================== IntersectionContextCmd::IntersectionContextCmd() { } //============================================================================== // IntersectionContextCmd::~IntersectionContextCmd //============================================================================== // Description: Comment // // Parameters: () // // Return: IntersectionContextCmd // //============================================================================== IntersectionContextCmd::~IntersectionContextCmd() { } //----------------------------------------------------------------------------- // c r e a t o r // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- void* IntersectionContextCmd::creator() { return new IntersectionContextCmd(); } //----------------------------------------------------------------------------- // m a k e O b j // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- MPxContext* IntersectionContextCmd::makeObj() { return new IntersectionContext(); } //============================================================================== // IntersectionContext::IntersectionContext //============================================================================== // Description: Comment // // Parameters: () // // Return: IntersectionContext // //============================================================================== IntersectionContext::IntersectionContext() : mXCurrent( 0 ), mYCurrent( 0 ), mIntersection( MObject::kNullObj ), mIntersectionTransform( MObject::kNullObj ) { SetHelpString(); setTitleString( "Intersection Overlay Tool" ); } //============================================================================== // IntersectionContext::~IntersectionContext //============================================================================== // Description: Comment // // Parameters: () // // Return: IntersectionContext // //============================================================================== IntersectionContext::~IntersectionContext() { } //============================================================================== // IntersectionContext::abortAction //============================================================================== // Description: Comment // // Parameters: () // // Return: void // //============================================================================== void IntersectionContext::abortAction() { ProcessState( ABORTED ); } //----------------------------------------------------------------------------- // c o m p l e t e A c t i o n // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- void IntersectionContext::completeAction() { ProcessState( COMPLETED ); } //----------------------------------------------------------------------------- // d e l e t e A c t i o n // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- void IntersectionContext::deleteAction() { ProcessState( DELETED ); } //----------------------------------------------------------------------------- // d o D r a g // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- MStatus IntersectionContext::doDrag( MEvent& event ) { event.getPosition( mXDrag, mYDrag ); ProcessState( MOUSEDRAG ); return MS::kSuccess; } //----------------------------------------------------------------------------- // d o E n t e r R e g i o n // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- MStatus IntersectionContext::doEnterRegion( MEvent& event ) { SetHelpString(); return MS::kSuccess; } //----------------------------------------------------------------------------- // d o H o l d // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- MStatus IntersectionContext::doHold( MEvent& event ) { MStatus status = MS::kSuccess; return status; } //----------------------------------------------------------------------------- // d o P r e s s // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- MStatus IntersectionContext::doPress( MEvent& event ) { event.getPosition( mXCurrent, mYCurrent ); ProcessState( BUTTONDOWN ); return MS::kSuccess; } //----------------------------------------------------------------------------- // d o R e l e a s e // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- MStatus IntersectionContext::doRelease( MEvent& event ) { if ( event.mouseButton() == MEvent::kLeftMouse ) { event.getPosition( mXCurrent, mYCurrent ); ProcessState( BUTTONUP ); } return MS::kSuccess; } //----------------------------------------------------------------------------- // t o o l O f f C l e a n u p // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- void IntersectionContext::toolOffCleanup() { if ( mIntersectionTransform != MObject::kNullObj ) { mIntersection = MObject::kNullObj; mIntersectionTransform = MObject::kNullObj; } } //----------------------------------------------------------------------------- // t o o l O n S e t u p // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- void IntersectionContext::toolOnSetup( MEvent& event ) { setCursor( MCursor::crossHairCursor ); } //----------------------------------------------------------------------------- // // P R I V A T E M E M B E R S // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // p r o c e s s S t a t e // // Synopsis: // // Parameters: NONE // // Returns: NOTHING // // Constraints: NONE // //----------------------------------------------------------------------------- void IntersectionContext::ProcessState( Stimulus stimulus ) { switch( stimulus ) { case BUTTONDOWN: { InitIntersection(); } break; case MOUSEDRAG: { //Scale the intersection according to drag dist. short diffX = mXCurrent - mXDrag; short diffY = mYCurrent - mYDrag; double dist = 25.0 + sqrt( ( diffX*diffX + diffY*diffY ) ) * SCALE_FACTOR; double scaleFactor[3] = { dist, dist, dist }; MFnTransform fnTransform( mIntersectionTransform ); fnTransform.setScale( scaleFactor ); } break; case BUTTONUP: case COMPLETED: { } break; case ABORTED: { if ( mIntersectionTransform != MObject::kNullObj ) { mIntersection = MObject::kNullObj; mIntersectionTransform = MObject::kNullObj; } } break; case DELETED: { if ( mIntersectionTransform != MObject::kNullObj ) { MGlobal::deleteNode( mIntersection ); MGlobal::deleteNode( mIntersectionTransform ); mIntersection = MObject::kNullObj; mIntersectionTransform = MObject::kNullObj; } } break; default: { } break; } SetHelpString(); } //============================================================================== // IntersectionContext::SetHelpString //============================================================================== // Description: Comment // // Parameters: () // // Return: void // //============================================================================== void IntersectionContext::SetHelpString() { mHelp = "Click and drag to create intersection."; setHelpString( mHelp ); } //============================================================================== // IntersectionContext::InitIntersection //============================================================================== // Description: Comment // // Parameters: () // // Return: void // //============================================================================== void IntersectionContext::InitIntersection() { //Get the mesh below the clicked point and find it's y height. short xStart, xEnd, yStart, yEnd; xStart = 0; xEnd = M3dView::active3dView().portWidth(); yStart = M3dView::active3dView().portHeight(); yEnd = 0; MGlobal::selectFromScreen( xStart, yStart, xEnd, yEnd, MGlobal::kReplaceList ); MSelectionList selectionList; MGlobal::getActiveSelectionList( selectionList ); if ( selectionList.length() > 0 ) { //Go through each selected object and see if the ray intersects it. MItSelectionList selectIt( selectionList, MFn::kMesh ); MPoint nearClick, farClick; M3dView activeView = M3dView::active3dView(); activeView.viewToWorld( mXCurrent, mYCurrent, nearClick, farClick ); MVector rayDir( MVector( farClick ) - MVector( nearClick ) ); MPointArray intersectPoints; MDagPath objDag; while ( !selectIt.isDone() ) { selectIt.getDagPath( objDag ); MFnMesh mesh( objDag ); mesh.intersect( nearClick, rayDir, intersectPoints, 0.001f, MSpace::kWorld ); if ( intersectPoints.length() > 0 ) { MObject transform; MExt::CreateNode( mIntersection, mIntersectionTransform, MString( IntersectionLocatorNode::stringId ) ); assert( !mIntersection.isNull() ); MExt::SetWorldPosition( intersectPoints[0], mIntersection ); MFnTransform fnTransform( mIntersectionTransform ); const double scale[3] = { 25.0, 25.0, 25.0 }; fnTransform.setScale( scale ); TrackEditor::AddChild( mIntersection ); break; } selectIt.next(); } } MGlobal::clearSelectionList(); }