etqw-sdk/source/game/effects/FootPrints.cpp

227 lines
5.3 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#include "../precompiled.h"
#pragma hdrstop
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "FootPrints.h"
#include "HardcodedParticleSystem.h"
/*********************************************************************************************************
sdFootPrintManagerLocal
*********************************************************************************************************/
class sdFootPrintManagerLocal : public sdFootPrintManager {
public:
sdFootPrintManagerLocal() : system( NULL ) {}
virtual void Init( void );
virtual void Deinit( void );
virtual bool AddFootPrint( const idVec3 & point, const idVec3 &forward, const idVec3 &up, bool right );
virtual void Think( void );
virtual renderEntity_t* GetRenderEntity( void );
virtual qhandle_t GetModelHandle( void );
private:
struct footprint {
idVec3 p;
idVec3 f;
idVec3 l;
int age;
};
static const int MAX_FOOTSTEPS = 128;
footprint footprints[ MAX_FOOTSTEPS ];
sdHardcodedParticleSystem *system;
unsigned short index;
unsigned int start;
unsigned int end;
};
sdFootPrintManagerLocal footPrintManagerLocal;
sdFootPrintManager *footPrintManager = &footPrintManagerLocal;
/*
==============
sdFootPrintManagerLocal::Init
==============
*/
void sdFootPrintManagerLocal::Init( void ) {
const sdDeclStringMap* map = gameLocal.declStringMapType[ "footPrintDef" ];
if ( !map ) {
gameLocal.Error( "sdFootPrintManagerLocal::Init stringMap 'footPrintDef' not found" );
return;
}
int maxnumpnts = MAX_FOOTSTEPS * 4;
int maxnumtris = MAX_FOOTSTEPS * 2;
system = new sdHardcodedParticleSystem;
system->AddSurfaceDB( declHolder.declMaterialType.LocalFind( map->GetDict().GetString( "material", "_black" ) ), maxnumpnts, maxnumtris * 3 );
system->GetRenderEntity().axis.Identity();
system->GetRenderEntity().origin.Zero();
start = 0;
end = 0;
}
/*
==============
sdFootPrintManagerLocal::Deinit
==============
*/
void sdFootPrintManagerLocal::Deinit( void ) {
delete system;
system = NULL;
}
/*
==============
sdFootPrintManagerLocal::AddFootPrint
==============
*/
bool sdFootPrintManagerLocal::AddFootPrint( const idVec3 & point, const idVec3 &forward, const idVec3 &up, bool right ) {
int num = end - start;
int index = end % MAX_FOOTSTEPS;
end++;
if ( num == MAX_FOOTSTEPS ) {
start++;
}
footprint *f = &footprints[ index ];
f->f = forward;
f->f.Normalize();
f->l = up.Cross( f->f );
f->f = f->l.Cross( up );
f->p = point;
f->age = gameLocal.time;
if ( !right ) {
f->l = -f->l;
}
return false;
}
/*
==============
sdFootPrintManagerLocal::Think
==============
*/
void sdFootPrintManagerLocal::Think( void ) {
system->SetDoubleBufferedModel();
while ( start < end ) {
int index = start % MAX_FOOTSTEPS;
footprint *f = &footprints[ index ];
if ( ( gameLocal.time - f->age ) > SEC2MS( 60.f ) ) {
start++;
} else {
break;
}
}
srfTriangles_t *surf = system->GetTriSurf( 0 );
surf->numIndexes = 0;
surf->numVerts = 0;
surf->bounds.Clear();
for (unsigned int i=start; i<end; i++) {
int index = i % MAX_FOOTSTEPS;
footprint *f = &footprints[ index ];
idDrawVert *v = &surf->verts[ surf->numVerts ];
vertIndex_t *idx = &surf->indexes[ surf->numIndexes ];
byte alpha = 255;
int a = ( gameLocal.time - f->age );
if ( a > SEC2MS( 50 ) ) {
alpha = ( byte )( idMath::ClampFloat( 0.f, 1.f, 1.f - ( ( a - SEC2MS( 50 ) ) / ( float )( SEC2MS( 10 ) ) ) ) * 255 );
}
v->Clear();
v->xyz = f->p + f->f * 8 + f->l * 3;
v->SetST( 0.f, 0.f );
v->color[0] = alpha;
v->color[1] = alpha;
v->color[2] = alpha;
v->color[3] = alpha;
v++;
v->Clear();
v->xyz = f->p + f->f * 8 - f->l * 3;
v->SetST( 1.f, 0.f );
v->color[0] = alpha;
v->color[1] = alpha;
v->color[2] = alpha;
v->color[3] = alpha;
v++;
v->Clear();
v->xyz = f->p - f->f * 8 + f->l * 3;
v->SetST( 0.f, 1.f );
v->color[0] = alpha;
v->color[1] = alpha;
v->color[2] = alpha;
v->color[3] = alpha;
v++;
v->Clear();
v->xyz = f->p - f->f * 8 - f->l * 3;
v->SetST( 1.f, 1.f );
v->color[0] = alpha;
v->color[1] = alpha;
v->color[2] = alpha;
v->color[3] = alpha;
v++;
idx[0] = surf->numVerts + 0;
idx[1] = surf->numVerts + 1;
idx[2] = surf->numVerts + 2;
idx[3] = surf->numVerts + 1;
idx[4] = surf->numVerts + 3;
idx[5] = surf->numVerts + 2;
surf->numIndexes += 6;
surf->numVerts += 4;
surf->bounds.AddPoint( f->p );
}
if ( surf->numVerts ) {
surf->bounds.ExpandSelf( 10.f );
system->GetRenderEntity().hModel->FreeVertexCache();
system->GetRenderEntity().hModel->SetBounds(surf->bounds);
system->GetRenderEntity().bounds = surf->bounds;
system->PresentRenderEntity();
}
}
/*
==============
sdFootPrintManagerLocal::GetRenderEntity
==============
*/
renderEntity_t* sdFootPrintManagerLocal::GetRenderEntity( void ) {
return system == NULL ? NULL : &system->GetRenderEntity();
}
/*
==============
sdFootPrintManagerLocal::GetModelHandle
==============
*/
int sdFootPrintManagerLocal::GetModelHandle( void ) {
return system == NULL ? -1 : system->GetModelHandle();
}