689 lines
20 KiB
C++
689 lines
20 KiB
C++
#include "worldbuildercommands.h"
|
|
#include "main/worldbuilder.h"
|
|
#include "utility/mui.h"
|
|
#include "utility/mext.h"
|
|
#include "resources/resource.h"
|
|
#include "main/constants.h"
|
|
#include "nodes/wbspline.h"
|
|
#include "nodes/splinelocatornode.h"
|
|
#include "nodes/triggervolumenode.h"
|
|
#include "nodes/railcamlocatornode.h"
|
|
|
|
const char* WBChangeDisplayCommand::stringId = "WB_ChangeDisplay";
|
|
const char* WBSetLocatorTypeCmd::stringId = "WB_SetLocatorType";
|
|
const char* WBSetPrefixCmd::stringId = "WB_SetPrefix";
|
|
const char* WBSnapLocatorCmd::stringId = "WB_SnapLocator";
|
|
const char* WBSplineCompleteCmd::stringId = "WB_SplineComplete";
|
|
const char* WBCoinSplineCompleteCmd::stringId = "WB_CoinSplineComplete";
|
|
const char* WBSelectObjectCmd::stringId = "WB_SelectObject";
|
|
|
|
//******************************************************************************
|
|
//
|
|
// Callbacks
|
|
//
|
|
//******************************************************************************
|
|
|
|
BOOL CALLBACK SetPrefixLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam )
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
SetDlgItemText( hWnd, IDC_EDIT1, WorldBuilder::GetPrefix() );
|
|
return true;
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
{
|
|
if ( LOWORD(wParam) == IDCANCEL ||
|
|
LOWORD(wParam) == IDC_BUTTON1 ||
|
|
LOWORD(wParam) == IDOK )
|
|
{
|
|
//Get the entry in the text field.
|
|
char name[WorldBuilder::MAX_PREFIX_LENGTH];
|
|
GetDlgItemText( hWnd, IDC_EDIT1, name, WorldBuilder::MAX_PREFIX_LENGTH );
|
|
|
|
WorldBuilder::SetPrefix( name );
|
|
EndDialog( hWnd, 0 ); //this is how you close the window.
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL CALLBACK SplineNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam )
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
SetDlgItemText( hWnd, IDC_EDIT2, WorldBuilder::GetPrefix() );
|
|
return true;
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
{
|
|
if ( LOWORD(wParam) == IDC_BUTTON1 || LOWORD(wParam) == IDOK )
|
|
{
|
|
//Get the entry in the text field.
|
|
char name[WBSpline::MAX_NAME_LEN];
|
|
GetDlgItemText( hWnd, IDC_EDIT1, name, WBSpline::MAX_NAME_LEN );
|
|
|
|
if ( strcmp(name, "") == 0 )
|
|
{
|
|
MExt::DisplayWarning("You must input a new name for the Spline!");
|
|
return false;
|
|
}
|
|
|
|
MString newName( WorldBuilder::GetPrefix() );
|
|
newName += MString( name );
|
|
|
|
WBSpline::SetName( newName.asChar() );
|
|
EndDialog( hWnd, 0 ); //this is how you close the window.
|
|
return true;
|
|
}
|
|
else if( LOWORD(wParam) == IDCANCEL )
|
|
{
|
|
WBSpline::SetName( "" );
|
|
EndDialog( hWnd, 0 ); //this is how you close the window.
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//******************************************************************************
|
|
//
|
|
// Commands
|
|
//
|
|
//******************************************************************************
|
|
|
|
//=============================================================================
|
|
// WBChangeDisplayCommand::creator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void* WBChangeDisplayCommand::creator()
|
|
{
|
|
return new WBChangeDisplayCommand();
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBChangeDisplayCommand::doIt
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( const MArgList& args )
|
|
//
|
|
// Return: MStatus
|
|
//
|
|
//=============================================================================
|
|
MStatus WBChangeDisplayCommand::doIt( const MArgList& args )
|
|
{
|
|
assert( args.length() == 2 );
|
|
int arg;
|
|
args.get(0, arg);
|
|
|
|
int on;
|
|
args.get(1, on);
|
|
|
|
WorldBuilder::SetDisplayLevel( arg, on == 1 );
|
|
|
|
//Careful, don't call this too often!
|
|
M3dView::active3dView().refresh( true, true );
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSetLocatorTypeCmd::creator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void* WBSetLocatorTypeCmd::creator()
|
|
{
|
|
return new WBSetLocatorTypeCmd();
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSetLocatorTypeCmd::doIt
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( const MArgList& args )
|
|
//
|
|
// Return: MStatus
|
|
//
|
|
//=============================================================================
|
|
MStatus WBSetLocatorTypeCmd::doIt( const MArgList& args )
|
|
{
|
|
assert( args.length() == 1 );
|
|
|
|
MString string;
|
|
args.get( 0, string );
|
|
|
|
LocatorType::Type type;
|
|
|
|
int i;
|
|
for ( i = 0; i < LocatorType::NUM_TYPES; ++i )
|
|
{
|
|
if ( string == MString( LocatorType::Name[i] ) )
|
|
{
|
|
type = (LocatorType::Type)i;
|
|
WorldBuilder::SetLocatorType( type );
|
|
|
|
return MStatus::kSuccess;
|
|
}
|
|
}
|
|
|
|
assert( false );
|
|
|
|
return MStatus::kFailure;
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSetPrefixCmd::creator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void* WBSetPrefixCmd::creator()
|
|
{
|
|
return new WBSetPrefixCmd();
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSetPrefixCmd::doIt
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( const MArgList& args )
|
|
//
|
|
// Return: MStatus
|
|
//
|
|
//=============================================================================
|
|
MStatus WBSetPrefixCmd::doIt( const MArgList& args )
|
|
{
|
|
assert( args.length() == 0 );
|
|
|
|
MUI::PopupDialogue( IDD_DIALOG2, &SetPrefixLocatorNameCallBack );
|
|
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSnapLocatorCmd::creator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void* WBSnapLocatorCmd::creator()
|
|
{
|
|
return new WBSnapLocatorCmd();
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSnapLocatorCmd::doIt
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( const MArgList& args )
|
|
//
|
|
// Return: MStatus
|
|
//
|
|
//=============================================================================
|
|
MStatus WBSnapLocatorCmd::doIt( const MArgList& args )
|
|
{
|
|
assert( args.length() == 1 );
|
|
|
|
double OFFSET = 0;
|
|
|
|
args.get( 0, OFFSET );
|
|
|
|
OFFSET *= WBConstants::Scale;
|
|
|
|
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 );
|
|
|
|
|
|
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 );
|
|
|
|
mesh.intersect( rotate, rayDir, intersectPoints, 0.001f, MSpace::kWorld );
|
|
|
|
if ( intersectPoints.length() > 0 )
|
|
{
|
|
MVector diff( intersectPoints[ 0 ] - rotate );
|
|
diff.y += OFFSET;
|
|
|
|
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 );
|
|
|
|
mesh.intersect( rotate, rayDir, intersectPoints, 0.001f, MSpace::kWorld );
|
|
|
|
if ( intersectPoints.length() > 0 )
|
|
{
|
|
MVector diff( intersectPoints[ 0 ] - rotate );
|
|
diff.y -= OFFSET;
|
|
|
|
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() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSplineCompleteCmd::creator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void* WBSplineCompleteCmd::creator()
|
|
{
|
|
return new WBSplineCompleteCmd();
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSplineCompleteCmd::doIt
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( const MArgList& args )
|
|
//
|
|
// Return: WBSplineCompleteCmd
|
|
//
|
|
//=============================================================================
|
|
MStatus WBSplineCompleteCmd::doIt( const MArgList& args )
|
|
{
|
|
MSelectionList selectionList;
|
|
|
|
MGlobal::getActiveSelectionList( selectionList );
|
|
|
|
if ( selectionList.length() == 0 )
|
|
{
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
MObject spline;
|
|
selectionList.getDependNode( 0, spline );
|
|
|
|
MStatus status;
|
|
|
|
MFnTransform fnTransform( spline, &status );
|
|
assert( status );
|
|
|
|
if ( status )
|
|
{
|
|
MDagPath dagPath;
|
|
selectionList.getDagPath(0, dagPath);
|
|
dagPath.extendToShape();
|
|
|
|
MFnNurbsCurve fnNurbs( dagPath, &status );
|
|
assert( status );
|
|
|
|
int numCvs = fnNurbs.numCVs();
|
|
assert( numCvs );
|
|
|
|
MPoint cv;
|
|
MBoundingBox bBox;
|
|
int i;
|
|
for ( i = 0; i < numCvs; ++i )
|
|
{
|
|
fnNurbs.getCV( i, cv, MSpace::kWorld );
|
|
bBox.expand( cv );
|
|
}
|
|
|
|
MPoint halfway = bBox.center();
|
|
|
|
double radius = bBox.height() > bBox.width() ? bBox.height() : bBox.width();
|
|
radius = radius > bBox.depth() ? radius : bBox.depth();
|
|
radius = radius / WBConstants::Scale / 2.0;
|
|
|
|
MFnDependencyNode fnDepNodeSpline( fnTransform.child(0) );
|
|
|
|
MUI::PopupDialogue( IDD_DIALOG1, SplineNameCallBack );
|
|
|
|
//Get the new name of the spline...
|
|
const char* name = WBSpline::GetName();
|
|
MString newName( name );
|
|
|
|
MObject locator, triggerVolume, transform;
|
|
|
|
//Create the spline locator
|
|
MExt::CreateNode( locator,
|
|
transform,
|
|
MString( SplineLocatorNode::stringId ),
|
|
&newName );
|
|
|
|
MExt::SetWorldPosition( halfway, locator );
|
|
|
|
WorldBuilder::AddChild( locator );
|
|
|
|
//Name the spline
|
|
MString splineName = newName + MString("Spline");
|
|
fnTransform.setName( splineName );
|
|
WorldBuilder::AddChild( fnDepNodeSpline.object() );
|
|
|
|
//Adding an extra attribute to the spline!!
|
|
MFnMessageAttribute msgAttr;
|
|
MObject locatorAttr;
|
|
locatorAttr = msgAttr.create( "locator", "l", &status );
|
|
assert( status );
|
|
|
|
msgAttr.setReadable( true );
|
|
msgAttr.setWritable( false );
|
|
|
|
fnDepNodeSpline.addAttribute( locatorAttr );
|
|
|
|
//Connect the Spline to the Locator.
|
|
MExt::Connect( fnDepNodeSpline.object(), "locator", locator, SplineLocatorNode::SPLINE_NAME_LONG );
|
|
|
|
//Create the Trigger Volume
|
|
MString triggerName = newName + MString( "Trigger" );
|
|
|
|
MExt::CreateNode( triggerVolume,
|
|
transform,
|
|
MString( TriggerVolumeNode::stringId ),
|
|
&triggerName );
|
|
|
|
MExt::SetWorldPosition( halfway, triggerVolume );
|
|
|
|
MFnTransform fnTransform( transform );
|
|
const double scale[3] = { radius, radius, radius };
|
|
|
|
//Scale this bad-boy!
|
|
fnTransform.setScale( scale );
|
|
|
|
//Connect the Trigger Volume to the Locator.
|
|
MExt::Connect( triggerVolume, TriggerVolumeNode::LOCATOR_NAME_LONG, locator, SplineLocatorNode::TRIGGERS_NAME_LONG );
|
|
|
|
WorldBuilder::AddChild( triggerVolume );
|
|
|
|
//Create the railcam
|
|
MObject railLocator;
|
|
MString railName = newName + MString( "RailCam" );
|
|
MExt::CreateNode( railLocator,
|
|
transform,
|
|
MString( RailCamLocatorNode::stringId ),
|
|
&railName );
|
|
|
|
fnNurbs.getCV( 0, cv, MSpace::kWorld );
|
|
MExt::SetWorldPosition( cv, railLocator );
|
|
MExt::Connect( railLocator, "message", locator, SplineLocatorNode::CAMERA_NAME_LONG );
|
|
MExt::Connect( fnDepNodeSpline.object(), "message", railLocator, RailCamLocatorNode::RAIL_NAME_LONG );
|
|
|
|
WorldBuilder::AddChild( railLocator );
|
|
}
|
|
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBCoinSplineCompleteCmd::creator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void* WBCoinSplineCompleteCmd::creator()
|
|
{
|
|
return new WBCoinSplineCompleteCmd();
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBCoinSplineCompleteCmd::doIt
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( const MArgList& args )
|
|
//
|
|
// Return: WBCoinSplineCompleteCmd
|
|
//
|
|
//=============================================================================
|
|
MStatus WBCoinSplineCompleteCmd::doIt( const MArgList& args )
|
|
{
|
|
MSelectionList selectionList;
|
|
|
|
MGlobal::getActiveSelectionList( selectionList );
|
|
|
|
if ( selectionList.length() == 0 )
|
|
{
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
|
|
MObject spline;
|
|
selectionList.getDependNode( 0, spline );
|
|
|
|
MStatus status;
|
|
|
|
MFnTransform fnTransform( spline, &status );
|
|
assert( status );
|
|
|
|
if ( status )
|
|
{
|
|
MDagPath dagPath;
|
|
selectionList.getDagPath(0, dagPath);
|
|
dagPath.extendToShape();
|
|
|
|
MFnNurbsCurve fnNurbs( dagPath, &status );
|
|
assert( status );
|
|
|
|
int numCvs = fnNurbs.numCVs();
|
|
assert( numCvs );
|
|
|
|
MFnDependencyNode fnDepNodeSpline( fnTransform.child(0) );
|
|
|
|
MUI::PopupDialogue( IDD_DIALOG1, SplineNameCallBack );
|
|
|
|
//Get the new name of the spline...
|
|
const char* name = WBSpline::GetName();
|
|
MString newName( name );
|
|
|
|
MObject locator, triggerVolume, transform;
|
|
|
|
//Create the spline locator
|
|
MExt::CreateNode( locator,
|
|
transform,
|
|
MString( SplineLocatorNode::stringId ),
|
|
&newName );
|
|
|
|
MExt::SetWorldPosition( MPoint(0,0,0), locator );
|
|
|
|
//Set this locator to say that it is a coin locator
|
|
MFnDependencyNode fnNode( locator );
|
|
fnNode.findPlug( SplineLocatorNode::sIsCoin ).setValue( true );
|
|
|
|
WorldBuilder::AddChild( locator );
|
|
|
|
//Name the spline
|
|
MString splineName = newName + MString("Spline");
|
|
fnTransform.setName( splineName );
|
|
WorldBuilder::AddChild( fnDepNodeSpline.object() );
|
|
|
|
//Adding an extra attribute to the spline!!
|
|
MFnMessageAttribute msgAttr;
|
|
MObject locatorAttr;
|
|
locatorAttr = msgAttr.create( "locator", "l", &status );
|
|
assert( status );
|
|
|
|
msgAttr.setReadable( true );
|
|
msgAttr.setWritable( false );
|
|
|
|
fnDepNodeSpline.addAttribute( locatorAttr );
|
|
|
|
//Add a num coins attribute to the spline
|
|
MFnNumericAttribute numAttr;
|
|
MObject numCoinAttr;
|
|
numCoinAttr = numAttr.create( "numCoins", "nc", MFnNumericData::kInt, 10, &status );
|
|
assert( status );
|
|
|
|
numAttr.setReadable( true );
|
|
numAttr.setWritable( true );
|
|
|
|
fnDepNodeSpline.addAttribute( numCoinAttr );
|
|
|
|
//Connect the Spline to the Locator.
|
|
MExt::Connect( fnDepNodeSpline.object(), "locator", locator, SplineLocatorNode::SPLINE_NAME_LONG );
|
|
}
|
|
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
//=============================================================================
|
|
// WBSelectObjectCmd::creator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void* WBSelectObjectCmd::creator()
|
|
{
|
|
return new WBSelectObjectCmd();
|
|
}
|
|
|
|
MStatus WBSelectObjectCmd::doIt( const MArgList& args )
|
|
{
|
|
assert( args.length() == 1 );
|
|
|
|
MString objName;
|
|
|
|
args.get( 0, objName );
|
|
|
|
WorldBuilder::SetSelectedLocator( objName.asChar() );
|
|
|
|
return MStatus::kSuccess;
|
|
} |