1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef PARTICLES_SIMPLE_H
#define PARTICLES_SIMPLE_H
#ifdef _WIN32
#pragma once
#endif
#include "particlemgr.h"
#include "particlesphererenderer.h"
#include "smartptr.h"
// ------------------------------------------------------------------------------------------------ //
// CParticleEffect is the base class that you can derive from to make a particle effect.
// These can be used two ways:
//
// 1. Allocate a CParticleEffect-based object using the class's static Create() function. This gives
// you back a smart pointer that handles the reference counting for you.
//
// 2. Contain a CParticleEffect object in your class.
// ------------------------------------------------------------------------------------------------ //
class CParticleEffect : public IParticleEffect
{
public:
DECLARE_CLASS_NOBASE( CParticleEffect );
friend class CRefCountAccessor;
// Call this before adding a bunch of particles to give it a rough estimate of where
// your particles are for sorting amongst other translucent entities.
void SetSortOrigin( const Vector &vSortOrigin );
PMaterialHandle GetPMaterial(const char *name);
Particle* AddParticle( unsigned int particleSize, PMaterialHandle material, const Vector &origin );
CParticleEffectBinding& GetBinding() { return m_ParticleEffect; }
const char *GetEffectName();
void AddFlags( int iFlags ) { m_Flags |= iFlags; }
void RemoveFlags( int iFlags ) { m_Flags &= ~iFlags; }
void SetDontRemove( bool bSet )
{
if( bSet )
AddFlags( FLAG_DONT_REMOVE );
else
RemoveFlags( FLAG_DONT_REMOVE );
}
// IParticleEffect overrides
public:
virtual void SetParticleCullRadius( float radius );
virtual void NotifyRemove( void );
virtual const Vector & GetSortOrigin();
virtual void NotifyDestroyParticle( Particle* pParticle );
virtual void Update( float flTimeDelta );
// All Create() functions should call this so the effect deletes itself
// when it is removed from the particle manager.
void SetDynamicallyAllocated( bool bDynamic=true );
virtual bool ShouldSimulate() const { return m_bSimulate; }
virtual void SetShouldSimulate( bool bSim ) { m_bSimulate = bSim; }
int AllocateToolParticleEffectId();
int GetToolParticleEffectId() const;
protected:
CParticleEffect( const char *pDebugName );
virtual ~CParticleEffect();
// Returns nonzero if Release() has been called.
int IsReleased();
enum
{
FLAG_ALLOCATED = (1<<1), // Most of the CParticleEffects are dynamically allocated but
// some are member variables of a class. If they're member variables.
FLAG_DONT_REMOVE = (1<<2),
};
// Used to track down bugs.
char const *m_pDebugName;
CParticleEffectBinding m_ParticleEffect;
Vector m_vSortOrigin;
int m_Flags; // Combination of CParticleEffect::FLAG_
bool m_bSimulate;
int m_nToolParticleEffectId;
private:
// Update the reference count.
void AddRef();
void Release();
int m_RefCount; // When this goes to zero and the effect has no more active
// particles, (and it's dynamically allocated), it will delete itself.
CParticleEffect( const CParticleEffect & ); // not defined, not accessible
};
inline int CParticleEffect::GetToolParticleEffectId() const
{
return m_nToolParticleEffectId;
}
inline int CParticleEffect::AllocateToolParticleEffectId()
{
m_nToolParticleEffectId = ParticleMgr()->AllocateToolParticleEffectId();
return m_nToolParticleEffectId;
}
//-----------------------------------------------------------------------------
// Particle flags
//-----------------------------------------------------------------------------
enum SimpleParticleFlag_t
{
SIMPLE_PARTICLE_FLAG_WINDBLOWN = 0x1,
SIMPLE_PARTICLE_FLAG_NO_VEL_DECAY = 0x2 // Used by the blood spray emitter. By default, it decays the
// particle velocity.
};
class SimpleParticle : public Particle
{
public:
SimpleParticle() : m_iFlags(0) {}
// AddSimpleParticle automatically initializes these fields.
Vector m_vecVelocity;
float m_flRoll;
float m_flDieTime; // How long it lives for.
float m_flLifetime; // How long it has been alive for so far.
unsigned char m_uchColor[3];
unsigned char m_uchStartAlpha;
unsigned char m_uchEndAlpha;
unsigned char m_uchStartSize;
unsigned char m_uchEndSize;
unsigned char m_iFlags; // See SimpleParticleFlag_t above
float m_flRollDelta;
};
// CSimpleEmitter implements a common way to simulate and render particles.
//
// Effects can add particles to the particle manager and point at CSimpleEmitter
// for the effect so they don't have to implement the simulation code. It simulates
// velocity, and fades their alpha from invisible to solid and back to invisible over their lifetime.
//
// Particles you add using this effect must use the class CParticleSimple::Particle.
class CSimpleEmitter : public CParticleEffect
{
// IParticleEffect overrides.
public:
DECLARE_CLASS( CSimpleEmitter, CParticleEffect );
static CSmartPtr<CSimpleEmitter> Create( const char *pDebugName );
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
virtual void RenderParticles( CParticleRenderIterator *pIterator );
void SetNearClip( float nearClipMin, float nearClipMax );
void SetDrawBeforeViewModel( bool state = true );
SimpleParticle* AddSimpleParticle( PMaterialHandle hMaterial, const Vector &vOrigin, float flDieTime=3, unsigned char uchSize=10 );
// Overridables for variants like CEmberEffect.
protected:
CSimpleEmitter( const char *pDebugName = NULL );
virtual ~CSimpleEmitter();
virtual float UpdateAlpha( const SimpleParticle *pParticle );
virtual float UpdateScale( const SimpleParticle *pParticle );
virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta );
virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
virtual Vector UpdateColor( const SimpleParticle *pParticle );
float m_flNearClipMin;
float m_flNearClipMax;
private:
CSimpleEmitter( const CSimpleEmitter & ); // not defined, not accessible
};
//==================================================
// EmberEffect
//==================================================
class CEmberEffect : public CSimpleEmitter
{
public:
CEmberEffect( const char *pDebugName );
static CSmartPtr<CEmberEffect> Create( const char *pDebugName );
virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
virtual Vector UpdateColor( const SimpleParticle *pParticle );
private:
CEmberEffect( const CEmberEffect & ); // not defined, not accessible
};
//==================================================
// FireSmokeEffect
//==================================================
class CFireSmokeEffect : public CSimpleEmitter
{
public:
CFireSmokeEffect( const char *pDebugName );
static CSmartPtr<CFireSmokeEffect> Create( const char *pDebugName );
virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
virtual float UpdateAlpha( const SimpleParticle *pParticle );
protected:
VPlane m_planeClip;
private:
CFireSmokeEffect( const CFireSmokeEffect & ); // not defined, not accessible
};
//==================================================
// CFireParticle
//==================================================
class CFireParticle : public CSimpleEmitter
{
public:
CFireParticle( const char *pDebugName );
static CSmartPtr<CFireParticle> Create( const char *pDebugName );
virtual Vector UpdateColor( const SimpleParticle *pParticle );
private:
CFireParticle( const CFireParticle & ); // not defined, not accessible
};
#endif // PARTICLES_SIMPLE_H
|