The-Simpsons-Hit-and-Run/game/code/loading/locatorloader.cpp

1119 lines
33 KiB
C++

//=============================================================================
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
//
// File: LocatorLoader.cpp
//
// Description: Implement LocatorLoader
//
// History: 24/05/2002 + Created -- Cary Brisebois
//
//=============================================================================
//========================================
// System Includes
//========================================
// Foundation Tech
#include <raddebug.hpp>
#include <radmath/radmath.hpp>
#include <p3d/chunkfile.hpp>
//========================================
// Project Includes
//========================================
#include <loading/LocatorLoader.h>
#include <constants/srrchunks.h>
#include <memory/srrmemory.h>
#include <meta/carstartlocator.h>
#include <meta/eventlocator.h>
#include <meta/locator.h>
#include <meta/locatortypes.h>
#include <meta/recttriggervolume.h>
#include <meta/spheretriggervolume.h>
#include <meta/splinelocator.h>
#include <meta/triggervolumetracker.h>
#include <meta/zoneeventlocator.h>
#include <meta/carstartlocator.h>
#include <meta/occlusionlocator.h>
#include <meta/interiorentrancelocator.h>
#include <meta/directionallocator.h>
#include <meta/actioneventlocator.h>
#include <meta/fovlocator.h>
#include <meta/staticcamlocator.h>
#include <meta/pedgrouplocator.h>
#include <meta/scriptlocator.h>
#include <camera/railcam.h>
#include <camera/staticcam.h>
#include <camera/supercamcentral.h>
#include <camera/supercammanager.h>
#include <render/RenderManager/RenderManager.h>
#include <render/Culling/WorldScene.h>
#include <mission/AnimatedIcon.h>
#include <mission/gameplaymanager.h>
#include <worldsim/parkedcars/parkedcarmanager.h>
#include <worldsim/coins/coinmanager.h>
#include <render/rendermanager/rendermanager.h>
#include <render/rendermanager/worldrenderlayer.h>
//******************************************************************************
//
// Global Data, Local Data, Local Classes
//
//******************************************************************************
void Swap(char* data_in, char* data_out, int n);
//******************************************************************************
//
// Public Member Functions
//
//******************************************************************************
int LocatorLoader::msZoneNameCount = 0;
//==============================================================================
// LocatorLoader::LocatorLoader
//==============================================================================
// Description: Constructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
LocatorLoader::LocatorLoader()
: tSimpleChunkHandler( SRR2::ChunkID::LOCATOR )
{
mpListenerCB = NULL;
}
//==============================================================================
// LocatorLoader::~LocatorLoader
//==============================================================================
// Description: Destructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
LocatorLoader::~LocatorLoader()
{
}
//=============================================================================
// LocatorLoader::LoadObject
//=============================================================================
// Description: Comment
//
// Parameters: (tChunkFile* f, tEntityStore* store)
//
// Return: tEntity
//
//=============================================================================
tEntity* LocatorLoader::LoadObject(tChunkFile* f, tEntityStore* store)
{
MEMTRACK_PUSH_GROUP( "Locator Loading" );
#ifdef RAD_GAMECUBE
HeapMgr()->PushHeap (GMA_GC_VMM);
#else
HeapMgr()->PushHeap (GMA_LEVEL_OTHER);
#endif
char name[256];
f->GetPString( name );
LocatorType::Type type;
type = (LocatorType::Type)(f->GetUInt());
unsigned int numElements = f->GetUInt();
unsigned int* elements = new unsigned int[ numElements ];
unsigned int i;
for( i = 0; i < numElements; i++ )
{
elements[ i ] = f->GetUInt();
}
rmt::Vector pos;
pos.x = f->GetFloat();
pos.y = f->GetFloat();
pos.z = f->GetFloat();
Locator* locator = NULL;
unsigned int numTriggers = f->GetUInt();
bool hasSubChunks = true;
switch( type )
{
case LocatorType::GENERIC:
{
MEMTRACK_PUSH_GROUP("Generic Locator");
locator = new Locator();
rAssert( locator );
hasSubChunks = false;
MEMTRACK_POP_GROUP("Generic Locator");
break;
}
case LocatorType::EVENT:
{
MEMTRACK_PUSH_GROUP("Event Locator");
EventLocator* eventloc = new EventLocator();
rAssert( eventloc );
eventloc->SetEventType( (LocatorEvent::Event)elements[ 0 ] );
if ( eventloc->GetEventType() == LocatorEvent::CAMERA_CUT )
{
//Make this locator inactive if the wreckless cam is not active.
//Hackish
SuperCam* sc = GetSuperCamManager()->GetSCC( 0 )->GetActiveSuperCam();
if ( GetGameplayManager()->mIsDemo || (sc && sc->GetType() == SuperCam::WRECKLESS_CAM) )
{
eventloc->SetFlag( Locator::ACTIVE, true );
}
else
{
eventloc->SetFlag( Locator::ACTIVE, false );
}
}
if ( numElements == 2 )
{
rAssert( eventloc->GetEventType() == LocatorEvent::FAR_PLANE ||
eventloc->GetEventType() == LocatorEvent::GOO_DAMAGE ||
eventloc->GetEventType() == LocatorEvent::LIGHT_CHANGE ||
eventloc->GetEventType() == LocatorEvent::TRAP ||
eventloc->GetEventType() == LocatorEvent::CHECK_POINT );
eventloc->SetData( elements[1] );
}
locator = eventloc;
MEMTRACK_POP_GROUP("Event Locator");
break;
}
case LocatorType::SPLINE:
{
MEMTRACK_PUSH_GROUP("Spline Locator");
SplineLocator* splineloc = new SplineLocator();
rAssert( splineloc );
locator = splineloc;
MEMTRACK_POP_GROUP("Spline Locator");
break;
}
case LocatorType::DYNAMIC_ZONE:
{
MEMTRACK_PUSH_GROUP("Zone Locator");
ZoneEventLocator* eventloc = new ZoneEventLocator();
rAssert( eventloc );
//this is where we convert the data into a string... ba-dum-ching!
eventloc->SetZoneSize( numElements * 4 ); //This is to prevent fragmentation.
char* zone = new char[numElements * 4 + 4];
memcpy( zone, elements, numElements * 4 );
zone[numElements * 4] = '\0';
#ifdef RAD_GAMECUBE
Swap( zone, zone, numElements * 4 + 4);
#endif
eventloc->SetZone( zone );
delete[] zone;
locator = eventloc;
MEMTRACK_POP_GROUP("Zone Locator");
break;
}
case LocatorType::CAR_START:
{
MEMTRACK_PUSH_GROUP("Car Locator");
CarStartLocator* carStartloc = new CarStartLocator();
rAssert( carStartloc );
float rotation = 0;
memcpy( (void*)(&rotation), (const void*)&elements[0], sizeof(float) );
//HACK
if ( numElements >= 2 )
{
//There is parked car data.
if ( elements[1] == 1 )
{
if ( !GetGameplayManager()->mIsDemo )
{
//Should place a parked car here. Add to ParkedCarManager
GetPCM().AddLocator( carStartloc );
}
}
if ( numElements > 2 )
{
//We have a special car here.
char* carName = new char[(numElements - 2) * 4 + 4];
memcpy( carName, &elements[2], (numElements - 2) * 4 );
carName[(numElements - 2) * 4] = '\0';
#ifdef RAD_GAMECUBE
Swap( carName, carName, (numElements - 2) * 4 + 4 );
#endif
//Do something with the name
GetPCM().AddFreeCar( carName, carStartloc );
delete carName;
}
}
carStartloc->SetRotation( rotation );
locator = carStartloc;
hasSubChunks = false;
MEMTRACK_POP_GROUP("Car Locator");
break;
}
case LocatorType::OCCLUSION:
{
MEMTRACK_PUSH_GROUP("Occlusion Locator");
OcclusionLocator* occLoc = new OcclusionLocator();
rAssert( occLoc );
occLoc->SetNumTriggers( numTriggers, GMA_LEVEL_OTHER );
bool first = true;
while( f->ChunksRemaining() )
{
f->BeginChunk();
switch( f->GetCurrentID() )
{
case SRR2::ChunkID::TRIGGER_VOLUME:
{
//Only add the first one to the trigger tracker.
LoadTriggerVolume( f, occLoc, first );
first = false;
break;
}
}
f->EndChunk();
}
//How many of the locators are occlusion, the rest are visiblers - 1
if ( numElements )
{
occLoc->SetNumOccTriggers( elements[0] );
}
else
{
occLoc->SetNumOccTriggers( numTriggers - 1 );
}
locator = occLoc;
hasSubChunks = false; //Special case, already loaded.
MEMTRACK_POP_GROUP("Occlusion Locator");
break;
}
case LocatorType::INTERIOR_ENTRANCE:
{
MEMTRACK_PUSH_GROUP("Interior Locator");
InteriorEntranceLocator* intEntLoc = new InteriorEntranceLocator();
rAssert( intEntLoc );
rAssert( numElements * 4 < 256 );
unsigned int length = numElements * 4;
char charData[256];
memcpy( charData, elements, numElements * 4 );
#ifdef RAD_GAMECUBE
Swap( charData, charData, numElements * 4 );
#endif
unsigned int chari = 0;
for ( chari = 0; chari < length; ++chari )
{
if ( charData[chari] == '\0' )
{
//Found the null.
break;
}
}
//this is where we convert the data into a string... ba-dum-ching!
intEntLoc->SetInteriorFileNameSize( chari ); //This is to prevent fragmentation.
intEntLoc->SetInteriorFileName( charData );
//Now get the transform.
unsigned int index = chari / 4;
if ( chari % 4 != 0 )
{
index++; //Add one to cover the extra.
}
rmt::Matrix mat;
mat.Identity();
unsigned int i;
for ( i = 0; i < 3; ++i )
{
rmt::Vector v;
memcpy( &v.x, &elements[index + 3 * i], sizeof(float) * 3 );
mat.m[i][0] = v.x;
mat.m[i][1] = v.y;
mat.m[i][2] = v.z;
}
intEntLoc->SetTransform( mat );
locator = intEntLoc;
MEMTRACK_POP_GROUP("Interior Locator");
break;
}
case LocatorType::DIRECTIONAL:
{
MEMTRACK_PUSH_GROUP("Directional Locator");
DirectionalLocator* dirLoc = new DirectionalLocator();
rAssert( dirLoc );
rmt::Matrix mat;
mat.Identity();
unsigned int i;
for ( i = 0; i < 3; ++i )
{
rmt::Vector v;
memcpy( &v.x, &elements[3 * i], sizeof(float) * 3 );
mat.m[i][0] = v.x;
mat.m[i][1] = v.y;
mat.m[i][2] = v.z;
}
dirLoc->SetTransform( mat );
locator = dirLoc;
hasSubChunks = false;
MEMTRACK_POP_GROUP("Directional Locator");
break;
}
case LocatorType::ACTION:
{
MEMTRACK_PUSH_GROUP("Action Locator");
ActionEventLocator* actLoc = new ActionEventLocator();
rAssert( actLoc );
rAssert(numElements >= 5);
rAssert( (numElements - 2) * 4 < 256 );
unsigned int length = (numElements - 2) * 4;
char charData[256];
memcpy( charData, elements, (numElements - 2) * 4 );
#ifdef RAD_GAMECUBE
Swap( charData, charData, (numElements - 2) * 4 );
#endif
//Go through the charData until we find all 3 strings.
const unsigned int numStrings = 3;
char stringArray[numStrings][128]; //If the name is larger than 128, I'll shoot myself.
unsigned int i;
unsigned int startChari = 0;
unsigned int chari = 0;
for ( i = 0; i < numStrings; ++i )
{
while ( charData[chari] != '\0' && chari != length )
{
++chari;
}
rAssertMsg( chari != length, "Missing text in action locator!" );
if ( chari != length )
{
rAssert( strlen(&charData[startChari]) < 128 );
strncpy( stringArray[i], &charData[startChari], chari - startChari );
stringArray[i][strlen(&charData[startChari])] = '\0';
++chari;
if ( i == numStrings - 1 )
{
//We're done
break;
}
}
//move past the NULLS
while ( charData[chari] == '\0' && chari != length )
{
++chari;
}
startChari = chari;
}
actLoc->SetObjNameSize( strlen(stringArray[0]) );
actLoc->SetObjName( stringArray[0] );
actLoc->SetJointNameSize( strlen(stringArray[1]) );
actLoc->SetJointName( stringArray[1] );
actLoc->SetActionNameSize( strlen(stringArray[2]) );
actLoc->SetActionName( stringArray[2] );
actLoc->SetButtonInput( (CharacterController::eIntention)elements[numElements - 2] );
actLoc->SetShouldTransform( elements[numElements - 1] == 1 ? true : false );
// TBJ [8/30/2002]
//
// I need to set the position of the locator before I add it to the game.
//
actLoc->SetLocation( pos );
// If AddToGame() fails, actLoc will be released.
// Hold on to it here.
//
actLoc->AddRef();
if ( actLoc->AddToGame( store ) )
{
locator = actLoc;
}
else
{
locator = NULL;
}
// If AddToGame() didn't addref the locator,
// this release will delete it.
//
actLoc->Release( );
MEMTRACK_POP_GROUP("Action Locator");
break;
}
case LocatorType::FOV:
{
MEMTRACK_PUSH_GROUP("FOV Locator");
FOVLocator* fovLoc = new FOVLocator();
rAssert( fovLoc );
float data[3];
memcpy( data, elements, sizeof(float) * 3 );
fovLoc->SetFOV( rmt::DegToRadian( data[0] ) );
fovLoc->SetTime( data[1] );
fovLoc->SetRate( data[2] );
locator = fovLoc;
hasSubChunks = true;
MEMTRACK_POP_GROUP("FOV Locator");
break;
}
case LocatorType::BREAKABLE_CAMERA:
{
MEMTRACK_PUSH_GROUP("Breakable Camera Locator");
/*
//TODO: what do we do with these??
float data[10];
memcpy( data, elements, sizeof(float) * 10 );
rmt::Matrix mat;
mat.Identity();
unsigned int i;
for ( i = 0; i < 9;)
{
mat.m[i][0] = data[i];
mat.m[i][1] = data[i + 1];
mat.m[i][2] = data[i + 2];
i += 3;
}
float FOV = data[9];
// Create a new action event locator
ActionEventLocator* actLoc = new ActionEventLocator();
/*
actLoc->SetObjNameSize( strlen(stringArray[0]) );
actLoc->SetObjName( stringArray[0] );
actLoc->SetJointNameSize( strlen(stringArray[1]) );
actLoc->SetJointName( stringArray[1] );
actLoc->SetActionNameSize( strlen(stringArray[2]) );
actLoc->SetActionName( stringArray[2] );
actLoc->SetButtonInput( (CharacterController::eIntention)elements[numElements - 2] );
actLoc->SetShouldTransform( elements[numElements - 1] == 1 ? true : false );
*/
/*
actLoc->SetLocation( pos );
const char* ObjName = "Alien Camera Obj";
actLoc->SetObjNameSize( strlen( ObjName ) );
actLoc->SetObjName( ObjName );
const char* ActionName = "AlienCamera";
actLoc->SetActionNameSize( strlen( ActionName ) );
actLoc->SetActionName( ActionName );
actLoc->SetButtonInput( CharacterController::Attack );
bool addSuccess = actLoc->AddToGame( store );
// rAssertMsg( addSuccess, "Could not add camera locator to the game" );
*/
MEMTRACK_POP_GROUP("Breakable Camera Locator");
break;
}
case LocatorType::STATIC_CAMERA:
{
MEMTRACK_PUSH_GROUP("Static Camera Locator");
StaticCamLocator* scLoc = new StaticCamLocator();
StaticCam* sCam = new StaticCam();
rAssert( numElements < 32 );
float data[32];
memcpy( data, elements, sizeof(float) * numElements );
rmt::Vector offset;
offset.x = data[0];
offset.y = data[1];
offset.z = data[2];
sCam->SetTargetOffset( offset );
float FOV = data[3];
sCam->SetMaxFOV( rmt::DegToRadian( FOV ) );
float lag = data[4];
sCam->SetTargetLag( lag );
int track;
memcpy( &track, &data[5], sizeof( int ) ); //This is sucky, sorry.
bool tracking = track == 1 ? true : false;
float trate = 0.04f;
if ( numElements >= 7 )
{
memcpy( &trate, &data[6], sizeof(float) );
}
if ( numElements >= 8 )
{
int flags = 0;
memcpy( &flags, &data[7], sizeof( int ) ); //This is sucky, sorry.
scLoc->SetOneShot( (flags & 1) > 0 );
if ( (flags & (1 << 1)) ) //This is the hacky way that I export this info.
{
//Disable fov on controller for this cam.
sCam->SetFOVLag( 0.0f );
}
}
if ( numElements >= 9 )
{
int inOut = 0;
memcpy( &inOut, &data[8], sizeof( int ) ); //This is sucky, sorry.
scLoc->SetCutInOut( inOut == 1 );
int intData = 0;
memcpy( &intData, &data[9], sizeof( int ) ); //This is sucky, sorry.
scLoc->SetCarOnly( (intData & 1) == 1 );
scLoc->SetOnFootOnly( (intData & (1 << 1)) == 1 << 1 );
}
sCam->SetTransitionPositionRate( trate );
sCam->SetTransitionTargetRate( trate );
sCam->SetTracking( tracking );
sCam->SetPosition( pos );
scLoc->SetStaticCam( sCam );
locator = scLoc;
hasSubChunks = true;
MEMTRACK_POP_GROUP( "Static Camera Locator" );
break;
}
case LocatorType::PED_GROUP:
{
MEMTRACK_PUSH_GROUP("Ped Group Locator");
PedGroupLocator* pgLoc = new PedGroupLocator();
rAssert( pgLoc );
unsigned int group = 0;
memcpy( (void*)(&group), (const void*)elements, sizeof(unsigned int) );
pgLoc->SetGroupNum( group );
locator = pgLoc;
hasSubChunks = true;
MEMTRACK_POP_GROUP( "Ped Group Locator" );
break;
}
case LocatorType::SCRIPT:
{
MEMTRACK_PUSH_GROUP("Script Locator");
ScriptLocator* sLoc = new ScriptLocator();
rAssert( sLoc );
char* text = new char[numElements * 4 + 4];
memcpy( text, elements, numElements * 4 );
text[numElements * 4] = '\0';
#ifdef RAD_GAMECUBE
Swap( text, text, numElements * 4 + 4 );
#endif
sLoc->SetString( text );
delete[] text;
locator = sLoc;
hasSubChunks = true;
MEMTRACK_POP_GROUP( "Script Locator" );
break;
}
case LocatorType::COIN:
{
MEMTRACK_PUSH_GROUP("Coin Locator");
//Adding world coin to coin manager
GetCoinManager()->AddWorldCoin( pos, GetRenderManager()->pWorldRenderLayer()->GetCurSectionName().GetUID() );
locator = NULL;
MEMTRACK_POP_GROUP( "Coin Locator" );
break;
}
default:
{
MEMTRACK_PUSH_GROUP("Unknown Locator");
rDebugString( "Bad locator loaded.. UNKNOWN type!\n" );
Locator* loc = new Locator();
rAssert( loc );
locator = loc;
MEMTRACK_POP_GROUP( "Unknown Locator" );
break;
}
}
// locator might be NULL if it was not successfully added to game.
//
// TBJ [8/30/2002]
//
if( locator != NULL )
{
if ( hasSubChunks )
{
locator->SetNumTriggers( numTriggers, HeapMgr()->GetCurrentHeap() );
while( f->ChunksRemaining() )
{
f->BeginChunk();
switch( f->GetCurrentID() )
{
case SRR2::ChunkID::TRIGGER_VOLUME:
{
LoadTriggerVolume( f, static_cast<TriggerLocator*>(locator) );
break;
}
case SRR2::ChunkID::SPLINE:
{
if ( locator->GetDataType() == LocatorType::SPLINE )
{
RailCam* railCam = LoadSpline( f, static_cast<SplineLocator*>(locator) );
rAssert( railCam );
static_cast<SplineLocator*>(locator)->SetRailCam( railCam );
}
else
{
RailCam* railCam = LoadSpline( f, NULL );
rAssert( railCam );
}
break;
}
case SRR2::ChunkID::EXTRA_MATRIX:
{
rmt::Matrix mat;
f->GetData(&(mat), 16, tFile::DWORD);
locator->SetMatrix( mat );
break;
}
}
f->EndChunk();
}
}
locator->SetName( name );
locator->SetLocation( pos );
//locator->SetFlag( Locator::ACTIVE, false );
}
delete[] elements;
MEMTRACK_POP_GROUP("Locator Loading");
#ifdef RAD_GAMECUBE
HeapMgr()->PopHeap (GMA_GC_VMM);
#else
HeapMgr()->PopHeap (GMA_LEVEL_OTHER);
#endif
//
// Some locators should not be added to the inventory
//
if( type == LocatorType::DYNAMIC_ZONE )
{
//
// All the locators called load_something are never looked up
//
if( strncmp( name, "load", 4 ) == 0 )
{
msZoneNameCount++;
char tempName[256];
sprintf( tempName, "mfa%d%s", msZoneNameCount, name);
locator->SetName(tempName);
}
}
return locator;
}
///////////////////////////////////////////////////////////////////////
// IWrappedLoader
///////////////////////////////////////////////////////////////////////
//========================================================================
// LocatorLoader::SetRegdListener
//========================================================================
//
// Description: Register a new listener/caretaker, notify old listener of
// severed connection.
//
// Parameters: pListenerCB: Callback to call OnChunkLoaded
// pUserData: Data to pass along for filtering, etc
//
// Return: None.
//
// Constraints: None.
//
//========================================================================
void LocatorLoader::SetRegdListener
(
ChunkListenerCallback* pListenerCB,
int iUserData
)
{
//
// Follow protocol; notify old Listener, that it has been
// "disconnected".
//
if( mpListenerCB != NULL )
{
mpListenerCB->OnChunkLoaded( NULL, iUserData, 0 );
}
mpListenerCB = pListenerCB;
mUserData = iUserData;
}
//========================================================================
// LocatorLoader::ModRegdListener
//========================================================================
//
// Description: Just fuck with the current pUserData
//
// Parameters: None.
//
// Return: None.
//
// Constraints: None.
//
//========================================================================
void LocatorLoader::ModRegdListener
(
ChunkListenerCallback* pListenerCB,
int iUserData
)
{
#if 0
char DebugBuf[255];
sprintf( DebugBuf, "GeometryWrappedLoader::ModRegdListener: pListenerCB %X vs mpListenerCB %X\n", pListenerCB, mpListenerCB );
rDebugString( DebugBuf );
#endif
rAssert( pListenerCB == mpListenerCB );
mUserData = iUserData;
}
//******************************************************************************
//
// Private Member Functions
//
//******************************************************************************
//=============================================================================
// LocatorLoader::LoadTriggerVolume
//=============================================================================
// Description: Comment
//
// Parameters: ( tChunkFile* f,
// TriggerLocator* locator,
// bool addToTracker )
//
// Return: void
//
//=============================================================================
bool LocatorLoader::LoadTriggerVolume( tChunkFile* f,
TriggerLocator* locator,
bool addToTracker )
{
bool good = true;
MEMTRACK_PUSH_GROUP("Trigger Volume Loading");
#ifdef RAD_GAMECUBE
HeapMgr()->PushHeap( GMA_GC_VMM );
#else
HeapMgr()->PushHeap (GMA_LEVEL_OTHER);
#endif
if( f->GetCurrentID() == SRR2::ChunkID::TRIGGER_VOLUME )
{
char volname[256];
rmt::Matrix mat;
rmt::Vector scale;
rmt::Vector pos;
TriggerVolume* vol = NULL;
f->GetPString( volname );
unsigned int voltype = f->GetUInt();
scale.x = f->GetFloat();
scale.y = f->GetFloat();
scale.z = f->GetFloat();
float val;
for( unsigned int v = 0; v < 4; v++ )
{
for( unsigned int u = 0; u < 4; u++ )
{
val = f->GetFloat();
mat.m[v][u] = val;
}
}
pos = mat.Row(3);
switch( voltype )
{
case TriggerVolume::SPHERE:
{
MEMTRACK_PUSH_GROUP("Sphere Trigger");
SphereTriggerVolume* sphere = new SphereTriggerVolume();
// this is a sphere, so the radii should be equal
sphere->SetSphereRadius( scale.x );
vol = sphere;
MEMTRACK_POP_GROUP("Sphere Trigger");
break;
}
case TriggerVolume::RECTANGLE:
{
MEMTRACK_PUSH_GROUP("Rectangle Trigger");
RectTriggerVolume* box = new RectTriggerVolume( pos,
mat.Row(0),
mat.Row(1),
mat.Row(2),
scale.x,
scale.y,
scale.z );
vol = box;
MEMTRACK_POP_GROUP("Rectangle Trigger");
break;
}
default:
{
// never come here again!
MEMTRACK_PUSH_GROUP("Unknown Trigger");
rAssert( false );
MEMTRACK_POP_GROUP("Unknown Trigger");
break;
}
}
vol->SetName( volname );
vol->SetLocator( locator );
locator->AddTriggerVolume( vol );
vol->SetPosition( pos );
if ( addToTracker )
{
GetTriggerVolumeTracker()->AddTrigger( vol );
// dont notify the render manager (listener), instead, circumvent and add directly to the tree
//mpListenerCB->OnChunkLoaded(vol, mUserData, _id);
//GetRenderManager()->pWorldScene()->Add(vol); //Now we are adding to the DSG.
}
good = true;
}
else
{
good = false;
}
MEMTRACK_POP_GROUP("Trigger Volume Loading");
#ifdef RAD_GAMECUBE
HeapMgr()->PopHeap( GMA_GC_VMM );
#else
HeapMgr()->PopHeap (GMA_LEVEL_OTHER);
#endif
return good;
}
//=============================================================================
// LocatorLoader::LoadSpline
//=============================================================================
// Description: Comment
//
// Parameters: ( tChunkFile* f, SplineLocator* splineLoc )
//
// Return: RailCam*
//
//=============================================================================
RailCam* LocatorLoader::LoadSpline( tChunkFile* f, SplineLocator* splineLoc )
{
if( f->GetCurrentID() == SRR2::ChunkID::SPLINE )
{
MEMTRACK_PUSH_GROUP("Rail Cam");
char name[256];
f->GetPString( name );
int numCVs = f->GetInt();
rmt::SplineCurve newSpline;
newSpline.SetNumVertices( numCVs );
for( int i = 0; i < numCVs; i++ )
{
rmt::Vector v;
v.x = f->GetFloat();
v.y = f->GetFloat();
v.z = f->GetFloat();
newSpline.SetCntrlVertex( i, v );
}
rAssert( f->ChunksRemaining() );
//Load the railcam...
RailCam* newRailCam = new RailCam();
f->BeginChunk();
f->GetString( name );
newRailCam->SetBehaviour( (RailCam::Behaviour)f->GetUInt() );
newRailCam->SetMinRadius( f->GetFloat() );
newRailCam->SetMaxRadius( f->GetFloat() );
newRailCam->SetTrackRail( f->GetUInt() == 1 ? true : false );
newRailCam->SetTrackDist( f->GetFloat() );
newRailCam->SetReverseSense( f->GetUInt() == 1 ? true : false );
newRailCam->SetMaxFOV( rmt::DegToRadian( f->GetFloat() ) );
rmt::Vector targetOffset;
f->GetData( &targetOffset.x, 3, tFile::DWORD );
newRailCam->SetTargetOffset( targetOffset );
rmt::Vector play;
f->GetData( &play.x, 3, tFile::DWORD );
//newRailCam->SetAxisPlay( play );
//Hack to get some data
if ( play.x > 0.001f )
{
newRailCam->SetTransitionPositionRate( play.x );
newRailCam->SetTransitionTargetRate( play.x );
}
if ( play.y == 1.0f ) //This is set to one when we want to disable the lag.
{
//Disable FOV lagging.
newRailCam->SetFOVLag( 0.0f );
}
if ( splineLoc )
{
//Play.z is hiding stuff too
int hiddenX = (int)play.z; //I hate this.
splineLoc->SetCarOnly( (hiddenX & 0x00000001) != 0 );
splineLoc->SetCutInOut( (hiddenX & 0x0000002) != 0 );
splineLoc->SetReset( (hiddenX & 0x00000004) != 0 );
splineLoc->SetOnFootOnly( (hiddenX & 0x00000008) != 0 );
}
newRailCam->SetPositionLag( f->GetFloat() );
newRailCam->SetTargetLag( f->GetFloat() );
newRailCam->SetSplineCurve( newSpline );
f->EndChunk();
MEMTRACK_POP_GROUP("Rail Cam");
return newRailCam;
}
return NULL;
}
//Endian swap.
inline void Swap( char* data_in, char* data_out, int n )
{
rAssert( n % 4 == 0 );
char tmp1, tmp2, tmp3, tmp4;
for(int i = 0; i < n; i += 4)
{
tmp1 = data_in[i];
tmp2 = data_in[i+1];
tmp3 = data_in[i+2];
tmp4 = data_in[i+3];
data_out[i] = tmp4;
data_out[i+1] = tmp3;
data_out[i+2] = tmp2;
data_out[i+3] = tmp1;
}
}