You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
603 lines
18 KiB
603 lines
18 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "clienteffectprecachesystem.h" |
|
#include "fx_sparks.h" |
|
#include "iefx.h" |
|
#include "c_te_effect_dispatch.h" |
|
#include "particles_ez.h" |
|
#include "decals.h" |
|
#include "engine/IEngineSound.h" |
|
#include "fx_quad.h" |
|
#include "tier0/vprof.h" |
|
#include "fx.h" |
|
#include "fx_water.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectSplash ) |
|
CLIENTEFFECT_MATERIAL( "effects/splash1" ) |
|
CLIENTEFFECT_MATERIAL( "effects/splash2" ) |
|
CLIENTEFFECT_MATERIAL( "effects/splash4" ) |
|
CLIENTEFFECT_MATERIAL( "effects/slime1" ) |
|
CLIENTEFFECT_REGISTER_END() |
|
|
|
|
|
#define SPLASH_MIN_SPEED 50.0f |
|
#define SPLASH_MAX_SPEED 100.0f |
|
|
|
ConVar cl_show_splashes( "cl_show_splashes", "1" ); |
|
|
|
static Vector s_vecSlimeColor( 46.0f/255.0f, 90.0f/255.0f, 36.0f/255.0f ); |
|
|
|
// Each channel does not contribute to the luminosity equally, as represented here |
|
#define RED_CHANNEL_CONTRIBUTION 0.30f |
|
#define GREEN_CHANNEL_CONTRIBUTION 0.59f |
|
#define BLUE_CHANNEL_CONTRIBUTION 0.11f |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Returns a normalized tint and luminosity for a specified color |
|
// Input : &color - normalized input color to extract information from |
|
// *tint - normalized tint of that color |
|
// *luminosity - normalized luminosity of that color |
|
//----------------------------------------------------------------------------- |
|
void UTIL_GetNormalizedColorTintAndLuminosity( const Vector &color, Vector *tint, float *luminosity ) |
|
{ |
|
// Give luminosity if requested |
|
if ( luminosity != NULL ) |
|
{ |
|
// Each channel contributes differently than the others |
|
*luminosity = ( color.x * RED_CHANNEL_CONTRIBUTION ) + |
|
( color.y * GREEN_CHANNEL_CONTRIBUTION ) + |
|
( color.z * BLUE_CHANNEL_CONTRIBUTION ); |
|
} |
|
|
|
// Give tint if requested |
|
if ( tint != NULL ) |
|
{ |
|
if ( color == vec3_origin ) |
|
{ |
|
*tint = vec3_origin; |
|
} |
|
else |
|
{ |
|
float maxComponent = MAX( color.x, MAX( color.y, color.z ) ); |
|
*tint = color / maxComponent; |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &origin - |
|
// &normal - |
|
// scale - |
|
//----------------------------------------------------------------------------- |
|
void FX_WaterRipple( const Vector &origin, float scale, Vector *pColor, float flLifetime, float flAlpha ) |
|
{ |
|
VPROF_BUDGET( "FX_WaterRipple", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); |
|
trace_t tr; |
|
|
|
Vector color = pColor ? *pColor : Vector( 0.8f, 0.8f, 0.75f ); |
|
|
|
Vector startPos = origin + Vector(0,0,8); |
|
Vector endPos = origin + Vector(0,0,-64); |
|
|
|
UTIL_TraceLine( startPos, endPos, MASK_WATER, NULL, COLLISION_GROUP_NONE, &tr ); |
|
|
|
if ( tr.fraction < 1.0f ) |
|
{ |
|
//Add a ripple quad to the surface |
|
FX_AddQuad( tr.endpos + ( tr.plane.normal * 0.5f ), |
|
tr.plane.normal, |
|
16.0f*scale, |
|
128.0f*scale, |
|
0.7f, |
|
flAlpha, // start alpha |
|
0.0f, // end alpha |
|
0.25f, |
|
random->RandomFloat( 0, 360 ), |
|
random->RandomFloat( -16.0f, 16.0f ), |
|
color, |
|
flLifetime, |
|
"effects/splashwake1", |
|
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &origin - |
|
// &normal - |
|
//----------------------------------------------------------------------------- |
|
void FX_GunshotSplash( const Vector &origin, const Vector &normal, float scale ) |
|
{ |
|
VPROF_BUDGET( "FX_GunshotSplash", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); |
|
|
|
if ( cl_show_splashes.GetBool() == false ) |
|
return; |
|
|
|
Vector color; |
|
float luminosity; |
|
|
|
// Get our lighting information |
|
FX_GetSplashLighting( origin + ( normal * scale ), &color, &luminosity ); |
|
|
|
float flScale = scale / 8.0f; |
|
|
|
if ( flScale > 4.0f ) |
|
{ |
|
flScale = 4.0f; |
|
} |
|
|
|
// Setup our trail emitter |
|
CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "splash" ); |
|
|
|
if ( !sparkEmitter ) |
|
return; |
|
|
|
sparkEmitter->SetSortOrigin( origin ); |
|
sparkEmitter->m_ParticleCollision.SetGravity( 800.0f ); |
|
sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); |
|
sparkEmitter->SetVelocityDampen( 2.0f ); |
|
sparkEmitter->GetBinding().SetBBox( origin - Vector( 32, 32, 32 ), origin + Vector( 32, 32, 32 ) ); |
|
|
|
PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/splash2" ); |
|
|
|
TrailParticle *tParticle; |
|
|
|
Vector offDir; |
|
Vector offset; |
|
float colorRamp; |
|
|
|
//Dump out drops |
|
for ( int i = 0; i < 16; i++ ) |
|
{ |
|
offset = origin; |
|
offset[0] += random->RandomFloat( -8.0f, 8.0f ) * flScale; |
|
offset[1] += random->RandomFloat( -8.0f, 8.0f ) * flScale; |
|
|
|
tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset ); |
|
|
|
if ( tParticle == NULL ) |
|
break; |
|
|
|
tParticle->m_flLifetime = 0.0f; |
|
tParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); |
|
|
|
offDir = normal + RandomVector( -0.8f, 0.8f ); |
|
|
|
tParticle->m_vecVelocity = offDir * random->RandomFloat( SPLASH_MIN_SPEED * flScale * 3.0f, SPLASH_MAX_SPEED * flScale * 3.0f ); |
|
tParticle->m_vecVelocity[2] += random->RandomFloat( 32.0f, 64.0f ) * flScale; |
|
|
|
tParticle->m_flWidth = random->RandomFloat( 1.0f, 3.0f ); |
|
tParticle->m_flLength = random->RandomFloat( 0.025f, 0.05f ); |
|
|
|
colorRamp = random->RandomFloat( 0.75f, 1.25f ); |
|
|
|
tParticle->m_color.r = MIN( 1.0f, color[0] * colorRamp ) * 255; |
|
tParticle->m_color.g = MIN( 1.0f, color[1] * colorRamp ) * 255; |
|
tParticle->m_color.b = MIN( 1.0f, color[2] * colorRamp ) * 255; |
|
tParticle->m_color.a = luminosity * 255; |
|
} |
|
|
|
// Setup the particle emitter |
|
CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" ); |
|
pSimple->SetSortOrigin( origin ); |
|
pSimple->SetClipHeight( origin.z ); |
|
pSimple->SetParticleCullRadius( scale * 2.0f ); |
|
pSimple->GetBinding().SetBBox( origin - Vector( 32, 32, 32 ), origin + Vector( 32, 32, 32 ) ); |
|
|
|
SimpleParticle *pParticle; |
|
|
|
//Main gout |
|
for ( int i = 0; i < 8; i++ ) |
|
{ |
|
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, origin ); |
|
|
|
if ( pParticle == NULL ) |
|
break; |
|
|
|
pParticle->m_flLifetime = 0.0f; |
|
pParticle->m_flDieTime = 2.0f; //NOTENOTE: We use a clip plane to realistically control our lifespan |
|
|
|
pParticle->m_vecVelocity.Random( -0.2f, 0.2f ); |
|
pParticle->m_vecVelocity += ( normal * random->RandomFloat( 4.0f, 6.0f ) ); |
|
|
|
VectorNormalize( pParticle->m_vecVelocity ); |
|
|
|
pParticle->m_vecVelocity *= 50 * flScale * (8-i); |
|
|
|
colorRamp = random->RandomFloat( 0.75f, 1.25f ); |
|
|
|
pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; |
|
pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; |
|
pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; |
|
|
|
pParticle->m_uchStartSize = 24 * flScale * RemapValClamped( i, 7, 0, 1, 0.5f ); |
|
pParticle->m_uchEndSize = MIN( 255, pParticle->m_uchStartSize * 2 ); |
|
|
|
pParticle->m_uchStartAlpha = RemapValClamped( i, 7, 0, 255, 32 ) * luminosity; |
|
pParticle->m_uchEndAlpha = 0; |
|
|
|
pParticle->m_flRoll = random->RandomInt( 0, 360 ); |
|
pParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f ); |
|
} |
|
|
|
// Do a ripple |
|
FX_WaterRipple( origin, flScale, &color, 1.5f, luminosity ); |
|
|
|
//Play a sound |
|
CLocalPlayerFilter filter; |
|
|
|
EmitSound_t ep; |
|
ep.m_nChannel = CHAN_VOICE; |
|
ep.m_pSoundName = "Physics.WaterSplash"; |
|
ep.m_flVolume = 1.0f; |
|
ep.m_SoundLevel = SNDLVL_NORM; |
|
ep.m_pOrigin = &origin; |
|
|
|
|
|
C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, ep ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &origin - |
|
// &normal - |
|
// scale - |
|
// *pColor - |
|
//----------------------------------------------------------------------------- |
|
void FX_GunshotSlimeSplash( const Vector &origin, const Vector &normal, float scale ) |
|
{ |
|
if ( cl_show_splashes.GetBool() == false ) |
|
return; |
|
|
|
VPROF_BUDGET( "FX_GunshotSlimeSplash", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); |
|
|
|
#if 0 |
|
|
|
float colorRamp; |
|
float flScale = MIN( 1.0f, scale / 8.0f ); |
|
|
|
PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/slime1" ); |
|
PMaterialHandle hMaterial2 = ParticleMgr()->GetPMaterial( "effects/splash4" ); |
|
|
|
Vector color; |
|
float luminosity; |
|
|
|
// Get our lighting information |
|
FX_GetSplashLighting( origin + ( normal * scale ), &color, &luminosity ); |
|
|
|
Vector offDir; |
|
Vector offset; |
|
|
|
TrailParticle *tParticle; |
|
|
|
CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "splash" ); |
|
|
|
if ( !sparkEmitter ) |
|
return; |
|
|
|
sparkEmitter->SetSortOrigin( origin ); |
|
sparkEmitter->m_ParticleCollision.SetGravity( 800.0f ); |
|
sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); |
|
sparkEmitter->SetVelocityDampen( 2.0f ); |
|
if ( IsXbox() ) |
|
{ |
|
sparkEmitter->GetBinding().SetBBox( origin - Vector( 32, 32, 64 ), origin + Vector( 32, 32, 64 ) ); |
|
} |
|
|
|
//Dump out drops |
|
for ( int i = 0; i < 24; i++ ) |
|
{ |
|
offset = origin; |
|
offset[0] += random->RandomFloat( -16.0f, 16.0f ) * flScale; |
|
offset[1] += random->RandomFloat( -16.0f, 16.0f ) * flScale; |
|
|
|
tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset ); |
|
|
|
if ( tParticle == NULL ) |
|
break; |
|
|
|
tParticle->m_flLifetime = 0.0f; |
|
tParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); |
|
|
|
offDir = normal + RandomVector( -0.6f, 0.6f ); |
|
|
|
tParticle->m_vecVelocity = offDir * random->RandomFloat( SPLASH_MIN_SPEED * flScale * 3.0f, SPLASH_MAX_SPEED * flScale * 3.0f ); |
|
tParticle->m_vecVelocity[2] += random->RandomFloat( 32.0f, 64.0f ) * flScale; |
|
|
|
tParticle->m_flWidth = random->RandomFloat( 3.0f, 6.0f ) * flScale; |
|
tParticle->m_flLength = random->RandomFloat( 0.025f, 0.05f ) * flScale; |
|
|
|
colorRamp = random->RandomFloat( 0.75f, 1.25f ); |
|
|
|
tParticle->m_color.r = MIN( 1.0f, color.x * colorRamp ) * 255; |
|
tParticle->m_color.g = MIN( 1.0f, color.y * colorRamp ) * 255; |
|
tParticle->m_color.b = MIN( 1.0f, color.z * colorRamp ) * 255; |
|
tParticle->m_color.a = 255 * luminosity; |
|
} |
|
|
|
// Setup splash emitter |
|
CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" ); |
|
pSimple->SetSortOrigin( origin ); |
|
pSimple->SetClipHeight( origin.z ); |
|
pSimple->SetParticleCullRadius( scale * 2.0f ); |
|
|
|
if ( IsXbox() ) |
|
{ |
|
pSimple->GetBinding().SetBBox( origin - Vector( 32, 32, 64 ), origin + Vector( 32, 32, 64 ) ); |
|
} |
|
|
|
SimpleParticle *pParticle; |
|
|
|
// Tint |
|
colorRamp = random->RandomFloat( 0.75f, 1.0f ); |
|
color = Vector( 1.0f, 0.8f, 0.0f ) * color * colorRamp; |
|
|
|
//Main gout |
|
for ( int i = 0; i < 8; i++ ) |
|
{ |
|
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial2, origin ); |
|
|
|
if ( pParticle == NULL ) |
|
break; |
|
|
|
pParticle->m_flLifetime = 0.0f; |
|
pParticle->m_flDieTime = 2.0f; //NOTENOTE: We use a clip plane to realistically control our lifespan |
|
|
|
pParticle->m_vecVelocity.Random( -0.2f, 0.2f ); |
|
pParticle->m_vecVelocity += ( normal * random->RandomFloat( 4.0f, 6.0f ) ); |
|
|
|
VectorNormalize( pParticle->m_vecVelocity ); |
|
|
|
pParticle->m_vecVelocity *= 50 * flScale * (8-i); |
|
|
|
colorRamp = random->RandomFloat( 0.75f, 1.25f ); |
|
|
|
pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; |
|
pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; |
|
pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; |
|
|
|
pParticle->m_uchStartSize = 24 * flScale * RemapValClamped( i, 7, 0, 1, 0.5f ); |
|
pParticle->m_uchEndSize = MIN( 255, pParticle->m_uchStartSize * 2 ); |
|
|
|
pParticle->m_uchStartAlpha = RemapValClamped( i, 7, 0, 255, 32 ) * luminosity; |
|
pParticle->m_uchEndAlpha = 0; |
|
|
|
pParticle->m_flRoll = random->RandomInt( 0, 360 ); |
|
pParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f ); |
|
} |
|
|
|
#else |
|
|
|
QAngle vecAngles; |
|
VectorAngles( normal, vecAngles ); |
|
if ( scale < 2.0f ) |
|
{ |
|
DispatchParticleEffect( "slime_splash_01", origin, vecAngles ); |
|
} |
|
else if ( scale < 4.0f ) |
|
{ |
|
DispatchParticleEffect( "slime_splash_02", origin, vecAngles ); |
|
} |
|
else |
|
{ |
|
DispatchParticleEffect( "slime_splash_03", origin, vecAngles ); |
|
} |
|
|
|
#endif |
|
|
|
//Play a sound |
|
CLocalPlayerFilter filter; |
|
|
|
EmitSound_t ep; |
|
ep.m_nChannel = CHAN_VOICE; |
|
ep.m_pSoundName = "Physics.WaterSplash"; |
|
ep.m_flVolume = 1.0f; |
|
ep.m_SoundLevel = SNDLVL_NORM; |
|
ep.m_pOrigin = &origin; |
|
|
|
C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, ep ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void SplashCallback( const CEffectData &data ) |
|
{ |
|
Vector normal; |
|
|
|
AngleVectors( data.m_vAngles, &normal ); |
|
|
|
if ( data.m_fFlags & FX_WATER_IN_SLIME ) |
|
{ |
|
FX_GunshotSlimeSplash( data.m_vOrigin, Vector(0,0,1), data.m_flScale ); |
|
} |
|
else |
|
{ |
|
FX_GunshotSplash( data.m_vOrigin, Vector(0,0,1), data.m_flScale ); |
|
} |
|
} |
|
|
|
DECLARE_CLIENT_EFFECT( "watersplash", SplashCallback ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &data - |
|
//----------------------------------------------------------------------------- |
|
void GunshotSplashCallback( const CEffectData &data ) |
|
{ |
|
if ( data.m_fFlags & FX_WATER_IN_SLIME ) |
|
{ |
|
FX_GunshotSlimeSplash( data.m_vOrigin, Vector(0,0,1), data.m_flScale ); |
|
} |
|
else |
|
{ |
|
FX_GunshotSplash( data.m_vOrigin, Vector(0,0,1), data.m_flScale ); |
|
} |
|
} |
|
|
|
DECLARE_CLIENT_EFFECT( "gunshotsplash", GunshotSplashCallback ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &data - |
|
//----------------------------------------------------------------------------- |
|
void RippleCallback( const CEffectData &data ) |
|
{ |
|
float flScale = data.m_flScale / 8.0f; |
|
|
|
Vector color; |
|
float luminosity; |
|
|
|
// Get our lighting information |
|
FX_GetSplashLighting( data.m_vOrigin + ( Vector(0,0,1) * 4.0f ), &color, &luminosity ); |
|
|
|
FX_WaterRipple( data.m_vOrigin, flScale, &color, 1.5f, luminosity ); |
|
} |
|
|
|
DECLARE_CLIENT_EFFECT( "waterripple", RippleCallback ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pDebugName - |
|
// Output : WaterDebrisEffect* |
|
//----------------------------------------------------------------------------- |
|
WaterDebrisEffect* WaterDebrisEffect::Create( const char *pDebugName ) |
|
{ |
|
return new WaterDebrisEffect( pDebugName ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pParticle - |
|
// timeDelta - |
|
// Output : float |
|
//----------------------------------------------------------------------------- |
|
float WaterDebrisEffect::UpdateAlpha( const SimpleParticle *pParticle ) |
|
{ |
|
return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pParticle - |
|
// timeDelta - |
|
// Output : float |
|
//----------------------------------------------------------------------------- |
|
float CSplashParticle::UpdateRoll( SimpleParticle *pParticle, float timeDelta ) |
|
{ |
|
pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta; |
|
|
|
pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -4.0f ); |
|
|
|
//Cap the minimum roll |
|
if ( fabs( pParticle->m_flRollDelta ) < 0.5f ) |
|
{ |
|
pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.5f : -0.5f; |
|
} |
|
|
|
return pParticle->m_flRoll; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pParticle - |
|
// timeDelta - |
|
//----------------------------------------------------------------------------- |
|
void CSplashParticle::UpdateVelocity( SimpleParticle *pParticle, float timeDelta ) |
|
{ |
|
//Decellerate |
|
static float dtime; |
|
static float decay; |
|
|
|
if ( dtime != timeDelta ) |
|
{ |
|
dtime = timeDelta; |
|
float expected = 3.0f; |
|
decay = exp( log( 0.0001f ) * dtime / expected ); |
|
} |
|
|
|
pParticle->m_vecVelocity *= decay; |
|
pParticle->m_vecVelocity[2] -= ( 800.0f * timeDelta ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pParticle - |
|
// Output : float |
|
//----------------------------------------------------------------------------- |
|
float CSplashParticle::UpdateAlpha( const SimpleParticle *pParticle ) |
|
{ |
|
if ( m_bUseClipHeight ) |
|
{ |
|
float flAlpha = pParticle->m_uchStartAlpha / 255.0f; |
|
|
|
return flAlpha * RemapValClamped(pParticle->m_Pos.z, |
|
m_flClipHeight, |
|
m_flClipHeight - ( UpdateScale( pParticle ) * 0.5f ), |
|
1.0f, |
|
0.0f ); |
|
} |
|
|
|
return (pParticle->m_uchStartAlpha/255.0f) + ( (float)(pParticle->m_uchEndAlpha/255.0f) - (float)(pParticle->m_uchStartAlpha/255.0f) ) * (pParticle->m_flLifetime / pParticle->m_flDieTime); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &clipPlane - |
|
//----------------------------------------------------------------------------- |
|
void CSplashParticle::SetClipHeight( float flClipHeight ) |
|
{ |
|
m_bUseClipHeight = true; |
|
m_flClipHeight = flClipHeight; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pIterator - |
|
//----------------------------------------------------------------------------- |
|
void CSplashParticle::SimulateParticles( CParticleSimulateIterator *pIterator ) |
|
{ |
|
float timeDelta = pIterator->GetTimeDelta(); |
|
|
|
SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst(); |
|
|
|
while ( pParticle ) |
|
{ |
|
//Update velocity |
|
UpdateVelocity( pParticle, timeDelta ); |
|
pParticle->m_Pos += pParticle->m_vecVelocity * timeDelta; |
|
|
|
// Clip by height if requested |
|
if ( m_bUseClipHeight ) |
|
{ |
|
// See if we're below, and therefore need to clip |
|
if ( pParticle->m_Pos.z + UpdateScale( pParticle ) < m_flClipHeight ) |
|
{ |
|
pIterator->RemoveParticle( pParticle ); |
|
pParticle = (SimpleParticle*)pIterator->GetNext(); |
|
continue; |
|
} |
|
} |
|
|
|
//Should this particle die? |
|
pParticle->m_flLifetime += timeDelta; |
|
UpdateRoll( pParticle, timeDelta ); |
|
|
|
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime ) |
|
pIterator->RemoveParticle( pParticle ); |
|
|
|
pParticle = (SimpleParticle*)pIterator->GetNext(); |
|
} |
|
}
|
|
|