diff options
Diffstat (limited to 'tools/worldbuilder/code/nodes/splinelocatornode.cpp')
-rw-r--r-- | tools/worldbuilder/code/nodes/splinelocatornode.cpp | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/tools/worldbuilder/code/nodes/splinelocatornode.cpp b/tools/worldbuilder/code/nodes/splinelocatornode.cpp new file mode 100644 index 0000000..14765be --- /dev/null +++ b/tools/worldbuilder/code/nodes/splinelocatornode.cpp @@ -0,0 +1,439 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: SplineLocatorNode.cpp +// +// Description: Implement SplineLocatorNode +// +// History: 05/06/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/SplineLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/mext.h" +#include "utility/glext.h" +#include "nodes/triggervolumenode.h" +#include "nodes/wbspline.h" +#include "nodes/railcamlocatornode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +const char* SplineLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* SplineLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject SplineLocatorNode::sTriggers; + +const char* SplineLocatorNode::SPLINE_NAME_LONG = "spline"; +const char* SplineLocatorNode::SPLINE_NAME_SHORT = "spl"; +MObject SplineLocatorNode::sSpline; + +const char* SplineLocatorNode::CAMERA_NAME_LONG = "camera"; +const char* SplineLocatorNode::CAMERA_NAME_SHORT = "cam"; +MObject SplineLocatorNode::sCamera; + +const char* SplineLocatorNode::IS_COIN_SHORT = "ic"; +const char* SplineLocatorNode::IS_COIN_LONG = "isCoin"; +MObject SplineLocatorNode::sIsCoin; + + +const char* SplineLocatorNode::stringId = "SplineLocatorNode"; +MTypeId SplineLocatorNode::id = WBConstants::NodeIDs::SplineLocator; + + +MPointArray GetCoinPoints( MObject& nurbsCurve, MObject& locator, bool justWP ) +{ + MFnDagNode fnDagNode( nurbsCurve ); + MDagPath dagPath; + fnDagNode.getPath( dagPath ); + + MStatus status; + + MFnNurbsCurve fnNurbs( dagPath, &status ); + assert( status ); + + const char* name = fnNurbs.name().asChar(); + + MPointArray points; + + if ( status ) + { + int numCVs = fnNurbs.numCVs( &status ); + assert( status ); + + //Get the number of coins + int numCoins = 0; + fnDagNode.findPlug( MString("numCoins") ).getValue( numCoins ); + assert( numCoins ); + + if ( numCoins == 0 ) + { + MExt::DisplayError( "Coin spline: %s has no coins!", fnDagNode.name().asChar() ); + } + else + { + //Need to undo funny transformations... + MMatrix mat; + mat.setToIdentity(); + + MObject transform; + MFnDependencyNode locDepNode( locator ); + MDagPath locatorDagPath; + MExt::FindDagNodeByName( &locatorDagPath, locDepNode.name() ); + MFnDagNode locDagNode( locatorDagPath ); + + const char* otherName = locDagNode.name().asChar(); + + transform = locDagNode.parent( 0 ); + MFnDependencyNode transNode( transform ); + MDagPath transPath; + MExt::FindDagNodeByName( &transPath, transNode.name() ); + MFnTransform fnTransform( transPath ); + + const char* nameHere = fnTransform.name().asChar(); + + MFnTransform splineTrans( dagPath ); //This is the splines transform. + MPoint splinePos( splineTrans.translation( MSpace::kWorld ) ); + + + mat = fnTransform.transformationMatrix(); + + mat = mat.inverse(); + + double numCoinSpans = fnNurbs.numSpans(); + + double coinsPerFullSpan = (double)numCoins / numCoinSpans; + + //Draw a coin at even intervals. + double interval = 1.0 / coinsPerFullSpan; + + double i; + for ( i = 0; i < numCoins; ++i ) + { + MPoint point; + fnNurbs.getPointAtParam( interval * i, point, MSpace::kWorld ); + + if ( !justWP ) + { + //Put in world space + point *= mat; + point += splinePos; + } + + points.append( point ); + } + } + } + + return points; +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// SplineLocatorNode::SplineLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SplineLocatorNode::SplineLocatorNode() +{ +} + +//============================================================================== +// SplineLocatorNode::~SplineLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SplineLocatorNode::~SplineLocatorNode() +{ +} + +//============================================================================= +// SplineLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void SplineLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + MStatus status; + MFnDependencyNode fnNode( thisMObject() ); + bool isCoins = false; + fnNode.findPlug( sIsCoin ).getValue( isCoins ); + if ( isCoins ) + { + + const char* name = fnNode.name().asChar(); + + //When we are in render mode, we draw the lines between the nodes. + //If this was in GL_SELECTION_MODE, we would not draw the lines, so they won't interfere + //with selection. + GLint value; + glGetIntegerv( GL_RENDER_MODE, &value ); + + //Draw things here we don't want selectable. + if ( (value == GL_RENDER) ) + { + //Get the attached Maya spline. + MPlugArray sources, targets; + //Get the spline associated with this bad-boy. + MPlug splinePlug = fnNode.findPlug( sSpline ); + MExt::ResolveConnections( &sources, &targets, splinePlug, true, false ); + assert( sources.length() == 1 ); + + MPointArray points = GetCoinPoints( sources[0].node(), thisMObject(), false ); + unsigned int i; + for ( i = 0; i < points.length(); ++i ) + { + GLExt::drawO( 1.0 * WBConstants::Scale, points[i].x, points[i].y + 0.25, points[i].z, 3.0f ); + } + } + } +} + +//============================================================================= +// SplineLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus SplineLocatorNode::initialize() +{ + MFnMessageAttribute msgAttr; + MStatus status; + + sTriggers = msgAttr.create( TRIGGERS_NAME_LONG, TRIGGERS_NAME_SHORT, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( msgAttr.setReadable( false ) ); + RETURN_STATUS_ON_FAILURE( msgAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( msgAttr.setArray( true ) ); + RETURN_STATUS_ON_FAILURE( msgAttr.setIndexMatters( false ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sTriggers ) ); + + sSpline = msgAttr.create( SPLINE_NAME_LONG, SPLINE_NAME_SHORT, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( msgAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( msgAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sSpline ) ); + + sCamera = msgAttr.create( CAMERA_NAME_LONG, CAMERA_NAME_SHORT, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( msgAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( msgAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sCamera ) ); + + MFnNumericAttribute numAttr; + sIsCoin = numAttr.create( IS_COIN_LONG, IS_COIN_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sIsCoin ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// SplineLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void SplineLocatorNode::postConstructor() +{ + setExistWithoutInConnections( false ); + setExistWithoutOutConnections( false ); +} + +//============================================================================= +// SplineLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& splineLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* SplineLocatorNode::Export( MObject& splineLocatorNode ) +{ + MFnDagNode fnNode( splineLocatorNode ); + + if ( fnNode.typeId() == SplineLocatorNode::id ) + { + bool isCoinSpline = false; + fnNode.findPlug( sIsCoin ).getValue( isCoinSpline ); + if ( isCoinSpline ) + { + //Export a coin spline. + MPlugArray sources, targets; + //Get the spline associated with this bad-boy. + MPlug splinePlug = fnNode.findPlug( sSpline ); + MExt::ResolveConnections( &sources, &targets, splinePlug, true, false ); + assert( sources.length() == 1 ); + + MPointArray points = GetCoinPoints( sources[0].node(), splineLocatorNode, true ); + + tlWBLocatorChunk* locator = NULL; + + unsigned int coinCount = 0; + + if ( points.length() > 0 ) + { + locator = new tlWBLocatorChunk; + + locator->SetType( LocatorType::GENERIC ); + + unsigned int i; + for ( i = 0; i < points.length(); ++i ) + { + tlWBLocatorChunk* coinLoc = new tlWBLocatorChunk; + coinLoc->SetType( LocatorType::COIN ); + + tlPoint point; + point.x = points[i].x / WBConstants::Scale; + point.y = points[i].y / WBConstants::Scale; + point.z = -points[i].z / WBConstants::Scale; + + coinLoc->SetPosition( point ); + + char name[256]; + sprintf( name, "%sCoin%d", fnNode.name().asChar(), coinCount ); + coinLoc->SetName( name ); + ++coinCount; + + + locator->AppendSubChunk( coinLoc ); + } + } + + return locator; + + } + else + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::SPLINE ); + + //The data here is the event associated with this locator. + locator->SetNumDataElements( 0 ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, splineLocatorNode ); + + //Set the values. + tlPoint point; + + point[0] = thisPosition[0] / WBConstants::Scale; + point[1] = thisPosition[1] / WBConstants::Scale; + point[2] = -thisPosition[2] / WBConstants::Scale; //Maya vs. P3D... + locator->SetPosition( point ); + + MPlugArray sources, targets; + //Get the spline associated with this bad-boy. + MPlug splinePlug = fnNode.findPlug( sSpline ); + MExt::ResolveConnections( &sources, &targets, splinePlug, true, false ); + assert( sources.length() == 1 ); + + tlDataChunk* splineChunk = WBSpline::Export( sources[ 0 ].node() ); + assert( splineChunk ); + + if ( splineChunk ) + { + //Get the camera and append it here. + MPlug railCamPlug = fnNode.findPlug( sCamera ); + MExt::ResolveConnections( &sources, &targets, railCamPlug, true, false ); + assert( targets.length() == 1 ); + + tlDataChunk* railCamChunk = RailCamLocatorNode::Export( sources[0].node() ); + assert( railCamChunk ); + splineChunk->AppendSubChunk( railCamChunk ); + + locator->AppendSubChunk( splineChunk ); + } + else + { + MExt::DisplayError( "No spline attached to: %s!", fnNode.name().asChar() ); + } + + //Make the trigger volumes a sub-chunk of the locator... + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + unsigned int i; + for ( i = 0; i < sources.length(); ++i ) + { + tlDataChunk* trigger = TriggerVolumeNode::Export( sources[ i ].node() ); + assert( trigger ); + + locator->AppendSubChunk( trigger ); + } + + locator->SetNumTriggers( i ); + + return locator; + } + + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** |