366 lines
11 KiB
C++
366 lines
11 KiB
C++
//=============================================================================
|
|
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
|
|
//
|
|
// File:
|
|
//
|
|
// Description: Implementation of class WorldCollisionSolverAgentManager
|
|
//
|
|
// History: 6/14/2002 + Created -- NAME
|
|
//
|
|
//=============================================================================
|
|
|
|
//========================================
|
|
// System Includes
|
|
//========================================
|
|
// Foundation Tech
|
|
#include <raddebug.hpp>
|
|
|
|
//========================================
|
|
// Project Includes
|
|
//========================================
|
|
#include <worldsim/worldcollisionsolveragent.h>
|
|
#include <worldsim/redbrick/redbrickcollisionsolveragent.h>
|
|
#include <worldsim/physicsairef.h>
|
|
#include <memory/srrmemory.h>
|
|
|
|
#include <camera/supercamcentral.h>
|
|
|
|
#include <render/DSG/collisionentitydsg.h>
|
|
|
|
//******************************************************************************
|
|
//
|
|
// Global Data, Local Data, Local Classes
|
|
//
|
|
//******************************************************************************
|
|
|
|
//******************************************************************************
|
|
//
|
|
// Public Member Functions
|
|
//
|
|
//******************************************************************************
|
|
|
|
//==============================================================================
|
|
// WorldCollisionSolverAgentManager::WorldCollisionSolverAgentManager
|
|
//==============================================================================
|
|
// Description: Constructor.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: N/A.
|
|
//
|
|
//==============================================================================
|
|
WorldCollisionSolverAgentManager::WorldCollisionSolverAgentManager()
|
|
{
|
|
mpCollisionSolverAgentArray[ 0 ] = new(GMA_PERSISTENT) RedBrickCollisionSolverAgent;
|
|
mpCollisionSolverAgentArray[ 0 ]->AddRef();
|
|
}
|
|
|
|
//==============================================================================
|
|
// WorldCollisionSolverAgentManager::~WorldCollisionSolverAgentManager
|
|
//==============================================================================
|
|
// Description: Destructor.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: N/A.
|
|
//
|
|
//==============================================================================
|
|
WorldCollisionSolverAgentManager::~WorldCollisionSolverAgentManager()
|
|
{
|
|
int i;
|
|
for ( i = 0; i < NUM_SOLVERS; i++ )
|
|
{
|
|
if ( mpCollisionSolverAgentArray[ i ] )
|
|
{
|
|
mpCollisionSolverAgentArray[ i ]->Release();
|
|
mpCollisionSolverAgentArray[ i ] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// WorldCollisionSolverAgentManager::CollisionEvent
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: (SimState* inSimStateA, int indexA, SimState* inSimStateB, int indexB, const rmt::Vector& inPos, float inDvN, float inDvT, SimulatedObject** simA, SimulatedObject** simB)
|
|
//
|
|
// Return: Solving_Answer
|
|
//
|
|
//=============================================================================
|
|
Solving_Answer WorldCollisionSolverAgentManager::CollisionEvent(SimState* inSimStateA, int indexA, SimState* inSimStateB, int indexB, const rmt::Vector& inPos, float inDvN, float inDvT, SimulatedObject** simA, SimulatedObject** simB)
|
|
{
|
|
return Solving_Continue;
|
|
}
|
|
|
|
|
|
/*
|
|
==============================================================================
|
|
WorldCollisionSolverAgentManager::PreCollisionEvent
|
|
==============================================================================
|
|
Description: Comment
|
|
|
|
Parameters: (Collision& inCollision, int inPass)
|
|
|
|
Return: Solving_Answer
|
|
|
|
=============================================================================
|
|
*/
|
|
Solving_Answer WorldCollisionSolverAgentManager::PreCollisionEvent(Collision& inCollision, int inPass)
|
|
{
|
|
CollisionObject* collObjA = inCollision.mCollisionObjectA;
|
|
CollisionObject* collObjB = inCollision.mCollisionObjectB;
|
|
|
|
SimState* simStateA = collObjA->GetSimState();
|
|
SimState* simStateB = collObjB->GetSimState();
|
|
|
|
|
|
if(inCollision.mCollisionVolumeA->Type() == sim::BBoxVolumeType || inCollision.mCollisionVolumeB->Type() == sim::BBoxVolumeType)
|
|
{
|
|
return Solving_Aborted;
|
|
}
|
|
|
|
|
|
|
|
|
|
int i;
|
|
for ( i = 0; i < NUM_SOLVERS; i++ )
|
|
{
|
|
rAssert( mpCollisionSolverAgentArray[ i ] != (CollisionSolverAgent*)0 );
|
|
if ( Solving_Aborted == mpCollisionSolverAgentArray[ i ]->PreCollisionEvent( inCollision, inPass ) )
|
|
{
|
|
return Solving_Aborted;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// this is a bit messy, but I don't want to have to derive supercamcentral from CollisionEntityDSG
|
|
if(simStateA && simStateA->mAIRefIndex == PhysicsAIRef::CameraSphere)
|
|
{
|
|
rmt::Vector fixOffset = inCollision.mNormal;
|
|
float dist = inCollision.mDistance;
|
|
|
|
if(dist < 0.0f)
|
|
{
|
|
dist *= -1.0f;
|
|
}
|
|
|
|
fixOffset.Scale(dist);
|
|
|
|
SuperCamCentral* scc = (SuperCamCentral*)(simStateA->mAIRefPointer);
|
|
scc->AddCameraCollisionOffset(fixOffset);
|
|
|
|
return Solving_Aborted;
|
|
|
|
}
|
|
if(simStateB && simStateB->mAIRefIndex == PhysicsAIRef::CameraSphere)
|
|
{
|
|
// normal always points B to A
|
|
// distance -ve means interpenetration
|
|
|
|
rmt::Vector fixOffset = inCollision.mNormal;
|
|
|
|
|
|
float dist = inCollision.mDistance;
|
|
|
|
if(dist < 0.0f)
|
|
{
|
|
dist *= -1.0f;
|
|
}
|
|
|
|
fixOffset.Scale(-1.0f * dist);
|
|
|
|
SuperCamCentral* scc = (SuperCamCentral*)(simStateB->mAIRefPointer);
|
|
scc->AddCameraCollisionOffset(fixOffset);
|
|
|
|
return Solving_Aborted;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
if( simStateA && simStateB && ( simStateA->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveableGroundPlane ||
|
|
simStateB->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveableGroundPlane) )
|
|
{
|
|
//char buffy[128];
|
|
rReleaseString("something collided with a moveableobject groundplane\n");
|
|
|
|
}
|
|
*/
|
|
|
|
CollisionEntityDSG* pObjA = static_cast<CollisionEntityDSG*>( simStateA->mAIRefPointer );
|
|
CollisionEntityDSG* pObjB = static_cast<CollisionEntityDSG*>( simStateB->mAIRefPointer );
|
|
|
|
//bool bSolveA = false;
|
|
//bool bSolveB = false;
|
|
Solving_Answer answerA = Solving_Continue;
|
|
Solving_Answer answerB = Solving_Continue;
|
|
|
|
if ( pObjA )
|
|
{
|
|
//bSolveA = pObjA->ReactToCollision( simStateB, inCollision );
|
|
answerA = pObjA->PreReactToCollision( simStateB, inCollision );
|
|
}
|
|
if ( pObjB )
|
|
{
|
|
//bSolveB = pObjB->ReactToCollision( simStateA, inCollision );
|
|
answerB = pObjB->PreReactToCollision( simStateA, inCollision );
|
|
}
|
|
//if ( bSolveA || bSolveB )
|
|
if(answerA == Solving_Aborted || answerB == Solving_Aborted)
|
|
{
|
|
return Solving_Aborted;
|
|
}
|
|
return CollisionSolverAgent::PreCollisionEvent(inCollision, inPass);
|
|
}
|
|
|
|
/*
|
|
==============================================================================
|
|
WorldCollisionSolverAgentManager::TestImpulse
|
|
==============================================================================
|
|
Description: Comment
|
|
|
|
Parameters: (rmt::Vector& mImpulse, Collision& inCollision)
|
|
|
|
Return: Solving_Answer
|
|
|
|
=============================================================================
|
|
*/
|
|
Solving_Answer WorldCollisionSolverAgentManager::TestImpulse(rmt::Vector& impulse, Collision& inCollision)
|
|
{
|
|
int i;
|
|
|
|
// vehicle is special and will be dealt with in the redbrick collision solver agent
|
|
|
|
// other ordinary shit will get the PostReactToCollision call here.
|
|
|
|
for ( i = 0; i < NUM_SOLVERS; i++ )
|
|
{
|
|
rAssert( mpCollisionSolverAgentArray[ i ] != (CollisionSolverAgent*)0 );
|
|
if ( Solving_Aborted == mpCollisionSolverAgentArray[ i ]->TestImpulse( impulse, inCollision ) )
|
|
{
|
|
return Solving_Aborted;
|
|
}
|
|
}
|
|
|
|
CollisionObject* collObjA = inCollision.mCollisionObjectA;
|
|
CollisionObject* collObjB = inCollision.mCollisionObjectB;
|
|
|
|
SimState* simStateA = collObjA->GetSimState();
|
|
SimState* simStateB = collObjB->GetSimState();
|
|
|
|
CollisionEntityDSG* pObjA = static_cast<CollisionEntityDSG*>( simStateA->mAIRefPointer );
|
|
CollisionEntityDSG* pObjB = static_cast<CollisionEntityDSG*>( simStateB->mAIRefPointer );
|
|
|
|
Solving_Answer answerA = Solving_Continue;
|
|
Solving_Answer answerB = Solving_Continue;
|
|
|
|
if(pObjA)
|
|
{
|
|
answerA = pObjA->PostReactToCollision(impulse, inCollision);
|
|
}
|
|
if(pObjB)
|
|
{
|
|
answerB = pObjB->PostReactToCollision(impulse, inCollision);
|
|
}
|
|
|
|
if(answerA == Solving_Aborted || answerB == Solving_Aborted)
|
|
{
|
|
return Solving_Aborted;
|
|
}
|
|
|
|
/*
|
|
if( simStateA && simStateB && ( simStateA->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveableGroundPlane ||
|
|
simStateB->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveableGroundPlane) )
|
|
{
|
|
//char buffy[128];
|
|
rReleaseString("something is testing impulse with a moveableobject groundplane\n");
|
|
|
|
}
|
|
*/
|
|
|
|
|
|
return CollisionSolverAgent::TestImpulse(impulse, inCollision);
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
==============================================================================
|
|
WorldCollisionSolverAgentManager::TestCache
|
|
==============================================================================
|
|
Description: Comment
|
|
|
|
Parameters: (SimState* inSimState, int inIndex)
|
|
|
|
Return: Solving_Answer
|
|
|
|
=============================================================================
|
|
*/
|
|
Solving_Answer WorldCollisionSolverAgentManager::TestCache(SimState* inSimState, int inIndex)
|
|
{
|
|
int i;
|
|
for ( i = 0; i < NUM_SOLVERS; i++ )
|
|
{
|
|
rAssert( mpCollisionSolverAgentArray[ i ] != (CollisionSolverAgent*)0 );
|
|
if ( Solving_Aborted == mpCollisionSolverAgentArray[ i ]->TestCache( inSimState, inIndex ) )
|
|
{
|
|
return Solving_Aborted;
|
|
}
|
|
}
|
|
return Solving_Continue;
|
|
}
|
|
|
|
|
|
|
|
|
|
Solving_Answer WorldCollisionSolverAgentManager::EndObjectCollision(SimState* inSimState, int inIndex)
|
|
{
|
|
|
|
int i;
|
|
for ( i = 0; i < NUM_SOLVERS; i++ )
|
|
{
|
|
rAssert( mpCollisionSolverAgentArray[ i ] != (CollisionSolverAgent*)0 );
|
|
if ( Solving_Aborted == mpCollisionSolverAgentArray[ i ]->EndObjectCollision(inSimState, inIndex) )
|
|
{
|
|
return Solving_Aborted;
|
|
}
|
|
}
|
|
return Solving_Continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
==============================================================================
|
|
WorldCollisionSolverAgentManager::ResetCollisionFlags
|
|
==============================================================================
|
|
Description: Comment
|
|
|
|
Parameters: ()
|
|
|
|
Return: void
|
|
|
|
=============================================================================
|
|
*/
|
|
void WorldCollisionSolverAgentManager::ResetCollisionFlags()
|
|
{
|
|
int i;
|
|
for ( i = 0; i < NUM_SOLVERS; i++ )
|
|
{
|
|
rAssert( mpCollisionSolverAgentArray[ i ] != (CollisionSolverAgent*)0 );
|
|
mpCollisionSolverAgentArray[ i ]->ResetCollisionFlags();
|
|
}
|
|
}
|
|
//******************************************************************************
|
|
//
|
|
// Private Member Functions
|
|
//
|
|
//******************************************************************************
|