summaryrefslogtreecommitdiffstats
path: root/tools/objectsnapper/code/commands/snapselected.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/objectsnapper/code/commands/snapselected.cpp')
-rw-r--r--tools/objectsnapper/code/commands/snapselected.cpp435
1 files changed, 435 insertions, 0 deletions
diff --git a/tools/objectsnapper/code/commands/snapselected.cpp b/tools/objectsnapper/code/commands/snapselected.cpp
new file mode 100644
index 0000000..e6ab048
--- /dev/null
+++ b/tools/objectsnapper/code/commands/snapselected.cpp
@@ -0,0 +1,435 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File:
+//
+// Description: Implement SnapSelectedCmd
+//
+// History: 18/03/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+
+//========================================
+// Project Includes
+//========================================
+#include "snapselected.h"
+#include "utility/MUI.h"
+#include "utility/mext.h"
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+const char* SnapSelectedCmd::stringId = "OS_SnapSelected";
+const double OSScale = 100.0;
+
+enum SnapType
+{
+ ALL,
+ SINGLE,
+ TREELINE
+};
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// SnapSelectedCmd::SnapSelectedCmd
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+SnapSelectedCmd::SnapSelectedCmd()
+{
+ mObjDagPaths.clear();
+ mNewPositions.clear();
+ mOldPositions.clear();
+}
+
+//==============================================================================
+// SnapSelectedCmd::~SnapSelectedCmd
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+SnapSelectedCmd::~SnapSelectedCmd()
+{
+}
+
+//==============================================================================
+// SnapSelectedCmd::creator
+//==============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//==============================================================================
+void* SnapSelectedCmd::creator()
+{
+ return new SnapSelectedCmd();
+}
+
+//==============================================================================
+// SnapSelectedCmd::doit
+//==============================================================================
+// Description: Comment
+//
+// Parameters: ( const MArgList& args )
+//
+// Return: MStatus
+//
+//==============================================================================
+MStatus SnapSelectedCmd::doIt( const MArgList& args )
+{
+ if ( !MUI::ConfirmDialog( "Are you sure you want to snap these objects?\nYou can not UNDO this command." ) == MUI::YES )
+ {
+ //quit.
+ return MStatus::kSuccess;
+ }
+
+ assert( args.length() == 2 );
+
+ double OFFSET = 0;
+ int snapType = ALL;
+
+ args.get( 0, OFFSET );
+ args.get( 1, snapType );
+
+ OFFSET *= OSScale;
+
+ MSelectionList list;
+ MGlobal::getActiveSelectionList( list );
+
+ MItSelectionList i( list );
+
+ MFnDagNode fnDagNode;
+ MDagPath dagPath;
+ MItDag itDag;
+ MObject obj;
+ MDagPath objDagPath;
+ MObject childObj;
+
+ //For all selected objects.
+ for ( ; !i.isDone(); i.next() )
+ {
+ i.getDagPath( dagPath );
+
+ itDag.reset( dagPath, MItDag::kBreadthFirst, MFn::kTransform );
+
+ for ( ; !itDag.isDone() && itDag.depth() < 2; itDag.next() )
+ {
+ obj = itDag.item();
+ fnDagNode.setObject( obj );
+
+ const char* objName = fnDagNode.name().asChar();
+ const char* objTypeName = fnDagNode.typeName().asChar();
+
+ int childCount = fnDagNode.childCount();
+
+ int whichChild;
+
+ for ( whichChild = 0; whichChild < childCount; ++whichChild )
+ {
+ childObj = fnDagNode.child( whichChild );
+ fnDagNode.setObject( childObj );
+
+ const char* childObjName = fnDagNode.name().asChar();
+ const char* childObjTypeName = fnDagNode.typeName().asChar();
+
+ //Find a mesh below me and move my pivot to the intersection.
+ itDag.getPath( objDagPath );
+ MFnTransform fnTrans( objDagPath );
+
+ //Get all the child meshes of this obj node to prevent snapping to
+ //something that is part of me.
+
+ MStringArray meshNames;
+
+ GetChildMeshNames( objDagPath, meshNames );
+
+
+ MVector pos = fnTrans.translation( MSpace::kWorld );
+ MPoint rotate = fnTrans.rotatePivot( MSpace::kWorld );
+ MVector rayDir( 0, -1.0, 0 );
+
+ MItDag meshIt( MItDag::kDepthFirst, MFn::kMesh );
+ MDagPath meshDagPath;
+ MPointArray intersectPoints;
+
+ bool found = false;
+
+ for ( ; !meshIt.isDone(); meshIt.next() )
+ {
+ meshIt.getPath( meshDagPath );
+ MFnMesh mesh( meshDagPath );
+
+ const char* meshName = mesh.name().asChar();
+
+ unsigned int i;
+ bool nameFound = false;
+ for ( i = 0; i < meshNames.length(); ++i )
+ {
+ if ( meshNames[i] == mesh.name() )
+ {
+ nameFound = true;
+ break;
+ }
+ }
+
+ if ( nameFound )
+ {
+ continue;
+ }
+
+ if ( snapType == TREELINE )
+ {
+
+ }
+ else
+ {
+ mesh.intersect( rotate, rayDir, intersectPoints, 0.001f, MSpace::kWorld );
+
+ if ( intersectPoints.length() > 0 )
+ {
+ MVector diff( intersectPoints[ 0 ] - rotate );
+ diff.y += OFFSET;
+
+ //Prepare the command for the redo it ( which does all the work )
+ mObjDagPaths.append( fnTrans.dagPath() );
+ mNewPositions.append( diff );
+
+ //Save the old position.
+ MVector vector = fnTrans.translation( MSpace::kObject );
+ mOldPositions.append( vector );
+
+// //Move the transform.
+// fnTrans.translateBy( diff, MSpace::kWorld );
+
+ found = true;
+
+ break;
+ }
+ }
+ }
+
+ if ( !found )
+ {
+ //Look up
+ MPoint rotate = fnTrans.rotatePivot( MSpace::kWorld );
+ MVector rayDir( 0, 1.0, 0 );
+
+ MItDag meshIt( MItDag::kDepthFirst, MFn::kMesh );
+ MDagPath meshDagPath;
+ MPointArray intersectPoints;
+
+ for ( ; !meshIt.isDone(); meshIt.next() )
+ {
+ meshIt.getPath( meshDagPath );
+ MFnMesh mesh( meshDagPath );
+
+ const char* meshName = mesh.name().asChar();
+
+ unsigned int i;
+ bool nameFound = false;
+ for ( i = 0; i < meshNames.length(); ++i )
+ {
+ if ( meshNames[i] == mesh.name() )
+ {
+ nameFound = true;
+ break;
+ }
+ }
+
+ if ( nameFound )
+ {
+ continue;
+ }
+
+ if ( snapType == TREELINE )
+ {
+
+ }
+ else
+ {
+ mesh.intersect( rotate, rayDir, intersectPoints, 0.001f, MSpace::kWorld );
+
+ if ( intersectPoints.length() > 0 )
+ {
+ MVector diff( intersectPoints[ 0 ] - rotate );
+ diff.y -= OFFSET;
+
+ //Prepare the command for the redo it ( which does all the work )
+ mObjDagPaths.append( fnTrans.dagPath() );
+ mNewPositions.append( diff );
+
+ //Save the old position.
+ MVector vector = fnTrans.translation( MSpace::kObject );
+ mOldPositions.append( vector );
+
+// //Move the transform.
+// fnTrans.translateBy( diff, MSpace::kWorld );
+
+ found = true;
+
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !found )
+ {
+ MString errorMsg( "The object: " );
+ errorMsg += fnTrans.name();
+ errorMsg += MString( " has no mesh below it.\nNo snapping done on it." );
+
+ MUI::InfoDialog( errorMsg.asChar() );
+ }
+ }
+
+ if ( snapType == SINGLE )
+ {
+ //No more iterations.
+ break;
+ }
+ }
+ }
+
+ redoIt();
+
+ return MStatus::kSuccess;
+}
+
+//=============================================================================
+// SnapSelectedCmd::undoIt
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: MStatus
+//
+//=============================================================================
+MStatus SnapSelectedCmd::undoIt()
+{
+ unsigned int i;
+ for ( i = 0; i < mObjDagPaths.length(); ++i )
+ {
+ if ( mObjDagPaths[i].isValid() )
+ {
+ //Move this guy to the new position.
+ MFnTransform fnTransform( mObjDagPaths[i] );
+
+ fnTransform.setTranslation( mOldPositions[i], MSpace::kObject );
+ }
+ else
+ {
+ MExt::DisplayError( "Error performing snap due to invalid object or change in heirarchy" );
+ }
+ }
+
+ return MStatus::kSuccess;
+}
+
+//=============================================================================
+// SnapSelectedCmd::redoIt
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: MStatus
+//
+//=============================================================================
+MStatus SnapSelectedCmd::redoIt()
+{
+ unsigned int i;
+ for ( i = 0; i < mObjDagPaths.length(); ++i )
+ {
+ if ( mObjDagPaths[i].isValid() )
+ {
+ //Move this guy to the new position.
+ MFnTransform fnTransform( mObjDagPaths[i] );
+
+ fnTransform.translateBy( mNewPositions[i], MSpace::kWorld );
+ }
+ else
+ {
+ MExt::DisplayError( "Error performing snap due to invalid object or change in heirarchy" );
+ }
+ }
+
+ return MStatus::kSuccess;
+}
+
+//=============================================================================
+// SnapSelectedCmd::isUndoable
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: bool
+//
+//=============================================================================
+bool SnapSelectedCmd::isUndoable() const
+{
+ return true;
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// SnapSelectedCmd::GetChildMeshNames
+//==============================================================================
+// Description: Comment
+//
+// Parameters: ( MDagPath objDagPath, MStringArray& names )
+//
+// Return: void
+//
+//==============================================================================
+void SnapSelectedCmd::GetChildMeshNames( MDagPath objDagPath, MStringArray& names )
+{
+ names.clear();
+
+ MItDag itDag;
+ itDag.reset( objDagPath, MItDag::kDepthFirst, MFn::kMesh );
+
+ for ( ; !itDag.isDone(); itDag.next() )
+ {
+ MDagPath dagPath;
+ itDag.getPath( dagPath );
+ MFnMesh fnMesh( dagPath );
+
+ names.append( fnMesh.name() );
+
+ const char* meshName = fnMesh.name().asChar();
+ }
+
+}