summaryrefslogtreecommitdiffstats
path: root/tools/trackeditor/code/contexts/ppcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/trackeditor/code/contexts/ppcontext.cpp')
-rw-r--r--tools/trackeditor/code/contexts/ppcontext.cpp717
1 files changed, 717 insertions, 0 deletions
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 );
+}
+