summaryrefslogtreecommitdiffstats
path: root/tools/worldbuilder/code/gameengine
diff options
context:
space:
mode:
authorSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
committerSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
commiteb4b3404aa00220d659e532151dab13d642c17a3 (patch)
tree7e1107c4995489a26c4007e41b53ea8d00ab2134 /tools/worldbuilder/code/gameengine
downloadThe-Simpsons-Hit-and-Run-TSH&R-PC.tar
The-Simpsons-Hit-and-Run-TSH&R-PC.tar.gz
The-Simpsons-Hit-and-Run-TSH&R-PC.tar.bz2
The-Simpsons-Hit-and-Run-TSH&R-PC.tar.lz
The-Simpsons-Hit-and-Run-TSH&R-PC.tar.xz
The-Simpsons-Hit-and-Run-TSH&R-PC.tar.zst
The-Simpsons-Hit-and-Run-TSH&R-PC.zip
Diffstat (limited to 'tools/worldbuilder/code/gameengine')
-rw-r--r--tools/worldbuilder/code/gameengine/gameengine.cpp749
-rw-r--r--tools/worldbuilder/code/gameengine/gameengine.h85
-rw-r--r--tools/worldbuilder/code/gameengine/mayacamera.cpp151
-rw-r--r--tools/worldbuilder/code/gameengine/mayacamera.h49
-rw-r--r--tools/worldbuilder/code/gameengine/wbcamtarget.cpp296
-rw-r--r--tools/worldbuilder/code/gameengine/wbcamtarget.h90
6 files changed, 1420 insertions, 0 deletions
diff --git a/tools/worldbuilder/code/gameengine/gameengine.cpp b/tools/worldbuilder/code/gameengine/gameengine.cpp
new file mode 100644
index 0000000..6aedada
--- /dev/null
+++ b/tools/worldbuilder/code/gameengine/gameengine.cpp
@@ -0,0 +1,749 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: GameEngine.cpp
+//
+// Description: Implement GameEngine
+//
+// History: 19/07/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+
+#ifdef WORLD_BUILDER
+#include "main/toolhack.h"
+#endif
+
+#include <assert.h>
+#include <tlmatrix.hpp>
+#include <tlpoint.hpp>
+#include <p3d/pointcamera.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include "GameEngine.h"
+#include "nodes/railcamlocatornode.h"
+#include "nodes/staticcameralocatornode.h"
+#include "nodes/fovlocatornode.h"
+#include "nodes/splinelocatornode.h"
+#include "nodes/triggervolumenode.h"
+#include "nodes/staticcameralocatornode.h"
+#include "..\..\..\game\code\meta\recttriggervolume.h"
+#include "..\..\..\game\code\meta\spheretriggervolume.h"
+#include "..\..\..\game\code\meta\triggervolume.h"
+#include "utility\mext.h"
+#include "utility\glext.h"
+#include "main\constants.h"
+#include "wbcamtarget.h"
+
+#include "..\..\..\game\code\camera\railcam.h"
+#include "..\..\..\game\code\camera\staticcam.h"
+#include "utility/transformmatrix.h"
+
+#include <radtime.hpp>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+GameEngine* GameEngine::mInstance = NULL;
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// GameEngine::CreateInstance
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void GameEngine::CreateInstance()
+{
+ assert( mInstance == NULL );
+
+ mInstance = new GameEngine();
+}
+
+//=============================================================================
+// GameEngine::DestroyInstance
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void GameEngine::DestroyInstance()
+{
+ assert( mInstance );
+
+ delete mInstance;
+ mInstance = NULL;
+}
+
+//=============================================================================
+// GameEngine::GetInstance
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: GameEngine
+//
+//=============================================================================
+GameEngine* GameEngine::GetInstance()
+{
+ return mInstance;
+}
+
+//=============================================================================
+// GameEngine::UpdateRailCam
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( MObject& railCam )
+//
+// Return: void
+//
+//=============================================================================
+void GameEngine::UpdateRailCam( MObject& railCamObj )
+{
+ MStatus status;
+
+ MFnDependencyNode fnDepNode ( railCamObj );
+
+ MPlug activePlug = fnDepNode.findPlug( RailCamLocatorNode::sActive, &status );
+ assert( status );
+
+ bool active = false;
+ activePlug.getValue( active );
+
+ //Test to see if this is active.
+ if ( active )
+ {
+ MString targetName;
+ fnDepNode.findPlug( RailCamLocatorNode::sTarget, &status ).getValue( targetName );
+ assert( status );
+
+ //Test to see if this has a target...
+ if ( targetName.length() != 0 )
+ {
+ MDagPath targetPath;
+ MObject targetObj;
+ if ( !MExt::FindDagNodeByName( &targetPath, targetName ) )
+ {
+ //The target does not exist...
+ return;
+ }
+
+ targetObj = targetPath.node();
+
+ RailCam* railCam = dynamic_cast<RailCamLocatorNode*>(fnDepNode.userNode())->GetRailCam();
+ assert( railCam );
+
+ WBCamTarget* target = dynamic_cast<RailCamLocatorNode*>(fnDepNode.userNode())->GetTarget();
+ assert( target );
+
+ target->SetTarget( targetObj );
+
+ rmt::Vector position;
+ target->GetPosition( &position );
+
+ //Get the spline locator (it has the triggers)
+ MPlug railPlug = fnDepNode.findPlug( MString( "message" ), &status );
+ assert( status );
+
+ MPlugArray targets;
+ railPlug.connectedTo( targets, false, true, &status );
+ assert( status );
+
+ assert( targets.length() == 1 );
+ if ( targets.length() != 1 )
+ {
+ return;
+ }
+
+ MObject splineLoc = targets[0].node();
+
+ MFnDependencyNode splineFNDepNode( splineLoc );
+ MPlug triggersPlug = splineFNDepNode.findPlug( SplineLocatorNode::sTriggers, &status );
+ assert( status );
+
+ MPlugArray sources;
+ MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false );
+
+ unsigned int i;
+ for ( i = 0; i < sources.length(); ++i )
+ {
+ //Test to see if the target is in a trigger volume for this
+ //Test against all triggers...
+ MFnDependencyNode triggerFNDepNode( sources[i].node() );
+ int type = 0;
+ triggerFNDepNode.findPlug( TriggerVolumeNode::sType, &status ).getValue( type );
+ assert( status );
+
+ bool inside = false;
+
+ tlMatrix mat;
+ tlPoint scale;
+ TriggerVolumeNode::GetScaleAndMatrix( sources[i].node(), mat, scale );
+
+ switch ( type )
+ {
+ case TriggerVolumeNode::RECTANGLE:
+ {
+ RectTriggerVolume* trigVol = new RectTriggerVolume( mat.GetRow( 3 ),
+ mat.GetRow( 0 ),
+ mat.GetRow( 1 ),
+ mat.GetRow( 2 ),
+ scale.x,
+ scale.y,
+ scale.z );
+
+ inside = trigVol->Contains( position );
+
+ trigVol->Release();
+ }
+ break;
+ case TriggerVolumeNode::SPHERE:
+ {
+ SphereTriggerVolume* trigVol = new SphereTriggerVolume( mat.GetRow( 3 ), scale.x );
+
+ inside = trigVol->Contains( position );
+
+ trigVol->Release();
+ }
+ break;
+ default:
+ assert( false );
+ }
+
+ if ( inside )
+ {
+ //If the object is in a trigger volume update the camera and set
+ //the new position of the railCam
+
+ //We need to give it the splinecurve.
+ MPlug splineCurvePlug = fnDepNode.findPlug( RailCamLocatorNode::sRail, &status );
+ assert( status );
+
+ MPlugArray splines;
+ splineCurvePlug.connectedTo( splines, true, false, &status );
+ assert( status );
+
+ assert( splines.length() == 1 );
+ if ( splines.length() != 1 )
+ {
+ //Something has deleted the spline.
+ return;
+ }
+
+ MFnDependencyNode splineCurveFNDepNode( splines[0].node() );
+
+ MDagPath splineCurvePath;
+ bool found = MExt::FindDagNodeByName( &splineCurvePath, splineCurveFNDepNode.name() );
+ assert( found );
+
+ MFnNurbsCurve fnNurbsCurve( splineCurvePath, &status );
+ assert( status );
+
+ MPointArray cvs;
+ fnNurbsCurve.getCVs( cvs, MSpace::kWorld );
+
+ railCam->SetNumCVs( cvs.length() );
+
+ unsigned int cvCount;
+ for ( cvCount = 0; cvCount < cvs.length(); ++cvCount )
+ {
+ float x, y, z;
+
+ x = cvs[cvCount].x / WBConstants::Scale;
+ y = cvs[cvCount].y / WBConstants::Scale;
+ z = -cvs[cvCount].z / WBConstants::Scale;
+
+ rmt::Vector point( x, y, z );
+
+ railCam->SetVertex( cvCount, point );
+ }
+
+ railCam->SetTarget( target );
+
+
+ //Test for FOV changes.
+ UpdateFOV( railCam, position );
+
+ UpdateRailSettings( railCam, railCamObj );
+
+ railCam->Update( 16 );
+
+ rmt::Vector newPos;
+ railCam->GetCamera()->GetPosition( &newPos );
+ rmt::Vector newTarg;
+ railCam->GetCamera()->GetTarget( &newTarg );
+ rmt::Vector newVUp;
+ railCam->GetCamera()->GetVUp( &newVUp );
+ float fov, aspect;
+ railCam->GetCamera()->GetFOV( &fov, &aspect );
+
+ mMayaCam->Set( newPos, newTarg, newVUp, rmt::RadianToDeg(fov) );
+
+ MPoint newPoint;
+ newPoint.x = newPos.x * WBConstants::Scale;
+ newPoint.y = newPos.y * WBConstants::Scale;
+ newPoint.z = -newPos.z * WBConstants::Scale;
+
+ MExt::SetWorldPosition( newPoint, railCamObj );
+
+ //Get out of the loop.
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+//=============================================================================
+// GameEngine::UpdateStaticCam
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( MObject& staticCam )
+//
+// Return: void
+//
+//=============================================================================
+void GameEngine::UpdateStaticCam( MObject& staticCamObj )
+{
+ MStatus status;
+
+ MFnDependencyNode fnDepNode ( staticCamObj );
+
+ MPlug activePlug = fnDepNode.findPlug( StaticCameraLocatorNode::sActive, &status );
+ assert( status );
+
+ bool active = false;
+ activePlug.getValue( active );
+
+ //Test to see if this is active.
+ if ( active )
+ {
+ bool tracking = false;
+ fnDepNode.findPlug( StaticCameraLocatorNode::sTracking, &status ).getValue( tracking );
+ assert( status );
+
+ MString targetName;
+ fnDepNode.findPlug( StaticCameraLocatorNode::sTarget, &status ).getValue( targetName );
+ assert( status );
+
+ //Test to see if this has a target...
+ if ( targetName.length() != 0 )
+ {
+ MDagPath targetPath;
+ MObject targetObj;
+ if ( !MExt::FindDagNodeByName( &targetPath, targetName ) )
+ {
+ //The target does not exist...
+ return;
+ }
+
+ //Now we have a target to test for being in the cameras trigger volume
+ targetObj = targetPath.node();
+
+ StaticCam* staticCam = reinterpret_cast<StaticCameraLocatorNode*>(fnDepNode.userNode())->GetStaticCam();
+ assert( staticCam );
+
+ WBCamTarget* target = reinterpret_cast<StaticCameraLocatorNode*>(fnDepNode.userNode())->GetTarget();
+ assert( target );
+
+ target->SetTarget( targetObj );
+
+ rmt::Vector position;
+ target->GetPosition( &position );
+
+ //Test the trigger volumes
+ MPlug triggersPlug = fnDepNode.findPlug( StaticCameraLocatorNode::sTriggers, &status );
+ assert( status );
+
+ MPlugArray sources, targets;
+ MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false );
+
+ unsigned int i;
+ for ( i = 0; i < sources.length(); ++i )
+ {
+ //Test to see if the target is in a trigger volume for this
+ //Test against all triggers...
+ MFnDependencyNode triggerFNDepNode( sources[i].node() );
+ int type = 0;
+ triggerFNDepNode.findPlug( TriggerVolumeNode::sType, &status ).getValue( type );
+ assert( status );
+
+ bool inside = false;
+
+ tlMatrix mat;
+ tlPoint scale;
+ TriggerVolumeNode::GetScaleAndMatrix( sources[i].node(), mat, scale );
+
+ switch ( type )
+ {
+ case TriggerVolumeNode::RECTANGLE:
+ {
+ RectTriggerVolume* trigVol = new RectTriggerVolume( mat.GetRow( 3 ),
+ mat.GetRow( 0 ),
+ mat.GetRow( 1 ),
+ mat.GetRow( 2 ),
+ scale.x,
+ scale.y,
+ scale.z );
+
+ inside = trigVol->Contains( position );
+
+ trigVol->Release();
+ }
+ break;
+ case TriggerVolumeNode::SPHERE:
+ {
+ SphereTriggerVolume* trigVol = new SphereTriggerVolume( mat.GetRow( 3 ), scale.x );
+
+ inside = trigVol->Contains( position );
+
+ trigVol->Release();
+ }
+ break;
+ default:
+ assert( false );
+ }
+
+ if ( inside )
+ {
+ //If the object is in a trigger volume update the camera and set
+ //the new position of the static cam
+
+ staticCam->SetTarget( target );
+
+
+ //Test for FOV changes.
+ UpdateFOV( staticCam, position );
+
+ UpdateStaticCamSettings( staticCam, staticCamObj );
+
+ staticCam->Update( 16 );
+
+ rmt::Vector newPos;
+ staticCam->GetCamera()->GetPosition( &newPos );
+ rmt::Vector newTarg;
+ staticCam->GetCamera()->GetTarget( &newTarg );
+ rmt::Vector newVUp;
+ staticCam->GetCamera()->GetVUp( &newVUp );
+ float fov, aspect;
+ staticCam->GetCamera()->GetFOV( &fov, &aspect );
+
+ mMayaCam->Set( newPos, newTarg, newVUp, rmt::RadianToDeg(fov) );
+
+ MPoint newPoint;
+ newPoint.x = newPos.x * WBConstants::Scale;
+ newPoint.y = newPos.y * WBConstants::Scale;
+ newPoint.z = -newPos.z * WBConstants::Scale;
+
+ MExt::SetWorldPosition( newPoint, staticCamObj );
+
+ //Get out of the loop.
+ break;
+ }
+ }
+ }
+ }
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// GameEngine::GameEngine
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+GameEngine::GameEngine() :
+ mTimeStart(0)
+{
+ mMayaCam = new MayaCamera();
+}
+
+//==============================================================================
+// GameEngine::~GameEngine
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+GameEngine::~GameEngine()
+{
+ Init();
+
+ delete mMayaCam;
+}
+
+void GameEngine::Init()
+{
+}
+
+//=============================================================================
+// GameEngine::UpdateRailSettings
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( RailCam* railCam, MObject obj )
+//
+// Return: void
+//
+//=============================================================================
+void GameEngine::UpdateRailSettings( RailCam* railCam, MObject obj )
+{
+ MFnDependencyNode fnDepNode( obj );
+
+ int behav;
+ fnDepNode.findPlug( RailCamLocatorNode::sBehaviour).getValue( behav );
+ railCam->SetBehaviour( (RailCam::Behaviour)(behav) );
+
+ float minRad;
+ fnDepNode.findPlug( RailCamLocatorNode::sMinRadius ).getValue( minRad );
+ railCam->SetMinRadius( minRad );
+
+ float maxRad;
+ fnDepNode.findPlug( RailCamLocatorNode::sMaxRadius ).getValue( maxRad );
+ railCam->SetMaxRadius( maxRad );
+
+ bool trackRail;
+ fnDepNode.findPlug( RailCamLocatorNode::sTrackRail ).getValue( trackRail );
+ railCam->SetTrackRail( trackRail );
+
+ float trackDist;
+ fnDepNode.findPlug( RailCamLocatorNode::sTrackDist ).getValue( trackDist );
+ railCam->SetTrackDist( trackDist );
+
+ bool reverse;
+ fnDepNode.findPlug( RailCamLocatorNode::sReverseSense ).getValue( reverse );
+ railCam->SetReverseSense( reverse );
+
+ float fov;
+ fnDepNode.findPlug( RailCamLocatorNode::sFOV ).getValue( fov );
+ railCam->SetFOV( rmt::DegToRadian(fov) );
+
+ float x, y, z;
+ fnDepNode.findPlug( RailCamLocatorNode::sFacingOffset ).child(0).getValue( x );
+ fnDepNode.findPlug( RailCamLocatorNode::sFacingOffset ).child(1).getValue( y );
+ fnDepNode.findPlug( RailCamLocatorNode::sFacingOffset ).child(2).getValue( z );
+ railCam->SetTargetOffset( rmt::Vector( x, y, z ) );
+
+ //Same with axis play... TODO
+
+ float posLag;
+ fnDepNode.findPlug( RailCamLocatorNode::sPositionLag ).getValue( posLag );
+ railCam->SetPositionLag( posLag );
+
+ float targLag;
+ fnDepNode.findPlug( RailCamLocatorNode::sTargetLag ).getValue( targLag );
+ railCam->SetTargetLag( targLag );
+}
+
+//=============================================================================
+// GameEngine::UpdateStaticCamSettings
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( StaticCam* staticCam, MObject obj )
+//
+// Return: void
+//
+//=============================================================================
+void GameEngine::UpdateStaticCamSettings( StaticCam* staticCam, MObject obj )
+{
+ MFnDependencyNode fnDepNode( obj );
+
+ float fov;
+ fnDepNode.findPlug( StaticCameraLocatorNode::sFOV ).getValue( fov );
+ staticCam->SetFOV( rmt::DegToRadian(fov) );
+
+ float targLag;
+ fnDepNode.findPlug( StaticCameraLocatorNode::sTargetLag ).getValue( targLag );
+ staticCam->SetTargetLag( targLag );
+
+ MPoint worldPos;
+ MExt::GetWorldPosition( &worldPos, obj );
+
+ rmt::Vector pos;
+ pos.x = worldPos.x / WBConstants::Scale;
+ pos.y = worldPos.y / WBConstants::Scale;
+ pos.z = -worldPos.z / WBConstants::Scale;
+
+ staticCam->SetPosition( pos );
+
+ bool tracking = false;
+ fnDepNode.findPlug( StaticCameraLocatorNode::sTracking ).getValue( tracking );
+ staticCam->SetTracking( tracking );
+
+ float x, y, z;
+ fnDepNode.findPlug( StaticCameraLocatorNode::sFacingOffset ).child(0).getValue( x );
+ fnDepNode.findPlug( StaticCameraLocatorNode::sFacingOffset ).child(1).getValue( y );
+ fnDepNode.findPlug( StaticCameraLocatorNode::sFacingOffset ).child(2).getValue( z );
+
+ if ( tracking )
+ {
+ staticCam->SetTargetOffset( rmt::Vector( x, y, z ) );
+ }
+ else
+ {
+ //Figure out the transformation on the locator node and apply it to the offset.
+ MObject transform;
+ MFnDagNode fnDAGNode( obj );
+ transform = fnDAGNode.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];
+
+ if ( x == 0 && y == 0 && z == 0 )
+ {
+ z = 1.0f;
+ }
+
+ tlPoint offset( x, y, z );
+ offset = VectorTransform( hmatrix, offset );
+
+ rmt::Vector targPos = pos;
+ targPos.Add( offset );
+ staticCam->SetTargetOffset( targPos );
+ }
+}
+
+//=============================================================================
+// GameEngine::UpdateFOV
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( SuperCam* cam, const rmt::Vector position )
+//
+// Return: void
+//
+//=============================================================================
+void GameEngine::UpdateFOV( SuperCam* cam, const rmt::Vector position )
+{
+ MStatus status;
+ MItDag dagIt( MItDag::kDepthFirst, MFn::kLocator );
+
+ bool inside = false;
+
+ while ( !dagIt.isDone() )
+ {
+ MFnDependencyNode fnNode( dagIt.item() );
+ if ( fnNode.typeId() == FOVLocatorNode::id )
+ {
+ //This is a FOV locator, let's see if we're in it's trigger volume.
+
+ MPlug triggersPlug = fnNode.findPlug( FOVLocatorNode::sTriggers, &status );
+ assert( status );
+
+ MPlugArray sources, targets;
+ MExt::ResolveConnections( &sources, &targets, triggersPlug, true, false );
+
+ unsigned int i;
+ for ( i = 0; i < sources.length(); ++i )
+ {
+ //Test to see if the target is in a trigger volume for this
+ //Test against all triggers...
+ MFnDependencyNode triggerFNDepNode( sources[i].node() );
+ int type = 0;
+ triggerFNDepNode.findPlug( TriggerVolumeNode::sType, &status ).getValue( type );
+ assert( status );
+
+ tlMatrix mat;
+ tlPoint scale;
+ TriggerVolumeNode::GetScaleAndMatrix( sources[i].node(), mat, scale );
+
+ switch ( type )
+ {
+ case TriggerVolumeNode::RECTANGLE:
+ {
+ RectTriggerVolume* trigVol = new RectTriggerVolume( mat.GetRow( 3 ),
+ mat.GetRow( 0 ),
+ mat.GetRow( 1 ),
+ mat.GetRow( 2 ),
+ scale.x,
+ scale.y,
+ scale.z );
+
+ inside = trigVol->Contains( position );
+
+ trigVol->Release();
+ }
+ break;
+ case TriggerVolumeNode::SPHERE:
+ {
+ SphereTriggerVolume* trigVol = new SphereTriggerVolume( mat.GetRow( 3 ), scale.x );
+
+ inside = trigVol->Contains( position );
+
+ trigVol->Release();
+ }
+ break;
+ default:
+ assert( false );
+ }
+
+ if ( inside )
+ {
+ float fov;
+ float time;
+ float rate;
+ fnNode.findPlug( FOVLocatorNode::sFOV ).getValue( fov );
+ fnNode.findPlug( FOVLocatorNode::sTime ).getValue( time );
+ fnNode.findPlug( FOVLocatorNode::sRate ).getValue( rate );
+
+ cam->SetFOVOverride( rmt::DegToRadian( fov ) );
+ cam->OverrideFOV( true, time, rate );
+
+ break;
+ }
+ }
+ }
+
+ dagIt.next();
+ }
+
+ if ( !inside )
+ {
+ cam->OverrideFOV( false, 2000, 0.04f );
+ }
+}
diff --git a/tools/worldbuilder/code/gameengine/gameengine.h b/tools/worldbuilder/code/gameengine/gameengine.h
new file mode 100644
index 0000000..b3b3fa0
--- /dev/null
+++ b/tools/worldbuilder/code/gameengine/gameengine.h
@@ -0,0 +1,85 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: gameengine.h
+//
+// Description: Blahblahblah
+//
+// History: 19/07/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+#ifndef GAMEENGINE_H
+#define GAMEENGINE_H
+
+//========================================
+// Nested Includes
+//========================================
+#include "main/toolhack.h"
+
+#include "precompiled/PCH.h"
+
+#include "mayacamera.h"
+
+//========================================
+// Forward References
+//========================================
+class RailCam;
+class SuperCam;
+class WBCamTarget;
+class StaticCam;
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class GameEngine
+{
+public:
+ static void CreateInstance();
+ static void DestroyInstance();
+
+ static GameEngine* GetInstance();
+
+ void UpdateRailCam( MObject& railCam );
+ void UpdateStaticCam( MObject& staticCam );
+
+ MayaCamera& GetMayaCam();
+
+private:
+ void UpdateRailSettings( RailCam* railCam, MObject obj );
+ void UpdateStaticCamSettings( StaticCam* staticCam, MObject obj );
+
+ static GameEngine* mInstance;
+ MayaCamera* mMayaCam;
+
+ unsigned int mTimeStart;
+
+ GameEngine();
+ virtual ~GameEngine();
+ void Init();
+ void UpdateFOV( SuperCam* cam, const rmt::Vector position );
+
+ //Prevent wasteful constructor creation.
+ GameEngine( const GameEngine& gameengine );
+ GameEngine& operator=( const GameEngine& gameengine );
+};
+
+//=============================================================================
+// GameEngine::GetMayaCam
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+inline MayaCamera& GameEngine::GetMayaCam()
+{
+ return *mMayaCam;
+}
+
+#endif //GAMEENGINE_H
diff --git a/tools/worldbuilder/code/gameengine/mayacamera.cpp b/tools/worldbuilder/code/gameengine/mayacamera.cpp
new file mode 100644
index 0000000..6104cd5
--- /dev/null
+++ b/tools/worldbuilder/code/gameengine/mayacamera.cpp
@@ -0,0 +1,151 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: MayaCamera.cpp
+//
+// Description: Implement MayaCamera
+//
+// History: 22/07/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include "MayaCamera.h"
+#include "main/constants.h"
+#include "utility/mext.h"
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+const MString WB_CAM_NAME( "WorldBuilderCam" );
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// MayaCamera::MayaCamera
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+MayaCamera::MayaCamera()
+{
+ EnsureCamExists();
+}
+
+//==============================================================================
+// MayaCamera::~MayaCamera
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+MayaCamera::~MayaCamera()
+{
+}
+
+//=============================================================================
+// MayaCamera::EnsureCamExists
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void MayaCamera::EnsureCamExists()
+{
+ MStatus status;
+ MFnCamera fnCamera;
+
+ MDagPath path;
+
+ if ( !MExt::FindDagNodeByName( &path, WB_CAM_NAME ) )
+ {
+ fnCamera.create( &status );
+ assert( status );
+
+ fnCamera.setName( WB_CAM_NAME + MString( "Camera" ) );
+
+ MFnDependencyNode transform( fnCamera.parent( 0 ) );
+
+ MString transName = WB_CAM_NAME;
+ transform.setName( transName );
+ }
+}
+
+//=============================================================================
+// MayaCamera::Set
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( const rmt::Vector& position, const rmt::Vector& target, const rmt::Vector& vup, float fov )
+//
+// Return: void
+//
+//=============================================================================
+void MayaCamera::Set( const rmt::Vector& position, const rmt::Vector& target, const rmt::Vector& vup, float fov )
+{
+ MStatus status;
+
+ EnsureCamExists();
+
+ MDagPath path;
+ bool found = MExt::FindDagNodeByName( &path, WB_CAM_NAME );
+ assert( found );
+
+ MFnCamera fnCamera( path, &status );
+ assert( status );
+
+
+ //Scale it so you can see it.
+ MFnTransform fnTransform( fnCamera.parent( 0 ) );
+ const double scale[3] = { 200, 200, 200 } ;
+ fnTransform.setScale( scale );
+
+ MPoint eyePosition;
+ eyePosition.x = position.x * WBConstants::Scale;
+ eyePosition.y = position.y * WBConstants::Scale;
+ eyePosition.z = -position.z * WBConstants::Scale;
+
+ MVector viewDirection;
+ viewDirection.x = (target.x - position.x) * WBConstants::Scale;
+ viewDirection.y = (target.y - position.y) * WBConstants::Scale;
+ viewDirection.z = -(target.z - position.z) * WBConstants::Scale;
+
+ MVector viewUp;
+ viewUp.x = vup.x;
+ viewUp.y = vup.y;
+ viewUp.z = -vup.z;
+
+ status = fnCamera.set( eyePosition, viewDirection, viewUp, rmt::DegToRadian(fov), 4/3 );
+ assert( status );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/tools/worldbuilder/code/gameengine/mayacamera.h b/tools/worldbuilder/code/gameengine/mayacamera.h
new file mode 100644
index 0000000..a013366
--- /dev/null
+++ b/tools/worldbuilder/code/gameengine/mayacamera.h
@@ -0,0 +1,49 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: mayacamera.h
+//
+// Description: Blahblahblah
+//
+// History: 22/07/2002 + Created -- CaryBrisebois
+//
+//=============================================================================
+
+#ifndef MAYACAMERA_H
+#define MAYACAMERA_H
+
+//========================================
+// Nested Includes
+//========================================
+#include "precompiled/PCH.h"
+
+#include <radmath/radmath.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class MayaCamera
+{
+public:
+ MayaCamera();
+ virtual ~MayaCamera();
+
+ void EnsureCamExists();
+ void Set( const rmt::Vector& position, const rmt::Vector& target, const rmt::Vector& vup, float fov );
+
+private:
+
+ //Prevent wasteful constructor creation.
+ MayaCamera( const MayaCamera& mayacamera );
+ MayaCamera& operator=( const MayaCamera& mayacamera );
+};
+
+
+#endif //MAYACAMERA_H
diff --git a/tools/worldbuilder/code/gameengine/wbcamtarget.cpp b/tools/worldbuilder/code/gameengine/wbcamtarget.cpp
new file mode 100644
index 0000000..add8eb4
--- /dev/null
+++ b/tools/worldbuilder/code/gameengine/wbcamtarget.cpp
@@ -0,0 +1,296 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: WBCamTarget.cpp
+//
+// Description: Implement WBCamTarget
+//
+// History: 19/07/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+
+//========================================
+// Project Includes
+//========================================
+#include "main/toolhack.h"
+#include <toollib.hpp>
+
+#include "WBCamTarget.h"
+#include "utility/transformmatrix.h"
+#include "main/constants.h"
+
+#include "utility/mext.h"
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+void GetMatrix( MObject& obj, tlMatrix& hmatrix )
+{
+ MFnDagNode fnNode( obj );
+
+ MObject transform;
+ transform = fnNode.parent( 0 );
+ MFnTransform fnTransform( transform );
+
+ MDagPath dagPath;
+ if ( MExt::FindDagNodeByName( &dagPath, fnTransform.name() ) )
+ {
+ TransformMatrix tm( dagPath );
+
+ tm.GetHierarchyMatrixLHS( hmatrix );
+ }
+ else
+ {
+ MExt::DisplayError( "Target matrix is screwy!" );
+ }
+}
+
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// WBCamTarget::WBCamTarget
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+WBCamTarget::WBCamTarget() :
+ mTarget( MObject::kNullObj )
+{
+}
+
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: MObject& target.
+//
+// Return: N/A.
+//
+//==============================================================================
+WBCamTarget::WBCamTarget( MObject& target ) :
+ mTarget( target )
+{
+}
+
+//==============================================================================
+// WBCamTarget::~WBCamTarget
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+WBCamTarget::~WBCamTarget()
+{
+}
+
+//=============================================================================
+// WBCamTarget::GetPosition
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( rmt::Vector* position )
+//
+// Return: void
+//
+//=============================================================================
+void WBCamTarget::GetPosition( rmt::Vector* position )
+{
+ tlMatrix hmatrix;
+ GetMatrix( mTarget, hmatrix );
+
+ tlPoint point = hmatrix.GetRow( 3 );
+
+ *position = point;
+
+ *position /= WBConstants::Scale;
+}
+
+//=============================================================================
+// WBCamTarget::GetHeading
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( rmt::Vector* heading )
+//
+// Return: void
+//
+//=============================================================================
+void WBCamTarget::GetHeading( rmt::Vector* heading )
+{
+ tlMatrix hmatrix;
+ GetMatrix( mTarget, hmatrix );
+
+ tlPoint point = hmatrix.GetRow( 2 );
+
+ *heading = point;
+
+ *heading /= WBConstants::Scale;
+}
+
+//=============================================================================
+// WBCamTarget::GetVUP
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( rmt::Vector* vup )
+//
+// Return: void
+//
+//=============================================================================
+void WBCamTarget::GetVUP( rmt::Vector* vup )
+{
+ tlMatrix hmatrix;
+ GetMatrix( mTarget, hmatrix );
+
+ tlPoint point = hmatrix.GetRow( 1 );
+
+ *vup = point;
+
+ *vup /= WBConstants::Scale;
+}
+
+//=============================================================================
+// WBCamTarget::GetVelocity
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( rmt::Vector* velocity )
+//
+// Return: void
+//
+//=============================================================================
+void WBCamTarget::GetVelocity( rmt::Vector* velocity )
+{
+}
+
+//=============================================================================
+// WBCamTarget::GetID
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: unsigned
+//
+//=============================================================================
+unsigned int WBCamTarget::GetID()
+{
+ return 1;
+}
+
+//=============================================================================
+// WBCamTarget::IsCar
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: bool
+//
+//=============================================================================
+bool WBCamTarget::IsCar()
+{
+ return false;
+}
+
+//=============================================================================
+// WBCamTarget::IsAirborn
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: bool
+//
+//=============================================================================
+bool WBCamTarget::IsAirborn()
+{
+ return false;
+}
+
+//=============================================================================
+// WBCamTarget::IsUnstable
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: bool
+//
+//=============================================================================
+bool WBCamTarget::IsUnstable()
+{
+ return false;
+}
+
+//=============================================================================
+// WBCamTarget::IsQuickTurn
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: bool
+//
+//=============================================================================
+bool WBCamTarget::IsQuickTurn()
+{
+ return false;
+}
+
+//=============================================================================
+// WBCamTarget::GetFirstPersonPosition
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( rmt::Vector* position )
+//
+// Return: void
+//
+//=============================================================================
+void WBCamTarget::GetFirstPersonPosition( rmt::Vector* position )
+{
+ return;
+}
+
+//=============================================================================
+// WBCamTarget::GetName
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: const
+//
+//=============================================================================
+const char* const WBCamTarget::GetName()
+{
+ MFnDependencyNode fnDepNode( mTarget );
+
+ return fnDepNode.name().asChar();
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/tools/worldbuilder/code/gameengine/wbcamtarget.h b/tools/worldbuilder/code/gameengine/wbcamtarget.h
new file mode 100644
index 0000000..21a629c
--- /dev/null
+++ b/tools/worldbuilder/code/gameengine/wbcamtarget.h
@@ -0,0 +1,90 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: wbcamtarget.h
+//
+// Description: Blahblahblah
+//
+// History: 19/07/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+#ifndef WBCAMTARGET_H
+#define WBCAMTARGET_H
+
+//========================================
+// Nested Includes
+//========================================
+#include "precompiled/PCH.h"
+
+#include "..\..\..\game\code\camera\isupercamtarget.h"
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class WBCamTarget : public ISuperCamTarget
+{
+public:
+ WBCamTarget();
+ WBCamTarget( MObject& target );
+ virtual ~WBCamTarget();
+
+ virtual void GetPosition( rmt::Vector* position );
+ virtual void GetHeading( rmt::Vector* heading );
+ virtual void GetVUP( rmt::Vector* vup );
+ virtual void GetVelocity( rmt::Vector* velocity );
+ virtual unsigned int GetID();
+ virtual bool IsCar();
+ virtual bool IsAirborn();
+ virtual bool IsUnstable();
+ virtual bool IsQuickTurn();
+ virtual bool IsInReverse() { return false; };
+ virtual void GetFirstPersonPosition( rmt::Vector* position );
+
+ virtual const char* const GetName();
+
+ void SetTarget( MObject& target );
+ const MObject& GetTarget() const;
+
+private:
+ MObject& mTarget;
+};
+
+//=============================================================================
+// WBCamTarget::SetTarget
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( MObject& target )
+//
+// Return: void
+//
+//=============================================================================
+inline void WBCamTarget::SetTarget( MObject& target )
+{
+ mTarget = target;
+}
+
+//=============================================================================
+// WBCamTarget::GetTarget
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: MObject
+//
+//=============================================================================
+inline const MObject& WBCamTarget::GetTarget() const
+{
+ return mTarget;
+}
+
+#endif //WBCAMTARGET_H