Counter Strike : Global Offensive Source Code
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.
|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "particle_prototype.h"
#include "particle_util.h"
#include "baseparticleentity.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// ------------------------------------------------------------------------- //
// Definitions
// ------------------------------------------------------------------------- //
#define NUM_MOVIEEXPLOSION_EMITTERS 50
#define EXPLOSION_EMITTER_LIFETIME 3
#define EMITTED_PARTICLE_LIFETIME 1
// ------------------------------------------------------------------------- //
// Classes
// ------------------------------------------------------------------------- //
class MovieExplosionEmitter { public: Vector m_Pos; Vector m_Velocity; float m_Lifetime; TimedEvent m_ParticleSpawn; };
class C_MovieExplosion : public C_BaseParticleEntity, public IPrototypeAppEffect { public: DECLARE_CLASS( C_MovieExplosion, C_BaseParticleEntity ); DECLARE_CLIENTCLASS();
C_MovieExplosion(); ~C_MovieExplosion();
// C_BaseEntity.
public: virtual void OnDataChanged(DataUpdateType_t updateType);
// IPrototypeAppEffect.
public: virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs);
// IParticleEffect.
public: virtual void Update(float fTimeDelta); virtual void RenderParticles( CParticleRenderIterator *pIterator ); virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
public: MovieExplosionEmitter m_Emitters[NUM_MOVIEEXPLOSION_EMITTERS]; float m_EmitterLifetime;
CParticleMgr *m_pParticleMgr; PMaterialHandle m_iFireballMaterial;
// Setup for temporary usage in SimulateAndRender.
float m_EmitterAlpha;
private: C_MovieExplosion( const C_MovieExplosion & );
};
// Expose to the particle app.
EXPOSE_PROTOTYPE_EFFECT(MovieExplosion, C_MovieExplosion);
IMPLEMENT_CLIENTCLASS_DT(C_MovieExplosion, DT_MovieExplosion, MovieExplosion) END_RECV_TABLE()
// ------------------------------------------------------------------------- //
// C_MovieExplosion
// ------------------------------------------------------------------------- //
C_MovieExplosion::C_MovieExplosion() { m_pParticleMgr = NULL; }
C_MovieExplosion::~C_MovieExplosion() { if(m_pParticleMgr) m_pParticleMgr->RemoveEffect( &m_ParticleEffect ); }
void C_MovieExplosion::OnDataChanged(DataUpdateType_t updateType) { C_BaseEntity::OnDataChanged(updateType);
if(updateType == DATA_UPDATE_CREATED) { Start( ParticleMgr(), NULL ); } }
void C_MovieExplosion::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs) { if(!pParticleMgr->AddEffect(&m_ParticleEffect, this)) return;
// Setup our emitters.
for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++) { MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter]; pEmitter->m_Velocity = RandomVector(-1, 1) * 200;
pEmitter->m_Pos = GetAbsOrigin(); pEmitter->m_Lifetime = 0; pEmitter->m_ParticleSpawn.Init(15); } m_EmitterLifetime = 0;
// Get our materials.
m_iFireballMaterial = m_ParticleEffect.FindOrAddMaterial("particle/particle_sphere");
m_pParticleMgr = pParticleMgr; }
void C_MovieExplosion::Update(float fTimeDelta) { if(!m_pParticleMgr) return;
m_EmitterLifetime += fTimeDelta; if(m_EmitterLifetime > EXPLOSION_EMITTER_LIFETIME) return;
m_EmitterAlpha = (float)sin(m_EmitterLifetime * 3.14159f / EXPLOSION_EMITTER_LIFETIME);
// Simulate the emitters and have them spit out particles.
for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++) { MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter];
pEmitter->m_Pos = pEmitter->m_Pos + pEmitter->m_Velocity * fTimeDelta; pEmitter->m_Velocity = pEmitter->m_Velocity * 0.9;
float tempDelta = fTimeDelta; while(pEmitter->m_ParticleSpawn.NextEvent(tempDelta)) { StandardParticle_t *pParticle = (StandardParticle_t*)m_ParticleEffect.AddParticle( sizeof(StandardParticle_t), m_iFireballMaterial);
if(pParticle) { pParticle->m_Pos = pEmitter->m_Pos; pParticle->m_Velocity = pEmitter->m_Velocity * 0.2f + RandomVector(-20, 20); } } } }
void C_MovieExplosion::RenderParticles( CParticleRenderIterator *pIterator ) { const StandardParticle_t *pParticle = (const StandardParticle_t*)pIterator->GetFirst(); while ( pParticle ) { // Draw.
Vector tPos; TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos); float sortKey = tPos.z;
float lifetimePercent = pParticle->m_Lifetime / EMITTED_PARTICLE_LIFETIME; Vector color; color.x = sin(lifetimePercent * 3.14159); color.y = color.x * 0.5f; color.z = 0; RenderParticle_ColorSize( pIterator->GetParticleDraw(), tPos, color, m_EmitterAlpha * sin(3.14159 * lifetimePercent), 10);
pParticle = (const StandardParticle_t*)pIterator->GetNext( sortKey ); } }
void C_MovieExplosion::SimulateParticles( CParticleSimulateIterator *pIterator ) { StandardParticle_t *pParticle = (StandardParticle_t*)pIterator->GetFirst(); while ( pParticle ) { // Update its lifetime.
pParticle->m_Lifetime += pIterator->GetTimeDelta(); if(pParticle->m_Lifetime > 1) { pIterator->RemoveParticle( pParticle ); } else { // Move it (this comes after rendering to make it clear that moving the particle here won't change
// its rendering for this frame since m_TransformedPos has already been set).
pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * pIterator->GetTimeDelta(); } pParticle = (StandardParticle_t*)pIterator->GetNext(); } }
|