488 lines
13 KiB
C++
488 lines
13 KiB
C++
//========================================================================
|
|
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
|
|
//
|
|
// File: InstStatEntityDSG.cpp
|
|
//
|
|
// Description: Implementation for InstStatEntityDSG class.
|
|
//
|
|
// History: Implemented --Devin [6/17/2002]
|
|
//========================================================================
|
|
|
|
//========================================
|
|
// System Includes
|
|
//========================================
|
|
|
|
//========================================
|
|
// Project Includes
|
|
//========================================
|
|
#include <p3d/utility.hpp>
|
|
#include <render/DSG/InstStatEntityDSG.h>
|
|
#include <memory/srrmemory.h>
|
|
#include <render/IntersectManager/IntersectManager.h>
|
|
#include <p3d/matrixstack.hpp>
|
|
#include <p3d/view.hpp>
|
|
#include <p3d/camera.hpp>
|
|
#include <p3d/billboardobject.hpp>
|
|
//************************************************************************
|
|
//
|
|
// Global Data, Local Data, Local Classes
|
|
//
|
|
//************************************************************************
|
|
|
|
//************************************************************************
|
|
//
|
|
// Public Member Functions : InstStatEntityDSG Interface
|
|
//
|
|
//************************************************************************
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
InstStatEntityDSG::InstStatEntityDSG()
|
|
: mpMatrix( NULL ),
|
|
mpShadowDrawable( NULL ),
|
|
mpShadowMatrix( NULL )
|
|
{
|
|
}
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
InstStatEntityDSG::~InstStatEntityDSG()
|
|
{
|
|
BEGIN_PROFILE( "InstStatEntityDSG Destroy" );
|
|
if(mpMatrix)
|
|
{
|
|
delete mpMatrix;
|
|
}
|
|
if ( mpShadowDrawable )
|
|
{
|
|
mpShadowDrawable->Release();
|
|
mpShadowDrawable = NULL;
|
|
}
|
|
if ( mpShadowMatrix )
|
|
{
|
|
delete mpShadowMatrix;
|
|
}
|
|
|
|
END_PROFILE( "InstStatEntityDSG Destroy" );
|
|
}
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
|
|
void InstStatEntityDSG::Display()
|
|
{
|
|
if(IS_DRAW_LONG) return;
|
|
#ifdef PROFILER_ENABLED
|
|
char profileName[] = " InstStatEntityDSG Display";
|
|
#endif
|
|
DSG_BEGIN_PROFILE(profileName)
|
|
if(CastsShadow())
|
|
{
|
|
BillboardQuadManager::Enable();
|
|
}
|
|
p3d::pddi->PushMultMatrix(PDDI_MATRIX_MODELVIEW, mpMatrix);
|
|
mpDrawstuff->Display();
|
|
p3d::pddi->PopMatrix(PDDI_MATRIX_MODELVIEW);
|
|
|
|
if(CastsShadow())
|
|
{
|
|
BillboardQuadManager::Disable();
|
|
DisplaySimpleShadow();
|
|
}
|
|
|
|
DSG_END_PROFILE(profileName)
|
|
}
|
|
|
|
//========================================================================
|
|
// InstStatEntityDSG::DisplaySimpleShadow
|
|
//========================================================================
|
|
//
|
|
// Description: Draws the given shadow drawable after translation by the
|
|
// shadow matrix
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
|
|
void InstStatEntityDSG::DisplaySimpleShadow()
|
|
{
|
|
BEGIN_PROFILE("DisplaySimpleShadow")
|
|
p3d::pddi->SetZWrite(false);
|
|
if ( mpShadowDrawable != NULL )
|
|
{
|
|
if ( mpShadowMatrix == NULL )
|
|
{
|
|
mpShadowMatrix = CreateShadowMatrix( mpMatrix->Row( 3 ) );
|
|
}
|
|
if ( mpShadowMatrix )
|
|
{
|
|
|
|
// Create a camera that pushes the shadow a meter towards
|
|
// the camera
|
|
rmt::Vector camPos;
|
|
p3d::context->GetView()->GetCamera()->GetWorldPosition( &camPos );
|
|
camPos.Sub( mpShadowMatrix->Row(3) );
|
|
camPos.Normalize();
|
|
|
|
// Move the shadow towards the camera by the following distance.
|
|
const float Z_FIGHTING_OFFSET = 0.2f;
|
|
camPos.Scale( Z_FIGHTING_OFFSET );
|
|
|
|
// Final shadow transform = position/orientation * tocamera translation
|
|
rmt::Matrix shadowTransform( *mpShadowMatrix );
|
|
shadowTransform.Row( 3 ).Add( camPos );
|
|
|
|
// Display
|
|
p3d::stack->PushMultiply( shadowTransform );
|
|
mpShadowDrawable->Display();
|
|
p3d::stack->Pop();
|
|
}
|
|
}
|
|
p3d::pddi->SetZWrite(true);
|
|
END_PROFILE("DisplaySimpleShadow")
|
|
}
|
|
//========================================================================
|
|
// InstStatEntityDSG::RecomputeShadowPosition
|
|
//========================================================================
|
|
//
|
|
// Description: Finds the intersection point and computes mpShadowMatrix
|
|
//
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
void InstStatEntityDSG::RecomputeShadowPosition()
|
|
{
|
|
if ( mpShadowMatrix )
|
|
{
|
|
rmt::Vector position;
|
|
GetPosition( &position );
|
|
ComputeShadowMatrix( position, mpShadowMatrix );
|
|
}
|
|
}
|
|
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
void InstStatEntityDSG::GetBoundingBox(rmt::Box3D* box)
|
|
{
|
|
rmt::Box3D fuckinTempBox;
|
|
mpDrawstuff->GetBoundingBox(&fuckinTempBox);
|
|
|
|
if ( rmt::Fabs(fuckinTempBox.Height()) > 10000.0f &&
|
|
rmt::Fabs(fuckinTempBox.Width()) > 10000.0f &&
|
|
rmt::Fabs(fuckinTempBox.Length()) > 10000.0f )
|
|
{
|
|
fuckinTempBox.low = rmt::Vector( -1.0f, -1.0f, -1.0f );
|
|
fuckinTempBox.high = rmt::Vector( 1.0f, 1.0f, 1.0f );
|
|
}
|
|
|
|
mpMatrix->Transform(fuckinTempBox.low, &box->low);
|
|
mpMatrix->Transform(fuckinTempBox.high, &box->high);
|
|
}
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
void InstStatEntityDSG::GetBoundingSphere(rmt::Sphere* pSphere)
|
|
{
|
|
rmt::Sphere fuckinTempSphere;
|
|
mpDrawstuff->GetBoundingSphere(&fuckinTempSphere);
|
|
|
|
mpMatrix->Transform(fuckinTempSphere.centre, &pSphere->centre);
|
|
pSphere->radius = fuckinTempSphere.radius;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Accessors
|
|
///////////////////////////////////////////////////////////////////////
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
rmt::Matrix* InstStatEntityDSG::pMatrix()
|
|
{
|
|
return mpMatrix;
|
|
}
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
tGeometry* InstStatEntityDSG::pGeo()
|
|
{
|
|
rAssert(false);
|
|
return (tGeometry*)mpDrawstuff;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Load interface
|
|
///////////////////////////////////////////////////////////////////////
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
void InstStatEntityDSG::LoadSetUp
|
|
(
|
|
rmt::Matrix* ipMatrix,
|
|
tGeometry* ipGeo,
|
|
tDrawable* ipShadow
|
|
)
|
|
{
|
|
mpMatrix = ipMatrix;
|
|
mpDrawstuff = ipGeo;
|
|
|
|
mpDrawstuff->AddRef();
|
|
|
|
//mShaderUID = ipGeo->GetShader(0)->GetUID();
|
|
ipGeo->ProcessShaders(*this);
|
|
|
|
if ( ipShadow )
|
|
{
|
|
tRefCounted::Assign( mpShadowDrawable, ipShadow );
|
|
|
|
mpShadowMatrix = CreateShadowMatrix( ipMatrix->Row( 3 ) );
|
|
}
|
|
}
|
|
//========================================================================
|
|
// InstStatEntityDSG::
|
|
//========================================================================
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
//========================================================================
|
|
void InstStatEntityDSG::LoadSetUp
|
|
(
|
|
rmt::Matrix* ipMatrix,
|
|
tDrawable* ipGeo,
|
|
tDrawable* ipShadow
|
|
)
|
|
{
|
|
mpMatrix = ipMatrix;
|
|
mpDrawstuff = ipGeo;
|
|
|
|
mpDrawstuff->AddRef();
|
|
ipGeo->ProcessShaders(*this);
|
|
|
|
if ( ipShadow )
|
|
{
|
|
tRefCounted::Assign( mpShadowDrawable, ipShadow );
|
|
|
|
mpShadowMatrix = CreateShadowMatrix( ipMatrix->Row( 3 ) );
|
|
}
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
// InstStatEntityDSG::pPosition
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: rmt
|
|
//
|
|
//=============================================================================
|
|
rmt::Vector* InstStatEntityDSG::pPosition()
|
|
{
|
|
rAssert( false );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//=============================================================================
|
|
// InstStatEntityDSG::rPosition
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: const
|
|
//
|
|
//=============================================================================
|
|
const rmt::Vector& InstStatEntityDSG::rPosition()
|
|
{
|
|
rAssert( false );
|
|
|
|
return mPosn;
|
|
}
|
|
|
|
//=============================================================================
|
|
// InstStatEntityDSG::GetPosition
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( rmt::Vector* ipPosn )
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void InstStatEntityDSG::GetPosition( rmt::Vector* ipPosn )
|
|
{
|
|
rmt::Sphere sphere;
|
|
mpDrawstuff->GetBoundingSphere(&sphere);
|
|
*ipPosn = sphere.centre;
|
|
|
|
ipPosn->Transform( *mpMatrix );
|
|
}
|
|
|
|
//************************************************************************
|
|
//
|
|
// Protected Member Functions : InstStatEntityDSG
|
|
//
|
|
//************************************************************************
|
|
|
|
|
|
rmt::Matrix*
|
|
InstStatEntityDSG::CreateShadowMatrix( const rmt::Vector& position )
|
|
{
|
|
|
|
rmt::Matrix* pResult;
|
|
rmt::Matrix shadowMat;
|
|
if ( ComputeShadowMatrix( position, &shadowMat ) )
|
|
{
|
|
HeapMgr()->PushHeap( GMA_LEVEL_OTHER );
|
|
pResult = new rmt::Matrix();
|
|
HeapMgr()->PopHeap( GMA_LEVEL_OTHER );
|
|
*pResult = shadowMat;
|
|
|
|
}
|
|
else
|
|
{
|
|
pResult = NULL ;
|
|
}
|
|
return pResult;
|
|
|
|
}
|
|
|
|
bool
|
|
InstStatEntityDSG::ComputeShadowMatrix( const rmt::Vector& in_position, rmt::Matrix* out_pMatrix )
|
|
{
|
|
// Determine where our shadow casting object intersects the ground plane
|
|
rmt::Vector groundNormal(0,1,0);
|
|
rmt::Vector groundPlaneIntersectionPoint;
|
|
|
|
const float INTERSECT_TEST_RADIUS = 10.0f;
|
|
bool foundPlane;
|
|
rmt::Vector deepestIntersectPos, deepestIntersectNormal;
|
|
|
|
// Get rid of the fact that FindIntersection doesn't want a const value
|
|
// and I'm above casting away constness
|
|
|
|
rmt::Vector searchPosition = in_position;
|
|
searchPosition.y += 10.0f;
|
|
|
|
GetIntersectManager()->FindIntersection( searchPosition,
|
|
foundPlane,
|
|
groundNormal,
|
|
groundPlaneIntersectionPoint );
|
|
|
|
if ( foundPlane )
|
|
{
|
|
out_pMatrix->Identity();
|
|
out_pMatrix->FillTranslate( groundPlaneIntersectionPoint );
|
|
rmt::Vector worldRight( 1,0,0 );
|
|
rmt::Vector forward;
|
|
forward.CrossProduct( worldRight, groundNormal );
|
|
out_pMatrix->FillHeading( forward, groundNormal );
|
|
}
|
|
return foundPlane;
|
|
|
|
}
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// Private Member Functions : InstStatEntityDSG
|
|
//
|
|
//************************************************************************
|