diff options
Diffstat (limited to 'tools/worldbuilder/code/nodes')
35 files changed, 9047 insertions, 0 deletions
diff --git a/tools/worldbuilder/code/nodes/actioneventlocatornode.cpp b/tools/worldbuilder/code/nodes/actioneventlocatornode.cpp new file mode 100644 index 0000000..5d6b577 --- /dev/null +++ b/tools/worldbuilder/code/nodes/actioneventlocatornode.cpp @@ -0,0 +1,651 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: ActionEventLocatorNode.cpp +// +// Description: Implement ActionEventLocatorNode +// +// History: 30/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <afxwin.h> + +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/ActionEventLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "utility/transformmatrix.h" +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" +#include "../../../game/code/ai/actionnames.h" +#include "../../../game/code/worldsim/character/charactercontroller.h" + +int SortFunc( const void* pName1, const void* pName2 ) +{ + return stricmp( *(char**)pName1, *(char**)pName2 ); +} + +void UpdateJoints( HWND hWnd, MObject& root ) +{ + CWnd* wnd = CWnd::FromHandle( GetDlgItem( hWnd, IDC_COMBO2 ) ); + CComboBox* jointList = (CComboBox*)( wnd ); + + assert( jointList ); + + jointList->ResetContent(); + + MObjectArray jointArray; + if ( MExt::FindAllTransforms( &jointArray, root ) ) + { + unsigned int i; + for ( i = 0; i < jointArray.length(); ++i ) + { + MFnDependencyNode fnNode( jointArray[i] ); + + jointList->AddString( fnNode.name().asChar() ); + } + } + else + { + jointList->AddString( "NO JOINTS!" ); + } + + jointList->SetCurSel( 0 ); +} + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId ActionEventLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::ActionEventLocator ); +const char* ActionEventLocatorNode::stringId = "ActionEventLocatorNode"; + +const int ActionEventLocatorNode::ACTIVE_COLOUR = 15; +const int ActionEventLocatorNode::INACTIVE_COLOUR = 12; +const float ActionEventLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* ActionEventLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* ActionEventLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject ActionEventLocatorNode::sTriggers; + +const char* ActionEventLocatorNode::OBJECT_NAME_SHORT = "acnobjt"; +const char* ActionEventLocatorNode::OBJECT_NAME_LONG = "actionObject"; +MObject ActionEventLocatorNode::sObject; + +const char* ActionEventLocatorNode::JOINT_NAME_SHORT = "jnt"; +const char* ActionEventLocatorNode::JOINT_NAME_LONG = "joint"; +MObject ActionEventLocatorNode::sJoint; + +const char* ActionEventLocatorNode::ACTION_NAME_SHORT = "actn"; +const char* ActionEventLocatorNode::ACTION_NAME_LONG = "action"; +MObject ActionEventLocatorNode::sActionType; + +const char* ActionEventLocatorNode::BUTTON_NAME_SHORT = "btninpt"; +const char* ActionEventLocatorNode::BUTTON_NAME_LONG = "buttonInput"; +MObject ActionEventLocatorNode::sButtonInput; + +const char* ActionEventLocatorNode::TRANSFORM_NAME_SHORT = "st"; +const char* ActionEventLocatorNode::TRANSFORM_NAME_LONG = "shouldTransform"; +MObject ActionEventLocatorNode::sTransform; + +const char* ActionEventLocatorNode::EXPORT_TRANSFORM_NAME_SHORT = "exptTrans"; +const char* ActionEventLocatorNode::EXPORT_TRANSFORM_NAME_LONG = "exportTransform"; +MObject ActionEventLocatorNode::sExportTransform; + +char ActionEventLocatorNode::sNewName[MAX_NAME_LEN]; +char ActionEventLocatorNode::sNewObj[MAX_NAME_LEN]; +char ActionEventLocatorNode::sNewJoint[MAX_NAME_LEN]; + +const char* ActionEventLocatorNode::names[ActionButton::ActionNameSize]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK ActionEventLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + SetDlgItemText( hWnd, IDC_EDIT2, WorldBuilder::GetPrefix() ); + SetDlgItemText( hWnd, IDC_EDIT3, "" ); + + CWnd* wnd = CWnd::FromHandle( GetDlgItem( hWnd, IDC_COMBO1 ) ); + CComboBox* objectList = (CComboBox*)( wnd ); + + assert( objectList ); + + objectList->ResetContent(); + + bool foundSkeletonRoots = false; + MObjectArray skeletonRoots; + + if ( MExt::FindAllSkeletonRoots( &skeletonRoots ) ) + { + //Fill up with all the roots. + unsigned int i; + for ( i = 0; i < skeletonRoots.length(); ++i ) + { + MFnDependencyNode fnNode( skeletonRoots[i] ); + + objectList->AddString( fnNode.name().asChar() ); + } + + foundSkeletonRoots = true; + } + else + { + objectList->AddString( "NO SKELETON ROOTS!" ); + } + + objectList->SetCurSel( 0 ); + + char objName[256]; + GetDlgItemText( hWnd, IDC_COMBO1, objName, 256 ); + + MDagPath path; + MExt::FindDagNodeByName( &path, MString( objName ) ); + + UpdateJoints( hWnd, path.node() ); + + return true; + } + break; + case WM_COMMAND: + { + if ( LOWORD(wParam) == IDC_BUTTON1 || LOWORD(wParam) == IDOK ) + { + //Get the entry in the text field. + char name[ActionEventLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, ActionEventLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Action Event Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + ActionEventLocatorNode::SetNewName( newName.asChar() ); + + //Do the Object name too... + GetDlgItemText( hWnd, IDC_COMBO1, name, ActionEventLocatorNode::MAX_NAME_LEN ); + + MString possibleName( name ); + MString corrected = possibleName; + int index = possibleName.index( ':' ); + if ( index != -1 ) + { + corrected = possibleName.substring( index + 1, possibleName.length() - 1 ); + } + else + + if ( strcmp(corrected.asChar(), "") == 0 ) + { + MExt::DisplayWarning("You must input an object name!"); + return false; + } + + ActionEventLocatorNode::SetNewObj( corrected.asChar() ); + + //Do the Object name too... + GetDlgItemText( hWnd, IDC_COMBO2, name, ActionEventLocatorNode::MAX_NAME_LEN ); + + possibleName = MString( name ); + corrected = possibleName; + index = possibleName.index( ':' ); + if ( index != -1 ) + { + corrected = possibleName.substring( index + 1, possibleName.length() - 1 ); + } + + if ( strcmp(corrected.asChar(), "") == 0 ) + { + MExt::DisplayWarning("You must input a joint name!"); + return false; + } + + ActionEventLocatorNode::SetNewJoint( corrected.asChar() ); + + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + ActionEventLocatorNode::SetNewName( "" ); + ActionEventLocatorNode::SetNewObj( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if ( LOWORD(wParam) == IDC_COMBO1 ) + { + DWORD hiWord = HIWORD(wParam); + + if ( hiWord == CBN_SELCHANGE ) + { + char objName[256]; + GetDlgItemText( hWnd, IDC_COMBO1, objName, 256 ); + + MDagPath path; + MExt::FindDagNodeByName( &path, MString( objName ) ); + + UpdateJoints( hWnd, path.node() ); + } + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// ActionEventLocatorNode::ActionEventLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ActionEventLocatorNode::ActionEventLocatorNode() +{ + unsigned int i; + for ( i = 0; i < MAX_NAME_LEN; ++i ) + { + sNewJoint[i] = '\0'; + } +} + +//============================================================================== +// ActionEventLocatorNode::~ActionEventLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ActionEventLocatorNode::~ActionEventLocatorNode() +{ +} + +//============================================================================= +// ActionEventLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* ActionEventLocatorNode::creator() +{ + return new ActionEventLocatorNode(); +} + +//============================================================================= +// ActionEventLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void ActionEventLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::ACTION_EVENT_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + MPlugArray sources, targets; + MFnDagNode fnNode( thisMObject() ); + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + unsigned int i; + for ( i = 0; i < sources.length(); ++i ) + { + //Draw a box around the source trigger volume. + MPoint triggerWP, thisWP; + + MExt::GetWorldPosition( &triggerWP, sources[i].node() ); + + //MExt::GetWorldPosition( &thisWP, thisMObject() ); + MMatrix mat = MExt::GetWorldMatrix( thisMObject() ); + MMatrix invMat = mat.inverse(); + + MPoint triggerLP; + //triggerLP = triggerWP - thisWP; + triggerLP = triggerWP * invMat; + + view.setDrawColor( 8, M3dView::kActiveColors ); + + GLExt::drawLine( MPoint(0,0,0), triggerLP, 5.0f ); + } + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawPyramid( SCALE, 0,0,0, 5.0 ); + GLExt::drawA( SCALE, 0,1,0, 5.0 ); + GLExt::drawArrow( MPoint( 0, 0, 0 ), MPoint( 0, 0, -1 * WBConstants::Scale ), 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// ActionEventLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus ActionEventLocatorNode::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 ) ); + + MFnTypedAttribute typedAttr; + sObject = typedAttr.create( OBJECT_NAME_LONG, OBJECT_NAME_SHORT, MFnData::kString, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typedAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typedAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sObject ) ); + + sJoint = typedAttr.create( JOINT_NAME_LONG, JOINT_NAME_SHORT, MFnData::kString, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typedAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typedAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sJoint ) ); + + MFnEnumAttribute enumAttr; + sActionType = enumAttr.create( ACTION_NAME_LONG, ACTION_NAME_SHORT, 0, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( enumAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( enumAttr.setWritable( true ) ); + + unsigned int i; + for ( i = 0; i < ActionButton::ActionNameSize; ++i ) + { + names[i] = ActionButton::ActionName[i]; + } + + // Sorting seems to make a mess of things. + // commenting out for now. + // TBJ [8/9/2002] + // + //qsort( names, ActionButton::ActionNameSize, sizeof( char* ), SortFunc ); + + for ( i = 0; i < ActionButton::ActionNameSize; ++i ) + { + RETURN_STATUS_ON_FAILURE( enumAttr.addField( MString( names[i] ), i ) ); + } + + RETURN_STATUS_ON_FAILURE( addAttribute( sActionType ) ); + + sButtonInput = enumAttr.create( BUTTON_NAME_LONG, BUTTON_NAME_SHORT, CharacterController::DoAction, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( enumAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( enumAttr.setWritable( true ) ); + for ( i = 0; i < ActionButton::ButtonNameListSize; ++i ) + { + RETURN_STATUS_ON_FAILURE( enumAttr.addField( MString( ActionButton::ButtonName[i] ), i ) ); + } + + RETURN_STATUS_ON_FAILURE( addAttribute( sButtonInput ) ); + + MFnNumericAttribute numericAttr; + sTransform = numericAttr.create( TRANSFORM_NAME_LONG, TRANSFORM_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTransform ) ); + + sExportTransform = numericAttr.create( EXPORT_TRANSFORM_NAME_LONG, EXPORT_TRANSFORM_NAME_SHORT, MFnNumericData::kBoolean, true, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sExportTransform ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// ActionEventLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void ActionEventLocatorNode::postConstructor() +{ +} + +//============================================================================= +// ActionEventLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& actionEventLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* ActionEventLocatorNode::Export( MObject& actionEventLocatorNode ) +{ + MFnDagNode fnNode( actionEventLocatorNode ); + + if ( fnNode.typeId() == ActionEventLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::ACTION ); + + MString objName; + MString jointName; + int actionInt; + MString actionName; + int button; + bool shouldTransform; + + //Get the data + fnNode.findPlug( ActionEventLocatorNode::sObject ).getValue( objName ); + if ( objName.length() == 0 ) + { + objName.set( "<null>" ); + } + + fnNode.findPlug( ActionEventLocatorNode::sJoint ).getValue( jointName ); + if ( jointName.length() == 0 ) + { + jointName.set( "<null>" ); + } + fnNode.findPlug( ActionEventLocatorNode::sActionType ).getValue( actionInt ); + + actionName = MString( names[actionInt] ); + + fnNode.findPlug( ActionEventLocatorNode::sButtonInput ).getValue( button ); + fnNode.findPlug( ActionEventLocatorNode::sTransform ).getValue( shouldTransform ); + + //Save it out. + unsigned int length = (objName.length() / 4 + 1) + + (jointName.length() / 4 + 1) + + (actionName.length() / 4 + 1) + + 2; //button and shouldTransform + + unsigned long* data = new unsigned long[length]; + + unsigned int i; + for ( i = 0; i < length; ++i ) + { + data[i] = 0; + } + + unsigned int next = 0; + memcpy( data, objName.asChar(), objName.length() ); + next = objName.length() / 4 + 1; + + memcpy( &data[next], jointName.asChar(), jointName.length() ); + next += jointName.length() / 4 + 1; + + memcpy( &data[next], actionName.asChar(), actionName.length() ); + next += actionName.length() / 4 + 1; + + memcpy( &data[next], &button, sizeof(int) ); + next++; + + memcpy( &data[next], &shouldTransform, sizeof(bool) ); + + locator->SetDataElements( data, length ); + locator->SetNumDataElements( length ); + + delete data; + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, actionEventLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + for ( i = 0; i < sources.length(); ++i ) + { + tlDataChunk* trigger = TriggerVolumeNode::Export( sources[ i ].node() ); + assert( trigger ); + + locator->AppendSubChunk( trigger ); + } + + locator->SetNumTriggers( i ); + + //Add the matrix if we're supposed to. + bool exportTrans = false; + fnNode.findPlug( sExportTransform ).getValue( exportTrans ); + if ( exportTrans ) + { + //Also get the direction. + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( hmatrix ); + //Make this p3d friendly... + hmatrix.element[3][0] /= WBConstants::Scale; + hmatrix.element[3][1] /= WBConstants::Scale; + hmatrix.element[3][2] /= WBConstants::Scale; + + tlExtraMatrixChunk* emChunk = new tlExtraMatrixChunk(); + emChunk->SetMatrix( hmatrix ); + + locator->AppendSubChunk( emChunk ); + } + + return locator; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/actioneventlocatornode.h b/tools/worldbuilder/code/nodes/actioneventlocatornode.h new file mode 100644 index 0000000..0019a9b --- /dev/null +++ b/tools/worldbuilder/code/nodes/actioneventlocatornode.h @@ -0,0 +1,205 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: actioneventlocatornode.h +// +// Description: Blahblahblah +// +// History: 29/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef ACTIONEVENTLOCATORNODE_H +#define ACTIONEVENTLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" +#include "../../../game/code/ai/actionnames.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK ActionEventLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class ActionEventLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + ActionEventLocatorNode(); + virtual ~ActionEventLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& eventLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + static void SetNewObj( const char* name ); + static const char* const GetNewObj(); + static void SetNewJoint( const char* name ); + static const char* const GetNewJoint(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* OBJECT_NAME_SHORT; + static const char* OBJECT_NAME_LONG; + static MObject sObject; + + static const char* JOINT_NAME_SHORT; + static const char* JOINT_NAME_LONG; + static MObject sJoint; + + static const char* ACTION_NAME_SHORT; + static const char* ACTION_NAME_LONG; + static MObject sActionType; + + static const char* BUTTON_NAME_SHORT; + static const char* BUTTON_NAME_LONG; + static MObject sButtonInput; + + static const char* TRANSFORM_NAME_SHORT; + static const char* TRANSFORM_NAME_LONG; + static MObject sTransform; + + static const char* EXPORT_TRANSFORM_NAME_SHORT; + static const char* EXPORT_TRANSFORM_NAME_LONG; + static MObject sExportTransform; +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + static char sNewObj[MAX_NAME_LEN]; + static char sNewJoint[MAX_NAME_LEN]; + + //We want the names in alphapetical order. + static const char* names[ActionButton::ActionNameSize]; + + //Prevent wasteful constructor creation. + ActionEventLocatorNode( const ActionEventLocatorNode& actioneventlocatornode ); + ActionEventLocatorNode& operator=( const ActionEventLocatorNode& actioneventlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// ActionEventLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void ActionEventLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// ActionEventLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const ActionEventLocatorNode::GetNewName() +{ + return sNewName; +} + +//============================================================================= +// ActionEventLocatorNode::SetNewObj +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void ActionEventLocatorNode::SetNewObj( const char* name ) +{ + strncpy( sNewObj, name, MAX_NAME_LEN); +} + +//============================================================================= +// ActionEventLocatorNode::GetNewObj +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const ActionEventLocatorNode::GetNewObj() +{ + return sNewObj; +} + +//============================================================================= +// ActionEventLocatorNode::SetNewJoint +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void ActionEventLocatorNode::SetNewJoint( const char* name ) +{ + strncpy( sNewJoint, name, MAX_NAME_LEN); +} + +//============================================================================= +// ActionEventLocatorNode::GetNewJoint +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const ActionEventLocatorNode::GetNewJoint() +{ + return sNewJoint; +} + +#endif //ACTIONEVENTLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/breakablecameralocatornode.cpp b/tools/worldbuilder/code/nodes/breakablecameralocatornode.cpp new file mode 100644 index 0000000..0b0cd5c --- /dev/null +++ b/tools/worldbuilder/code/nodes/breakablecameralocatornode.cpp @@ -0,0 +1,327 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: BreakableCameraLocatorNode.cpp +// +// Description: Implement BreakableCameraLocatorNode +// +// History: 9/17/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> + +//======================================== +// Project Includes +//======================================== +#include "BreakableCameraLocatorNode.h" + +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "utility/transformmatrix.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId BreakableCameraLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::BreakableCameraLocator ); +const char* BreakableCameraLocatorNode::stringId = "BreakableCameraLocatorNode"; + +const int BreakableCameraLocatorNode::ACTIVE_COLOUR = 15; +const int BreakableCameraLocatorNode::INACTIVE_COLOUR = 12; +const float BreakableCameraLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +char BreakableCameraLocatorNode::sNewName[MAX_NAME_LEN]; + +const char* BreakableCameraLocatorNode::FOV_NAME_SHORT = "fov"; +const char* BreakableCameraLocatorNode::FOV_NAME_LONG = "fieldOfView"; +MObject BreakableCameraLocatorNode::sFOV; + + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK BreakableCameraLocatorNameCallBack( 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[BreakableCameraLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, BreakableCameraLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Breakable Camera Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + BreakableCameraLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + BreakableCameraLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// BreakableCameraLocatorNode::BreakableCameraLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +BreakableCameraLocatorNode::BreakableCameraLocatorNode() +{ +} + +//============================================================================== +// BreakableCameraLocatorNode::~BreakableCameraLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +BreakableCameraLocatorNode::~BreakableCameraLocatorNode() +{ +} + +//============================================================================= +// BreakableCameraLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* BreakableCameraLocatorNode::creator() +{ + return new BreakableCameraLocatorNode(); +} + +//============================================================================= +// BreakableCameraLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void BreakableCameraLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::DIRECTIONAL_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE * 0.15f, 0,0,0, 5.0f ); + GLExt::drawCamera3D( SCALE * 0.3f, 0,0.5f,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// BreakableCameraLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus BreakableCameraLocatorNode::initialize() +{ + MStatus status; + MFnNumericAttribute numAttr; + sFOV = numAttr.create( FOV_NAME_LONG, FOV_NAME_SHORT, MFnNumericData::kFloat, 90.0f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMin(0.1f) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMax(180.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sFOV ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// BreakableCameraLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void BreakableCameraLocatorNode::postConstructor() +{ +} + +//============================================================================= +// BreakableCameraLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& breakableCameraLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* BreakableCameraLocatorNode::Export( MObject& breakableCameraLocatorNode ) +{ + MFnDagNode fnNode( breakableCameraLocatorNode ); + + if ( fnNode.typeId() == BreakableCameraLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::BREAKABLE_CAMERA ); + + //Also get the direction. + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( hmatrix ); + //Make this p3d friendly... + hmatrix.element[3][0] /= WBConstants::Scale; + hmatrix.element[3][1] /= WBConstants::Scale; + hmatrix.element[3][2] /= WBConstants::Scale; + + unsigned int length = (3 * 3) + 1; //3 vectors + 1 float + + unsigned long* data; + + data = new unsigned long[ length ]; + + unsigned int row; + for ( row = 0; row < 3; ++row ) + { + tlPoint point = hmatrix.GetRow( row ); + + memcpy( &data[row * 3], &point.x, sizeof(float) * 3 ); + } + + float fov = 90.0f; + fnNode.findPlug( sFOV ).getValue( fov ); + memcpy( &data[row * 3], &fov, sizeof(float) ); + + locator->SetDataElements( data, length ); + locator->SetNumDataElements( length ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, breakableCameraLocatorNode ); + + //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 ); + + return locator; + } + + return NULL; +} +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/breakablecameralocatornode.h b/tools/worldbuilder/code/nodes/breakablecameralocatornode.h new file mode 100644 index 0000000..84a4cea --- /dev/null +++ b/tools/worldbuilder/code/nodes/breakablecameralocatornode.h @@ -0,0 +1,113 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: breakablecameralocatornode.h +// +// Description: Blahblahblah +// +// History: 9/17/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef BREAKABLECAMERALOCATORNODE_H +#define BREAKABLECAMERALOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK BreakableCameraLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class BreakableCameraLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + BreakableCameraLocatorNode(); + virtual ~BreakableCameraLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& interiorEntranceLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* FOV_NAME_SHORT; + static const char* FOV_NAME_LONG; + static MObject sFOV; + +private: + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + BreakableCameraLocatorNode( const BreakableCameraLocatorNode& breakablecameralocatornode ); + BreakableCameraLocatorNode& operator=( const BreakableCameraLocatorNode& breakablecameralocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// BreakableCameraLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void BreakableCameraLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// BreakableCameraLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const BreakableCameraLocatorNode::GetNewName() +{ + return sNewName; +} + + +#endif //BREAKABLECAMERALOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/carstartlocatornode.cpp b/tools/worldbuilder/code/nodes/carstartlocatornode.cpp new file mode 100644 index 0000000..2b7dfff --- /dev/null +++ b/tools/worldbuilder/code/nodes/carstartlocatornode.cpp @@ -0,0 +1,347 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: CarStartLocatorNode.cpp +// +// Description: Implement CarStartLocatorNode +// +// History: 28/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/CarStartLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatorevents.h" +#include "../../../game/code/meta/locatortypes.h" + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId CarStartLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::CarStartLocator ); +const char* CarStartLocatorNode::stringId = "CarStartLocatorNode"; + +const int CarStartLocatorNode::ACTIVE_COLOUR = 15; +const int CarStartLocatorNode::INACTIVE_COLOUR = 12; +const float CarStartLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +char CarStartLocatorNode::sNewName[MAX_NAME_LEN]; + +const char* CarStartLocatorNode::ISPARKED_NAME_SHORT = "ip"; +const char* CarStartLocatorNode::ISPARKED_NAME_LONG = "isParked"; +MObject CarStartLocatorNode::sIsParked; + +const char* CarStartLocatorNode::SPECIAL_NAME_SHORT = "spc"; +const char* CarStartLocatorNode::SPECIAL_NAME_LONG = "specialName"; +MObject CarStartLocatorNode::sSpecialCarName; + + + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK CarStartLocatorNameCallBack( 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[CarStartLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, CarStartLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Car Start Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + CarStartLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + CarStartLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// CarStartLocatorNode::CarStartLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +CarStartLocatorNode::CarStartLocatorNode() +{ +} + +//============================================================================== +// CarStartLocatorNode::~CarStartLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +CarStartLocatorNode::~CarStartLocatorNode() +{ +} + +//============================================================================= +// CarStartLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* CarStartLocatorNode::creator() +{ + return new CarStartLocatorNode(); +} + +//============================================================================= +// CarStartLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void CarStartLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::CARSTART_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawPyramid( SCALE, 0,0,0, 5.0 ); + GLExt::drawCar( SCALE, 0,1,0, 5.0 ); + GLExt::drawArrow( MPoint( 0, 0, 0 ), MPoint( 0, 0, 1 * WBConstants::Scale ), 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// CarStartLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus CarStartLocatorNode::initialize() +{ + MStatus status; + + MFnNumericAttribute numericAttr; + sIsParked = numericAttr.create( ISPARKED_NAME_LONG, ISPARKED_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sIsParked ) ); + + MFnTypedAttribute typedAttr; + sSpecialCarName = typedAttr.create( SPECIAL_NAME_LONG, SPECIAL_NAME_SHORT, MFnData::kString, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typedAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typedAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sSpecialCarName ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// CarStartLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void CarStartLocatorNode::postConstructor() +{ +} + +//============================================================================= +// CarStartLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& CarStartLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* CarStartLocatorNode::Export( MObject& carStartLocatorNode ) +{ + MFnDagNode fnNode( carStartLocatorNode ); + + if ( fnNode.typeId() == CarStartLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::CAR_START ); + + unsigned int numDataElements = 2; + + MString specialName; + fnNode.findPlug( sSpecialCarName ).getValue( specialName ); + if ( specialName.length() > 0 ) + { + //Add the length of the string + 1 to the num of + //elements. + numDataElements += specialName.length() / 4 + 1; + } + + unsigned long* data = new unsigned long[numDataElements]; //1 (rotation) + 1 (isParked) + special name len + 1 + memset( data, 0, numDataElements * 4 ); + + //The data here is the Y rotation associated with this locator. + double rotationDouble; + MObject transform = fnNode.parent( 0 ); + MFnDependencyNode fnDepNode( transform ); + fnDepNode.findPlug( MString("ry") ).getValue( rotationDouble ); + + //This is for p3d! + rotationDouble *= -1; + + float rotationFloat = (float)rotationDouble; + + memcpy( &data[0], &rotationFloat, sizeof(float) ); + + + //Do the is Parked Car + bool isParked = false; + fnNode.findPlug( sIsParked ).getValue( isParked ); + data[1] = isParked ? 1 : 0; + + if ( specialName.length() > 0 ) + { + //Add the name + memcpy( &data[2], specialName.asChar(), specialName.length() ); + } + + locator->SetDataElements( data, numDataElements ); + locator->SetNumDataElements( numDataElements ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, carStartLocatorNode ); + + //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 ); + + return locator; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/carstartlocatornode.h b/tools/worldbuilder/code/nodes/carstartlocatornode.h new file mode 100644 index 0000000..6ffa52c --- /dev/null +++ b/tools/worldbuilder/code/nodes/carstartlocatornode.h @@ -0,0 +1,117 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: carstartlocatornode.h +// +// Description: Blahblahblah +// +// History: 28/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef CARSTARTLOCATORNODE_H +#define CARSTARTLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK CarStartLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + + +class CarStartLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + CarStartLocatorNode(); + virtual ~CarStartLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& eventLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* ISPARKED_NAME_SHORT; + static const char* ISPARKED_NAME_LONG; + static MObject sIsParked; + + static const char* SPECIAL_NAME_SHORT; + static const char* SPECIAL_NAME_LONG; + static MObject sSpecialCarName; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + CarStartLocatorNode( const CarStartLocatorNode& carstartlocatornode ); + CarStartLocatorNode& operator=( const CarStartLocatorNode& carstartlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// CarStartLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void CarStartLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// CarStartLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const CarStartLocatorNode::GetNewName() +{ + return sNewName; +} + +#endif //CARSTARTLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/directionallocatornode.cpp b/tools/worldbuilder/code/nodes/directionallocatornode.cpp new file mode 100644 index 0000000..483df4b --- /dev/null +++ b/tools/worldbuilder/code/nodes/directionallocatornode.cpp @@ -0,0 +1,312 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: DirectionalLocatorNode.cpp +// +// Description: Implement DirectionalLocatorNode +// +// History: 29/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/DirectionalLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "utility/transformmatrix.h" +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId DirectionalLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::DirectionalLocator ); +const char* DirectionalLocatorNode::stringId = "DirectionalLocatorNode"; + +const int DirectionalLocatorNode::ACTIVE_COLOUR = 15; +const int DirectionalLocatorNode::INACTIVE_COLOUR = 12; +const float DirectionalLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +char DirectionalLocatorNode::sNewName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK DirectionalLocatorNameCallBack( 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[DirectionalLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, DirectionalLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Driectional Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + DirectionalLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + DirectionalLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// DirectionalLocatorNode::DirectionalLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +DirectionalLocatorNode::DirectionalLocatorNode() +{ +} + +//============================================================================== +// DirectionalLocatorNode::~DirectionalLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +DirectionalLocatorNode::~DirectionalLocatorNode() +{ +} + +//============================================================================= +// DirectionalLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* DirectionalLocatorNode::creator() +{ + return new DirectionalLocatorNode(); +} + +//============================================================================= +// DirectionalLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void DirectionalLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::DIRECTIONAL_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawArrow( MPoint( 0, 0, 0 ), MPoint( 0, 0, -1 * WBConstants::Scale ), 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// DirectionalLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus DirectionalLocatorNode::initialize() +{ + return MStatus::kSuccess; +} + +//============================================================================= +// DirectionalLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void DirectionalLocatorNode::postConstructor() +{ +} + +//============================================================================= +// DirectionalLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& directionalLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* DirectionalLocatorNode::Export( MObject& directionalLocatorNode ) +{ + MFnDagNode fnNode( directionalLocatorNode ); + + if ( fnNode.typeId() == DirectionalLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::DIRECTIONAL ); + + //Also get the direction. + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( hmatrix ); + //Make this p3d friendly... + hmatrix.element[3][0] /= WBConstants::Scale; + hmatrix.element[3][1] /= WBConstants::Scale; + hmatrix.element[3][2] /= WBConstants::Scale; + + unsigned int length = 3 * 3; //3 vectors + + unsigned long* data; + + data = new unsigned long[ length ]; + + unsigned int row; + for ( row = 0; row < 3; ++row ) + { + tlPoint point = hmatrix.GetRow( row ); + + memcpy( &data[row * 3], &point.x, sizeof(float) * 3 ); + } + + locator->SetDataElements( data, length ); + locator->SetNumDataElements( length ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, directionalLocatorNode ); + + //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 ); + + return locator; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/directionallocatornode.h b/tools/worldbuilder/code/nodes/directionallocatornode.h new file mode 100644 index 0000000..766d83a --- /dev/null +++ b/tools/worldbuilder/code/nodes/directionallocatornode.h @@ -0,0 +1,107 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: directionallocatornode.h +// +// Description: Blahblahblah +// +// History: 29/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef DIRECTIONALLOCATORNODE_H +#define DIRECTIONALLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK DirectionalLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class DirectionalLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + DirectionalLocatorNode(); + virtual ~DirectionalLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& interiorEntranceLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + +private: + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + DirectionalLocatorNode( const DirectionalLocatorNode& directionallocatornode ); + DirectionalLocatorNode& operator=( const DirectionalLocatorNode& directionallocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// DirectionalLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void DirectionalLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// DirectionalLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const DirectionalLocatorNode::GetNewName() +{ + return sNewName; +} + +#endif //DIRECTIONALLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/eventlocatornode.cpp b/tools/worldbuilder/code/nodes/eventlocatornode.cpp new file mode 100644 index 0000000..ff2c620 --- /dev/null +++ b/tools/worldbuilder/code/nodes/eventlocatornode.cpp @@ -0,0 +1,460 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: EventLocatorNode.cpp +// +// Description: Implement EventLocatorNode +// +// History: 16/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "EventLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" + +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatorevents.h" +#include "../../../game/code/meta/locatortypes.h" + +#include "utility/transformmatrix.h" + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId EventLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::EventLocator ); +const char* EventLocatorNode::stringId = "EventLocatorNode"; + +const int EventLocatorNode::ACTIVE_COLOUR = 15; +const int EventLocatorNode::INACTIVE_COLOUR = 12; +const float EventLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* EventLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* EventLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject EventLocatorNode::sTriggers; + +const char* EventLocatorNode::EVENT_NAME_SHORT = "e"; +const char* EventLocatorNode::EVENT_NAME_LONG = "event"; +MObject EventLocatorNode::sEvent; + +const char* EventLocatorNode::EXTRA_NAME_SHORT = "ex"; +const char* EventLocatorNode::EXTRA_NAME_LONG = "extraData"; +MObject EventLocatorNode::sExtraData; + +char EventLocatorNode::sNewName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK EventLocatorNameCallBack( 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[EventLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, EventLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Event Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + EventLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + EventLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// EventLocatorNode::EventLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +EventLocatorNode::EventLocatorNode() +{ +} + +//============================================================================== +// EventLocatorNode::~EventLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +EventLocatorNode::~EventLocatorNode() +{ +} + +//============================================================================= +// EventLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* EventLocatorNode::creator() +{ + return new EventLocatorNode(); +} + +//============================================================================= +// EventLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void EventLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::EVENT_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + + //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) ) + { + MPlugArray sources, targets; + MFnDagNode fnNode( thisMObject() ); + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + //Need to undo funny transformations... + MMatrix mat; + mat.setToIdentity(); + + MObject transform; + transform = fnNode.parent( 0 ); + MFnDependencyNode transNode( transform ); + MDagPath transPath; + MExt::FindDagNodeByName( &transPath, transNode.name() ); + MFnTransform fnTransform( transPath ); + + mat = fnTransform.transformationMatrix(); + + mat = mat.inverse(); + + MPoint triggerWP, thisWP; + MExt::GetWorldPosition( &thisWP, thisMObject() ); + + unsigned int i; + for ( i = 0; i < targets.length(); ++i ) + { + //Draw a box around the source trigger volume. + MExt::GetWorldPosition( &triggerWP, sources[i].node() ); + + MPoint triggerLP; + triggerLP = triggerWP; // - thisWP; + + triggerLP *= mat; + + view.setDrawColor( 8, M3dView::kActiveColors ); + + GLExt::drawLine( MPoint(0,0,0), triggerLP, 5.0f ); + } + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawPyramid( SCALE, 0,0,0, 5.0 ); + GLExt::drawE( SCALE, 0,1,0, 5.0 ); + + MFnDagNode fnNode( thisMObject() ); + int event; + fnNode.findPlug( sEvent ).getValue( event ); + + if ( event == LocatorEvent::DEATH || + event == LocatorEvent::WHACKY_GRAVITY || + event == LocatorEvent::CHECK_POINT ) + { + GLExt::drawArrow( MPoint( 0, 0, 0 ), MPoint( 0, 0, -1 * WBConstants::Scale ), 5.0 ); + } + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// EventLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus EventLocatorNode::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 ) ); + + MFnEnumAttribute enumAttr; + sEvent = enumAttr.create( EVENT_NAME_LONG, EVENT_NAME_SHORT, LocatorEvent::CHECK_POINT, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( enumAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( enumAttr.setWritable( true ) ); + + unsigned int i; + for ( i = 0; i < LocatorEvent::SPECIAL; ++i ) //This is the part in the + //enum where the regular + //events end. + { + RETURN_STATUS_ON_FAILURE( enumAttr.addField( MString( LocatorEvent::Name[i] ), i ) ); + } + + RETURN_STATUS_ON_FAILURE( addAttribute( sEvent ) ); + + MFnTypedAttribute typAttr; + sExtraData = typAttr.create( EXTRA_NAME_LONG, EXTRA_NAME_SHORT, MFnData::kString, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sExtraData ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// EventLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void EventLocatorNode::postConstructor() +{ +} + +//============================================================================= +// EventLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& eventLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* EventLocatorNode::Export( MObject& eventLocatorNode ) +{ + MFnDagNode fnNode( eventLocatorNode ); + + if ( fnNode.typeId() == EventLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::EVENT ); + + //The data here is the event associated with this locator. + int event; + fnNode.findPlug( sEvent ).getValue( event ); + + if ( event == static_cast<int>( LocatorEvent::FAR_PLANE ) || + event == static_cast<int>( LocatorEvent::GOO_DAMAGE ) || + event == static_cast<int>( LocatorEvent::COIN_ZONE ) || + event == static_cast<int>( LocatorEvent::CHECK_POINT ) || + event == static_cast<int>( LocatorEvent::TRAP ) || + event == static_cast<int>( LocatorEvent::LIGHT_CHANGE ) ) + { + //Add some extra data. + unsigned long data[2]; + data[0] = event; + + MString extraData; + fnNode.findPlug( sExtraData ).getValue( extraData ); + assert( extraData.isInt() ); + if ( extraData.isInt() ) + { + int extra = extraData.asInt(); + memcpy( &data[1], &extra, sizeof(int) ); + } + else + { + MExt::DisplayWarning( "Event locator: %s has bad extra data, it is probably an old version.(defaulting to 0)", fnNode.name().asChar() ); + data[1] = 0; + } + + locator->SetDataElements( data, 2 ); + locator->SetNumDataElements( 2 ); + } + else + { + //Do the old way. + unsigned long data = event; + locator->SetDataElements( &data, 1 ); + locator->SetNumDataElements( 1 ); + } + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, eventLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + 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 ); + + if ( event == LocatorEvent::DEATH || + event == LocatorEvent::WHACKY_GRAVITY || + event == LocatorEvent::CHECK_POINT ) + { + //Also get the direction. + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( hmatrix ); + //Make this p3d friendly... + hmatrix.element[3][0] /= WBConstants::Scale; + hmatrix.element[3][1] /= WBConstants::Scale; + hmatrix.element[3][2] /= WBConstants::Scale; + + tlExtraMatrixChunk* emChunk = new tlExtraMatrixChunk(); + emChunk->SetMatrix( hmatrix ); + + locator->AppendSubChunk( emChunk ); + } + + return locator; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/eventlocatornode.h b/tools/worldbuilder/code/nodes/eventlocatornode.h new file mode 100644 index 0000000..901dd8c --- /dev/null +++ b/tools/worldbuilder/code/nodes/eventlocatornode.h @@ -0,0 +1,121 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: eventlocatornode.h +// +// Description: Blahblahblah +// +// History: 16/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef EVENTLOCATORNODE_H +#define EVENTLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK EventLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class EventLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + EventLocatorNode(); + virtual ~EventLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& eventLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* EVENT_NAME_SHORT; + static const char* EVENT_NAME_LONG; + static MObject sEvent; + + static const char* EXTRA_NAME_SHORT; + static const char* EXTRA_NAME_LONG; + static MObject sExtraData; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + EventLocatorNode( const EventLocatorNode& eventlocatornode ); + EventLocatorNode& operator=( const EventLocatorNode& eventlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// EventLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void EventLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// EventLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const EventLocatorNode::GetNewName() +{ + return sNewName; +} + +#endif //EVENTLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/fovlocatornode.cpp b/tools/worldbuilder/code/nodes/fovlocatornode.cpp new file mode 100644 index 0000000..90f9301 --- /dev/null +++ b/tools/worldbuilder/code/nodes/fovlocatornode.cpp @@ -0,0 +1,361 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: FOVLocatorNode.cpp +// +// Description: Implement FOVLocatorNode +// +// History: 03/08/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/FOVLocatorNode.h" + +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId FOVLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::FOVLocator ); +const char* FOVLocatorNode::stringId = "FOVLocatorNode"; + +const char* FOVLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* FOVLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject FOVLocatorNode::sTriggers; + +const char* FOVLocatorNode::FOV_NAME_SHORT = "f"; +const char* FOVLocatorNode::FOV_NAME_LONG = "fov"; +MObject FOVLocatorNode::sFOV; + +const char* FOVLocatorNode::TIME_NAME_SHORT = "tm"; +const char* FOVLocatorNode::TIME_NAME_LONG = "time"; +MObject FOVLocatorNode::sTime; + +const char* FOVLocatorNode::RATE_NAME_SHORT = "ra"; +const char* FOVLocatorNode::RATE_NAME_LONG = "rate"; +MObject FOVLocatorNode::sRate; + +const int FOVLocatorNode::ACTIVE_COLOUR = 15; +const int FOVLocatorNode::INACTIVE_COLOUR = 12; +const float FOVLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +char FOVLocatorNode::sNewName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK FOVLocatorNameCallBack( 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[FOVLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, FOVLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the FOV Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + FOVLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + FOVLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// FOVLocatorNode::FOVLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +FOVLocatorNode::FOVLocatorNode() +{ +} + +//============================================================================== +// FOVLocatorNode::~FOVLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +FOVLocatorNode::~FOVLocatorNode() +{ +} + +//============================================================================= +// FOVLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* FOVLocatorNode::creator() +{ + return new FOVLocatorNode(); +} + +//============================================================================= +// FOVLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void FOVLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::CARSTART_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// FOVLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus FOVLocatorNode::initialize() +{ + MStatus status; + + MFnMessageAttribute msgAttr; + 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 ) ); + + MFnNumericAttribute numAttr; + sFOV = numAttr.create( FOV_NAME_LONG, FOV_NAME_SHORT, MFnNumericData::kFloat, 90.0f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMin(0.1f) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMax(180.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sFOV ) ); + + sTime = numAttr.create( TIME_NAME_LONG, TIME_NAME_SHORT, MFnNumericData::kFloat, 2.0f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMax(10.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTime ) ); + + sRate = numAttr.create( RATE_NAME_LONG, RATE_NAME_SHORT, MFnNumericData::kFloat, 0.04f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numAttr.setMax(1.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sRate ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// FOVLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void FOVLocatorNode::postConstructor() +{ +} + +//============================================================================= +// FOVLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& FOVLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* FOVLocatorNode::Export( MObject& fovLocatorNode ) +{ + MFnDagNode fnNode( fovLocatorNode ); + + if ( fnNode.typeId() == FOVLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::FOV ); + + float fov = 90.0f; + float time = 2.0f; + float rate = 0.04f; + + fnNode.findPlug( sFOV ).getValue( fov ); + fnNode.findPlug( sTime ).getValue( time ); + fnNode.findPlug( sRate ).getValue( rate ); + + unsigned long data[3]; + memcpy( data, &fov, sizeof(float) ); + memcpy( &(data[1]), &time, sizeof(float) ); + memcpy( &(data[2]), &rate, sizeof(float) ); + + locator->SetDataElements( data, 3 ); + locator->SetNumDataElements( 3 ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, fovLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + 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 +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/fovlocatornode.h b/tools/worldbuilder/code/nodes/fovlocatornode.h new file mode 100644 index 0000000..ac531a3 --- /dev/null +++ b/tools/worldbuilder/code/nodes/fovlocatornode.h @@ -0,0 +1,124 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: fovlocatornode.h +// +// Description: Blahblahblah +// +// History: 03/08/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef FOVLOCATORNODE_H +#define FOVLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK FOVLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class FOVLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + FOVLocatorNode(); + virtual ~FOVLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& eventLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* FOV_NAME_SHORT; + static const char* FOV_NAME_LONG; + static MObject sFOV; + + static const char* TIME_NAME_SHORT; + static const char* TIME_NAME_LONG; + static MObject sTime; + + static const char* RATE_NAME_SHORT; + static const char* RATE_NAME_LONG; + static MObject sRate; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + FOVLocatorNode( const FOVLocatorNode& fovlocatornode ); + FOVLocatorNode& operator=( const FOVLocatorNode& fovlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// FOVLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void FOVLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// FOVLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const FOVLocatorNode::GetNewName() +{ + return sNewName; +} + +#endif //FOVLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/genericlocatornode.cpp b/tools/worldbuilder/code/nodes/genericlocatornode.cpp new file mode 100644 index 0000000..ef81a26 --- /dev/null +++ b/tools/worldbuilder/code/nodes/genericlocatornode.cpp @@ -0,0 +1,287 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: GenericLocatorNode.cpp +// +// Description: Implement GenericLocatorNode +// +// History: 27/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/GenericLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatorevents.h" +#include "../../../game/code/meta/locatortypes.h" + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId GenericLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::GenericLocator ); +const char* GenericLocatorNode::stringId = "GenericLocatorNode"; + +const int GenericLocatorNode::ACTIVE_COLOUR = 15; +const int GenericLocatorNode::INACTIVE_COLOUR = 12; +const float GenericLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +char GenericLocatorNode::sNewName[MAX_NAME_LEN]; + + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK GenericLocatorNameCallBack( 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[GenericLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, GenericLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Generic Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + GenericLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + GenericLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// GenericLocatorNode::GenericLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +GenericLocatorNode::GenericLocatorNode() +{ +} + +//============================================================================== +// GenericLocatorNode::~GenericLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +GenericLocatorNode::~GenericLocatorNode() +{ +} + +//============================================================================= +// GenericLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* GenericLocatorNode::creator() +{ + return new GenericLocatorNode(); +} + +//============================================================================= +// GenericLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void GenericLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::GENERIC_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// GenericLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus GenericLocatorNode::initialize() +{ + return MStatus::kSuccess; +} + +//============================================================================= +// GenericLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void GenericLocatorNode::postConstructor() +{ +} + +//============================================================================= +// GenericLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& GenericLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* GenericLocatorNode::Export( MObject& genericLocatorNode ) +{ + MFnDagNode fnNode( genericLocatorNode ); + + if ( fnNode.typeId() == GenericLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + if ( fnNode.name().substring(0, 3) == MString("coin") ) + { + locator->SetType( LocatorType::COIN ); + } + else + { + locator->SetType( LocatorType::GENERIC ); + } + + locator->SetNumDataElements( 0 ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, genericLocatorNode ); + + //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 ); + + return locator; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/genericlocatornode.h b/tools/worldbuilder/code/nodes/genericlocatornode.h new file mode 100644 index 0000000..6a69682 --- /dev/null +++ b/tools/worldbuilder/code/nodes/genericlocatornode.h @@ -0,0 +1,108 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: genericlocatornode.h +// +// Description: Blahblahblah +// +// History: 27/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef GENERICLOCATORNODE_H +#define GENERICLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK GenericLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class GenericLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + GenericLocatorNode(); + virtual ~GenericLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& GenericLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + GenericLocatorNode( const GenericLocatorNode& genericlocatornode ); + GenericLocatorNode& operator=( const GenericLocatorNode& genericlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// GenericLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void GenericLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// GenericLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const GenericLocatorNode::GetNewName() +{ + return sNewName; +} + +#endif //GENERICLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/interiorentrancelocatornode.cpp b/tools/worldbuilder/code/nodes/interiorentrancelocatornode.cpp new file mode 100644 index 0000000..1765423 --- /dev/null +++ b/tools/worldbuilder/code/nodes/interiorentrancelocatornode.cpp @@ -0,0 +1,409 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: InteriorEntranceLocatorNode.cpp +// +// Description: Implement InteriorEntranceLocatorNode +// +// History: 29/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + + +//======================================== +// Project Includes +//======================================== +#include "nodes/InteriorEntranceLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" + +#include "utility/transformmatrix.h" +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId InteriorEntranceLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::InteriorEntranceLocator ); +const char* InteriorEntranceLocatorNode::stringId = "InteriorEntranceLocatorNode"; + +const int InteriorEntranceLocatorNode::ACTIVE_COLOUR = 15; +const int InteriorEntranceLocatorNode::INACTIVE_COLOUR = 12; +const float InteriorEntranceLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* InteriorEntranceLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* InteriorEntranceLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject InteriorEntranceLocatorNode::sTriggers; + +const char* InteriorEntranceLocatorNode::ZONE_NAME_SHORT = "z"; +const char* InteriorEntranceLocatorNode::ZONE_NAME_LONG = "zone"; +MObject InteriorEntranceLocatorNode::sZone; + +char InteriorEntranceLocatorNode::sNewName[MAX_NAME_LEN]; +char InteriorEntranceLocatorNode::sZoneName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK InteriorEntranceLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + SetDlgItemText( hWnd, IDC_EDIT2, WorldBuilder::GetPrefix() ); + SetDlgItemText( hWnd, IDC_EDIT3, "" ); + return true; + } + break; + case WM_COMMAND: + { + if ( LOWORD(wParam) == IDC_BUTTON1 || LOWORD(wParam) == IDOK ) + { + //Get the entry in the text field. + char name[InteriorEntranceLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, InteriorEntranceLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Interior Entrance Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + InteriorEntranceLocatorNode::SetNewName( newName.asChar() ); + + //Do the zone name too... + GetDlgItemText( hWnd, IDC_EDIT3, name, InteriorEntranceLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a file name for the zone!"); + return false; + } + + InteriorEntranceLocatorNode::SetZoneName( name ); + + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + InteriorEntranceLocatorNode::SetNewName( "" ); + InteriorEntranceLocatorNode::SetZoneName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// InteriorEntranceLocatorNode::InteriorEntranceLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +InteriorEntranceLocatorNode::InteriorEntranceLocatorNode() +{ +} + +//============================================================================== +// InteriorEntranceLocatorNode::~InteriorEntranceLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +InteriorEntranceLocatorNode::~InteriorEntranceLocatorNode() +{ +} + +//============================================================================= +// InteriorEntranceLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* InteriorEntranceLocatorNode::creator() +{ + return new InteriorEntranceLocatorNode(); +} + +//============================================================================= +// InteriorEntranceLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void InteriorEntranceLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::INTERIOR_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + MPlugArray sources, targets; + MFnDagNode fnNode( thisMObject() ); + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + unsigned int i; + for ( i = 0; i < targets.length(); ++i ) + { + //Draw a box around the source trigger volume. + MPoint triggerWP, thisWP; + MExt::GetWorldPosition( &triggerWP, sources[i].node() ); + + MExt::GetWorldPosition( &thisWP, thisMObject() ); + + MPoint triggerLP; + triggerLP = triggerWP - thisWP; + + view.setDrawColor( 8, M3dView::kActiveColors ); + + GLExt::drawLine( MPoint(0,0,0), triggerLP, 5.0f ); + } + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawPyramid( SCALE, 0,0,0, 5.0 ); + GLExt::drawArrow( MPoint( 0, 0, 0 ), MPoint( 0, 0, -1 * WBConstants::Scale ), 5.0 ); + GLExt::drawD( SCALE, 0,1,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// InteriorEntranceLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus InteriorEntranceLocatorNode::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 ) ); + + MFnTypedAttribute typAttr; + sZone = typAttr.create( ZONE_NAME_LONG, ZONE_NAME_SHORT, MFnData::kString, MObject::kNullObj, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sZone ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// InteriorEntranceLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void InteriorEntranceLocatorNode::postConstructor() +{ +} + +//============================================================================= +// InteriorEntranceLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& interiorEntranceLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* InteriorEntranceLocatorNode::Export( MObject& interiorEntranceLocatorNode ) +{ + MFnDagNode fnNode( interiorEntranceLocatorNode ); + + if ( fnNode.typeId() == InteriorEntranceLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::INTERIOR_ENTRANCE ); + + //The data here is the zone associated with this locator. + MString zone; + fnNode.findPlug( sZone ).getValue( zone ); + + //Also get the direction. + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( hmatrix ); + //Make this p3d friendly... + hmatrix.element[3][0] /= WBConstants::Scale; + hmatrix.element[3][1] /= WBConstants::Scale; + hmatrix.element[3][2] /= WBConstants::Scale; + + + unsigned int length = (zone.length() / 4 + 1) + 3 * 3; //string + 3 vectors + + unsigned long* data; + + data = new unsigned long[ length ]; + unsigned int i; + for ( i = 0; i < length; ++i ) + { + data[i] = 0; + } + + memcpy( data, zone.asChar(), zone.length() ); + ((char*)(data))[zone.length()] = '\0'; + + unsigned int row; + for ( row = 0; row < 3; ++row ) + { + tlPoint point = hmatrix.GetRow( row ); + + memcpy( &data[(zone.length() / 4 + 1) + row * 3], &point.x, sizeof(float) * 3 ); + } + + locator->SetDataElements( data, length ); + locator->SetNumDataElements( length ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, interiorEntranceLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + for ( i = 0; i < sources.length(); ++i ) + { + tlDataChunk* trigger = TriggerVolumeNode::Export( sources[ i ].node() ); + assert( trigger ); + + locator->AppendSubChunk( trigger ); + } + + locator->SetNumTriggers( i ); + + delete data; + + return locator; + } + + return NULL; +} + + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/interiorentrancelocatornode.h b/tools/worldbuilder/code/nodes/interiorentrancelocatornode.h new file mode 100644 index 0000000..c338e85 --- /dev/null +++ b/tools/worldbuilder/code/nodes/interiorentrancelocatornode.h @@ -0,0 +1,151 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: interiorentrancelocatornode.h +// +// Description: Blahblahblah +// +// History: 29/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef INTERIORENTRANCELOCATORNODE_H +#define INTERIORENTRANCELOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK InteriorEntranceLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + + +class InteriorEntranceLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + InteriorEntranceLocatorNode(); + virtual ~InteriorEntranceLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& interiorEntranceLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + static void SetZoneName( const char* name ); + static const char* const GetZoneName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* ZONE_NAME_SHORT; + static const char* ZONE_NAME_LONG; + static MObject sZone; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + static char sZoneName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + InteriorEntranceLocatorNode( const InteriorEntranceLocatorNode& interiorentrancelocatornode ); + InteriorEntranceLocatorNode& operator=( const InteriorEntranceLocatorNode& interiorentrancelocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// InteriorEntranceLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void InteriorEntranceLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// InteriorEntranceLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const InteriorEntranceLocatorNode::GetNewName() +{ + return sNewName; +} + +//============================================================================= +// InteriorEntranceLocatorNode::SetZoneName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void InteriorEntranceLocatorNode::SetZoneName( const char* name ) +{ + strncpy( sZoneName, name, MAX_NAME_LEN); +} + +//============================================================================= +// InteriorEntranceLocatorNode::GetZoneName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const InteriorEntranceLocatorNode::GetZoneName() +{ + return sZoneName; +} + + +#endif //INTERIORENTRANCELOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/occlusionlocatornode.cpp b/tools/worldbuilder/code/nodes/occlusionlocatornode.cpp new file mode 100644 index 0000000..2e93554 --- /dev/null +++ b/tools/worldbuilder/code/nodes/occlusionlocatornode.cpp @@ -0,0 +1,374 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: OcclusionLocatorNode.cpp +// +// Description: Implement OcclusionLocatorNode +// +// History: 28/06/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/OcclusionLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" + +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId OcclusionLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::OcclusionLocator ); +const char* OcclusionLocatorNode::stringId = "OcclusionLocatorNode"; + +const int OcclusionLocatorNode::ACTIVE_COLOUR = 15; +const int OcclusionLocatorNode::INACTIVE_COLOUR = 12; +const float OcclusionLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* OcclusionLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* OcclusionLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject OcclusionLocatorNode::sTriggers; + +char OcclusionLocatorNode::sNewName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK OcclusionLocatorNameCallBack( 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[OcclusionLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, OcclusionLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Occlusion Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + OcclusionLocatorNode::SetNewName( newName.asChar() ); + + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + OcclusionLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// OcclusionLocatorNode::OcclusionLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +OcclusionLocatorNode::OcclusionLocatorNode() +{ +} + +//============================================================================== +// OcclusionLocatorNode::~OcclusionLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +OcclusionLocatorNode::~OcclusionLocatorNode() +{ +} + +//============================================================================= +// OcclusionLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* OcclusionLocatorNode::creator() +{ + return new OcclusionLocatorNode(); +} + +//============================================================================= +// OcclusionLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void OcclusionLocatorNode::draw( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::OCCLUSION_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + MPlugArray sources, targets; + MFnDagNode fnNode( thisMObject() ); + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + unsigned int i; + for ( i = 0; i < targets.length(); ++i ) + { + //Draw a box around the source trigger volume. + MPoint triggerWP, thisWP; + MExt::GetWorldPosition( &triggerWP, sources[i].node() ); + + MExt::GetWorldPosition( &thisWP, thisMObject() ); + + MPoint triggerLP; + triggerLP = triggerWP - thisWP; + + if ( i == 0 ) + { + //This is the triggering volume + view.setDrawColor( 3, M3dView::kActiveColors ); + } + else + { + //These are the occluding volumes. + view.setDrawColor( 8, M3dView::kActiveColors ); + } + + GLExt::drawLine( MPoint(0,0,0), triggerLP, 5.0f ); + } + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawPyramid( SCALE, 0,0,0, 5.0 ); + GLExt::drawO( SCALE, 0,1,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// OcclusionLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus OcclusionLocatorNode::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 ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// OcclusionLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void OcclusionLocatorNode::postConstructor() +{ +} + +//============================================================================= +// OcclusionLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& occlusionLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* OcclusionLocatorNode::Export( MObject& occlusionLocatorNode ) +{ + MFnDagNode fnNode( occlusionLocatorNode ); + + if ( fnNode.typeId() == OcclusionLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::OCCLUSION ); + + locator->SetNumDataElements( 0 ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, occlusionLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + + //Hold onto the visiblers until the end. + tlDataChunk* visiblers = new tlDataChunk; + unsigned long numVisiblers = 0; + unsigned long numRegular = 0; + + unsigned int i; + for ( i = 0; i < sources.length(); ++i ) + { + tlDataChunk* trigger = TriggerVolumeNode::Export( sources[ i ].node() ); + assert( trigger ); + + MFnDagNode fnTrigNode( sources[ i ].node() ); + + if ( fnTrigNode.name().substring( 0, 0 ) == MString("V") ) + { + visiblers->AppendSubChunk( trigger, 0 ); + ++numVisiblers; + } + else + { + locator->AppendSubChunk( trigger ); + ++numRegular; + } + + } + + + //Subtract one from the num regular to not cound the primary trigger. + numRegular--; + + //Now add the visiblers to the end of the list. + if ( numVisiblers ) + { + visiblers->TransferSubChunks( locator ); + + //Record how many of these triggers are regular. + locator->SetDataElements( &numRegular, 1 ); + locator->SetNumDataElements( 1 ); + } + + locator->SetNumTriggers( i ); + + + return locator; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/occlusionlocatornode.h b/tools/worldbuilder/code/nodes/occlusionlocatornode.h new file mode 100644 index 0000000..0c3d21e --- /dev/null +++ b/tools/worldbuilder/code/nodes/occlusionlocatornode.h @@ -0,0 +1,112 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: occlusionlocatornode.h +// +// Description: Blahblahblah +// +// History: 28/06/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef OCCLUSIONLOCATORNODE_H +#define OCCLUSIONLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK OcclusionLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class OcclusionLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + OcclusionLocatorNode(); + virtual ~OcclusionLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& occlusionLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + OcclusionLocatorNode( const OcclusionLocatorNode& occlusionlocatornode ); + OcclusionLocatorNode& operator=( const OcclusionLocatorNode& occlusionlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// OcclusionLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void OcclusionLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// OcclusionLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const OcclusionLocatorNode::GetNewName() +{ + return sNewName; +} + +#endif //OCCLUSIONLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/pedgrouplocator.cpp b/tools/worldbuilder/code/nodes/pedgrouplocator.cpp new file mode 100644 index 0000000..3ec6477 --- /dev/null +++ b/tools/worldbuilder/code/nodes/pedgrouplocator.cpp @@ -0,0 +1,371 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: PedGroupLocatorNode.cpp +// +// Description: Implement PedGroupLocatorNode +// +// History: 29/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/PedGroupLocator.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "utility/transformmatrix.h" +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId PedGroupLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::PedGroupLocator ); +const char* PedGroupLocatorNode::stringId = "PedGroupLocatorNode"; + +const int PedGroupLocatorNode::ACTIVE_COLOUR = 15; +const int PedGroupLocatorNode::INACTIVE_COLOUR = 12; +const float PedGroupLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* PedGroupLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* PedGroupLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject PedGroupLocatorNode::sTriggers; + +const char* PedGroupLocatorNode::GROUP_NAME_SHORT = "grp"; +const char* PedGroupLocatorNode::GROUP_NAME_LONG = "group"; +MObject PedGroupLocatorNode::sGroup; + +char PedGroupLocatorNode::sNewName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK PedGroupLocatorNameCallBack( 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[PedGroupLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, PedGroupLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Ped Group Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + PedGroupLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + PedGroupLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// PedGroupLocatorNode::PedGroupLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PedGroupLocatorNode::PedGroupLocatorNode() +{ +} + +//============================================================================== +// PedGroupLocatorNode::~PedGroupLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PedGroupLocatorNode::~PedGroupLocatorNode() +{ +} + +//============================================================================= +// PedGroupLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* PedGroupLocatorNode::creator() +{ + return new PedGroupLocatorNode(); +} + +//============================================================================= +// PedGroupLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void PedGroupLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::DIRECTIONAL_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + MPlugArray sources, targets; + MFnDagNode fnNode( thisMObject() ); + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + //Need to undo funny transformations... + MMatrix mat; + mat.setToIdentity(); + + MObject transform; + transform = fnNode.parent( 0 ); + MFnDependencyNode transNode( transform ); + MDagPath transPath; + MExt::FindDagNodeByName( &transPath, transNode.name() ); + MFnTransform fnTransform( transPath ); + + mat = fnTransform.transformationMatrix(); + + mat = mat.inverse(); + + MPoint triggerWP, thisWP; + MExt::GetWorldPosition( &thisWP, thisMObject() ); + + unsigned int i; + for ( i = 0; i < targets.length(); ++i ) + { + //Draw a box around the source trigger volume. + MExt::GetWorldPosition( &triggerWP, sources[i].node() ); + + MPoint triggerLP; + triggerLP = triggerWP; // - thisWP; + + triggerLP *= mat; + + view.setDrawColor( 8, M3dView::kActiveColors ); + + GLExt::drawLine( MPoint(0,0,0), triggerLP, 5.0f ); + } + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawStickMan( SCALE, 0, 1, 0, 5.0 ); + GLExt::drawStickMan( SCALE, 0.25, 1, 0, 5.0 ); + GLExt::drawStickMan( SCALE, -0.25, 1, 0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// PedGroupLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus PedGroupLocatorNode::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 ) ); + + MFnNumericAttribute numericAttr; + sGroup = numericAttr.create( GROUP_NAME_LONG, GROUP_NAME_SHORT, MFnNumericData::kInt, 0, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( false ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sGroup ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// PedGroupLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PedGroupLocatorNode::postConstructor() +{ +} + +//============================================================================= +// PedGroupLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& directionalLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* PedGroupLocatorNode::Export( MObject& pedGroupLocatorNode ) +{ + MFnDagNode fnNode( pedGroupLocatorNode ); + + if ( fnNode.typeId() == PedGroupLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::PED_GROUP ); + + //The data here is the event associated with this locator. + int group; + fnNode.findPlug( sGroup ).getValue( group ); + + unsigned long data = group; + locator->SetDataElements( &data, 1 ); + locator->SetNumDataElements( 1 ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, pedGroupLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + 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 +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/pedgrouplocator.h b/tools/worldbuilder/code/nodes/pedgrouplocator.h new file mode 100644 index 0000000..e70aded --- /dev/null +++ b/tools/worldbuilder/code/nodes/pedgrouplocator.h @@ -0,0 +1,115 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: pedgrouplocatornode.h +// +// Description: Blahblahblah +// +// History: 29/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef PEDGROUPLOCATORNODE_H +#define PEDGROUPLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK PedGroupLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class PedGroupLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + PedGroupLocatorNode(); + virtual ~PedGroupLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& interiorEntranceLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* GROUP_NAME_SHORT; + static const char* GROUP_NAME_LONG; + static MObject sGroup; + +private: + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + PedGroupLocatorNode( const PedGroupLocatorNode& pedgrouplocatornode ); + PedGroupLocatorNode& operator=( const PedGroupLocatorNode& pedgrouplocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// PedGroupLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void PedGroupLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// PedGroupLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const PedGroupLocatorNode::GetNewName() +{ + return sNewName; +} + +#endif //PEDGROUPLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/railcamlocatornode.cpp b/tools/worldbuilder/code/nodes/railcamlocatornode.cpp new file mode 100644 index 0000000..63beaf1 --- /dev/null +++ b/tools/worldbuilder/code/nodes/railcamlocatornode.cpp @@ -0,0 +1,584 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: RailCamLocatorNode.cpp +// +// Description: Implement RailCamLocatorNode +// +// History: 18/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> +#include <p3d/pointcamera.hpp> + +//======================================== +// Project Includes +//======================================== +#include "RailCamLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "nodes/triggervolumenode.h" +#include "utility/nodehelper.h" + +#include "gameengine/gameengine.h" +#include "gameengine/wbcamtarget.h" + +#include "resources/resource.h" + +#include "../../../game/code/camera/railcam.h" + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId RailCamLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::RailCamLocator ); +const char* RailCamLocatorNode::stringId = "RailCamLocatorNode"; + +const int RailCamLocatorNode::ACTIVE_COLOUR = 15; +const int RailCamLocatorNode::INACTIVE_COLOUR = 12; +const float RailCamLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* RailCamLocatorNode::RAIL_NAME_SHORT = "rail"; +const char* RailCamLocatorNode::RAIL_NAME_LONG = "camRail"; +MObject RailCamLocatorNode::sRail; + +const char* RailCamLocatorNode::BEHAVIOUR_NAME_SHORT = "behav"; +const char* RailCamLocatorNode::BEHAVIOUR_NAME_LONG = "behaviour"; +MObject RailCamLocatorNode::sBehaviour; + +const char* RailCamLocatorNode::MIN_RADIUS_NAME_SHORT = "minR"; +const char* RailCamLocatorNode::MIN_RADIUS_NAME_LONG = "minRadius"; +MObject RailCamLocatorNode::sMinRadius; + +const char* RailCamLocatorNode::MAX_RADIUS_NAME_SHORT = "maxR"; +const char* RailCamLocatorNode::MAX_RADIUS_NAME_LONG = "maxRadius"; +MObject RailCamLocatorNode::sMaxRadius; + +const char* RailCamLocatorNode::TRACK_RAIL_NAME_SHORT = "trkRl"; +const char* RailCamLocatorNode::TRACK_RAIL_NAME_LONG = "trackRail"; +MObject RailCamLocatorNode::sTrackRail; + +const char* RailCamLocatorNode::TRACK_DIST_NAME_SHORT = "tDst"; +const char* RailCamLocatorNode::TRACK_DIST_NAME_LONG = "trackDist"; +MObject RailCamLocatorNode::sTrackDist; + +const char* RailCamLocatorNode::REVERSE_SENSE_NAME_SHORT ="rvsns"; +const char* RailCamLocatorNode::REVERSE_SENSE_NAME_LONG = "reverseSense"; +MObject RailCamLocatorNode::sReverseSense; + + +const char* RailCamLocatorNode::FOV_NAME_SHORT = "fov"; +const char* RailCamLocatorNode::FOV_NAME_LONG = "fieldOfView"; +MObject RailCamLocatorNode::sFOV; + +const char* RailCamLocatorNode::FACING_OFFSET_NAME_SHORT = "facoff"; +const char* RailCamLocatorNode::FACING_OFFSET_NAME_LONG = "facingOffset"; +MObject RailCamLocatorNode::sFacingOffset; + +const char* RailCamLocatorNode::AXIS_PLAY_NAME_SHORT = "axsply"; +const char* RailCamLocatorNode::AXIS_PLAY_NAME_LONG = "axisPlay"; +MObject RailCamLocatorNode::sAxisPlay; + +const char* RailCamLocatorNode::ACTIVE_NAME_SHORT = "act"; +const char* RailCamLocatorNode::ACTIVE_NAME_LONG = "active"; +MObject RailCamLocatorNode::sActive; + +const char* RailCamLocatorNode::TARGET_NAME_SHORT = "trg"; +const char* RailCamLocatorNode::TARGET_NAME_LONG = "target"; +MObject RailCamLocatorNode::sTarget; + +const char* RailCamLocatorNode::POS_LAG_NAME_SHORT = "plg"; +const char* RailCamLocatorNode::POS_LAG_NAME_LONG = "positionLag"; +MObject RailCamLocatorNode::sPositionLag; + +const char* RailCamLocatorNode::TARGET_LAG_NAME_SHORT = "trglg"; +const char* RailCamLocatorNode::TARGET_LAG_NAME_LONG = "targetLag"; +MObject RailCamLocatorNode::sTargetLag; + +const char* RailCamLocatorNode::TRANSITION_TO_RATE_NAME_LONG = "transitionTo"; +const char* RailCamLocatorNode::TRANSITION_TO_RATE_NAME_SHORT = "trnto"; +MObject RailCamLocatorNode::sTransitionToRate; + +const char* RailCamLocatorNode::NOFOV_NAME_LONG = "noFOV"; +const char* RailCamLocatorNode::NOFOV_NAME_SHORT = "nf"; +MObject RailCamLocatorNode::sNoFOV; + +const char* RailCamLocatorNode::CAR_ONLY_NAME_LONG = "carOnly"; +const char* RailCamLocatorNode::CAR_ONLY_NAME_SHORT = "co"; +MObject RailCamLocatorNode::sCarOnly; + +const char* RailCamLocatorNode::ON_FOOT_ONLY_NAME_LONG = "onFootOnly"; +const char* RailCamLocatorNode::ON_FOOT_ONLY_NAME_SHORT = "ofo"; +MObject RailCamLocatorNode::sOnFootOnly; + +const char* RailCamLocatorNode::CUTALL_NAME_LONG = "cutInOut"; +const char* RailCamLocatorNode::CUTALL_NAME_SHORT = "cin"; +MObject RailCamLocatorNode::sCutAll; + +const char* RailCamLocatorNode::RESET_NAME_LONG = "reset"; +const char* RailCamLocatorNode::RESET_NAME_SHORT = "rst"; +MObject RailCamLocatorNode::sReset; + +char RailCamLocatorNode::sNewName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK RailCamLocatorNameCallBack( 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[RailCamLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, RailCamLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the RailCam Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + RailCamLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + RailCamLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//***************************************************************************** +// +// Public Member Functions +// +//***************************************************************************** + +//============================================================================= +// RailCamLocatorNode::RailCamLocatorNode +//============================================================================= +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================= +RailCamLocatorNode::RailCamLocatorNode() +{ + mRailCam = new RailCam(); + mRailCam->AddRef(); + mRailCam->SetPlayerID( 0 ); + + mRailCam->SetCamera( new tPointCamera() ); + + mCamTarget = new WBCamTarget(); +} + +//============================================================================= +// RailCamLocatorNode::~RailCamLocatorNode +//============================================================================= +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================= +RailCamLocatorNode::~RailCamLocatorNode() +{ + mRailCam->Release(); + mRailCam = NULL; + + if ( mCamTarget ) + { + delete mCamTarget; + } +} + +//============================================================================= +// RailCamLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* RailCamLocatorNode::creator() +{ + return new RailCamLocatorNode(); +} + +//============================================================================= +// RailCamLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void RailCamLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::RAILCAM_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + GameEngine::GetInstance()->UpdateRailCam( thisMObject() ); + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// RailCamLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus RailCamLocatorNode::initialize() +{ + MFnMessageAttribute msgAttr; + MStatus status; + + sRail = msgAttr.create( RAIL_NAME_LONG, RAIL_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( sRail ) ); + + MFnEnumAttribute enumAttr; + sBehaviour = enumAttr.create( BEHAVIOUR_NAME_LONG, BEHAVIOUR_NAME_SHORT, RailCam::PROJECTION, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( enumAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( enumAttr.setWritable( true ) ); + + unsigned int i; + for ( i = 1; i < RailCam::NUM_BEHAVIOUR; ++i ) + { + RETURN_STATUS_ON_FAILURE( enumAttr.addField( MString( RailCam::BehaviourNames[i-1] ), i ) ); + } + RETURN_STATUS_ON_FAILURE( addAttribute( sBehaviour ) ); + + MFnNumericAttribute numericAttr; + sMinRadius = numericAttr.create( MIN_RADIUS_NAME_LONG, MIN_RADIUS_NAME_SHORT, MFnNumericData::kFloat, 1.0f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(30.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sMinRadius ) ); + + sMaxRadius = numericAttr.create( MAX_RADIUS_NAME_LONG, MAX_RADIUS_NAME_SHORT, MFnNumericData::kFloat, 2.0f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(30.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sMaxRadius ) ); + + sTrackRail = numericAttr.create( TRACK_RAIL_NAME_LONG, TRACK_RAIL_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTrackRail ) ); + + sTrackDist = numericAttr.create( TRACK_DIST_NAME_LONG, TRACK_DIST_NAME_SHORT, MFnNumericData::kFloat, 0.0f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(-5.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(5.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setDefault( 0.0f ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTrackDist ) ); + + sReverseSense = numericAttr.create( REVERSE_SENSE_NAME_LONG, REVERSE_SENSE_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sReverseSense ) ); + + sFOV = numericAttr.create( FOV_NAME_LONG, FOV_NAME_SHORT, MFnNumericData::kInt, 90, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(180.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sFOV ) ); + + sFacingOffset = numericAttr.create( FACING_OFFSET_NAME_LONG, FACING_OFFSET_NAME_SHORT, MFnNumericData::k3Float, 0.0f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sFacingOffset ) ); + + sAxisPlay = numericAttr.create( AXIS_PLAY_NAME_LONG, AXIS_PLAY_NAME_SHORT, MFnNumericData::k3Float, 0.0f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sAxisPlay ) ); + + sActive = numericAttr.create( ACTIVE_NAME_LONG, ACTIVE_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sActive ) ); + + MFnTypedAttribute typedAttr; + sTarget = typedAttr.create( TARGET_NAME_LONG, TARGET_NAME_SHORT, MFnData::kString, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typedAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typedAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTarget ) ); + + sPositionLag = numericAttr.create( POS_LAG_NAME_LONG, POS_LAG_NAME_SHORT, MFnNumericData::kFloat, 0.04f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(1.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sPositionLag ) ); + + sTargetLag = numericAttr.create( TARGET_LAG_NAME_LONG, TARGET_LAG_NAME_SHORT, MFnNumericData::kFloat, 0.04f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(1.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTargetLag ) ); + + sTransitionToRate = numericAttr.create( TRANSITION_TO_RATE_NAME_LONG, TRANSITION_TO_RATE_NAME_SHORT, MFnNumericData::kFloat, 0.04f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(1.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTransitionToRate ) ); + + sNoFOV = numericAttr.create( NOFOV_NAME_LONG, NOFOV_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sNoFOV ) ); + + sCarOnly = numericAttr.create( CAR_ONLY_NAME_LONG, CAR_ONLY_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sCarOnly ) ); + + sOnFootOnly = numericAttr.create( ON_FOOT_ONLY_NAME_LONG, ON_FOOT_ONLY_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sOnFootOnly ) ); + + sCutAll = numericAttr.create( CUTALL_NAME_LONG, CUTALL_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sCutAll ) ); + + sReset = numericAttr.create( RESET_NAME_LONG, RESET_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sReset ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// RailCamLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void RailCamLocatorNode::postConstructor() +{ +} + +//============================================================================= +// RailCamLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& railCamLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* RailCamLocatorNode::Export( MObject& railCamLocatorNode ) +{ + MFnDagNode fnNode( railCamLocatorNode ); + + if ( fnNode.typeId() == RailCamLocatorNode::id ) + { + tlWBRailCamChunk* railChunk = new tlWBRailCamChunk(); + assert( railChunk ); + + railChunk->SetName( fnNode.name().asChar() ); + + int behaviour; + fnNode.findPlug( sBehaviour ).getValue( behaviour ); + railChunk->SetBehaviour( (RailCam::Behaviour)(behaviour) ); + + float minRad; + fnNode.findPlug( sMinRadius ).getValue( minRad ); + railChunk->SetMinRadius( minRad ); + + float maxRad; + fnNode.findPlug( sMaxRadius ).getValue( maxRad ); + railChunk->SetMaxRadius( maxRad ); + + bool trackRail; + fnNode.findPlug( sTrackRail ).getValue( trackRail ); + railChunk->SetTrackRail( trackRail ? 1 : 0 ); + + float trackDist; + fnNode.findPlug( sTrackDist ).getValue( trackDist ); + railChunk->SetTrackDist( trackDist ); + + bool reverseSense; + fnNode.findPlug( sReverseSense ).getValue( reverseSense ); + railChunk->SetReverseSense( reverseSense ? 1 : 0 ); + + float fov; + fnNode.findPlug( sFOV ).getValue( fov ); + railChunk->SetFOV( fov ); + + float x, y, z; + fnNode.findPlug( sFacingOffset ).child( 0 ).getValue( x ); + fnNode.findPlug( sFacingOffset ).child( 1 ).getValue( y ); + fnNode.findPlug( sFacingOffset ).child( 2 ).getValue( z ); + railChunk->SetTargetOffset( tlPoint( x, y, z ) ); + + // THIS IS A HACK. Since we're not going to support axis play. We're + // going to hide the transition rate in the data. Sorry. +// fnNode.findPlug( sAxisPlay ).child( 0 ).getValue( x ); +// fnNode.findPlug( sAxisPlay ).child( 1 ).getValue( y ); +// fnNode.findPlug( sAxisPlay ).child( 2 ).getValue( z ); + fnNode.findPlug( sTransitionToRate ).getValue( x ); //transition rate. + + //Now we're hiding the flags in the y.. THIS SUCKS! + bool noF = false; + fnNode.findPlug( sNoFOV ).getValue( noF ); + y = (float)( noF ? 1 : 0 ); + + //This just GETS WORSE! + int values = 0; + + bool carOnly = false; + fnNode.findPlug( sCarOnly ).getValue( carOnly ); + values |= ( carOnly ? 0x00000001 : 0 ); + + bool cut = false; + fnNode.findPlug( sCutAll ).getValue( cut ); + values |= ( cut ? 0x00000002 : 0 ); + + bool reset = false; + fnNode.findPlug( sReset ).getValue( reset ); + values |= ( reset ? 0x00000004 : 0 ); + + bool onFootOnly = false; + fnNode.findPlug( sOnFootOnly ).getValue( onFootOnly ); + values |= ( onFootOnly ? 0x00000008 : 0 ); + + if( carOnly && onFootOnly ) + { + MExt::DisplayError( "Rail Camera: %s has onFootOnly and carOnly flags set!\n", fnNode.name().asChar() ); + } + + z = (float)values; + railChunk->SetAxisPlay( tlPoint( x, y, z ) ); + + float posLag; + fnNode.findPlug( sPositionLag ).getValue( posLag ); + railChunk->SetPositionLag( posLag ); + + float targLag; + fnNode.findPlug( sTargetLag ).getValue( targLag ); + railChunk->SetTargetLag( targLag ); + + return railChunk; + } + + return NULL; +} + +//***************************************************************************** +// +// Private Member Functions +// +//***************************************************************************** diff --git a/tools/worldbuilder/code/nodes/railcamlocatornode.h b/tools/worldbuilder/code/nodes/railcamlocatornode.h new file mode 100644 index 0000000..ce89b03 --- /dev/null +++ b/tools/worldbuilder/code/nodes/railcamlocatornode.h @@ -0,0 +1,232 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: railcamlocatornode.h +// +// Description: Blahblahblah +// +// History: 18/07/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef RAILCAMLOCATORNODE_H +#define RAILCAMLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; +class RailCam; +class WBCamTarget; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK RailCamLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class RailCamLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + RailCamLocatorNode(); + virtual ~RailCamLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& railCamLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* RAIL_NAME_SHORT; + static const char* RAIL_NAME_LONG; + static MObject sRail; + + static const char* BEHAVIOUR_NAME_SHORT; + static const char* BEHAVIOUR_NAME_LONG; + static MObject sBehaviour; + + static const char* MIN_RADIUS_NAME_SHORT; + static const char* MIN_RADIUS_NAME_LONG; + static MObject sMinRadius; + + static const char* MAX_RADIUS_NAME_SHORT; + static const char* MAX_RADIUS_NAME_LONG; + static MObject sMaxRadius; + + static const char* TRACK_RAIL_NAME_SHORT; + static const char* TRACK_RAIL_NAME_LONG; + static MObject sTrackRail; + + static const char* TRACK_DIST_NAME_SHORT; + static const char* TRACK_DIST_NAME_LONG; + static MObject sTrackDist; + + static const char* REVERSE_SENSE_NAME_SHORT; + static const char* REVERSE_SENSE_NAME_LONG; + static MObject sReverseSense; + + + static const char* FOV_NAME_SHORT; + static const char* FOV_NAME_LONG; + static MObject sFOV; + + static const char* FACING_OFFSET_NAME_SHORT; + static const char* FACING_OFFSET_NAME_LONG; + static MObject sFacingOffset; + + static const char* AXIS_PLAY_NAME_SHORT; + static const char* AXIS_PLAY_NAME_LONG; + static MObject sAxisPlay; + + static const char* ACTIVE_NAME_SHORT; + static const char* ACTIVE_NAME_LONG; + static MObject sActive; + + static const char* TARGET_NAME_SHORT; + static const char* TARGET_NAME_LONG; + static MObject sTarget; + + static const char* POS_LAG_NAME_SHORT; + static const char* POS_LAG_NAME_LONG; + static MObject sPositionLag; + + static const char* TARGET_LAG_NAME_SHORT; + static const char* TARGET_LAG_NAME_LONG; + static MObject sTargetLag; + + static const char* TRANSITION_TO_RATE_NAME_LONG; + static const char* TRANSITION_TO_RATE_NAME_SHORT; + static MObject sTransitionToRate; + + static const char* NOFOV_NAME_LONG; + static const char* NOFOV_NAME_SHORT; + static MObject sNoFOV; + + static const char* CAR_ONLY_NAME_LONG; + static const char* CAR_ONLY_NAME_SHORT; + static MObject sCarOnly; + + static const char* ON_FOOT_ONLY_NAME_LONG; + static const char* ON_FOOT_ONLY_NAME_SHORT; + static MObject sOnFootOnly; + + static const char* CUTALL_NAME_LONG; + static const char* CUTALL_NAME_SHORT; + static MObject sCutAll; + + static const char* RESET_NAME_LONG; + static const char* RESET_NAME_SHORT; + static MObject sReset; + + //MPxNode stuff... + RailCam* GetRailCam(); + WBCamTarget* GetTarget(); + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + RailCam* mRailCam; + WBCamTarget* mCamTarget; + + //Prevent wasteful constructor creation. + RailCamLocatorNode( const RailCamLocatorNode& eventlocatornode ); + RailCamLocatorNode& operator=( const RailCamLocatorNode& railCamlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// RailCamLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void RailCamLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// RailCamLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const RailCamLocatorNode::GetNewName() +{ + return sNewName; +} + +//============================================================================= +// RailCamLocatorNode::GetRailCam +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: RailCam +// +//============================================================================= +inline RailCam* RailCamLocatorNode::GetRailCam() +{ + return mRailCam; +} + +//============================================================================= +// RailCamLocatorNode::GetTarget +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: WBCamTarget +// +//============================================================================= +inline WBCamTarget* RailCamLocatorNode::GetTarget() +{ + return mCamTarget; +} + +#endif //RAILCAMLOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/scriptlocatornode.cpp b/tools/worldbuilder/code/nodes/scriptlocatornode.cpp new file mode 100644 index 0000000..93d5c67 --- /dev/null +++ b/tools/worldbuilder/code/nodes/scriptlocatornode.cpp @@ -0,0 +1,377 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: ScriptLocatorNode.cpp +// +// Description: Implement ScriptLocatorNode +// +// History: 27/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/ScriptLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" + +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatorevents.h" +#include "../../../game/code/meta/locatortypes.h" + +#define HIINT(x) (((int)((x)>>32) & 0xFFFFFFFF)) +#define LOINT(x) ((int)x) + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId ScriptLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::ScriptLocator ); +const char* ScriptLocatorNode::stringId = "ScriptLocatorNode"; + +const int ScriptLocatorNode::ACTIVE_COLOUR = 15; +const int ScriptLocatorNode::INACTIVE_COLOUR = 12; +const float ScriptLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* ScriptLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* ScriptLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject ScriptLocatorNode::sTriggers; + +const char* ScriptLocatorNode::SCRIPT_NAME_SHORT = "s"; +const char* ScriptLocatorNode::SCRIPT_NAME_LONG = "script"; +MObject ScriptLocatorNode::sScript; + +char ScriptLocatorNode::sNewName[MAX_NAME_LEN]; +char ScriptLocatorNode::sScriptName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK ScriptLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + SetDlgItemText( hWnd, IDC_EDIT2, WorldBuilder::GetPrefix() ); + SetDlgItemText( hWnd, IDC_EDIT3, "" ); + return true; + } + break; + case WM_COMMAND: + { + if ( LOWORD(wParam) == IDC_BUTTON1 || LOWORD(wParam) == IDOK ) + { + //Get the entry in the text field. + char name[ScriptLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, ScriptLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Script Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + ScriptLocatorNode::SetNewName( newName.asChar() ); + + //Do the scripte name too... + GetDlgItemText( hWnd, IDC_EDIT3, name, ScriptLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a script name!"); + return false; + } + + ScriptLocatorNode::SetScriptName( name ); + + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + ScriptLocatorNode::SetNewName( "" ); + ScriptLocatorNode::SetScriptName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// ScriptLocatorNode::ScriptLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ScriptLocatorNode::ScriptLocatorNode() +{ +} + +//============================================================================== +// ScriptLocatorNode::~ScriptLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ScriptLocatorNode::~ScriptLocatorNode() +{ +} + +//============================================================================= +// ScriptLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* ScriptLocatorNode::creator() +{ + return new ScriptLocatorNode(); +} + +//============================================================================= +// ScriptLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void ScriptLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::SCRIPT_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + MPlugArray sources, targets; + MFnDagNode fnNode( thisMObject() ); + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + unsigned int i; + for ( i = 0; i < targets.length(); ++i ) + { + //Draw a box around the source trigger volume. + MPoint triggerWP, thisWP; + MExt::GetWorldPosition( &triggerWP, sources[i].node() ); + + MExt::GetWorldPosition( &thisWP, thisMObject() ); + + MPoint triggerLP; + triggerLP = triggerWP - thisWP; + + //TEMP + view.setDrawColor( 8, M3dView::kActiveColors ); + + GLExt::drawLine( MPoint(0,0,0), triggerLP, 5.0f ); + } + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawPyramid( SCALE, 0,0,0, 5.0 ); + GLExt::drawS( SCALE, 0,1,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// ScriptLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus ScriptLocatorNode::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 ) ); + + MFnTypedAttribute typedAttr; + sScript = typedAttr.create( SCRIPT_NAME_LONG, SCRIPT_NAME_SHORT, MFnData::kString, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typedAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typedAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sScript ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// ScriptLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void ScriptLocatorNode::postConstructor() +{ +} + +//============================================================================= +// ScriptLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& ScriptLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* ScriptLocatorNode::Export( MObject& scriptLocatorNode ) +{ + MFnDagNode fnNode( scriptLocatorNode ); + + if ( fnNode.typeId() == ScriptLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::SCRIPT ); + + //The data here is the event associated with this locator. + MString script; + fnNode.findPlug( sScript ).getValue( script ); + + unsigned int length = (script.length() / 4 + 1); + + unsigned long* data = new unsigned long[length]; + memset(data, 0, length * 4); + memcpy( data, script.asChar(), script.length() ); + + locator->SetDataElements( data, length ); + locator->SetNumDataElements( length ); + + delete[] data; + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, scriptLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + 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 +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/scriptlocatornode.h b/tools/worldbuilder/code/nodes/scriptlocatornode.h new file mode 100644 index 0000000..b7586ba --- /dev/null +++ b/tools/worldbuilder/code/nodes/scriptlocatornode.h @@ -0,0 +1,149 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: scriptlocatornode.h +// +// Description: Blahblahblah +// +// History: 27/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef SCRIPTLOCATORNODE_H +#define SCRIPTLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK ScriptLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class ScriptLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + ScriptLocatorNode(); + virtual ~ScriptLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& eventLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static void SetScriptName( const char* name ); + static const char* const GetScriptName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* SCRIPT_NAME_SHORT; + static const char* SCRIPT_NAME_LONG; + static MObject sScript; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + static char sScriptName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + ScriptLocatorNode( const ScriptLocatorNode& scriptlocatornode ); + ScriptLocatorNode& operator=( const ScriptLocatorNode& scriptlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// ScriptLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void ScriptLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// ScriptLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const ScriptLocatorNode::GetNewName() +{ + return sNewName; +} + +//============================================================================= +// ScriptLocatorNode::SetScriptName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void ScriptLocatorNode::SetScriptName( const char* name ) +{ + strncpy( sScriptName, name, MAX_NAME_LEN); +} + +//============================================================================= +// ScriptLocatorNode::GetScriptName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const ScriptLocatorNode::GetScriptName() +{ + return sScriptName; +} +#endif //SCRIPTLOCATORNODE_H 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 +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/splinelocatornode.h b/tools/worldbuilder/code/nodes/splinelocatornode.h new file mode 100644 index 0000000..4473d05 --- /dev/null +++ b/tools/worldbuilder/code/nodes/splinelocatornode.h @@ -0,0 +1,101 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: scriptlocatornode.h +// +// Description: Blahblahblah +// +// History: 16/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef SPLINELOCATORNODE_H +#define SPLINELOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class SplineLocatorNode : public MPxLocatorNode +{ +public: + SplineLocatorNode(); + virtual ~SplineLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& eventLocatorNode ); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* SPLINE_NAME_SHORT; + static const char* SPLINE_NAME_LONG; + static MObject sSpline; + + static const char* CAMERA_NAME_SHORT; + static const char* CAMERA_NAME_LONG; + static MObject sCamera; + + static const char* IS_COIN_SHORT; + static const char* IS_COIN_LONG; + static MObject sIsCoin; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + //Prevent wasteful constructor creation. + SplineLocatorNode( const SplineLocatorNode& eventlocatornode ); + SplineLocatorNode& operator=( const SplineLocatorNode& eventlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// SplineLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +inline void* SplineLocatorNode::creator() +{ + return new SplineLocatorNode(); +} + +#endif //SPLINELOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/staticcameralocatornode.cpp b/tools/worldbuilder/code/nodes/staticcameralocatornode.cpp new file mode 100644 index 0000000..c922d0f --- /dev/null +++ b/tools/worldbuilder/code/nodes/staticcameralocatornode.cpp @@ -0,0 +1,573 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: StaticCameraLocatorNode.cpp +// +// Description: Implement StaticCameraLocatorNode +// +// History: 9/17/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include "main/toolhack.h" +#include <raddebug.hpp> +#include <p3d/pointcamera.hpp> + +//======================================== +// Project Includes +//======================================== +#include "StaticCameraLocatorNode.h" + +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" +#include "utility/transformmatrix.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatortypes.h" +#include "../../../game/code/camera/staticcam.h" + +#include "nodes/triggervolumenode.h" + +#include "gameengine/gameengine.h" +#include "gameengine/wbcamtarget.h" + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId StaticCameraLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::StaticCameraLocator ); +const char* StaticCameraLocatorNode::stringId = "StaticCameraLocatorNode"; + +const int StaticCameraLocatorNode::ACTIVE_COLOUR = 15; +const int StaticCameraLocatorNode::INACTIVE_COLOUR = 12; +const float StaticCameraLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +char StaticCameraLocatorNode::sNewName[MAX_NAME_LEN]; + +const char* StaticCameraLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* StaticCameraLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject StaticCameraLocatorNode::sTriggers; + +const char* StaticCameraLocatorNode::FOV_NAME_SHORT = "fov"; +const char* StaticCameraLocatorNode::FOV_NAME_LONG = "fieldOfView"; +MObject StaticCameraLocatorNode::sFOV; + +const char* StaticCameraLocatorNode::TARGET_NAME_SHORT = "trg"; +const char* StaticCameraLocatorNode::TARGET_NAME_LONG = "target"; +MObject StaticCameraLocatorNode::sTarget; + +const char* StaticCameraLocatorNode::FACING_OFFSET_NAME_SHORT = "facoff"; +const char* StaticCameraLocatorNode::FACING_OFFSET_NAME_LONG = "facingOffset"; +MObject StaticCameraLocatorNode::sFacingOffset; + +const char* StaticCameraLocatorNode::TRACKING_NAME_SHORT = "trkng"; +const char* StaticCameraLocatorNode::TRACKING_NAME_LONG = "tracking"; +MObject StaticCameraLocatorNode::sTracking; + +const char* StaticCameraLocatorNode::TARGET_LAG_NAME_SHORT = "trglg"; +const char* StaticCameraLocatorNode::TARGET_LAG_NAME_LONG = "targetLag"; +MObject StaticCameraLocatorNode::sTargetLag; + +const char* StaticCameraLocatorNode::ACTIVE_NAME_SHORT = "act"; +const char* StaticCameraLocatorNode::ACTIVE_NAME_LONG = "active"; +MObject StaticCameraLocatorNode::sActive; + +const char* StaticCameraLocatorNode::TRANSITION_TO_RATE_NAME_LONG = "transitionTo"; +const char* StaticCameraLocatorNode::TRANSITION_TO_RATE_NAME_SHORT = "trnto"; +MObject StaticCameraLocatorNode::sTransitionToRate; + +const char* StaticCameraLocatorNode::ONESHOT_NAME_LONG = "oneShot"; +const char* StaticCameraLocatorNode::ONESHOT_NAME_SHORT = "oShot"; +MObject StaticCameraLocatorNode::sOneShot; + +const char* StaticCameraLocatorNode::NOFOV_NAME_LONG = "noFOV"; +const char* StaticCameraLocatorNode::NOFOV_NAME_SHORT = "nf"; +MObject StaticCameraLocatorNode::sNoFOV; + +const char* StaticCameraLocatorNode::CUTALL_NAME_LONG = "cutInOut"; +const char* StaticCameraLocatorNode::CUTALL_NAME_SHORT = "cin"; +MObject StaticCameraLocatorNode::sCutAll; + +const char* StaticCameraLocatorNode::CAR_ONLY_NAME_LONG = "carOnly"; +const char* StaticCameraLocatorNode::CAR_ONLY_NAME_SHORT = "co"; +MObject StaticCameraLocatorNode::sCarOnly; + +const char* StaticCameraLocatorNode::ON_FOOT_ONLY_NAME_LONG = "onFootOnly"; +const char* StaticCameraLocatorNode::ON_FOOT_ONLY_NAME_SHORT = "ofo"; +MObject StaticCameraLocatorNode::sOnFootOnly; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK StaticCameraLocatorNameCallBack( 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[StaticCameraLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, StaticCameraLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Static Camera Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + StaticCameraLocatorNode::SetNewName( newName.asChar() ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + StaticCameraLocatorNode::SetNewName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// BreakableCameraLocatorNode::StaticCameraLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +StaticCameraLocatorNode::StaticCameraLocatorNode() +{ + mStaticCam = new StaticCam(); + mStaticCam->AddRef(); + mStaticCam->SetPlayerID( 0 ); + + mStaticCam->SetCamera( new tPointCamera() ); + + mCamTarget = new WBCamTarget(); +} + +//============================================================================== +// StaticCameraLocatorNode::~StaticCameraLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +StaticCameraLocatorNode::~StaticCameraLocatorNode() +{ + mStaticCam->Release(); + mStaticCam = NULL; + + if ( mCamTarget ) + { + delete mCamTarget; + } +} + +//============================================================================= +// StaticCameraLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* StaticCameraLocatorNode::creator() +{ + return new StaticCameraLocatorNode(); +} + +//============================================================================= +// StaticCameraLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void StaticCameraLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::DIRECTIONAL_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + GameEngine::GetInstance()->UpdateStaticCam( thisMObject() ); + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0f ); + GLExt::drawCamera3D( SCALE, 0,0,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// StaticCameraLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus StaticCameraLocatorNode::initialize() +{ + MStatus status; + MFnMessageAttribute msgAttr; + 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 ) ); + + MFnNumericAttribute numericAttr; + sFOV = numericAttr.create( FOV_NAME_LONG, FOV_NAME_SHORT, MFnNumericData::kFloat, 90.0f, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.1f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(180.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sFOV ) ); + + MFnTypedAttribute typedAttr; + sTarget = typedAttr.create( TARGET_NAME_LONG, TARGET_NAME_SHORT, MFnData::kString, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typedAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typedAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTarget ) ); + + sFacingOffset = numericAttr.create( FACING_OFFSET_NAME_LONG, FACING_OFFSET_NAME_SHORT, MFnNumericData::k3Float, 0.0f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sFacingOffset ) ); + + sTracking = numericAttr.create( TRACKING_NAME_LONG, TRACKING_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTracking ) ); + + sTargetLag = numericAttr.create( TARGET_LAG_NAME_LONG, TARGET_LAG_NAME_SHORT, MFnNumericData::kFloat, 0.04f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(1.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTargetLag ) ); + + sActive = numericAttr.create( ACTIVE_NAME_LONG, ACTIVE_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sActive ) ); + + sTransitionToRate = numericAttr.create( TRANSITION_TO_RATE_NAME_LONG, TRANSITION_TO_RATE_NAME_SHORT, MFnNumericData::kFloat, 0.04f, &status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMin(0.0f) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setMax(1.0f) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sTransitionToRate ) ); + + sOneShot = numericAttr.create( ONESHOT_NAME_LONG, ONESHOT_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sOneShot ) ); + + sNoFOV = numericAttr.create( NOFOV_NAME_LONG, NOFOV_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sNoFOV ) ); + + sCutAll = numericAttr.create( CUTALL_NAME_LONG, CUTALL_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sCutAll ) ); + + sCarOnly = numericAttr.create( CAR_ONLY_NAME_LONG, CAR_ONLY_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sCarOnly ) ); + + sOnFootOnly = numericAttr.create( ON_FOOT_ONLY_NAME_LONG, ON_FOOT_ONLY_NAME_SHORT, MFnNumericData::kBoolean, false, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( numericAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( numericAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( addAttribute( sOnFootOnly ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// StaticCameraLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void StaticCameraLocatorNode::postConstructor() +{ +} + +//============================================================================= +// StaticCameraLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& staticCameraLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* StaticCameraLocatorNode::Export( MObject& staticCameraLocatorNode ) +{ + MFnDagNode fnNode( staticCameraLocatorNode ); + + if ( fnNode.typeId() == StaticCameraLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::STATIC_CAMERA ); + + //Set the position + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, staticCameraLocatorNode ); + + //Set the values. + tlPoint position; + + position[0] = thisPosition[0] / WBConstants::Scale; + position[1] = thisPosition[1] / WBConstants::Scale; + position[2] = -thisPosition[2] / WBConstants::Scale; //Maya vs. P3D... + locator->SetPosition( position ); + + //Also get the direction. + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + unsigned int length = (1 * 3) + 2 + 1 + 1 + 1 + 1 + 1; //1 vector + 2 floats + 1 bool + transition rate (offset + fov & lag + tracking + trate) + one shot + CUT_ALL + CarOnly/OnFootOnly + + unsigned long* data; + + data = new unsigned long[ length ]; + + rmt::Vector offset; + + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + + fnNode.findPlug( StaticCameraLocatorNode::sFacingOffset ).child(0).getValue( x ); + fnNode.findPlug( StaticCameraLocatorNode::sFacingOffset ).child(1).getValue( y ); + fnNode.findPlug( StaticCameraLocatorNode::sFacingOffset ).child(2).getValue( z ); + + bool tracking = false; + fnNode.findPlug( StaticCameraLocatorNode::sTracking ).getValue( tracking ); + + if ( tracking ) + { + offset = rmt::Vector( x, y, z ); + } + else + { + //Figure out the transformation on the locator node and apply it to the offset. + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( hmatrix ); + //Make this p3d friendly... + hmatrix.element[3][0]; + hmatrix.element[3][1]; + hmatrix.element[3][2]; + + tlPoint point( 0.0f, 0.0f, 10.0f ); + point = VectorTransform( hmatrix, point ); + + offset = position; + offset.Add( point ); + } + + //Copy the offset to the locator + memcpy( &data[0], &offset.x, 3 * sizeof(float) ); + + float fov = 90.0f; + fnNode.findPlug( sFOV ).getValue( fov ); + memcpy( &data[3], &fov, sizeof(float) ); + + float lag = 0.04f; + fnNode.findPlug( sTargetLag ).getValue( lag ); + memcpy( &data[4], &lag, sizeof(float) ); + + //Also tracking + if ( tracking ) + { + data[5] = 1; + } + else + { + data[5] = 0; + } + + float tRate = 0.04f; + fnNode.findPlug( sTransitionToRate ).getValue( tRate ); + memcpy( &data[6], &tRate, sizeof(float) ); + + bool oneShot = false; + fnNode.findPlug( sOneShot ).getValue( oneShot ); + if ( oneShot ) + { + data[7] = 1; + } + else + { + data[7] = 0; + } + + bool noFOV = false; + fnNode.findPlug( sNoFOV ).getValue( noFOV ); + data[7] |= ( (noFOV ? 1 : 0 ) << 1 ); + + bool cutInOut = false; + fnNode.findPlug( sCutAll ).getValue( cutInOut ); + data[8] = ( (cutInOut ? 1 : 0 ) ); + + bool carOnly = false; + fnNode.findPlug( sCarOnly ).getValue( carOnly ); + data[9] = ( (carOnly ? 1 : 0 ) ); + + bool onFootOnly = false; + fnNode.findPlug( sOnFootOnly ).getValue( onFootOnly ); + data[9] |= ( (onFootOnly ? 1 << 1 : 0 ) ); + + if( carOnly && onFootOnly ) + { + MExt::DisplayError( "Static Camera: %s has onFootOnly and carOnly flags set!\n", fnNode.name().asChar() ); + } + + locator->SetDataElements( data, length ); + locator->SetNumDataElements( length ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + 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 +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/staticcameralocatornode.h b/tools/worldbuilder/code/nodes/staticcameralocatornode.h new file mode 100644 index 0000000..88f0a64 --- /dev/null +++ b/tools/worldbuilder/code/nodes/staticcameralocatornode.h @@ -0,0 +1,198 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: staticcameralocatornode.h +// +// Description: Blahblahblah +// +// History: 9/17/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef STATICCAMERALOCATORNODE_H +#define STATICCAMERALOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; +class StaticCam; +class WBCamTarget; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK StaticCameraLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class StaticCameraLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + StaticCameraLocatorNode(); + virtual ~StaticCameraLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& staticCameraLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* FOV_NAME_SHORT; + static const char* FOV_NAME_LONG; + static MObject sFOV; + + static const char* TARGET_NAME_SHORT; + static const char* TARGET_NAME_LONG; + static MObject sTarget; + + static const char* FACING_OFFSET_NAME_SHORT; + static const char* FACING_OFFSET_NAME_LONG; + static MObject sFacingOffset; + + static const char* TRACKING_NAME_SHORT; + static const char* TRACKING_NAME_LONG; + static MObject sTracking; + + static const char* TARGET_LAG_NAME_SHORT; + static const char* TARGET_LAG_NAME_LONG; + static MObject sTargetLag; + + static const char* ACTIVE_NAME_SHORT; + static const char* ACTIVE_NAME_LONG; + static MObject sActive; + + static const char* TRANSITION_TO_RATE_NAME_LONG; + static const char* TRANSITION_TO_RATE_NAME_SHORT; + static MObject sTransitionToRate; + + static const char* ONESHOT_NAME_LONG; + static const char* ONESHOT_NAME_SHORT; + static MObject sOneShot; + + static const char* NOFOV_NAME_LONG; + static const char* NOFOV_NAME_SHORT; + static MObject sNoFOV; + + static const char* CUTALL_NAME_LONG; + static const char* CUTALL_NAME_SHORT; + static MObject sCutAll; + + static const char* CAR_ONLY_NAME_LONG; + static const char* CAR_ONLY_NAME_SHORT; + static MObject sCarOnly; + + static const char* ON_FOOT_ONLY_NAME_LONG; + static const char* ON_FOOT_ONLY_NAME_SHORT; + static MObject sOnFootOnly; + + //MPxNode stuff... + StaticCam* GetStaticCam(); + WBCamTarget* GetTarget(); + +private: + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + + StaticCam* mStaticCam; + WBCamTarget* mCamTarget; + + //Prevent wasteful constructor creation. + StaticCameraLocatorNode( const StaticCameraLocatorNode& staticcameralocatornode ); + StaticCameraLocatorNode& operator=( const StaticCameraLocatorNode& staticcameralocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// StaticCameraLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void StaticCameraLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// StaticCameraLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const StaticCameraLocatorNode::GetNewName() +{ + return sNewName; +} + +//============================================================================= +// StaticCameraLocatorNode::GetStaticCam +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: StaticCam +// +//============================================================================= +inline StaticCam* StaticCameraLocatorNode::GetStaticCam() +{ + return mStaticCam; +} + +//============================================================================= +// StaticCameraLocatorNode::GetTarget +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: WBCamTarget +// +//============================================================================= +inline WBCamTarget* StaticCameraLocatorNode::GetTarget() +{ + return mCamTarget; +} + +#endif //STATICCAMERALOCATORNODE_H diff --git a/tools/worldbuilder/code/nodes/triggertypes.h b/tools/worldbuilder/code/nodes/triggertypes.h new file mode 100644 index 0000000..4393649 --- /dev/null +++ b/tools/worldbuilder/code/nodes/triggertypes.h @@ -0,0 +1,10 @@ +#ifndef TRIGGER_TYPES +#define TRIGGER_TYPES + + enum TriggerType + { + SPHERE, + RECTANGLE + }; + +#endif
\ No newline at end of file diff --git a/tools/worldbuilder/code/nodes/triggervolumenode.cpp b/tools/worldbuilder/code/nodes/triggervolumenode.cpp new file mode 100644 index 0000000..6aa31dd --- /dev/null +++ b/tools/worldbuilder/code/nodes/triggervolumenode.cpp @@ -0,0 +1,435 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: TriggerVolumeNode.cpp +// +// Description: Implement TriggerVolumeNode +// +// History: 23/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <windows.h> +#include <GL/glu.h> +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/TriggerVolumeNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" + +#include "utility/transformmatrix.h" + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId TriggerVolumeNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::TriggerVolume ); +const char* TriggerVolumeNode::stringId = "TriggerVolumeNode"; + +const int TriggerVolumeNode::ACTIVE_COLOUR = 15; +const int TriggerVolumeNode::INACTIVE_COLOUR = 22; +const float TriggerVolumeNode::SCALE = 1.0f * WBConstants::Scale; +const float TriggerVolumeNode::LINE_WIDTH = 5.0f; + +const char* TriggerVolumeNode::LOCATOR_NAME_SHORT = "l"; +const char* TriggerVolumeNode::LOCATOR_NAME_LONG = "locator"; +MObject TriggerVolumeNode::sLocator; + +const char* TriggerVolumeNode::TYPE_NAME_SHORT = "typ"; +const char* TriggerVolumeNode::TYPE_NAME_LONG = "type"; +MObject TriggerVolumeNode::sType; + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// TriggerVolumeNode::TriggerVolumeNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TriggerVolumeNode::TriggerVolumeNode() : + mType( SPHERE ) +{ +} + +//============================================================================== +// TriggerVolumeNode::~TriggerVolumeNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TriggerVolumeNode::~TriggerVolumeNode() +{ +} + +//============================================================================= +// TriggerVolumeNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* TriggerVolumeNode::creator() +{ + return new TriggerVolumeNode(); +} + +//============================================================================= +// TriggerVolumeNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void TriggerVolumeNode::draw( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::TRIGGER_VOLUMES ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + // view.setDrawColor( INACTIVE_COLOUR, M3dView::kDormantColors ); + // GLExt::drawLine( localOrigin, localPosNN ); + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + + //Determine the type of trigger volume. + MFnDagNode fnDag( thisMObject() ); + + MStatus status; + MPlug typePlug = fnDag.findPlug( sType, &status ); + assert( status ); + + int type; + typePlug.getValue( type ); + + //Test to see if there was a change. + if( (Type)type != mType ) + { + //Hmm, changing trigger volume types... + + if ( (Type)type == SPHERE ) + { + //Becoming a sphere. + MObject transform; + + transform = fnDag.parent( 0 ); + assert( !transform.isNull() ); + + MFnDagNode fnTransDag( transform ); + + //Test the scaling factors. If one is larger than + //another, set them all to the same value. + MPlug scaleX, scaleY, scaleZ; + double x, y, z; + + scaleX = fnTransDag.findPlug( MString("sx"), &status ); + assert( status ); + scaleX.getValue( x ); + assert( status ); + + scaleY = fnTransDag.findPlug( MString("sy"), &status ); + assert( status ); + scaleY.getValue( y ); + assert( status ); + + scaleZ = fnTransDag.findPlug( MString("sz"), &status ); + assert( status ); + scaleZ.getValue( z ); + assert( status ); + + //which is larger? + double largest = 0; + if ( x > largest ) + { + largest = x; + } + if ( y > largest ) + { + largest = y; + } + if ( z > largest ) + { + largest = z; + } + + x = largest; + y = largest; + z = largest; + + scaleX.setValue( x ); + scaleY.setValue( y ); + scaleZ.setValue( z ); + + mType = SPHERE; + } + else if ( (Type)type == RECTANGLE ) + { + //Becoming a rectangle. + + mType = RECTANGLE; + } + else + { + //Don't know what this is! + assert( false ); + } + } + else + { + if ( mType == SPHERE ) + { + MObject transform; + + transform = fnDag.parent( 0 ); + assert( !transform.isNull() ); + + MFnDagNode fnTransDag( transform ); + + //Test the scaling factors. If one is larger than + //another, set them all to the same value. + MPlug scaleX, scaleY, scaleZ; + double x; + + scaleX = fnTransDag.findPlug( MString("sx"), &status ); + assert( status ); + scaleX.getValue( x ); + assert( status ); + + scaleY = fnTransDag.findPlug( MString("sy"), &status ); + assert( status ); + + scaleZ = fnTransDag.findPlug( MString("sz"), &status ); + assert( status ); + + scaleY.setValue( x ); + scaleZ.setValue( x ); + + GLExt::drawSphere( SCALE, 0,0,0, 5.0 ); + + } + else if ( mType == RECTANGLE ) + { + MPoint p1( SCALE, SCALE, -SCALE ); + MPoint p2( -SCALE, -SCALE, SCALE ); + + GLExt::drawBox( p1, p2, 5.0 ); + } + else + { + assert( false ); + } + } + + glPopAttrib(); + view.endGL(); + } +} + + +//============================================================================= +// TriggerVolumeNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus TriggerVolumeNode::initialize() +{ + MFnMessageAttribute msgAttr; + MStatus status; + + sLocator = msgAttr.create( LOCATOR_NAME_LONG, LOCATOR_NAME_SHORT, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( msgAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( msgAttr.setWritable( false ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sLocator ) ); + + MFnEnumAttribute enumAttr; + //Default to a SPHERE! + sType = enumAttr.create( TYPE_NAME_LONG, TYPE_NAME_SHORT, 0, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( enumAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( enumAttr.setWritable( true ) ); + RETURN_STATUS_ON_FAILURE( enumAttr.addField( MString( "sphere" ), SPHERE ) ); + RETURN_STATUS_ON_FAILURE( enumAttr.addField( MString( "rectangle" ), RECTANGLE ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sType ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// TriggerVolumeNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TriggerVolumeNode::postConstructor() +{ + //When my locator goes away, so do I. + setExistWithoutOutConnections( false ); +} + +//============================================================================= +// TriggerVolumeNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& triggerVolumeNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* TriggerVolumeNode::Export( MObject& triggerVolumeNode ) +{ + MFnDagNode fnNode( triggerVolumeNode ); + + if ( fnNode.typeId() == TriggerVolumeNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBTriggerVolumeChunk* trigger = new tlWBTriggerVolumeChunk; + + trigger->SetName( fnNode.name().asChar() ); + + int type; + fnNode.findPlug( sType ).getValue( type ); + trigger->SetType( type ); + + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( hmatrix ); + //Make this p3d friendly... + hmatrix.element[3][0] /= WBConstants::Scale; + hmatrix.element[3][1] /= WBConstants::Scale; + hmatrix.element[3][2] /= WBConstants::Scale; + + //This is the translation / rotation matrix + trigger->SetMatrix( hmatrix ); + + //This is the scale. + double scaleX, scaleY, scaleZ; + fnTransform.findPlug( MString( "sx" ) ).getValue( scaleX ); + fnTransform.findPlug( MString( "sy" ) ).getValue( scaleY ); + fnTransform.findPlug( MString( "sz" ) ).getValue( scaleZ ); + + trigger->SetScale( tlPoint( scaleX, scaleY, scaleZ ) ); + return trigger; + } + + return NULL; +} + +//============================================================================= +// TriggerVolumeNode::GetScaleAndMatrix +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& triggerVolumeNode, tlMatrix& mat, tlPoint& point) +// +// Return: void +// +//============================================================================= +void TriggerVolumeNode::GetScaleAndMatrix( MObject& triggerVolumeNode, tlMatrix& mat, tlPoint& point) +{ + MFnDagNode fnNode( triggerVolumeNode ); + + if ( fnNode.typeId() == TriggerVolumeNode::id ) + { + int type; + fnNode.findPlug( sType ).getValue( type ); + + MObject transform; + transform = fnNode.parent( 0 ); + MFnTransform fnTransform( transform ); + + MDagPath dagPath; + MExt::FindDagNodeByName( &dagPath, fnTransform.name() ); + TransformMatrix tm( dagPath ); + + tlMatrix hmatrix; + tm.GetHierarchyMatrixLHS( mat ); + //Make this p3d friendly... + mat.element[3][0] /= WBConstants::Scale; + mat.element[3][1] /= WBConstants::Scale; + mat.element[3][2] /= WBConstants::Scale; + + //This is the scale. + double scaleX, scaleY, scaleZ; + fnTransform.findPlug( MString( "sx" ) ).getValue( scaleX ); + fnTransform.findPlug( MString( "sy" ) ).getValue( scaleY ); + fnTransform.findPlug( MString( "sz" ) ).getValue( scaleZ ); + + point = tlPoint( scaleX, scaleY, scaleZ ); + } +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/triggervolumenode.h b/tools/worldbuilder/code/nodes/triggervolumenode.h new file mode 100644 index 0000000..b083af2 --- /dev/null +++ b/tools/worldbuilder/code/nodes/triggervolumenode.h @@ -0,0 +1,86 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: triggervolumenode.h +// +// Description: Blahblahblah +// +// History: 23/05/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef TRIGGERVOLUMENODE_H +#define TRIGGERVOLUMENODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class TriggerVolumeNode : public MPxLocatorNode +{ +public: + + enum Type + { + SPHERE, + RECTANGLE + }; + + TriggerVolumeNode(); + virtual ~TriggerVolumeNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& triggerVolumeNode ); + static void GetScaleAndMatrix( MObject& triggerVolumeNode, tlMatrix& mat, tlPoint& point); + + static MTypeId id; + static const char* stringId; + + static const char* LOCATOR_NAME_SHORT; + static const char* LOCATOR_NAME_LONG; + static MObject sLocator; + + static const char* TYPE_NAME_SHORT; + static const char* TYPE_NAME_LONG; + static MObject sType; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + static const float LINE_WIDTH; + + Type mType; + + //Prevent wasteful constructor creation. + TriggerVolumeNode( const TriggerVolumeNode& triggervolumenode ); + TriggerVolumeNode& operator=( const TriggerVolumeNode& triggervolumenode ); +}; + + +#endif //TRIGGERVOLUMENODE_H diff --git a/tools/worldbuilder/code/nodes/wbspline.cpp b/tools/worldbuilder/code/nodes/wbspline.cpp new file mode 100644 index 0000000..d0673f7 --- /dev/null +++ b/tools/worldbuilder/code/nodes/wbspline.cpp @@ -0,0 +1,109 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: WBSpline.cpp +// +// Description: Implement WBSpline +// +// History: 05/06/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/WBSpline.h" +#include "nodes/triggervolumenode.h" +#include "main/constants.h" + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +char WBSpline::sName[MAX_NAME_LEN]; + + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +void WBSpline::SetName( const char* name ) +{ + strncpy( sName, name, MAX_NAME_LEN ); +} + +const char* const WBSpline::GetName() +{ + return sName; +} + +//============================================================================= +// WBSpline::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& obj ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* WBSpline::Export( MObject& obj ) +{ + MStatus status; + + MFnDagNode fnDagNode( obj ); + MDagPath dagPath; + fnDagNode.getPath( dagPath ); + + MFnNurbsCurve fnNurbs( dagPath, &status ); + assert( status ); + + if ( status ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBSplineChunk* spline = new tlWBSplineChunk; + + spline->SetName( fnNurbs.name().asChar() ); + + int numCVs = fnNurbs.numCVs( &status ); + assert( status ); + + MPointArray cvs; + fnNurbs.getCVs( cvs, MSpace::kWorld ); + + tlPoint* tlCVs = new tlPoint[numCVs]; + + int i; + for ( i = 0; i < numCVs; ++i ) + { + tlCVs[i].x = cvs[i].x / WBConstants::Scale; + tlCVs[i].y = cvs[i].y / WBConstants::Scale; + tlCVs[i].z = -cvs[i].z / WBConstants::Scale; + } + + spline->SetCVs( tlCVs, numCVs ); + spline->SetNumCVs( numCVs ); + + delete[] tlCVs; + + return spline; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/wbspline.h b/tools/worldbuilder/code/nodes/wbspline.h new file mode 100644 index 0000000..87caf6d --- /dev/null +++ b/tools/worldbuilder/code/nodes/wbspline.h @@ -0,0 +1,54 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: wbspline.h +// +// Description: Blahblahblah +// +// History: 05/06/2002 + Created -- NAME +// +//============================================================================= + +#ifndef WBSPLINE_H +#define WBSPLINE_H + +//======================================== +// Nested Includes +//======================================== +#include "main/toolhack.h" + +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class WBSpline +{ +public: + static tlDataChunk* Export( MObject& obj ); + + enum { MAX_NAME_LEN = 256 }; + + static void SetName( const char* name ); + static const char* const GetName(); + static char sName[MAX_NAME_LEN]; + +private: + WBSpline(); + virtual ~WBSpline(); + + //Prevent wasteful constructor creation. + WBSpline( const WBSpline& wbspline ); + WBSpline& operator=( const WBSpline& wbspline ); +}; + + +#endif //WBSPLINE_H diff --git a/tools/worldbuilder/code/nodes/zoneeventlocatornode.cpp b/tools/worldbuilder/code/nodes/zoneeventlocatornode.cpp new file mode 100644 index 0000000..60d84d8 --- /dev/null +++ b/tools/worldbuilder/code/nodes/zoneeventlocatornode.cpp @@ -0,0 +1,377 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: ZoneEventLocatorNode.cpp +// +// Description: Implement ZoneEventLocatorNode +// +// History: 18/06/2002 + Created -- Cary Brisebois +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include "main/toolhack.h" +#include <toollib.hpp> + +//======================================== +// Project Includes +//======================================== +#include "nodes/ZoneEventLocatorNode.h" +#include "main/constants.h" +#include "main/worldbuilder.h" +#include "utility/glext.h" +#include "utility/mext.h" +#include "utility/nodehelper.h" + +#include "nodes/triggervolumenode.h" + +#include "resources/resource.h" + +#include "../../../game/code/meta/locatorevents.h" +#include "../../../game/code/meta/locatortypes.h" + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** +MTypeId ZoneEventLocatorNode::id( WBConstants::TypeIDPrefix, WBConstants::NodeIDs::ZoneEventLocator ); +const char* ZoneEventLocatorNode::stringId = "ZoneEventLocatorNode"; + +const int ZoneEventLocatorNode::ACTIVE_COLOUR = 15; +const int ZoneEventLocatorNode::INACTIVE_COLOUR = 12; +const float ZoneEventLocatorNode::SCALE = 1.0f * WBConstants::Scale; + +const char* ZoneEventLocatorNode::TRIGGERS_NAME_SHORT = "trigs"; +const char* ZoneEventLocatorNode::TRIGGERS_NAME_LONG = "triggers"; +MObject ZoneEventLocatorNode::sTriggers; + +const char* ZoneEventLocatorNode::ZONE_NAME_SHORT = "z"; +const char* ZoneEventLocatorNode::ZONE_NAME_LONG = "zone"; +MObject ZoneEventLocatorNode::sZone; + +char ZoneEventLocatorNode::sNewName[MAX_NAME_LEN]; +char ZoneEventLocatorNode::sZoneName[MAX_NAME_LEN]; + +//****************************************************************************** +// +// Callbacks +// +//****************************************************************************** + +BOOL CALLBACK ZoneEventLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + SetDlgItemText( hWnd, IDC_EDIT2, WorldBuilder::GetPrefix() ); + SetDlgItemText( hWnd, IDC_EDIT3, "" ); + return true; + } + break; + case WM_COMMAND: + { + if ( LOWORD(wParam) == IDC_BUTTON1 || LOWORD(wParam) == IDOK ) + { + //Get the entry in the text field. + char name[ZoneEventLocatorNode::MAX_NAME_LEN]; + GetDlgItemText( hWnd, IDC_EDIT1, name, ZoneEventLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a new name for the Zone Event Locator!"); + return false; + } + + MString newName( WorldBuilder::GetPrefix() ); + newName += MString( name ); + + ZoneEventLocatorNode::SetNewName( newName.asChar() ); + + //Do the zone name too... + GetDlgItemText( hWnd, IDC_EDIT3, name, ZoneEventLocatorNode::MAX_NAME_LEN ); + + if ( strcmp(name, "") == 0 ) + { + MExt::DisplayWarning("You must input a file name for the zone!"); + return false; + } + + ZoneEventLocatorNode::SetZoneName( name ); + + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + else if( LOWORD(wParam) == IDCANCEL ) + { + ZoneEventLocatorNode::SetNewName( "" ); + ZoneEventLocatorNode::SetZoneName( "" ); + EndDialog( hWnd, 0 ); //this is how you close the window. + return true; + } + + return false; + } + break; + default: + { + return false; + } + break; + } +} + + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// ZoneEventLocatorNode::ZoneEventLocatorNode +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ZoneEventLocatorNode::ZoneEventLocatorNode() +{ +} + +//============================================================================== +// ZoneEventLocatorNode::~ZoneEventLocatorNode +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ZoneEventLocatorNode::~ZoneEventLocatorNode() +{ +} + +//============================================================================= +// ZoneEventLocatorNode::creator +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void* ZoneEventLocatorNode::creator() +{ + return new ZoneEventLocatorNode(); +} + +//============================================================================= +// ZoneEventLocatorNode::draw +//============================================================================= +// Description: Comment +// +// Parameters: ( M3dView& view, const MDagPath& path, M3dView::DisplayStyle displayStyle, M3dView::DisplayStatus displayStatus ) +// +// Return: void +// +//============================================================================= +void ZoneEventLocatorNode::draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus ) +{ + if ( WorldBuilder::GetDisplayLevel() & WorldBuilder::ZONE_EVENT_LOCATORS ) + { + view.beginGL(); + glPushAttrib( GL_CURRENT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); + + //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) ) + { + MPlugArray sources, targets; + MFnDagNode fnNode( thisMObject() ); + MPlug triggersPlug = fnNode.findPlug( sTriggers ); + MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false ); + + unsigned int i; + for ( i = 0; i < targets.length(); ++i ) + { + //Draw a box around the source trigger volume. + MPoint triggerWP, thisWP; + MExt::GetWorldPosition( &triggerWP, sources[i].node() ); + + MExt::GetWorldPosition( &thisWP, thisMObject() ); + + MPoint triggerLP; + triggerLP = triggerWP - thisWP; + + view.setDrawColor( 8, M3dView::kActiveColors ); + + GLExt::drawLine( MPoint(0,0,0), triggerLP, 5.0f ); + } + } + + if ( displayStatus == M3dView::kDormant ) + { + int colour = NodeHelper::OverrideNodeColour( thisMObject(), INACTIVE_COLOUR ); + + view.setDrawColor( colour, M3dView::kDormantColors ); + } + else + { + view.setDrawColor( ACTIVE_COLOUR, M3dView::kActiveColors ); + } + + //Draw a star to represent the locator. + GLExt::drawCrossHair3D( SCALE, 0,0,0, 5.0 ); + GLExt::drawPyramid( SCALE, 0,0,0, 5.0 ); + GLExt::drawLBolt( SCALE, 0,1,0, 5.0 ); + + glPopAttrib(); + view.endGL(); + } +} + +//============================================================================= +// ZoneEventLocatorNode::initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: MStatus +// +//============================================================================= +MStatus ZoneEventLocatorNode::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 ) ); + + MFnTypedAttribute typAttr; + sZone = typAttr.create( ZONE_NAME_LONG, ZONE_NAME_SHORT, MFnData::kString, MObject::kNullObj, &status ); + RETURN_STATUS_ON_FAILURE( status ); + RETURN_STATUS_ON_FAILURE( typAttr.setReadable( true ) ); + RETURN_STATUS_ON_FAILURE( typAttr.setWritable( true ) ); + + RETURN_STATUS_ON_FAILURE( addAttribute( sZone ) ); + + return MStatus::kSuccess; +} + +//============================================================================= +// ZoneEventLocatorNode::postConstructor +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void ZoneEventLocatorNode::postConstructor() +{ +} + +//============================================================================= +// ZoneEventLocatorNode::Export +//============================================================================= +// Description: Comment +// +// Parameters: ( MObject& eventLocatorNode ) +// +// Return: tlDataChunk +// +//============================================================================= +tlDataChunk* ZoneEventLocatorNode::Export( MObject& zoneEventLocatorNode ) +{ + MFnDagNode fnNode( zoneEventLocatorNode ); + + if ( fnNode.typeId() == ZoneEventLocatorNode::id ) + { + //Create a tlDataChunk and return it filled with the appropriate data. + tlWBLocatorChunk* locator = new tlWBLocatorChunk; + + locator->SetName( fnNode.name().asChar() ); + + locator->SetType( LocatorType::DYNAMIC_ZONE ); + + //The data here is the zone associated with this locator. + MString zone; + fnNode.findPlug( sZone ).getValue( zone ); + + unsigned int length = zone.length() / 4 + 1; + + unsigned long* data; + + data = new unsigned long[ length ]; + + memcpy( data, zone.asChar(), zone.length() ); + ((char*)(data))[zone.length()] = '\0'; + + locator->SetDataElements( data, length ); + locator->SetNumDataElements( length ); + + MPoint thisPosition; + MExt::GetWorldPosition( &thisPosition, zoneEventLocatorNode ); + + //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 ); + + //Make the trigger volumes a sub-chunk of the locator... + MPlugArray sources, targets; + 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 ); + + delete data; + + return locator; + } + + return NULL; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/tools/worldbuilder/code/nodes/zoneeventlocatornode.h b/tools/worldbuilder/code/nodes/zoneeventlocatornode.h new file mode 100644 index 0000000..7f25565 --- /dev/null +++ b/tools/worldbuilder/code/nodes/zoneeventlocatornode.h @@ -0,0 +1,151 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: zoneeventlocatornode.h +// +// Description: Blahblahblah +// +// History: 18/06/2002 + Created -- Cary Brisebois +// +//============================================================================= + +#ifndef ZONEEVENTLOCATORNODE_H +#define ZONEEVENTLOCATORNODE_H + +//======================================== +// Nested Includes +//======================================== +#include "precompiled/PCH.h" + +//======================================== +// Forward References +//======================================== +class tlDataChunk; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= +BOOL CALLBACK ZoneEventLocatorNameCallBack( HWND hWnd, UINT uMsg, UINT wParam, long lParam ); + +class ZoneEventLocatorNode : public MPxLocatorNode +{ +public: + enum { MAX_NAME_LEN = 256 }; + + ZoneEventLocatorNode(); + virtual ~ZoneEventLocatorNode(); + + static void* creator(); + + virtual void draw( M3dView& view, + const MDagPath& path, + M3dView::DisplayStyle displayStyle, + M3dView::DisplayStatus displayStatus + ); + static MStatus initialize(); + virtual void postConstructor(); + + //This is how you export one of these. + static tlDataChunk* Export( MObject& eventLocatorNode ); + + static void SetNewName( const char* name ); + static const char* const GetNewName(); + static void SetZoneName( const char* name ); + static const char* const GetZoneName(); + + static MTypeId id; + static const char* stringId; + + static const char* TRIGGERS_NAME_SHORT; + static const char* TRIGGERS_NAME_LONG; + static MObject sTriggers; + + static const char* ZONE_NAME_SHORT; + static const char* ZONE_NAME_LONG; + static MObject sZone; + +private: + + static const int ACTIVE_COLOUR; + static const int INACTIVE_COLOUR; + static const float SCALE; + + static char sNewName[MAX_NAME_LEN]; + static char sZoneName[MAX_NAME_LEN]; + + //Prevent wasteful constructor creation. + ZoneEventLocatorNode( const ZoneEventLocatorNode& zoneeventlocatornode ); + ZoneEventLocatorNode& operator=( const ZoneEventLocatorNode& zoneeventlocatornode ); +}; + +//****************************************************************************** +// +// Inline Public Functions +// +//****************************************************************************** + +//============================================================================= +// ZoneEventLocatorNode::SetNewName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void ZoneEventLocatorNode::SetNewName( const char* name ) +{ + strncpy( sNewName, name, MAX_NAME_LEN); +} + +//============================================================================= +// ZoneEventLocatorNode::GetNewName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const ZoneEventLocatorNode::GetNewName() +{ + return sNewName; +} + +//============================================================================= +// ZoneEventLocatorNode::SetZoneName +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* name ) +// +// Return: void +// +//============================================================================= +inline void ZoneEventLocatorNode::SetZoneName( const char* name ) +{ + strncpy( sZoneName, name, MAX_NAME_LEN); +} + +//============================================================================= +// ZoneEventLocatorNode::GetZoneName +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: const char* const +// +//============================================================================= +inline const char* const ZoneEventLocatorNode::GetZoneName() +{ + return sZoneName; +} + + + +#endif //ZONEEVENTLOCATORNODE_H |