2018-08-27 13:13:17 +00:00
// Created by ivan_the_B
//
2018-08-27 13:13:36 +00:00
# include "TrailGenerator.h"
2018-08-27 13:13:17 +00:00
# include "Game_local.h"
2018-08-27 13:13:36 +00:00
# include "renderer/ModelManager.h"
2018-08-27 13:13:17 +00:00
//uncomment those to enable debug
//#define _DEBUG_CUSTOM_GEOM
//#define _DEBUG_TRAIL
static const dword trailGenerator_vertexColor = PackColor ( idVec4 ( 1 , 1 , 1 , 1 ) ) ;
static const char * trailGenerator_SnapshotName = " _TrailGenerator_Snapshot_ " ; //Note: all the trail models use this name. It's not used so it's ok.
static const int TRAIL_ID_INVALID_UNIQUE = 0 ;
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
idTrailManager
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
idTrailManager : : idTrailManager
= = = = = = = = = = = = = = = =
*/
idTrailManager : : idTrailManager ( void ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::idTrailManager \n " ) ;
# endif
initialized = false ;
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : Init
= = = = = = = = = = = = = = = =
*/
void idTrailManager : : Init ( void ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::Init \n " ) ;
# endif
Shutdown ( ) ;
memset ( trails , 0 , sizeof ( trails ) ) ;
memset ( uniqueIds , TRAIL_ID_INVALID_UNIQUE , sizeof ( uniqueIds ) ) ;
lastUniqueId = TRAIL_ID_INVALID_UNIQUE ;
minFreePos = 0 ; //first slot will be empty here
maxAllocPos = - 1 ; //no one
initialized = true ;
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : ~ idTrailManager
= = = = = = = = = = = = = = = =
*/
idTrailManager : : ~ idTrailManager ( void ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::~idTrailManager \n " ) ;
# endif
if ( ! initialized ) return ;
for ( int i = 0 ; i < MAX_TRAILS ; i + + ) {
if ( trails [ i ] ) {
delete trails [ i ] ;
trails [ i ] = NULL ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : Shutdown
= = = = = = = = = = = = = = = =
*/
void idTrailManager : : Shutdown ( void ) {
if ( ! initialized ) return ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::Shutdown \n " ) ;
# endif
//deallocate all the trails that are still in memory
for ( int i = 0 ; i < MAX_TRAILS ; i + + ) {
if ( trails [ i ] ) {
2018-08-27 13:13:36 +00:00
gameLocal . Warning ( " Someone created a trail (uid: %d), but never removed it! \n TrailManager will now take care to free the memory...but check your code! " , trails [ i ] - > GetUniqueId ( ) ) ;
2018-08-27 13:13:17 +00:00
delete trails [ i ] ;
trails [ i ] = NULL ;
}
}
initialized = false ;
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : Save
= = = = = = = = = = = = = = = =
*/
void idTrailManager : : Save ( idSaveGame * savefile ) const {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::Save \n " ) ;
# endif
savefile - > WriteBool ( initialized ) ;
savefile - > WriteInt ( lastUniqueId ) ;
savefile - > WriteInt ( minFreePos ) ;
savefile - > WriteInt ( maxAllocPos ) ;
for ( int i = 0 ; i < = maxAllocPos ; i + + ) { //only stuff before 'maxAllocPos'
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " saving int %d \n " , uniqueIds [ i ] ) ;
# endif
savefile - > WriteInt ( uniqueIds [ i ] ) ;
if ( uniqueIds [ i ] ! = TRAIL_ID_INVALID_UNIQUE ) {
trails [ i ] - > Save ( savefile ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : Restore
= = = = = = = = = = = = = = = =
*/
void idTrailManager : : Restore ( idRestoreGame * savefile ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::Restore \n " ) ;
# endif
savefile - > ReadBool ( initialized ) ;
savefile - > ReadInt ( lastUniqueId ) ;
savefile - > ReadInt ( minFreePos ) ;
savefile - > ReadInt ( maxAllocPos ) ;
//load the ones before 'maxAllocPos'
for ( int i = 0 ; i < = maxAllocPos ; i + + ) { //only stuff before 'maxAllocPos'
savefile - > ReadInt ( uniqueIds [ i ] ) ;
if ( uniqueIds [ i ] ! = TRAIL_ID_INVALID_UNIQUE ) { //it was there. NOTE: same local pos!
trails [ i ] = new idTrailGenerator ;
trails [ i ] - > Restore ( savefile ) ;
# ifdef _DEBUG_TRAIL
//test only
if ( trails [ i ] - > GetLocalPos ( ) ! = i ) {
gameLocal . Error ( " localPos != array position! (%d) " , i ) ;
}
gameLocal . Printf ( " restored: - localPos: %d, uniId: %d \n " , trails [ i ] - > GetLocalPos ( ) , trails [ i ] - > GetUniqueId ( ) ) ;
# endif
} else {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " restored: NULL at pos %d \n " , i ) ;
# endif
trails [ i ] = NULL ;
}
}
//null the others
for ( int i = maxAllocPos + 1 ; i < MAX_TRAILS ; i + + ) {
uniqueIds [ i ] = TRAIL_ID_INVALID_UNIQUE ;
trails [ i ] = NULL ;
}
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : FindTrailByUniqueId
= = = = = = = = = = = = = = = =
*/
int idTrailManager : : GetSafeUniqueId ( idTrailGenerator * trailGen ) {
return ( trailGen ? trailGen - > GetUniqueId ( ) : TRAIL_ID_INVALID_UNIQUE ) ;
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : FindTrailByUniqueId
= = = = = = = = = = = = = = = =
*/
idTrailGenerator * idTrailManager : : FindTrailByLocalPos ( int pos ) { //fast
if ( pos < 0 | | pos > = MAX_TRAILS ) {
return NULL ;
}
return trails [ pos ] ;
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : FindTrailByUniqueId
= = = = = = = = = = = = = = = =
*/
idTrailGenerator * idTrailManager : : FindTrailByUniqueId ( int id ) { //slow, but ensure it's not another trail at the same pos
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::FindTrailById... \n " ) ;
# endif
if ( id = = TRAIL_ID_INVALID_UNIQUE ) { return NULL ; }
for ( int i = 0 ; i < MAX_TRAILS ; i + + ) {
if ( trails [ i ] & & trails [ i ] - > GetUniqueId ( ) = = id ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " ...found at pos: %d \n " , i ) ;
# endif
return trails [ i ] ;
}
}
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " ...not found \n " ) ;
# endif
return NULL ;
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : Think
= = = = = = = = = = = = = = = =
*/
void idTrailManager : : Think ( void ) {
for ( int i = 0 ; i < = maxAllocPos ; i + + ) { //don't even check beyond 'maxAllocPos' because they all are null
if ( trails [ i ] & & trails [ i ] - > fading ) { //->IsFading()
trails [ i ] - > Fade ( ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : GetTrailGen
= = = = = = = = = = = = = = = =
*/
idTrailGenerator * idTrailManager : : NewTrailGen ( void ) {
int i ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::NewTrailGen \n " ) ;
# endif
if ( minFreePos = = MAX_TRAILS ) {
gameLocal . Error ( " No free slots for another trail! " ) ;
return NULL ;
}
idTrailGenerator * myGen = new idTrailGenerator ;
//set an unique id
lastUniqueId + + ;
myGen - > Init ( lastUniqueId , minFreePos ) ;
//add it to list
trails [ minFreePos ] = myGen ;
uniqueIds [ minFreePos ] = lastUniqueId ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " Added trail 'uid: %d' at pos: %d \n " , lastUniqueId , minFreePos ) ;
# endif
//-- upd max pos allocated --
if ( minFreePos > maxAllocPos ) { //note: minFreePos is were it was placed
maxAllocPos = minFreePos ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " new maxAllocPos: %d \n " , maxAllocPos ) ;
# endif
}
//-- upd min pos free -- (we are sure no one is free before 'minFreePos')
for ( i = minFreePos + 1 ; i < MAX_TRAILS ; i + + ) { //from here (well, next one) to max
if ( ! trails [ i ] ) { break ; } //null
}
minFreePos = i ; // MAX_TRAILS if full array
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " new minFreePos: %d \n " , minFreePos ) ;
if ( minFreePos = = MAX_TRAILS ) {
gameLocal . Warning ( " This was the last free slot for a trail! " ) ;
}
# endif
return myGen ;
}
/*
= = = = = = = = = = = = = = = =
idTrailManager : : RemoveTrailGen
= = = = = = = = = = = = = = = =
*/
void idTrailManager : : RemoveTrailGen ( idTrailGenerator * trailGen ) {
int i ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailManager::RemoveTrailGen \n " ) ;
# endif
if ( ! trailGen ) { return ; }
//delete
int localPos = trailGen - > GetLocalPos ( ) ;
delete trails [ localPos ] ;
trails [ localPos ] = NULL ;
//clear id
uniqueIds [ localPos ] = TRAIL_ID_INVALID_UNIQUE ;
//-- upd min pos free --
if ( localPos < minFreePos ) { //if this one is now the first NULL
minFreePos = localPos ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " new minFreePos: %d \n " , minFreePos ) ;
# endif
}
//-- upd max pos allocated --
if ( localPos = = maxAllocPos ) { //if this one was the last allocated... go back until we find the first used slot
for ( i = maxAllocPos - 1 ; i > = 0 ; i - - ) { //from prev one to 0
if ( trails [ i ] ) { break ; } //used
}
maxAllocPos = i ; // -1 if empty array
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " new maxAllocPos: %d \n " , maxAllocPos ) ;
# endif
}
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " Removed trail at pos: %d \n " , minFreePos ) ;
# endif
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
idTrailGenerator
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : idTrailGenerator
= = = = = = = = = = = = = = = =
*/
idTrailGenerator : : idTrailGenerator ( void ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailGenerator::idTrailGenerator \n " ) ;
# endif
initialized = false ;
//new
uniqueId = TRAIL_ID_INVALID_UNIQUE ;
localPos = MAX_TRAILS ;
//thinkFlags = 0;
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : Init
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : Init ( int uniId , int locPos ) {
//gameLocal.Printf("idTrailGenerator::Init\n");
if ( initialized ) {
gameLocal . Error ( " Cannot initialize the same trail twice " ) ;
}
uniqueId = uniId ; //used for restoring references!
localPos = locPos ; //used for callback! It's faster but cannot identify it univocally
//thinkFlags = 0;
//settings
enabled = false ;
fading = false ;
fadingTime = 0 ;
fadingEndTime = 0 ;
fadingColorStep . Zero ( ) ;
maxPoints = 0 ;
material = NULL ;
trailDef = NULL ;
trailDefName = " " ;
points . SetGranularity ( 2 ) ; //use 2 because we always add/remove couple of points.
//rendering
memset ( & renderEntity , 0 , sizeof ( renderEntity ) ) ;
renderEntity . entityNum = localPos ;
renderEntity . bounds . Clear ( ) ;
renderEntity . axis = mat3_identity ;
renderEntity . shaderParms [ SHADERPARM_RED ] = 1 ;
renderEntity . shaderParms [ SHADERPARM_GREEN ] = 1 ;
renderEntity . shaderParms [ SHADERPARM_BLUE ] = 1 ;
renderEntity . shaderParms [ 3 ] = 1 ;
renderEntity . hModel = renderModelManager - > AllocModel ( ) ;
renderEntity . hModel - > InitEmpty ( trailGenerator_SnapshotName ) ;
renderEntity . noShadow = 1 ;
renderEntity . callback = idTrailGenerator : : ModelCallback ;
renderEntity . bounds . AddPoint ( idVec3 ( - 100000 , - 100000 , - 100000 ) ) ; // huge bounds, so it will be present in every world area
renderEntity . bounds . AddPoint ( idVec3 ( 100000 , 100000 , 100000 ) ) ;
// add to renderer list
//renderEntityHandle = gameRenderWorld->AddEntityDef( &renderEntity );
renderEntityHandle = - 1 ; //don't add it to renderworld until it's disabled
lastRenderEntityUpdate = - 1 ;
modelChanged = false ;
initialized = true ;
}
//always call this after color/flags change on renderEntity
void idTrailGenerator : : UpdateVisuals ( void ) {
// add to refresh list
if ( renderEntityHandle = = - 1 ) {
renderEntityHandle = gameRenderWorld - > AddEntityDef ( & renderEntity ) ;
} else {
gameRenderWorld - > UpdateEntityDef ( renderEntityHandle , & renderEntity ) ; //save colors and other flags on renderEntity
}
}
//remove it from RenderWorld when disabled
void idTrailGenerator : : FreeEntityDef ( void ) {
if ( renderEntityHandle ! = - 1 ) {
gameRenderWorld - > FreeEntityDef ( renderEntityHandle ) ;
renderEntityHandle = - 1 ;
}
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : ~ idTrailGenerator
= = = = = = = = = = = = = = = =
*/
idTrailGenerator : : ~ idTrailGenerator ( void ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailGenerator::~idTrailGenerator \n " ) ;
# endif
if ( ! initialized ) { return ; }
// make sure the render entity is freed before the model is freed
if ( renderEntityHandle ! = - 1 ) {
gameRenderWorld - > FreeEntityDef ( renderEntityHandle ) ;
renderEntityHandle = - 1 ;
}
if ( renderEntity . hModel ! = NULL ) {
renderModelManager - > FreeModel ( renderEntity . hModel ) ;
renderEntity . hModel = NULL ;
}
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : Save
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : Save ( idSaveGame * savefile ) const {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailGenerator::Save \n " ) ;
# endif
//global
savefile - > WriteInt ( uniqueId ) ;
savefile - > WriteInt ( localPos ) ;
savefile - > WriteBool ( initialized ) ;
// settings
savefile - > WriteBool ( enabled ) ;
savefile - > WriteBool ( fading ) ;
savefile - > WriteVec3 ( fadingColorStep ) ;
savefile - > WriteInt ( fadingTime ) ;
savefile - > WriteInt ( fadingEndTime ) ;
savefile - > WriteInt ( maxPoints ) ;
savefile - > WriteMaterial ( material ) ;
//trail def
//trailDef is NOT saved, but can be retrieved from trailDefName
savefile - > WriteString ( trailDefName ) ;
//points are NOT saved!! The trail will be be empty.
//idList<idVec3> points;
//rendering
savefile - > WriteRenderEntity ( renderEntity ) ;
savefile - > WriteInt ( renderEntityHandle ) ;
savefile - > WriteInt ( lastRenderEntityUpdate ) ;
savefile - > WriteBool ( modelChanged ) ;
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : Restore
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : Restore ( idRestoreGame * savefile ) {
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " idTrailGenerator::Restore \n " ) ;
# endif
//global
savefile - > ReadInt ( uniqueId ) ; //used for restoring references!
savefile - > ReadInt ( localPos ) ;
savefile - > ReadBool ( initialized ) ;
// settings
savefile - > ReadBool ( enabled ) ;
savefile - > ReadBool ( fading ) ;
savefile - > ReadVec3 ( fadingColorStep ) ;
savefile - > ReadInt ( fadingTime ) ;
savefile - > ReadInt ( fadingEndTime ) ;
savefile - > ReadInt ( maxPoints ) ;
savefile - > ReadMaterial ( material ) ;
//trail def
savefile - > ReadString ( trailDefName ) ;
if ( trailDefName . Length ( ) ) {
trailDef = gameLocal . FindEntityDefDict ( trailDefName ) ;
} else {
trailDef = NULL ;
//gameLocal.Warning("trailDef not found!");
}
//points are NOT saved!!
points . Clear ( ) ;
points . SetGranularity ( 2 ) ;
//rendering
savefile - > ReadRenderEntity ( renderEntity ) ;
savefile - > ReadInt ( renderEntityHandle ) ;
savefile - > ReadInt ( lastRenderEntityUpdate ) ;
savefile - > ReadBool ( modelChanged ) ;
//fix - reallocate the model ( this was created on init )
renderEntity . entityNum = localPos ; //used for callback!
renderEntity . hModel = renderModelManager - > AllocModel ( ) ;
renderEntity . hModel - > InitEmpty ( trailGenerator_SnapshotName ) ;
renderEntity . callback = idTrailGenerator : : ModelCallback ;
renderEntity . noShadow = true ;
renderEntity . noSelfShadow = true ;
renderEntity . noDynamicInteractions = false ;
/*
// restore must retrieve renderEntityHandle from the renderer
if ( renderEntityHandle ! = - 1 ) {
renderEntityHandle = gameRenderWorld - > AddEntityDef ( & renderEntity ) ;
}
*/
if ( renderEntityHandle ! = - 1 ) {
renderEntityHandle = gameRenderWorld - > AddEntityDef ( & renderEntity ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : RestartTrail
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : RestartTrail ( void ) {
idVec3 color ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " RestartTrail %s \n " , trailDefName . c_str ( ) ) ;
# endif
if ( trailDef ) {
//restore the old color
trailDef - > GetVector ( " color " , " 1 1 1 " , color ) ;
renderEntity . shaderParms [ SHADERPARM_RED ] = color [ 0 ] ;
renderEntity . shaderParms [ SHADERPARM_GREEN ] = color [ 1 ] ;
renderEntity . shaderParms [ SHADERPARM_BLUE ] = color [ 2 ] ;
} else {
gameLocal . Warning ( " Trying to restart a trail without a def! \n " ) ;
return ;
}
//state
enabled = true ; //weapon will upd the position
fading = false ;
modelChanged = true ; //upd renderer
UpdateVisuals ( ) ; //make sure it's in the world and updated
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : StartTrail
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : StartTrail ( const char * newTrailDefName ) {
const char * materialName ;
idVec3 color ;
const idDict * newTrailDef ;
# ifdef _DEBUG_TRAIL
gameLocal . Printf ( " StartTrail %s \n " , newTrailDefName ) ;
# endif
newTrailDef = gameLocal . FindEntityDefDict ( newTrailDefName , false ) ;
if ( ! newTrailDef ) {
gameLocal . Error ( " Unknown def '%s' " , newTrailDefName ) ;
}
//NOTE: this works, but we assume that if it's the same def, RestartTrail() will be called instead.
if ( trailDef & & newTrailDef & & ( newTrailDef = = trailDef ) ) {
//gameLocal.Warning("Started a new Trail with the same def! use RestartTrail() instead to save performance!");
RestartTrail ( ) ;
return ;
}
//remove the points
//points.Clear(); //we can keep the old ones so, if we already are active the trail goes on.
//fadingTime
newTrailDef - > GetInt ( " fadeTime " , " 200 " , fadingTime ) ;
if ( fadingTime < 0 ) fadingTime = 0 ;
//maxPoints
newTrailDef - > GetInt ( " numFrames " , " 10 " , maxPoints ) ;
maxPoints = ( maxPoints < 1 ) ? 4 : ( maxPoints * 2 + 2 ) ; //1frame -> 4points, 2frame -> 6points, ...
//color
newTrailDef - > GetVector ( " color " , " 1 1 1 " , color ) ;
renderEntity . shaderParms [ SHADERPARM_RED ] = color [ 0 ] ;
renderEntity . shaderParms [ SHADERPARM_GREEN ] = color [ 1 ] ;
renderEntity . shaderParms [ SHADERPARM_BLUE ] = color [ 2 ] ;
//material
materialName = newTrailDef - > GetString ( " mtr_surface " , " " ) ;
material = declManager - > FindMaterial ( materialName ) ;
//remember the new trail def
trailDef = newTrailDef ;
trailDefName = newTrailDefName ;
//state
enabled = true ; //weapon will upd the position
fading = false ;
modelChanged = true ; //upd renderer
UpdateVisuals ( ) ; //make sure it's in the world and updated
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : FadeTrail
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : FadeTrail ( void ) {
idVec3 colorNow ;
if ( fadingTime < = 0 ) {
StopTrail ( ) ;
return ;
}
//color
colorNow [ 0 ] = renderEntity . shaderParms [ SHADERPARM_RED ] ;
colorNow [ 1 ] = renderEntity . shaderParms [ SHADERPARM_GREEN ] ;
colorNow [ 2 ] = renderEntity . shaderParms [ SHADERPARM_BLUE ] ;
//color step for each frame
fadingColorStep = ( vec3_zero - colorNow ) * USERCMD_MSEC / fadingTime ;
//time
fadingEndTime = gameLocal . time + fadingTime ;
//state
enabled = true ; //weapon will upd the position
fading = true ;
UpdateVisuals ( ) ; //make sure it's in the world and updated
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : StopTrail
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : StopTrail ( void ) {
if ( ! enabled ) return ;
//remove points
points . Clear ( ) ;
//state
enabled = false ;
fading = false ;
modelChanged = true ; //upd renderer
FreeEntityDef ( ) ; //remove from world
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : AddNewPoints
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : AddNewPoints ( const idVec3 & newPosL , const idVec3 & newPosH ) {
if ( ! enabled ) {
gameLocal . Warning ( " Cannot add points to a disabled trail! " ) ;
return ;
}
/*
//NOTE: this is commented out because we assume that sword is moving while trail is active.
if ( points . Num ( ) > = 2 ) {
if ( points [ 0 ] . Compare ( newPosL ) & & points [ 1 ] . Compare ( newPosH ) ) {
return ; //if points did not change don't upd anything
}
}
*/
//remove oldest points
while ( points . Num ( ) > = maxPoints ) { //example: maxPoints 6 and we have 6 -> remove 2 so we can add the new ones
points . RemoveIndex ( 0 ) ;
points . RemoveIndex ( 0 ) ;
}
points . Append ( newPosL ) ;
points . Append ( newPosH ) ;
modelChanged = true ; //upd renderer
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : RemoveOldestPoints
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : RemoveOldestPoints ( void ) {
if ( ! enabled ) {
gameLocal . Warning ( " Cannot remove points to a disabled trail! " ) ;
return ;
}
/*
//NOTE: this is commented out because we assume that sword is moving while trail is active.
if ( points . Num ( ) > = 2 ) {
if ( points [ 0 ] . Compare ( newPosL ) & & points [ 1 ] . Compare ( newPosH ) ) {
return ; //if points did not change don't upd anything
}
}
*/
//remove oldest points
if ( points . Num ( ) > = 2 ) {
points . RemoveIndex ( 0 ) ;
points . RemoveIndex ( 0 ) ;
modelChanged = true ; //upd renderer
}
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : UpdateRenderEntity
= = = = = = = = = = = = = = = =
*/
bool idTrailGenerator : : UpdateRenderEntity ( renderEntity_s * renderEntity , const renderView_t * renderView ) const {
int i , j , numTris , numPoints ;
float fitpct , fitoffset ;
srfTriangles_t * tris ;
modelSurface_t surface ;
idDrawVert * v ;
idPlane plane ;
idMat3 tangents ;
idFixedWinding winding ; //TODO: this is big...promote it to class member to save perf?
// this may be triggered by a model trace or other non-view related source,
// to which we should look like an empty model
if ( ! renderView ) {
return false ;
}
// regenerate only if modelChanged. Only one per frame.
//was: if ( !modelChanged || lastRenderEntityUpdate == gameLocal.time ) {
if ( lastRenderEntityUpdate = = gameLocal . time ) { //moved the "modelChanged" check in callback to save perf.
return false ;
}
lastRenderEntityUpdate = gameLocal . time ;
modelChanged = false ;
//gameLocal.Printf("UpdateRenderEntity at time: %d\n", lastRenderEntityUpdate);
//we need at least 4 points + even number
numPoints = points . Num ( ) ;
if ( numPoints < 4 ) { //|| (numPoints % 2 != 0) //number is always even thanks to creation policy.
//clean the model and return.
renderEntity - > hModel - > InitEmpty ( trailGenerator_SnapshotName ) ;
return true ;
}
//calculate number of tris and materialOffset-per-coupleOfTris pct
numTris = numPoints - 2 ; //examples: 4p -> 2t, 6p -> 4t, 8p ->6t
fitpct = 1.0f / ( numTris / 2.0f ) ; // numTris/2 is the number of steps. 4p -> 2t -> 1step, 6p -> 4t -> 2steps, 8p ->6t -> 3steps
// FIXME: re-use model surfaces? <-- we cannot do that: we would need to remove the oldest piece and shift the texture.
renderEntity - > hModel - > InitEmpty ( trailGenerator_SnapshotName ) ;
# ifdef _DEBUG_CUSTOM_GEOM
//debug
idBounds bbox ;
bbox . Zero ( ) ;
bbox . ExpandSelf ( 1 ) ;
idVec4 color ;
color [ 3 ] = 1 ; //alpha
for ( i = 0 ; i < numPoints ; i + + ) {
if ( i % 2 = = 0 ) {
color [ 0 ] = gameLocal . random . RandomFloat ( ) ;
color [ 1 ] = gameLocal . random . RandomFloat ( ) ;
color [ 2 ] = gameLocal . random . RandomFloat ( ) ;
}
gameRenderWorld - > DebugBounds ( color , bbox , points [ i ] , 20000 ) ;
}
# endif
// allocate triangle surfaces for the fractures and decals
tris = renderEntity - > hModel - > AllocSurfaceTriangles ( numTris * 3 , material - > ShouldCreateBackSides ( ) ? numTris * 6 : numTris * 3 ) ;
//packedColor = PackColor( idVec4( 1,1,1,1 ) );
/*
gameLocal . Printf ( " color found: %f, %f, %f \n " , renderEntity - > shaderParms [ SHADERPARM_RED ] , renderEntity - > shaderParms [ SHADERPARM_GREEN ] , renderEntity - > shaderParms [ SHADERPARM_BLUE ] ) ;
if ( & ( this - > renderEntity ) = = renderEntity ) {
gameLocal . Printf ( " Stesso renderEntity! \n " ) ;
}
*/
//gameLocal.Printf("iteration starts...\n ");
fitoffset = 1.0f ;
for ( i = 0 ; i < ( numPoints - 3 ) ; i + = 2 ) {
//gameLocal.Printf(",%d",i);
//re-use the same winding every time
winding . Clear ( ) ;
//points closer to the sword
winding . AddPoint ( idVec5 ( points [ i ] , idVec2 ( 0 , fitoffset ) ) ) ; //Lower point
winding . AddPoint ( idVec5 ( points [ i + 1 ] , idVec2 ( 1 , fitoffset ) ) ) ; //Higher point
//gameLocal.Printf("fitoffset: %f, fitoffset-fitpct: %f\n", fitoffset, (fitoffset-fitpct) );
fitoffset - = fitpct ; //decrease the texture offset so that the texture is correctly fit
if ( fitoffset < 0.0f ) { fitoffset = 0.0f ; } //solve approximation issues
//previous points
winding . AddPoint ( idVec5 ( points [ i + 3 ] , idVec2 ( 1 , fitoffset ) ) ) ; //Higher point
winding . AddPoint ( idVec5 ( points [ i + 2 ] , idVec2 ( 0 , fitoffset ) ) ) ; //Lower point
//get info from windings
winding . GetPlane ( plane ) ;
tangents = ( plane . Normal ( ) ) . ToMat3 ( ) ; //was: ( plane.Normal() * axis ).ToMat3();
//create tris given points in winding. Usually we have 4 points -> 2tris
for ( j = 2 ; j < winding . GetNumPoints ( ) ; j + + ) {
//first vertex is always placed at the first point
v = & tris - > verts [ tris - > numVerts + + ] ;
v - > Clear ( ) ;
v - > xyz = winding [ 0 ] . ToVec3 ( ) ;
v - > st [ 0 ] = winding [ 0 ] . s ;
v - > st [ 1 ] = winding [ 0 ] . t ;
v - > normal = tangents [ 0 ] ;
v - > tangents [ 0 ] = tangents [ 1 ] ;
v - > tangents [ 1 ] = tangents [ 2 ] ;
v - > SetColor ( trailGenerator_vertexColor ) ;
//second vertex
v = & tris - > verts [ tris - > numVerts + + ] ;
v - > Clear ( ) ;
v - > xyz = winding [ j - 1 ] . ToVec3 ( ) ;
v - > st [ 0 ] = winding [ j - 1 ] . s ;
v - > st [ 1 ] = winding [ j - 1 ] . t ;
v - > normal = tangents [ 0 ] ;
v - > tangents [ 0 ] = tangents [ 1 ] ;
v - > tangents [ 1 ] = tangents [ 2 ] ;
v - > SetColor ( trailGenerator_vertexColor ) ;
//third vertex
v = & tris - > verts [ tris - > numVerts + + ] ;
v - > Clear ( ) ;
v - > xyz = winding [ j ] . ToVec3 ( ) ;
v - > st [ 0 ] = winding [ j ] . s ;
v - > st [ 1 ] = winding [ j ] . t ;
v - > normal = tangents [ 0 ] ;
v - > tangents [ 0 ] = tangents [ 1 ] ;
v - > tangents [ 1 ] = tangents [ 2 ] ;
v - > SetColor ( trailGenerator_vertexColor ) ;
//set the index for each tris
tris - > indexes [ tris - > numIndexes + + ] = tris - > numVerts - 3 ;
tris - > indexes [ tris - > numIndexes + + ] = tris - > numVerts - 2 ;
tris - > indexes [ tris - > numIndexes + + ] = tris - > numVerts - 1 ;
if ( material - > ShouldCreateBackSides ( ) ) {
tris - > indexes [ tris - > numIndexes + + ] = tris - > numVerts - 2 ;
tris - > indexes [ tris - > numIndexes + + ] = tris - > numVerts - 3 ;
tris - > indexes [ tris - > numIndexes + + ] = tris - > numVerts - 1 ;
}
}
}
tris - > tangentsCalculated = true ;
SIMDProcessor - > MinMax ( tris - > bounds [ 0 ] , tris - > bounds [ 1 ] , tris - > verts , tris - > numVerts ) ;
memset ( & surface , 0 , sizeof ( surface ) ) ;
surface . shader = material ;
surface . id = 0 ;
surface . geometry = tris ;
renderEntity - > hModel - > AddSurface ( surface ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : ModelCallback
= = = = = = = = = = = = = = = =
*/
bool idTrailGenerator : : ModelCallback ( renderEntity_s * renderEntity , const renderView_t * renderView ) {
//gameLocal.Printf("idTrailGenerator::ModelCallback\n");
const idTrailGenerator * trailGen ;
trailGen = gameLocal . trailsManager - > trails [ renderEntity - > entityNum ] ;
if ( ! trailGen ) {
gameLocal . Error ( " idTrailGenerator::ModelCallback: callback with NULL trailGen " ) ;
}
if ( ! trailGen - > modelChanged ) {
return false ;
}
return trailGen - > UpdateRenderEntity ( renderEntity , renderView ) ;
}
/*
= = = = = = = = = = = = = = = =
idTrailGenerator : : Think
= = = = = = = = = = = = = = = =
*/
void idTrailGenerator : : Fade ( void ) { //TrailGenerator thinks before all the other entities.
//gameLocal.Printf("idTrailGenerator::Fade\n");
//if ( fading ) {
if ( fadingEndTime > gameLocal . time ) {
//gameLocal.Printf("fading...\n");
renderEntity . shaderParms [ SHADERPARM_RED ] + = fadingColorStep [ 0 ] ;
renderEntity . shaderParms [ SHADERPARM_GREEN ] + = fadingColorStep [ 1 ] ;
renderEntity . shaderParms [ SHADERPARM_BLUE ] + = fadingColorStep [ 2 ] ;
UpdateVisuals ( ) ; //make sure it's in the world and updated
} else {
StopTrail ( ) ;
}
//}
2018-08-27 13:13:36 +00:00
}