diff options
Diffstat (limited to '')
-rw-r--r-- | tools/trackeditor/code/contexts/bvcontext.cpp | 721 | ||||
-rw-r--r-- | tools/trackeditor/code/contexts/bvcontext.h | 98 | ||||
-rw-r--r-- | tools/trackeditor/code/contexts/intersectioncontext.cpp | 478 | ||||
-rw-r--r-- | tools/trackeditor/code/contexts/intersectioncontext.h | 82 | ||||
-rw-r--r-- | tools/trackeditor/code/contexts/ppcontext.cpp | 717 | ||||
-rw-r--r-- | tools/trackeditor/code/contexts/ppcontext.h | 97 | ||||
-rw-r--r-- | tools/trackeditor/code/contexts/treelinecontext.cpp | 402 | ||||
-rw-r--r-- | tools/trackeditor/code/contexts/treelinecontext.h | 139 |
8 files changed, 2734 insertions, 0 deletions
diff --git a/tools/trackeditor/code/contexts/bvcontext.cpp b/tools/trackeditor/code/contexts/bvcontext.cpp new file mode 100644 index 0000000..1a4e0a0 --- /dev/null +++ b/tools/trackeditor/code/contexts/bvcontext.cpp @@ -0,0 +1,721 @@ +//---------------------------------------- +// System Includes +//---------------------------------------- + + +//---------------------------------------- +// Project Includes +//---------------------------------------- + +#include "bvcontext.h" +#include "utility/Mext.h" +#include "nodes/walllocator.h" +#include "nodes/fenceline.h" +#include "nodes/nu.h" +#include "main/trackeditor.h" + +//---------------------------------------- +// Constants, Typedefs and Statics +//---------------------------------------- +const char* BVContext::stringId = "BVContext"; +int BVContext::sLeftSide = WallLocatorNode::LEFT; +const MString BVContext::DEFAULT_GROUP_NAME = "FenceLine"; +MObject BVContext::sCurrentGroup; + + +const char* BVSplitCmd::stringId = "BVSplitSelected"; + +//============================================================================== +// BVContextCmd::BVContextCmd +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: BVContextCmd +// +//============================================================================== +BVContextCmd::BVContextCmd() +{ +} + +//============================================================================== +// BVContextCmd::~BVContextCmd +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: BVContextCmd +// +//============================================================================== +BVContextCmd::~BVContextCmd() +{ +} + +//----------------------------------------------------------------------------- +// c r e a t o r +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +void* BVContextCmd::creator() +{ + return new BVContextCmd(); +} + +//----------------------------------------------------------------------------- +// m a k e O b j +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MPxContext* BVContextCmd::makeObj() +{ + return new BVContext(); +} + +//============================================================================== +// BVContext::BVContext +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: BVContext +// +//============================================================================== +BVContext::BVContext() : + mXCurrent( 0 ), + mYCurrent( 0 ) +{ + SetHelpString(); + + setTitleString( "Bounding Volume Path Tool" ); +} + +//============================================================================== +// BVContext::~BVContext +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: BVContext +// +//============================================================================== +BVContext::~BVContext() +{ +} + +//============================================================================== +// BVContext::abortAction +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void BVContext::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 BVContext::completeAction() +{ + ProcessState( COMPLETED ); +} + +//----------------------------------------------------------------------------- +// d e l e t e A c t i o n +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +void BVContext::deleteAction() +{ + ProcessState( DELETED ); +} + +//----------------------------------------------------------------------------- +// d o D r a g +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MStatus BVContext::doDrag( MEvent& event ) +{ + + event.getPosition( mXCurrent, mYCurrent ); + 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 BVContext::doEnterRegion( MEvent& event ) +{ + SetHelpString(); + + return MS::kSuccess; +} + +//----------------------------------------------------------------------------- +// d o H o l d +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MStatus BVContext::doHold( MEvent& event ) +{ + MStatus status = MS::kSuccess; + return status; +} + +//----------------------------------------------------------------------------- +// d o P r e s s +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MStatus BVContext::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 BVContext::doRelease( MEvent& event ) +{ + if ( event.mouseButton() == MEvent::kLeftMouse ) + { + event.getPosition( mXCurrent, mYCurrent ); + ProcessState( BUTTONUP ); + } + else if ( event.mouseButton() == MEvent::kMiddleMouse ) + { + //Toggle the leftness... + sLeftSide = sLeftSide == WallLocatorNode::LEFT ? WallLocatorNode::RIGHT : WallLocatorNode::LEFT; + + SetHelpString(); + } + + 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 BVContext::toolOffCleanup() +{ + CloseLoop(); + mPoints.clear(); + sCurrentGroup = MObject::kNullObj; +} + +//----------------------------------------------------------------------------- +// t o o l O n S e t u p +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +void BVContext::toolOnSetup( MEvent& event ) +{ + setCursor( MCursor::crossHairCursor ); + + mPoints.clear(); + sCurrentGroup = MObject::kNullObj; +} + +//----------------------------------------------------------------------------- +// +// 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 BVContext::ProcessState( Stimulus stimulus ) +{ + switch( stimulus ) + { + case BUTTONDOWN: + { + } + break; + + case BUTTONUP: + { + MObject newNode; + MObject nodeTransform; + + MExt::CreateNode( newNode, nodeTransform, MString( WallLocatorNode::stringId ) ); + + NODE_UTIL::DisableAttributes( newNode ); + + MExt::Attr::Set( sLeftSide, + newNode, + WallLocatorNode::LEFTRIGHT_NAME_LONG ); + + //Set the position + + MPoint vp( mXCurrent, mYCurrent, 0 ); + MPoint wp; + MExt::ViewToWorldAtY( &wp, vp, 0 ); + MExt::SetWorldPosition( wp, newNode ); + + AddPoint( newNode ); + } + break; + case DELETED: + { + DeleteLast(); + } + break; + case COMPLETED: + { + //Complete the loop and start a new one. + CloseLoop(); + } + break; + default: + { + } + break; + } + + SetHelpString(); +} + +//============================================================================== +// BVContext::AddPoint +//============================================================================== +// Description: Comment +// +// Parameters: ( MObject obj ) +// +// Return: void +// +//============================================================================== +void BVContext::AddPoint( MObject obj ) +{ + MStatus status; + unsigned int size = mPoints.length(); + + if ( size ) + { + MObject lastNode; + + lastNode = mPoints[ size - 1 ]; + + if ( lastNode.isNull() ) + { + //Someone has been deleting nodes. + MExt::DisplayError( "Someone has deleted something..." ); + return; + } + + MExt::Connect( lastNode, WallLocatorNode::NEXTNODE_NAME_LONG, obj, WallLocatorNode::PREVNODE_NAME_LONG ); + } + else + { + //Starting a new group + MObject flT; + MString name( DEFAULT_GROUP_NAME ); + + MExt::CreateNode( sCurrentGroup, flT, MString( FenceLineNode::stringId ), &name ); + + //Parent this group to the main TrackEditor Node if it exists. + TrackEditor::AddChild( sCurrentGroup ); + } + + mPoints.append( obj ); + + //Add the point (wall) to the current fence + FenceLineNode::AddWall( sCurrentGroup, obj ); +} + +//============================================================================== +// BVContext::DeleteLast +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void BVContext::DeleteLast() +{ + unsigned int size = mPoints.length(); + + if ( size ) + { + MStatus status; + + MObject obj = mPoints[ size - 1 ]; + mPoints.remove( size - 1 ); + + MExt::DeleteNode( obj, true ); + } + + if ( mPoints.length() == 0 && !sCurrentGroup.isNull() ) + { + //we deleted the last one. + //Remove the group object. + MExt::DeleteNode( sCurrentGroup, true ); + } +} + +//============================================================================== +// BVContext::CloseLoop +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void BVContext::CloseLoop() +{ + unsigned int size = mPoints.length(); + + if ( size == 1 ) + { + MExt::DisplayWarning( "There was only one point in the BV loop. It will be deleted." ); + + DeleteLast(); + } + else if ( size == 2 ) + { + MExt::DisplayWarning( "There were only two points in the BV loop. They will be deleted." ); + + DeleteLast(); + DeleteLast(); + } + else if ( size > 2 ) + { + MObject lastNode, firstNode; + MStatus status; + + lastNode = mPoints[ size - 1 ]; + firstNode = mPoints[ 0 ]; + + MExt::Connect( lastNode, WallLocatorNode::NEXTNODE_NAME_LONG, firstNode, WallLocatorNode::PREVNODE_NAME_LONG ); + + //Clear the points list to start a new loop. + mPoints.clear(); + sCurrentGroup; + } +} + +//============================================================================== +// BVContext::SetHelpString +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void BVContext::SetHelpString() +{ + mHelp = "Click to place nodes in the path."; + + if ( sLeftSide ) + { + mHelp += "LEFT-SIDED"; + } + else + { + mHelp += "RIGHT-SIDED"; + } + + setHelpString( mHelp ); + +} + +//SPLIT COMMAND +//============================================================================== +// BVSplitCmd::creator +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void* BVSplitCmd::creator() +{ + return new BVSplitCmd(); +} + +//============================================================================== +// BVSplitCmd::doIt +//============================================================================== +// Description: Comment +// +// Parameters: ( const MArgList &args ) +// +// Return: MStatus +// +//============================================================================== +MStatus BVSplitCmd::doIt( const MArgList &args ) +{ + MSelectionList selectionList; + + MGlobal::getActiveSelectionList( selectionList ); + + if ( selectionList.isEmpty() ) + { + //Nothing to do. + return MS::kSuccess; + } + + //Get the number of objects in the list. + unsigned int numObjs = selectionList.length(); + + MObject obj; + MFnDependencyNode fnNode; + MObjectArray objArray; + + unsigned int i; + for ( i = 0; i < numObjs; ++i ) + { + selectionList.getDependNode( i, obj ); + fnNode.setObject( obj ); + + if ( fnNode.typeId() == WallLocatorNode::id ) + { + //This is a wall locator, add it to the array. + objArray.append( obj ); + } + else + { + //This could be a transform, let's test the child node. + MFnDagNode dagNode( obj ); + if( dagNode.childCount() ) + { + //Get the first child + MObject child = dagNode.child( 0 ); + + fnNode.setObject( child ); + if ( fnNode.typeId() == WallLocatorNode::id ) + { + //This is a wall locator, add it to the array. + objArray.append( child ); + } + } + } + } + + if ( objArray.length() <= 1 ) + { + //Nothing to do. + return MS::kSuccess; + } + + //For each object in the objArray that is connected to another, create a node in-between... + MStatus status; + MObject obj1, obj2; + MFnDependencyNode fnNode1, fnNode2; + MPlug nextPlug, prevPlug; + + unsigned int j; + for ( i = 0; i < objArray.length() - 1; ++i ) + { + for ( j = i + 1; j < objArray.length(); ++j ) + { + //Check if i and j are connected. + obj1 = objArray[i]; + obj2 = objArray[j]; + + fnNode1.setObject( obj1 ); + fnNode2.setObject( obj2 ); + + //Compare obj1.next to obj2.prev + nextPlug = fnNode1.findPlug( WallLocatorNode::NEXTNODE_NAME_LONG, &status ); + assert( status ); + prevPlug = fnNode2.findPlug( WallLocatorNode::PREVNODE_NAME_LONG, &status ); + assert( status ); + + if ( MExt::IsConnected( nextPlug, prevPlug ) ) + { + //Split and connect these two objects. + Split( obj1, obj2 ); + } + else + { + //Compare obj2.next to obj1.prev + nextPlug = fnNode2.findPlug( WallLocatorNode::NEXTNODE_NAME_LONG, &status ); + assert( status ); + prevPlug = fnNode1.findPlug( WallLocatorNode::PREVNODE_NAME_LONG, &status ); + assert( status ); + + if ( MExt::IsConnected( nextPlug, prevPlug ) ) + { + //Split and connect these two objects. + Split( obj2, obj1 ); + } + } + } + } + + return MS::kSuccess; +} + +//============================================================================== +// BVSplitCmd::Split +//============================================================================== +// Description: Comment +// +// Parameters: ( MObject& node1, MObject& node2 ) +// +// Return: void +// +//============================================================================== +void BVSplitCmd::Split( MObject& node1, MObject& node2 ) +{ + //Take node1 and node2, create a newNode between them and connect + /// node1.next -> newNode.prev and newNode.next -> node2.prev + + //Disconnect the nodes. + MExt::DisconnectAll( node1, WallLocatorNode::NEXTNODE_NAME_LONG ); + + MObject newNode; + MObject nodeTransform; + + MExt::CreateNode( newNode, nodeTransform, MString( WallLocatorNode::stringId ) ); + + NODE_UTIL::DisableAttributes( newNode ); + + //This will split based on one of the others. + int isLeft; + MExt::Attr::Get( &isLeft, node1, WallLocatorNode::LEFTRIGHT_NAME_LONG ); + + MExt::Attr::Set( !isLeft == WallLocatorNode::LEFT ? WallLocatorNode::RIGHT : WallLocatorNode::LEFT, + newNode, + WallLocatorNode::LEFTRIGHT_NAME_LONG ); + + MPoint newWP = MExt::GetWorldPositionBetween( node1, node2 ); + //Lock the y to 0; + newWP[1] = 0; + + MExt::SetWorldPosition( newWP, newNode ); + + //Connect the nodes in their new order. + MExt::Connect( node1, WallLocatorNode::NEXTNODE_NAME_LONG, newNode, WallLocatorNode::PREVNODE_NAME_LONG ); + MExt::Connect( newNode, WallLocatorNode::NEXTNODE_NAME_LONG, node2, WallLocatorNode::PREVNODE_NAME_LONG ); + + //Make sure the node is parented properly... + + MFnDagNode fnDagNode( node1 ); + MObject parentT = fnDagNode.parent( 0 ); + + fnDagNode.setObject( parentT ); + MObject groupT = fnDagNode.parent( 0 ); + + FenceLineNode::AddWall( groupT, newNode ); +} + diff --git a/tools/trackeditor/code/contexts/bvcontext.h b/tools/trackeditor/code/contexts/bvcontext.h new file mode 100644 index 0000000..e444cd5 --- /dev/null +++ b/tools/trackeditor/code/contexts/bvcontext.h @@ -0,0 +1,98 @@ +#include "precompiled/PCH.h" + +#ifndef BVCONTEXT +#define BVCONTEXT + +//---------------------------------------- +// System Includes +//---------------------------------------- + + +//---------------------------------------- +// Forward References +//---------------------------------------- + +//----------------------------------------------------------------------------- +// +// B o u n d i n g v o l u m e C o n t e x t +// +//----------------------------------------------------------------------------- +class BVContext : public MPxContext +{ + public: + + enum Stimulus // Maskable values. + { + BUTTONDOWN = 0x0001, + BUTTONUP = 0x0002, + MOUSEDRAG = 0x0004, + COMPLETED = 0x0008, + DELETED = 0x0010, + ABORTED = 0x0020 + }; + + + BVContext(); + virtual ~BVContext(); + + static const char* stringId; + + virtual void toolOnSetup( MEvent& ); + virtual void toolOffCleanup(); + virtual MStatus doPress( MEvent& ); + virtual MStatus doDrag( MEvent& ); + virtual MStatus doRelease( MEvent& event ); + virtual MStatus doHold( MEvent& event ); + virtual MStatus doEnterRegion( MEvent& event ); + virtual void deleteAction(); + virtual void completeAction(); + virtual void abortAction(); + + static int sLeftSide; + static const MString DEFAULT_GROUP_NAME; + static MObject sCurrentGroup; + + private: + void ProcessState( Stimulus stimulus ); + void AddPoint( MObject obj ); + void DeleteLast(); + void CloseLoop(); + void SetHelpString(); + + MObjectArray mPoints; + MString mHelp; + + short mXCurrent, mYCurrent; +}; + +//----------------------------------------------------------------------------- +// +// B o u n d i n g v o l u m e C o n t e x t C m d +// +//----------------------------------------------------------------------------- +class BVContextCmd : public MPxContextCommand +{ + public: + BVContextCmd(); + virtual ~BVContextCmd(); + + static void* creator(); + + virtual MPxContext* makeObj(); + + private: +}; + +class BVSplitCmd : public MPxCommand +{ +public: + MStatus doIt( const MArgList& args ); + static void* creator(); + + static const char* stringId; + +private: + void Split( MObject& node1, MObject& node2 ); +}; + +#endif diff --git a/tools/trackeditor/code/contexts/intersectioncontext.cpp b/tools/trackeditor/code/contexts/intersectioncontext.cpp new file mode 100644 index 0000000..561d5bf --- /dev/null +++ b/tools/trackeditor/code/contexts/intersectioncontext.cpp @@ -0,0 +1,478 @@ +//---------------------------------------- +// System Includes +//---------------------------------------- +#include <math.h> + +//---------------------------------------- +// 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(); +} diff --git a/tools/trackeditor/code/contexts/intersectioncontext.h b/tools/trackeditor/code/contexts/intersectioncontext.h new file mode 100644 index 0000000..b54edd9 --- /dev/null +++ b/tools/trackeditor/code/contexts/intersectioncontext.h @@ -0,0 +1,82 @@ +#include "precompiled/PCH.h" + +#ifndef INTERSECTION_CONTEXT +#define INTERSECTION_CONTEXT + +//---------------------------------------- +// System Includes +//---------------------------------------- + + +//---------------------------------------- +// Forward References +//---------------------------------------- + +//----------------------------------------------------------------------------- +// +// I n t e r s e c t i o n C o n t e x t +// +//----------------------------------------------------------------------------- +class IntersectionContext : public MPxContext +{ + public: + + enum Stimulus // Maskable values. + { + BUTTONDOWN = 0x0001, + BUTTONUP = 0x0002, + MOUSEDRAG = 0x0004, + COMPLETED = 0x0008, + DELETED = 0x0010, + ABORTED = 0x0020 + }; + + + IntersectionContext(); + virtual ~IntersectionContext(); + + static const char* stringId; + + virtual void toolOnSetup( MEvent& ); + virtual void toolOffCleanup(); + virtual MStatus doPress( MEvent& ); + virtual MStatus doDrag( MEvent& ); + virtual MStatus doRelease( MEvent& event ); + virtual MStatus doHold( MEvent& event ); + virtual MStatus doEnterRegion( MEvent& event ); + virtual void deleteAction(); + virtual void completeAction(); + virtual void abortAction(); + + private: + void ProcessState( Stimulus stimulus ); + void SetHelpString(); + void InitIntersection(); + + MString mHelp; + + short mXCurrent, mYCurrent; + short mXDrag, mYDrag; + MObject mIntersection; + MObject mIntersectionTransform; +}; + +//----------------------------------------------------------------------------- +// +// I n t e r s e c t i o n C o n t e x t C m d +// +//----------------------------------------------------------------------------- +class IntersectionContextCmd : public MPxContextCommand +{ + public: + IntersectionContextCmd(); + virtual ~IntersectionContextCmd(); + + static void* creator(); + + virtual MPxContext* makeObj(); + + private: +}; + +#endif diff --git a/tools/trackeditor/code/contexts/ppcontext.cpp b/tools/trackeditor/code/contexts/ppcontext.cpp new file mode 100644 index 0000000..0a2a84b --- /dev/null +++ b/tools/trackeditor/code/contexts/ppcontext.cpp @@ -0,0 +1,717 @@ +//---------------------------------------- +// System Includes +//---------------------------------------- + + +//---------------------------------------- +// Project Includes +//---------------------------------------- + +#include "ppcontext.h" +#include "utility/Mext.h" +#include "nodes/pedpath.h" +#include "nodes/nu.h" +#include "nodes/walllocator.h" +#include "main/trackeditor.h" + +//---------------------------------------- +// Constants, Typedefs and Statics +//---------------------------------------- +const char* PPContext::stringId = "PPContext"; +const MString PPContext::DEFAULT_GROUP_NAME = "PedPath"; +MObject PPContext::sCurrentGroup; + + +const char* PPSplitCmd::stringId = "PPSplitSelected"; + +//============================================================================== +// PPContextCmd::PPContextCmd +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: PPContextCmd +// +//============================================================================== +PPContextCmd::PPContextCmd() +{ +} + +//============================================================================== +// PPContextCmd::~PPContextCmd +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: PPContextCmd +// +//============================================================================== +PPContextCmd::~PPContextCmd() +{ +} + +//----------------------------------------------------------------------------- +// c r e a t o r +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +void* PPContextCmd::creator() +{ + return new PPContextCmd(); +} + +//----------------------------------------------------------------------------- +// m a k e O b j +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MPxContext* PPContextCmd::makeObj() +{ + return new PPContext(); +} + +//============================================================================== +// PPContext::PPContext +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: PPContext +// +//============================================================================== +PPContext::PPContext() : + mXCurrent( 0 ), + mYCurrent( 0 ) +{ + SetHelpString(); + + setTitleString( "Pedestrian Path Tool" ); +} + +//============================================================================== +// PPContext::~PPContext +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: PPContext +// +//============================================================================== +PPContext::~PPContext() +{ +} + +//============================================================================== +// PPContext::abortAction +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void PPContext::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 PPContext::completeAction() +{ + ProcessState( COMPLETED ); +} + +//----------------------------------------------------------------------------- +// d e l e t e A c t i o n +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +void PPContext::deleteAction() +{ + ProcessState( DELETED ); +} + +//----------------------------------------------------------------------------- +// d o D r a g +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MStatus PPContext::doDrag( MEvent& event ) +{ + + event.getPosition( mXCurrent, mYCurrent ); + 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 PPContext::doEnterRegion( MEvent& event ) +{ + SetHelpString(); + + return MS::kSuccess; +} + +//----------------------------------------------------------------------------- +// d o H o l d +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MStatus PPContext::doHold( MEvent& event ) +{ + MStatus status = MS::kSuccess; + return status; +} + +//----------------------------------------------------------------------------- +// d o P r e s s +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +MStatus PPContext::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 PPContext::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 PPContext::toolOffCleanup() +{ + CloseLoop(); + mPoints.clear(); + sCurrentGroup = MObject::kNullObj; +} + +//----------------------------------------------------------------------------- +// t o o l O n S e t u p +// +// Synopsis: +// +// Parameters: NONE +// +// Returns: NOTHING +// +// Constraints: NONE +// +//----------------------------------------------------------------------------- +void PPContext::toolOnSetup( MEvent& event ) +{ + setCursor( MCursor::crossHairCursor ); + + mPoints.clear(); + sCurrentGroup = MObject::kNullObj; +} + +//----------------------------------------------------------------------------- +// +// 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 PPContext::ProcessState( Stimulus stimulus ) +{ + switch( stimulus ) + { + case BUTTONDOWN: + { + } + break; + + case BUTTONUP: + { + MObject newNode; + MObject nodeTransform; + + MExt::CreateNode( newNode, nodeTransform, MString( WallLocatorNode::stringId ) ); + +// NODE_UTIL::DisableAttributes( newNode, false ); + MFnDagNode fnDagNode( newNode ); + + MObject parent = fnDagNode.parent( 0 ); + MFnDependencyNode fnParent( parent ); + MPlug spPlug = fnParent.findPlug( MString( "scale" ) ); + spPlug.setLocked( true ); + + MPlug rpPlug = fnParent.findPlug( MString( "rotate" ) ); + rpPlug.setLocked( true ); + + + MExt::Attr::Set( WallLocatorNode::NONE, + newNode, + WallLocatorNode::LEFTRIGHT_NAME_LONG ); + + //Set the position + MPoint intersectPoint; + if ( !MExt::MeshClickIntersect( mXCurrent, mYCurrent, intersectPoint ) ) + { + //Put it at 0. + MPoint vp( mXCurrent, mYCurrent, 0 ); + MExt::ViewToWorldAtY( &intersectPoint, vp, 0 ); //This is to y = 0 + } + +// intersectPoint = intersectPoint / TEConstants::Scale; + + MExt::SetWorldPosition( intersectPoint, newNode ); + + AddPoint( newNode ); + } + break; + case DELETED: + { + DeleteLast(); + } + break; + case COMPLETED: + { + //Complete the loop and start a new one. + CloseLoop(); + } + break; + default: + { + } + break; + } + + SetHelpString(); +} + +//============================================================================== +// PPContext::AddPoint +//============================================================================== +// Description: Comment +// +// Parameters: ( MObject obj ) +// +// Return: void +// +//============================================================================== +void PPContext::AddPoint( MObject obj ) +{ + MStatus status; + unsigned int size = mPoints.length(); + + if ( size ) + { + MObject lastNode; + + lastNode = mPoints[ size - 1 ]; + + if ( lastNode.isNull() ) + { + //Someone has been deleting nodes. + MExt::DisplayError( "Someone has deleted something..." ); + return; + } + + MExt::Connect( lastNode, WallLocatorNode::NEXTNODE_NAME_LONG, obj, WallLocatorNode::PREVNODE_NAME_LONG ); + } + else + { + //Starting a new group + MObject flT; + MString name( DEFAULT_GROUP_NAME ); + + MExt::CreateNode( sCurrentGroup, flT, MString( PedPathNode::stringId ), &name ); + + //Parent this group to the main TrackEditor Node if it exists. + TrackEditor::AddChild( sCurrentGroup ); + } + + mPoints.append( obj ); + + //Add the point (wall) to the current fence + PedPathNode::AddWall( sCurrentGroup, obj ); +} + +//============================================================================== +// PPContext::DeleteLast +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void PPContext::DeleteLast() +{ + unsigned int size = mPoints.length(); + + if ( size ) + { + MStatus status; + + MObject obj = mPoints[ size - 1 ]; + mPoints.remove( size - 1 ); + + MExt::DeleteNode( obj, true ); + } + + if ( mPoints.length() == 0 && !sCurrentGroup.isNull() ) + { + //we deleted the last one. + //Remove the group object. + MExt::DeleteNode( sCurrentGroup, true ); + } +} + +//============================================================================== +// PPContext::CloseLoop +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void PPContext::CloseLoop() +{ + unsigned int size = mPoints.length(); + + if ( size == 1 ) + { + MExt::DisplayWarning( "There was only one point in the PP loop. It will be deleted." ); + + DeleteLast(); + } + else if ( size == 2 ) + { + MExt::DisplayWarning( "There were only two points in the PP loop. They will be deleted." ); + + DeleteLast(); + DeleteLast(); + } + else if ( size > 2 ) + { + MObject lastNode, firstNode; + MStatus status; + + lastNode = mPoints[ size - 1 ]; + firstNode = mPoints[ 0 ]; + + MExt::Connect( lastNode, WallLocatorNode::NEXTNODE_NAME_LONG, firstNode, WallLocatorNode::PREVNODE_NAME_LONG ); + + //Clear the points list to start a new loop. + mPoints.clear(); + sCurrentGroup; + } +} + +//============================================================================== +// PPContext::SetHelpString +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void PPContext::SetHelpString() +{ + mHelp = "Click to place nodes in the path."; + + setHelpString( mHelp ); + +} + +//SPLIT COMMAND +//============================================================================== +// PPSplitCmd::creator +//============================================================================== +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================== +void* PPSplitCmd::creator() +{ + return new PPSplitCmd(); +} + +//============================================================================== +// PPSplitCmd::doIt +//============================================================================== +// Description: Comment +// +// Parameters: ( const MArgList &args ) +// +// Return: MStatus +// +//============================================================================== +MStatus PPSplitCmd::doIt( const MArgList &args ) +{ + MSelectionList selectionList; + + MGlobal::getActiveSelectionList( selectionList ); + + if ( selectionList.isEmpty() ) + { + //Nothing to do. + return MS::kSuccess; + } + + //Get the number of objects in the list. + unsigned int numObjs = selectionList.length(); + + MObject obj; + MFnDependencyNode fnNode; + MObjectArray objArray; + + unsigned int i; + for ( i = 0; i < numObjs; ++i ) + { + selectionList.getDependNode( i, obj ); + fnNode.setObject( obj ); + + if ( fnNode.typeId() == WallLocatorNode::id ) + { + //This is a wall locator, add it to the array. + objArray.append( obj ); + } + else + { + //This could be a transform, let's test the child node. + MFnDagNode dagNode( obj ); + if( dagNode.childCount() ) + { + //Get the first child + MObject child = dagNode.child( 0 ); + + fnNode.setObject( child ); + if ( fnNode.typeId() == WallLocatorNode::id ) + { + //This is a wall locator, add it to the array. + objArray.append( child ); + } + } + } + } + + if ( objArray.length() <= 1 ) + { + //Nothing to do. + return MS::kSuccess; + } + + //For each object in the objArray that is connected to another, create a node in-between... + MStatus status; + MObject obj1, obj2; + MFnDependencyNode fnNode1, fnNode2; + MPlug nextPlug, prevPlug; + + unsigned int j; + for ( i = 0; i < objArray.length() - 1; ++i ) + { + for ( j = i + 1; j < objArray.length(); ++j ) + { + //Check if i and j are connected. + obj1 = objArray[i]; + obj2 = objArray[j]; + + fnNode1.setObject( obj1 ); + fnNode2.setObject( obj2 ); + + //Compare obj1.next to obj2.prev + nextPlug = fnNode1.findPlug( WallLocatorNode::NEXTNODE_NAME_LONG, &status ); + assert( status ); + prevPlug = fnNode2.findPlug( WallLocatorNode::PREVNODE_NAME_LONG, &status ); + assert( status ); + + if ( MExt::IsConnected( nextPlug, prevPlug ) ) + { + //Split and connect these two objects. + Split( obj1, obj2 ); + } + else + { + //Compare obj2.next to obj1.prev + nextPlug = fnNode2.findPlug( WallLocatorNode::NEXTNODE_NAME_LONG, &status ); + assert( status ); + prevPlug = fnNode1.findPlug( WallLocatorNode::PREVNODE_NAME_LONG, &status ); + assert( status ); + + if ( MExt::IsConnected( nextPlug, prevPlug ) ) + { + //Split and connect these two objects. + Split( obj2, obj1 ); + } + } + } + } + + return MS::kSuccess; +} + +//============================================================================== +// PPSplitCmd::Split +//============================================================================== +// Description: Comment +// +// Parameters: ( MObject& node1, MObject& node2 ) +// +// Return: void +// +//============================================================================== +void PPSplitCmd::Split( MObject& node1, MObject& node2 ) +{ + //Take node1 and node2, create a newNode between them and connect + /// node1.next -> newNode.prev and newNode.next -> node2.prev + + //Disconnect the nodes. + MExt::DisconnectAll( node1, WallLocatorNode::NEXTNODE_NAME_LONG ); + + MObject newNode; + MObject nodeTransform; + + MExt::CreateNode( newNode, nodeTransform, MString( WallLocatorNode::stringId ) ); + + ///NODE_UTIL::DisableAttributes( newNode ); + + //This will split based on one of the others. + MExt::Attr::Set( WallLocatorNode::NONE, + newNode, + WallLocatorNode::LEFTRIGHT_NAME_LONG ); + + MPoint newWP = MExt::GetWorldPositionBetween( node1, node2 ); + //Lock the y to 0; + newWP[1] = 0; + + MExt::SetWorldPosition( newWP, newNode ); + + //Connect the nodes in their new order. + MExt::Connect( node1, WallLocatorNode::NEXTNODE_NAME_LONG, newNode, WallLocatorNode::PREVNODE_NAME_LONG ); + MExt::Connect( newNode, WallLocatorNode::NEXTNODE_NAME_LONG, node2, WallLocatorNode::PREVNODE_NAME_LONG ); + + //Make sure the node is parented properly... + + MFnDagNode fnDagNode( node1 ); + MObject parentT = fnDagNode.parent( 0 ); + + fnDagNode.setObject( parentT ); + MObject groupT = fnDagNode.parent( 0 ); + + PedPathNode::AddWall( groupT, newNode ); +} + diff --git a/tools/trackeditor/code/contexts/ppcontext.h b/tools/trackeditor/code/contexts/ppcontext.h new file mode 100644 index 0000000..04e212d --- /dev/null +++ b/tools/trackeditor/code/contexts/ppcontext.h @@ -0,0 +1,97 @@ +#include "precompiled/PCH.h" + +#ifndef PPCONTEXT +#define PPCONTEXT + +//---------------------------------------- +// System Includes +//---------------------------------------- + + +//---------------------------------------- +// Forward References +//---------------------------------------- + +//----------------------------------------------------------------------------- +// +// B o u n d i n g v o l u m e C o n t e x t +// +//----------------------------------------------------------------------------- +class PPContext : public MPxContext +{ + public: + + enum Stimulus // Maskable values. + { + BUTTONDOWN = 0x0001, + BUTTONUP = 0x0002, + MOUSEDRAG = 0x0004, + COMPLETED = 0x0008, + DELETED = 0x0010, + ABORTED = 0x0020 + }; + + + PPContext(); + virtual ~PPContext(); + + static const char* stringId; + + virtual void toolOnSetup( MEvent& ); + virtual void toolOffCleanup(); + virtual MStatus doPress( MEvent& ); + virtual MStatus doDrag( MEvent& ); + virtual MStatus doRelease( MEvent& event ); + virtual MStatus doHold( MEvent& event ); + virtual MStatus doEnterRegion( MEvent& event ); + virtual void deleteAction(); + virtual void completeAction(); + virtual void abortAction(); + + static const MString DEFAULT_GROUP_NAME; + static MObject sCurrentGroup; + + private: + void ProcessState( Stimulus stimulus ); + void AddPoint( MObject obj ); + void DeleteLast(); + void CloseLoop(); + void SetHelpString(); + + MObjectArray mPoints; + MString mHelp; + + short mXCurrent, mYCurrent; +}; + +//----------------------------------------------------------------------------- +// +// B o u n d i n g v o l u m e C o n t e x t C m d +// +//----------------------------------------------------------------------------- +class PPContextCmd : public MPxContextCommand +{ + public: + PPContextCmd(); + virtual ~PPContextCmd(); + + static void* creator(); + + virtual MPxContext* makeObj(); + + private: +}; + +class PPSplitCmd : public MPxCommand +{ +public: + MStatus doIt( const MArgList& args ); + static void* creator(); + + static const char* stringId; + +private: + void Split( MObject& node1, MObject& node2 ); +}; + +#endif diff --git a/tools/trackeditor/code/contexts/treelinecontext.cpp b/tools/trackeditor/code/contexts/treelinecontext.cpp new file mode 100644 index 0000000..5c5ba56 --- /dev/null +++ b/tools/trackeditor/code/contexts/treelinecontext.cpp @@ -0,0 +1,402 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: TreeLineContext.cpp +// +// Description: Implement TreeLineContext +// +// History: 27/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Project Includes +//======================================== +#include "contexts/TreeLineContext.h" +#include "utility/mext.h" +#include "main/constants.h" +#include "main/trackeditor.h" +#include "nodes/treelineshapenode.h" + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +const char* TreeLineContext::stringId = "TreeLineContext"; +MObject TreeLineContext::mCurrentTreeLine; +bool TreeLineContext::mWorking = false; + + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// TreeLineContext::TreeLineContext +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TreeLineContext::TreeLineContext() : + mXCurrent( 0 ), + mYCurrent( 0 ) +{ + SetHelpString(); + + setTitleString( "Ye Tree Line Tool" ); + +} + +//============================================================================== +// TreeLineContext::~TreeLineContext +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TreeLineContext::~TreeLineContext() +{ +} + +//============================================================================= +// TreeLineContext::toolOnSetup +//============================================================================= +// Description: Comment +// +// Parameters: ( MEvent& ) +// +// Return: void +// +//============================================================================= +void TreeLineContext::toolOnSetup( MEvent& event ) +{ + setCursor( MCursor::crossHairCursor ); + + mPoints.clear(); + mWorking = false; + mCurrentTreeLine = MObject::kNullObj; +} + +//============================================================================= +// TreeLineContext::toolOffCleanup +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TreeLineContext::toolOffCleanup() +{ + mPoints.clear(); + mCurrentTreeLine = MObject::kNullObj; +} + +//============================================================================= +// TreeLineContext::doPress +//============================================================================= +// Description: Comment +// +// Parameters: ( MEvent& event ) +// +// Return: MStatus +// +//============================================================================= +MStatus TreeLineContext::doPress( MEvent& event ) +{ + event.getPosition( mXCurrent, mYCurrent ); + ProcessState( BUTTONDOWN ); + return MStatus::kSuccess; +} + +//============================================================================= +// TreeLineContext::doDrag +//============================================================================= +// Description: Comment +// +// Parameters: ( MEvent& event ) +// +// Return: MStatus +// +//============================================================================= +MStatus TreeLineContext::doDrag( MEvent& event ) +{ + event.getPosition( mXCurrent, mYCurrent ); + ProcessState( MOUSEDRAG ); + return MStatus::kSuccess; +} + +//============================================================================= +// TreeLineContext::doRelease +//============================================================================= +// Description: Comment +// +// Parameters: ( MEvent& event ) +// +// Return: MStatus +// +//============================================================================= +MStatus TreeLineContext::doRelease( MEvent& event ) +{ + if ( event.mouseButton() == MEvent::kLeftMouse ) + { + event.getPosition( mXCurrent, mYCurrent ); + ProcessState( BUTTONUP ); + } + + return MStatus::kSuccess; +} + +//============================================================================= +// TreeLineContext::doHold +//============================================================================= +// Description: Comment +// +// Parameters: ( MEvent& event ) +// +// Return: MStatus +// +//============================================================================= +MStatus TreeLineContext::doHold( MEvent& event ) +{ + return MStatus::kSuccess; +} + +//============================================================================= +// TreeLineContext::doEnterRegion +//============================================================================= +// Description: Comment +// +// Parameters: ( MEvent& event ) +// +// Return: MStatus +// +//============================================================================= +MStatus TreeLineContext::doEnterRegion( MEvent& event ) +{ + SetHelpString(); + + return MStatus::kSuccess; +} + +//============================================================================= +// TreeLineContext::deleteAction +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TreeLineContext::deleteAction() +{ + ProcessState( DELETED ); +} + +//============================================================================= +// TreeLineContext::completeAction +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TreeLineContext::completeAction() +{ + ProcessState( COMPLETED ); +} + +//============================================================================= +// TreeLineContext::abortAction +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TreeLineContext::abortAction() +{ + ProcessState( ABORTED ); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// TreeLineContext::ProcessState +//============================================================================= +// Description: Comment +// +// Parameters: ( Stimulus stimulus ) +// +// Return: void +// +//============================================================================= +void TreeLineContext::ProcessState( Stimulus stimulus ) +{ + switch( stimulus ) + { + case BUTTONDOWN: + { + } + break; + + case BUTTONUP: + { + if ( !mWorking ) + { + //Let's create our working Treeline! + MObject transform; + MString name( TETreeLine::TreelineShapeNode::stringId ); + MExt::CreateNode( &mCurrentTreeLine, + &transform, + MString( TETreeLine::TreelineShapeNode::stringId ), + &name ); + mWorking = true; + + MFnTransform fnTransform( transform ); + fnTransform.findPlug( MString("translate") ).setLocked( true ); + fnTransform.findPlug( MString("rotate") ).setLocked( true ); + fnTransform.findPlug( MString("scale") ).setLocked( true ); + + TrackEditor::AddChild( mCurrentTreeLine ); + } + + //Set the position + MPoint intersectPoint; + if ( !MExt::MeshClickIntersect( mXCurrent, mYCurrent, intersectPoint ) ) + { + //Put it at 0. + MPoint vp( mXCurrent, mYCurrent, 0 ); + MExt::ViewToWorldAtY( &intersectPoint, vp, 0 ); //This is to y = 0 + } + + intersectPoint = intersectPoint / TEConstants::Scale; + + MStatus status; + MFnDependencyNode fnDepNode( mCurrentTreeLine ); + + MPlug verticesPlug = fnDepNode.findPlug( TETreeLine::TreelineShapeNode::mControlPoints, &status ); + assert( status ); + + unsigned int elementCount = verticesPlug.numElements(); + MPlug vertex = verticesPlug.elementByLogicalIndex( elementCount, &status ); + assert( status ); + + MPlug x = vertex.child( TETreeLine::TreelineShapeNode::mControlValueX, &status ); + assert( status ); + + x.setValue( intersectPoint.x * TEConstants::Scale ); + + MPlug y = vertex.child( TETreeLine::TreelineShapeNode::mControlValueY, &status ); + assert( status ); + y.setValue( intersectPoint.y * TEConstants::Scale ); + + MPlug z = vertex.child( TETreeLine::TreelineShapeNode::mControlValueZ, &status ); + assert( status ); + z.setValue( intersectPoint.z * TEConstants::Scale ); + + MGlobal::select( mCurrentTreeLine, MGlobal::kReplaceList ); + } + break; + case DELETED: + { + DeleteLast(); + } + break; + case ABORTED: + case COMPLETED: + { + //Start new treeline + mWorking = false; + mCurrentTreeLine = MObject::kNullObj; + } + break; + default: + { + } + break; + } + + SetHelpString(); +} + +//============================================================================= +// TreeLineContext::AddPoint +//============================================================================= +// Description: Comment +// +// Parameters: ( MPoint& point ) +// +// Return: void +// +//============================================================================= +void TreeLineContext::AddPoint( MPoint& point ) +{ + mPoints.append( point ); +} + +//============================================================================= +// TreeLineContext::DeleteLast +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TreeLineContext::DeleteLast() +{ + unsigned int size = mPoints.length(); + + if ( size ) + { + MStatus status; + + mPoints.remove( size - 1 ); + } +} + +//============================================================================= +// TreeLineContext::SetHelpString +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TreeLineContext::SetHelpString() +{ + mHelp = "Click to place vertices in the line."; + + setHelpString( mHelp ); +} diff --git a/tools/trackeditor/code/contexts/treelinecontext.h b/tools/trackeditor/code/contexts/treelinecontext.h new file mode 100644 index 0000000..a9833b7 --- /dev/null +++ b/tools/trackeditor/code/contexts/treelinecontext.h @@ -0,0 +1,139 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: treelinecontext.h +// +// Description: Blahblahblah +// +// History: 27/05/2002 + Created -- Cary Brisebois +// +//============================================================================= +#include "precompiled/PCH.h" + +#ifndef TREELINECONTEXT_H +#define TREELINECONTEXT_H + +//======================================== +// Nested Includes +//======================================== + + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class TreeLineContext : public MPxContext +{ +public: + + enum Stimulus // Maskable values. + { + BUTTONDOWN = 0x0001, + BUTTONUP = 0x0002, + MOUSEDRAG = 0x0004, + COMPLETED = 0x0008, + DELETED = 0x0010, + ABORTED = 0x0020 + }; + + TreeLineContext(); + virtual ~TreeLineContext(); + + static const char* stringId; + + virtual void toolOnSetup( MEvent& event); + virtual void toolOffCleanup(); + virtual MStatus doPress( MEvent& event); + virtual MStatus doDrag( MEvent& event ); + virtual MStatus doRelease( MEvent& event ); + virtual MStatus doHold( MEvent& event ); + virtual MStatus doEnterRegion( MEvent& event ); + virtual void deleteAction(); + virtual void completeAction(); + virtual void abortAction(); + +private: + void ProcessState( Stimulus stimulus ); + void AddPoint( MPoint& point ); + void DeleteLast(); + void SetHelpString(); + + MPointArray mPoints; + MString mHelp; + + static MObject mCurrentTreeLine; + static bool mWorking; + + short mXCurrent, mYCurrent; + +private: + + //Prevent wasteful constructor creation. + TreeLineContext( const TreeLineContext& treelinecontext ); + TreeLineContext& operator=( const TreeLineContext& treelinecontext ); +}; + +//****************************************************************************** +// +// TreeLineContextCmd +// +//****************************************************************************** + +class TreeLineContextCmd : public MPxContextCommand +{ + public: + TreeLineContextCmd() {}; + virtual ~TreeLineContextCmd() {}; + + static void* creator(); + + virtual MPxContext* makeObj(); + + private: +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// TreeLineContextCmd::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +inline void* TreeLineContextCmd::creator() +{ + return new TreeLineContextCmd(); +} + +//============================================================================= +// TreeLineContextCmd::makeObj +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MPxContext +// +//============================================================================= +inline MPxContext* TreeLineContextCmd::makeObj() +{ + return new TreeLineContext(); +} + + +#endif //TREELINECONTEXT_H + |