The-Simpsons-Hit-and-Run/game/code/meta/recttriggervolume.cpp

462 lines
13 KiB
C++

//=============================================================================
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
//
// File:
//
// Description: Implement RectTriggerVolume
//
// History: 03/04/2002 + Created -- Cary Brisebois
//
//=============================================================================
//========================================
// System Includes
//========================================
// Foundation Tech
#include <raddebug.hpp>
#include <raddebugwatch.hpp>
//========================================
// Project Includes
//========================================
#ifndef WORLD_BUILDER
#include <meta/recttriggervolume.h>
#include <memory/srrmemory.h>
#include <debug/profiler.h>
#else
#define BEGIN_PROFILE(s)
#define END_PROFILE(s)
#include "recttriggervolume.h"
#endif
//******************************************************************************
//
// Global Data, Local Data, Local Classes
//
//******************************************************************************
//******************************************************************************
//
// Public Member Functions
//
//******************************************************************************
//==============================================================================
// RectTriggerVolume::RectTriggerVolume
//==============================================================================
// Description: Constructor.
//
// Parameters: ( const rmt::Vector& center,
// const rmt::Vector& axisX,
// const rmt::Vector& axisY,
// const rmt::Vector& axisZ,
// float extentX,
// float extentY,
// float extentZ )
//
// Return: N/A.
//
//==============================================================================
RectTriggerVolume::RectTriggerVolume( const rmt::Vector& center,
const rmt::Vector& axisX,
const rmt::Vector& axisY,
const rmt::Vector& axisZ,
float extentX,
float extentY,
float extentZ ) :
mAxisX( axisX ),
mAxisY( axisY ),
mAxisZ( axisZ ),
mExtentX( extentX ),
mExtentY( extentY ),
mExtentZ( extentZ )
{
SetPosition( center );
UpdateW2T();
mRadius = rmt::Sqrt(extentX*extentX+extentY*extentY+extentZ*extentZ);
}
//==============================================================================
// RectTriggerVolume::~RectTriggerVolume
//==============================================================================
// Description: Destructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
RectTriggerVolume::~RectTriggerVolume()
{
}
//=============================================================================
// RectTriggerVolume::Contains
//=============================================================================
// Description: Comment
//
// Parameters: ( const rmt::Vector& point, float epsilon )
//
// Return: bool
//
//=============================================================================
bool RectTriggerVolume::Contains ( const rmt::Vector& point,
float epsilon ) const
{
//BEGIN_PROFILE( "Rect Contains" );
//Transform the point to rect space
rmt::Vector temp;
temp.Sub( GetPosition(), point );
temp.Transform( mWorld2Trigger );
if( (temp.x >= -mExtentX ) &&
(temp.x <= mExtentX ) &&
(temp.y >= -mExtentY ) &&
(temp.y <= mExtentY) &&
(temp.z >= -mExtentZ ) &&
(temp.z <= mExtentZ ) )
{
//END_PROFILE( "Rect Contains" );
return true;
}
//END_PROFILE( "Rect Contains" );
return false;
}
//=============================================================================
// RectTriggerVolume::IntersectsBox
//=============================================================================
// Description: Comment
//
// Parameters: ( const rmt::Vector& p1,
// const rmt::Vector& p2,
// const rmt::Vector& p3,
// const rmt::Vector& p4 )
//
// Return: bool
//
//=============================================================================
bool RectTriggerVolume::IntersectsBox( const rmt::Vector& p1,
const rmt::Vector& p2,
const rmt::Vector& p3,
const rmt::Vector& p4 ) const
{
if ( Contains( p1 ) || Contains( p2 ) || Contains( p3 ) || Contains( p4 ) )
{
return true;
}
return false;
}
//=============================================================================
// RectTriggerVolume::IntersectsBox
//=============================================================================
// Description: Comment
//
// Parameters: ( const rmt::Box3D& box )
//
// Return: bool
//
//=============================================================================
bool RectTriggerVolume::IntersectsBox( const rmt::Box3D& box )
{
rmt::Vector p1, p2, p3, p4;
p1 = box.low;
p2 = box.high;
p3 = box.low;
p3.x = box.high.x;
p4 = box.high;
p4.x = box.low.x;
return IntersectsBox( p1, p2, p3, p4 );
}
//=============================================================================
// RectTriggerVolume::IntersectsSphere
//=============================================================================
// Description: Comment
//
// Parameters: ( const rmt::Vector& position, float radius )
//
// Return: bool
//
//=============================================================================
bool RectTriggerVolume::IntersectsSphere( const rmt::Vector& position,
float radius ) const
{
return Contains( position, radius );
}
//=============================================================================
// RectTriggerVolume::IntersectLine
//=============================================================================
// Description: Comment
//
// Parameters: ( const rmt::Vector& p1, const rmt::Vector& p2 )
//
// Return: bool
//
//=============================================================================
bool RectTriggerVolume::IntersectLine( const rmt::Vector& p1, const rmt::Vector& p2 ) const
{
if ( Contains( p1 ) || Contains( p2 ) )
{
return true;
}
return false;
}
//=============================================================================
// RectTriggerVolume::GetBoundingBox
//=============================================================================
// Description: Comment
//
// Parameters: (rmt::Vector& p1, rmt::Vector& p2)
//
// Return: bool
//
//=============================================================================
bool RectTriggerVolume::GetBoundingBox (rmt::Vector& p1, rmt::Vector& p2) const
{
//TODO: Make this work.
return false;
}
//=============================================================================
// RectTriggerVolume::GetType
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: TriggerVolume
//
//=============================================================================
TriggerVolume::Type RectTriggerVolume::GetType() const
{
return RECTANGLE;
}
//////////////////////////////////////////////////////////////////////////
// tDrawable interface
//////////////////////////////////////////////////////////////////////////
//========================================================================
// recttriggervolume::
//========================================================================
//
// Description:
//
// Parameters: None.
//
// Return: None.
//
// Constraints: None.
//
//========================================================================
void RectTriggerVolume::GetBoundingBox(rmt::Box3D* box)
{
box->low.x = GetPosition().x-mExtentX;
box->low.y = GetPosition().y-mExtentY;
box->low.z = GetPosition().z-mExtentZ;
box->high.x = GetPosition().x+mExtentX;
box->high.y = GetPosition().y+mExtentY;
box->high.z = GetPosition().z+mExtentZ;
}
//========================================================================
// recttriggervolume::
//========================================================================
//
// Description:
//
// Parameters: None.
//
// Return: None.
//
// Constraints: None.
//
//========================================================================
void RectTriggerVolume::GetBoundingSphere(rmt::Sphere* sphere)
{
sphere->centre = GetPosition();
sphere->radius = mRadius;
}
void RectTriggerVolume::SetTransform(rmt::Matrix& m)
{
mAxisX = m.Row(0);
mAxisY = m.Row(1);
mAxisZ = m.Row(2);
SetPosition(m.Row(3));
UpdateW2T();
}
//******************************************************************************
//
// Private Member Functions
//
//******************************************************************************
//=============================================================================
// RectTriggerVolume::UpdateW2T
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void RectTriggerVolume::UpdateW2T()
{
mTrigger2World.Row(0) = mAxisX;
mTrigger2World.Row(1) = mAxisY;
mTrigger2World.Row(2) = mAxisZ;
mTrigger2World.Row(3) = GetPosition();
mTrigger2World.m[0][3] = 0.0f;
mTrigger2World.m[1][3] = 0.0f;
mTrigger2World.m[2][3] = 0.0f;
mTrigger2World.m[3][3] = 0.0f;
mWorld2Trigger = mTrigger2World;
mWorld2Trigger.Invert(); //This is orthonormal!!!
//We only use the rot/scale...
mWorld2Trigger.IdentityTranslation();
}
//=============================================================================
// RectTriggerVolume::InitPoints
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void RectTriggerVolume::InitPoints()
{
#ifndef WORLD_BUILDER
#ifndef RAD_RELEASE
MEMTRACK_PUSH_GROUP( "RectTriggerVolume" );
numFaces = 12 * 3;
numVerts = 8;
verts = new(GMA_LEVEL_OTHER) pddiVector[numVerts];
faces = new(GMA_LEVEL_OTHER) unsigned short[numFaces];
unsigned int face = 0;
// Joel made the sphere normals inverted,
// so all these normals have to be inverted too
faces[face++] = 0;
faces[face++] = 1;
faces[face++] = 2;
faces[face++] = 2;
faces[face++] = 3;
faces[face++] = 0;
faces[face++] = 0;
faces[face++] = 6;
faces[face++] = 7;
faces[face++] = 7;
faces[face++] = 1;
faces[face++] = 0;
faces[face++] = 1;
faces[face++] = 7;
faces[face++] = 4;
faces[face++] = 4;
faces[face++] = 2;
faces[face++] = 1;
faces[face++] = 2;
faces[face++] = 4;
faces[face++] = 5;
faces[face++] = 5;
faces[face++] = 3;
faces[face++] = 2;
faces[face++] = 3;
faces[face++] = 5;
faces[face++] = 6;
faces[face++] = 6;
faces[face++] = 0;
faces[face++] = 3;
faces[face++] = 6;
faces[face++] = 5;
faces[face++] = 4;
faces[face++] = 4;
faces[face++] = 7;
faces[face++] = 6;
rAssert( static_cast< int >( face ) == numFaces );
MEMTRACK_POP_GROUP( "RectTriggerVolume" );
#endif
#endif
}
void RectTriggerVolume::CalcPoints()
{
#ifndef RAD_RELEASE
rmt::Vector radius( GetExtentX(), GetExtentY(), GetExtentZ() );
verts[0].Set( -radius.x, -radius.y, -radius.z );
verts[4].Set( radius.x, radius.y, radius.z );
// counter-clockwise from verts[0]
verts[1].Set( verts[0].x, verts[0].y, verts[4].z );
verts[2].Set( verts[4].x, verts[0].y, verts[4].z );
verts[3].Set( verts[4].x, verts[0].y, verts[0].z );
// counter-clockwise from verts[4]
verts[5].Set( verts[4].x, verts[4].y, verts[0].z );
verts[6].Set( verts[0].x, verts[4].y, verts[0].z );
verts[7].Set( verts[0].x, verts[4].y, verts[4].z );
for( unsigned int i = 0; i < 8; i++ )
{
mTrigger2World.Transform( verts[ i ], &verts[ i ] );
}
#endif
}
//==============================================================================
// RectTriggerVolume::RectTriggerVolume
//==============================================================================
// Description: Constructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
RectTriggerVolume::RectTriggerVolume() :
mAxisX( rmt::Vector( 1.0f, 0, 0 ) ),
mAxisY( rmt::Vector( 0, 1.0f, 0 ) ),
mAxisZ( rmt::Vector( 0, 0, 1.0f ) ),
mExtentX( 1.0f ),
mExtentY( 1.0f ),
mExtentZ( 1.0f )
{
}