sqwarmed/sdk_src/game/client/c_te_particlesystem.cpp

283 lines
7.0 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "c_te_particlesystem.h"
#include "movevars_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
int ramp1[][3] =
{
{ 255, 243, 227 },
{ 223, 171, 39 },
{ 191, 119, 47 },
{ 127, 59, 43 },
{ 99, 47, 31 },
{ 75, 35, 19 },
{ 47, 23, 11 },
{ 175, 103, 35 },
};
int ramp2[][3] =
{
{ 255, 243, 227 },
{ 239, 203, 31 },
{ 223, 171, 39 },
{ 207, 143, 43 },
{ 191, 119, 47 },
{ 175, 99, 47 },
{ 143, 67, 51 },
{ 115, 55, 35 },
};
int ramp3[][3] =
{
{ 223, 171, 39 },
{ 191, 119, 47 },
{ 91, 91, 91 },
{ 75, 75, 75 },
{ 63, 63, 63 },
{ 47, 47, 47 },
};
#define SPARK_COLORCOUNT 9
int gSparkRamp[ SPARK_COLORCOUNT ][3] =
{
{ 255, 255, 255 },
{ 255, 247, 199 },
{ 255, 243, 147 },
{ 255, 243, 27 },
{ 239, 203, 31 },
{ 223, 171, 39 },
{ 207, 143, 43 },
{ 127, 59, 43 },
{ 35, 19, 7 }
};
// ------------------------------------------------------------------------ //
// C_TEParticleSystem.
// ------------------------------------------------------------------------ //
IMPLEMENT_CLIENTCLASS_DT(C_TEParticleSystem, DT_TEParticleSystem, CTEParticleSystem)
RecvPropFloat( RECVINFO(m_vecOrigin[0]) ),
RecvPropFloat( RECVINFO(m_vecOrigin[1]) ),
RecvPropFloat( RECVINFO(m_vecOrigin[2]) ),
END_RECV_TABLE()
C_TEParticleSystem::C_TEParticleSystem()
{
m_vecOrigin.Init();
}
// ------------------------------------------------------------------------ //
// CTEParticleRenderer implementation.
// ------------------------------------------------------------------------ //
CTEParticleRenderer::CTEParticleRenderer( const char *pDebugName ) :
CParticleEffect( pDebugName )
{
m_ParticleSize = 1.5f;
m_MaterialHandle = INVALID_MATERIAL_HANDLE;
}
CTEParticleRenderer::~CTEParticleRenderer()
{
}
CSmartPtr<CTEParticleRenderer> CTEParticleRenderer::Create( const char *pDebugName, const Vector &vOrigin )
{
CTEParticleRenderer *pRet = new CTEParticleRenderer( pDebugName );
if( pRet )
{
pRet->SetDynamicallyAllocated( true );
pRet->SetSortOrigin( vOrigin );
}
return pRet;
}
StandardParticle_t* CTEParticleRenderer::AddParticle()
{
if(m_MaterialHandle == INVALID_MATERIAL_HANDLE)
{
m_MaterialHandle = m_ParticleEffect.FindOrAddMaterial("particle/particledefault");
}
StandardParticle_t *pParticle =
(StandardParticle_t*)BaseClass::AddParticle( sizeof(StandardParticle_t), m_MaterialHandle, m_vSortOrigin );
if(pParticle)
pParticle->m_EffectDataWord = 0; // (ramp)
return pParticle;
}
void CTEParticleRenderer::RenderParticles( CParticleRenderIterator *pIterator )
{
const StandardParticle_t *pParticle = (const StandardParticle_t*)pIterator->GetFirst();
while ( pParticle )
{
// Render.
Vector tPos;
TransformParticle(ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos);
float sortKey = tPos.z;
Vector vColor(pParticle->m_Color[0]/255.9f, pParticle->m_Color[1]/255.9f, pParticle->m_Color[2]/255.9f);
RenderParticle_ColorSize(
pIterator->GetParticleDraw(),
tPos,
vColor,
pParticle->m_Color[3]/255.9f,
m_ParticleSize);
pParticle = (const StandardParticle_t*)pIterator->GetNext( sortKey );
}
}
void CTEParticleRenderer::SimulateParticles( CParticleSimulateIterator *pIterator )
{
StandardParticle_t *pParticle = (StandardParticle_t*)pIterator->GetFirst();
while ( pParticle )
{
// Remove the particle?
SetParticleLifetime(pParticle, GetParticleLifetime(pParticle) - pIterator->GetTimeDelta());
if(GetParticleLifetime(pParticle) < 0)
{
pIterator->RemoveParticle( pParticle );
}
else
{
float ft = pIterator->GetTimeDelta();
float time3 = 15.0 * ft;
float time2 = 10.0 * ft;
float time1 = 5.0 * ft;
float dvel = 4* ft ;
float grav = ft * sv_gravity.GetFloat() * 0.05f;
int (*colorIndex)[3];
int iRamp;
switch(GetParticleType(pParticle))
{
case pt_static:
break;
case pt_fire:
pParticle->m_EffectDataWord += (unsigned short)(time1 * (1 << SIMSHIFT));
iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
if(iRamp >= 6)
{
pParticle->m_Lifetime = -1;
}
else
{
colorIndex = &ramp3[ iRamp ];
pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
}
pParticle->m_Velocity[2] += grav;
break;
case pt_explode:
pParticle->m_EffectDataWord += (unsigned short)(time2 * (1 << SIMSHIFT));
iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
if(iRamp >= 8)
{
pParticle->m_Lifetime = -1;
}
else
{
colorIndex = &ramp1[ iRamp ];
pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
}
pParticle->m_Velocity = pParticle->m_Velocity + pParticle->m_Velocity * dvel;
pParticle->m_Velocity[2] -= grav;
break;
case pt_explode2:
pParticle->m_EffectDataWord += (unsigned short)(time3 * (1 << SIMSHIFT));
iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
if(iRamp >= 8)
{
pParticle->m_Lifetime = -1;
}
else
{
colorIndex = &ramp2[ iRamp ];
pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
}
pParticle->m_Velocity = pParticle->m_Velocity - pParticle->m_Velocity * ft;
pParticle->m_Velocity[2] -= grav;
break;
case pt_grav:
pParticle->m_Velocity[2] -= grav * 20;
break;
case pt_slowgrav:
pParticle->m_Velocity[2] = grav;
break;
case pt_vox_grav:
pParticle->m_Velocity[2] -= grav * 8;
break;
case pt_vox_slowgrav:
pParticle->m_Velocity[2] -= grav * 4;
break;
case pt_blob:
case pt_blob2:
pParticle->m_EffectDataWord += (unsigned short)(time2 * (1 << SIMSHIFT));
iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
if(iRamp >= SPARK_COLORCOUNT)
{
pParticle->m_EffectDataWord = 0;
iRamp = 0;
}
colorIndex = &gSparkRamp[ iRamp ];
pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
pParticle->m_Velocity[0] -= pParticle->m_Velocity[0]*0.5*ft;
pParticle->m_Velocity[1] -= pParticle->m_Velocity[1]*0.5*ft;
pParticle->m_Velocity[2] -= grav * 5;
if ( random->RandomInt(0,3) )
{
SetParticleType(pParticle, pt_blob);
pParticle->SetAlpha(0);
}
else
{
SetParticleType(pParticle, pt_blob2);
pParticle->SetAlpha(255.9f);
}
break;
}
// Update position.
pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * ft;
}
pParticle = (StandardParticle_t*)pIterator->GetNext();
}
}