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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
// * This file is part of the COLOBOT source code
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/**
* \file graphics/engine/particle.h
* \brief Particle rendering - CParticle class (aka particule)
*/
#pragma once
#include "engine.h"
#include "sound/sound.h"
class CInstanceManager;
class CRobotMain;
class CObject;
class CSoundInterface;
// Graphics module namespace
namespace Gfx {
const short MAXPARTICULE = 500;
const short MAXPARTITYPE = 5;
const short MAXTRACK = 100;
const short MAXTRACKLEN = 10;
const short MAXPARTIFOG = 100;
const short MAXWHEELTRACE = 1000;
const short SH_WORLD = 0; // particle in the world in the interface
const short SH_FRONT = 1; // particle in the world on the interface
const short SH_INTERFACE = 2; // particle in the interface
const short SH_MAX = 3;
// type == 0 -> triangles
// type == 1 -> effect00 (black background)
// type == 2 -> effect01 (black background)
// type == 3 -> effect02 (black background)
// type == 4 -> text (white background)
enum ParticleType
{
PARTIEXPLOT = 1, // technology explosion
PARTIEXPLOO = 2, // organic explosion
PARTIMOTOR = 3, // the engine exhaust gas
PARTIGLINT = 4, // reflection
PARTIBLITZ = 5, // lightning recharging battery
PARTICRASH = 6, // dust after fall
PARTIGAS = 7, // gas from the reactor
PARTIFIRE = 9, // fireball shrinks
PARTIFIREZ = 10, // fireball grows
PARTIBLUE = 11, // blue ball
PARTISELY = 12, // yellow selection
PARTISELR = 13, // red selection
PARTIGUN1 = 18, // a bullet (fireball)
PARTIGUN2 = 19, // bullet 2 (ant)
PARTIGUN3 = 20, // bullet 3 (spider)
PARTIGUN4 = 21, // bullet 4 (orgaball)
PARTIFRAG = 22, // triangular fragment
PARTIQUEUE = 23, // inflamed tail
PARTIORGANIC1 = 24, // organic ball mother
PARTIORGANIC2 = 25, // organic ball daughter
PARTISMOKE1 = 26, // black smoke
PARTISMOKE2 = 27, // black smoke
PARTISMOKE3 = 28, // black smoke
PARTISMOKE4 = 29, // black smoke
PARTIBLOOD = 30, // human blood
PARTIBLOODM = 31, // blood laying
PARTIVAPOR = 32, // steam
PARTIVIRUS1 = 33, // virus 1
PARTIVIRUS2 = 34, // virus 2
PARTIVIRUS3 = 35, // virus 3
PARTIVIRUS4 = 36, // virus 4
PARTIVIRUS5 = 37, // virus 5
PARTIVIRUS6 = 38, // virus 6
PARTIVIRUS7 = 39, // virus 7
PARTIVIRUS8 = 40, // virus 8
PARTIVIRUS9 = 41, // virus 9
PARTIVIRUS10 = 42, // virus 10
PARTIRAY1 = 43, // ray 1 (turn)
PARTIRAY2 = 44, // ray 2 (electric arc)
PARTIRAY3 = 45, // ray 3
PARTIRAY4 = 46, // ray 4
PARTIFLAME = 47, // flame
PARTIBUBBLE = 48, // bubble
PARTIFLIC = 49, // circles in the water
PARTIEJECT = 50, // ejection from the reactor
PARTISCRAPS = 51, // waste from the reactor
PARTITOTO = 52, // reactor of tot
PARTIERROR = 53, // toto says no
PARTIWARNING = 54, // foo says blah
PARTIINFO = 54, // toto says yes
PARTIQUARTZ = 55, // reflection crystal
PARTISPHERE0 = 56, // explosion sphere
PARTISPHERE1 = 57, // energy sphere
PARTISPHERE2 = 58, // analysis sphere
PARTISPHERE3 = 59, // shield sphere
PARTISPHERE4 = 60, // information sphere (emit)
PARTISPHERE5 = 61, // botanical sphere (gravity root)
PARTISPHERE6 = 62, // information sphere (receive)
PARTISPHERE7 = 63, // sphere
PARTISPHERE8 = 64, // sphere
PARTISPHERE9 = 65, // sphere
PARTIGUNDEL = 66, // bullet destroyed by shield
PARTIPART = 67, // object part
PARTITRACK1 = 68, // drag 1
PARTITRACK2 = 69, // drag 2
PARTITRACK3 = 70, // drag 3
PARTITRACK4 = 71, // drag 4
PARTITRACK5 = 72, // drag 5
PARTITRACK6 = 73, // drag 6
PARTITRACK7 = 74, // drag 7
PARTITRACK8 = 75, // drag 8
PARTITRACK9 = 76, // drag 9
PARTITRACK10 = 77, // drag 10
PARTITRACK11 = 78, // drag 11
PARTITRACK12 = 79, // drag 12
PARTITRACK13 = 80, // drag 13
PARTITRACK14 = 81, // drag 14
PARTITRACK15 = 82, // drag 15
PARTITRACK16 = 83, // drag 16
PARTITRACK17 = 84, // drag 17
PARTITRACK18 = 85, // drag 18
PARTITRACK19 = 86, // drag 19
PARTITRACK20 = 87, // drag 20
PARTIGLINTb = 88, // blue reflection
PARTIGLINTr = 89, // red reflection
PARTILENS1 = 90, // brilliance 1 (orange)
PARTILENS2 = 91, // brilliance 2 (yellow)
PARTILENS3 = 92, // brilliance 3 (red)
PARTILENS4 = 93, // brilliance 4 (violet)
PARTICONTROL = 94, // reflection on button
PARTISHOW = 95, // shows a place
PARTICHOC = 96, // shock wave
PARTIGFLAT = 97, // shows if the ground is flat
PARTIRECOVER = 98, // blue ball recycler
PARTIROOT = 100, // gravity root smoke
PARTIPLOUF0 = 101, // splash
PARTIPLOUF1 = 102, // splash
PARTIPLOUF2 = 103, // splash
PARTIPLOUF3 = 104, // splash
PARTIPLOUF4 = 105, // splash
PARTIDROP = 106, // drop
PARTIFOG0 = 107, // fog 0
PARTIFOG1 = 108, // fog 1
PARTIFOG2 = 109, // fog 2
PARTIFOG3 = 110, // fog 3
PARTIFOG4 = 111, // fog 4
PARTIFOG5 = 112, // fog 5
PARTIFOG6 = 113, // fog 6
PARTIFOG7 = 114, // fog 7
PARTIFOG8 = 115, // fog 8
PARTIFOG9 = 116, // fog 9
PARTILIMIT1 = 117, // shows the limits 1
PARTILIMIT2 = 118, // shows the limits 2
PARTILIMIT3 = 119, // shows the limits 3
PARTILIMIT4 = 120, // shows the limits 4
PARTIWATER = 121, // drop of water
PARTIEXPLOG1 = 122, // ball explosion 1
PARTIEXPLOG2 = 123, // ball explosion 2
PARTIBASE = 124, // gases of spaceship
PARTITRACE0 = 140, // trace
PARTITRACE1 = 141, // trace
PARTITRACE2 = 142, // trace
PARTITRACE3 = 143, // trace
PARTITRACE4 = 144, // trace
PARTITRACE5 = 145, // trace
PARTITRACE6 = 146, // trace
PARTITRACE7 = 147, // trace
PARTITRACE8 = 148, // trace
PARTITRACE9 = 149, // trace
PARTITRACE10 = 150, // trace
PARTITRACE11 = 151, // trace
PARTITRACE12 = 152, // trace
PARTITRACE13 = 153, // trace
PARTITRACE14 = 154, // trace
PARTITRACE15 = 155, // trace
PARTITRACE16 = 156, // trace
PARTITRACE17 = 157, // trace
PARTITRACE18 = 158, // trace
PARTITRACE19 = 159, // trace
};
enum ParticlePhase
{
PARPHSTART = 0,
PARPHEND = 1,
};
struct Particle
{
char used; // TRUE -> particle used
char ray; // TRUE -> ray with goal
unsigned short uniqueStamp; // unique mark
short sheet; // sheet (0..n)
ParticleType type; // type PARTI*
ParticlePhase phase; // phase PARPH*
float mass; // mass of the particle (in rebounding)
float weight; // weight of the particle (for noise)
float duration; // length of life
Math::Vector pos; // absolute position (relative if object links)
Math::Vector goal; // goal position (if ray)
Math::Vector speed; // speed of displacement
float windSensitivity;
short bounce; // number of rebounds
Math::Point dim; // dimensions of the rectangle
float zoom; // zoom (0..1)
float angle; // angle of rotation
float intensity; // intensity
Math::Point texSup; // coordinated upper texture
Math::Point texInf; // coordinated lower texture
float time; // age of the particle (0..n)
float phaseTime; // age at the beginning of phase
float testTime; // time since last test
CObject* objLink; // father object (for example reactor)
CObject* objFather; // father object (for example reactor)
short objRank; // rank of the object, or -1
short trackRank; // rank of the drag
};
struct Track
{
char used; // TRUE -> drag used
char drawParticle;
float step; // duration of not
float last; // increase last not memorized
float intensity; // intensity at starting (0..1)
float width; // tail width
int posUsed; // number of positions in "pos"
int head; // head to write index
Math::Vector pos[MAXTRACKLEN];
float len[MAXTRACKLEN];
};
struct WheelTrace
{
ParticleType type; // type PARTI*
Math::Vector pos[4]; // rectangle positions
float startTime; // beginning of life
};
/**
* \class CParticle
* \brief Particle engine
*
* Functions are only stubs for now.
*/
class CParticle
{
public:
CParticle(CInstanceManager* iMan, CEngine* engine);
~CParticle();
void SetDevice(CDevice* device);
void FlushParticle();
void FlushParticle(int sheet);
int CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim,
ParticleType type, float duration=1.0f, float mass=0.0f,
float windSensitivity=1.0f, int sheet=0);
int CreateFrag(Math::Vector pos, Math::Vector speed, EngineTriangle *triangle,
ParticleType type, float duration=1.0f, float mass=0.0f,
float windSensitivity=1.0f, int sheet=0);
int CreatePart(Math::Vector pos, Math::Vector speed, ParticleType type,
float duration=1.0f, float mass=0.0f, float weight=0.0f,
float windSensitivity=1.0f, int sheet=0);
int CreateRay(Math::Vector pos, Math::Vector goal, ParticleType type, Math::Point dim,
float duration=1.0f, int sheet=0);
int CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type,
float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f);
void CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3,
const Math::Vector &p4, ParticleType type);
void DeleteParticle(ParticleType type);
void DeleteParticle(int channel);
void SetObjectLink(int channel, CObject *object);
void SetObjectFather(int channel, CObject *object);
void SetPosition(int channel, Math::Vector pos);
void SetDimension(int channel, Math::Point dim);
void SetZoom(int channel, float zoom);
void SetAngle(int channel, float angle);
void SetIntensity(int channel, float intensity);
void SetParam(int channel, Math::Vector pos, Math::Point dim, float zoom, float angle, float intensity);
void SetPhase(int channel, ParticlePhase phase, float duration);
bool GetPosition(int channel, Math::Vector &pos);
Color GetFogColor(Math::Vector pos);
void SetFrameUpdate(int sheet, bool update);
void FrameParticle(float rTime);
void DrawParticle(int sheet);
bool WriteWheelTrace(const char *filename, int width, int height, Math::Vector dl, Math::Vector ur);
protected:
void DeleteRank(int rank);
bool CheckChannel(int &channel);
void DrawParticleTriangle(int i);
void DrawParticleNorm(int i);
void DrawParticleFlat(int i);
void DrawParticleFog(int i);
void DrawParticleRay(int i);
void DrawParticleSphere(int i);
void DrawParticleCylinder(int i);
void DrawParticleWheel(int i);
CObject* SearchObjectGun(Math::Vector old, Math::Vector pos, ParticleType type, CObject *father);
CObject* SearchObjectRay(Math::Vector pos, Math::Vector goal, ParticleType type, CObject *father);
void Play(Sound sound, Math::Vector pos, float amplitude);
bool TrackMove(int i, Math::Vector pos, float progress);
void TrackDraw(int i, ParticleType type);
protected:
CInstanceManager* m_iMan;
CEngine* m_engine;
CDevice* m_device;
CTerrain* m_terrain;
CWater* m_water;
CRobotMain* m_main;
CSoundInterface* m_sound;
Particle m_particule[MAXPARTICULE*MAXPARTITYPE];
EngineTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0
Track m_track[MAXTRACK];
int m_wheelTraceTotal;
int m_wheelTraceIndex;
WheelTrace m_wheelTrace[MAXWHEELTRACE];
int m_totalInterface[MAXPARTITYPE][SH_MAX];
bool m_frameUpdate[SH_MAX];
int m_fogTotal;
int m_fog[MAXPARTIFOG];
int m_uniqueStamp;
int m_exploGunCounter;
float m_lastTimeGunDel;
float m_absTime;
};
} // namespace Gfx
|