//========= 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::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(); } }