diff options
author | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
commit | f9158592e1478b2013afc7041d9ed041cf2d2f4a (patch) | |
tree | b16e389d7988700e21b4c9741044cefa536dcbae /libraries/irrlicht-1.8/source/Irrlicht/CParticleSystemSceneNode.cpp | |
parent | Libraries readme updated with change markers and more of the Irrlicht changes. (diff) | |
download | SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.zip SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.gz SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.bz2 SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.xz |
Update Irrlicht to 1.8.1. Include actual change markers this time. lol
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CParticleSystemSceneNode.cpp | 721 |
1 files changed, 0 insertions, 721 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CParticleSystemSceneNode.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CParticleSystemSceneNode.cpp deleted file mode 100644 index e8b8510..0000000 --- a/libraries/irrlicht-1.8/source/Irrlicht/CParticleSystemSceneNode.cpp +++ /dev/null | |||
@@ -1,721 +0,0 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #include "CParticleSystemSceneNode.h" | ||
6 | #include "os.h" | ||
7 | #include "ISceneManager.h" | ||
8 | #include "ICameraSceneNode.h" | ||
9 | #include "IVideoDriver.h" | ||
10 | |||
11 | #include "CParticleAnimatedMeshSceneNodeEmitter.h" | ||
12 | #include "CParticleBoxEmitter.h" | ||
13 | #include "CParticleCylinderEmitter.h" | ||
14 | #include "CParticleMeshEmitter.h" | ||
15 | #include "CParticlePointEmitter.h" | ||
16 | #include "CParticleRingEmitter.h" | ||
17 | #include "CParticleSphereEmitter.h" | ||
18 | #include "CParticleAttractionAffector.h" | ||
19 | #include "CParticleFadeOutAffector.h" | ||
20 | #include "CParticleGravityAffector.h" | ||
21 | #include "CParticleRotationAffector.h" | ||
22 | #include "CParticleScaleAffector.h" | ||
23 | #include "SViewFrustum.h" | ||
24 | |||
25 | namespace irr | ||
26 | { | ||
27 | namespace scene | ||
28 | { | ||
29 | |||
30 | //! constructor | ||
31 | CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter, | ||
32 | ISceneNode* parent, ISceneManager* mgr, s32 id, | ||
33 | const core::vector3df& position, const core::vector3df& rotation, | ||
34 | const core::vector3df& scale) | ||
35 | : IParticleSystemSceneNode(parent, mgr, id, position, rotation, scale), | ||
36 | Emitter(0), ParticleSize(core::dimension2d<f32>(5.0f, 5.0f)), LastEmitTime(0), | ||
37 | MaxParticles(0xffff), Buffer(0), ParticlesAreGlobal(true) | ||
38 | { | ||
39 | #ifdef _DEBUG | ||
40 | setDebugName("CParticleSystemSceneNode"); | ||
41 | #endif | ||
42 | |||
43 | Buffer = new SMeshBuffer(); | ||
44 | if (createDefaultEmitter) | ||
45 | { | ||
46 | IParticleEmitter* e = createBoxEmitter(); | ||
47 | setEmitter(e); | ||
48 | e->drop(); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | |||
53 | //! destructor | ||
54 | CParticleSystemSceneNode::~CParticleSystemSceneNode() | ||
55 | { | ||
56 | if (Emitter) | ||
57 | Emitter->drop(); | ||
58 | if (Buffer) | ||
59 | Buffer->drop(); | ||
60 | |||
61 | removeAllAffectors(); | ||
62 | } | ||
63 | |||
64 | |||
65 | //! Gets the particle emitter, which creates the particles. | ||
66 | IParticleEmitter* CParticleSystemSceneNode::getEmitter() | ||
67 | { | ||
68 | return Emitter; | ||
69 | } | ||
70 | |||
71 | |||
72 | //! Sets the particle emitter, which creates the particles. | ||
73 | void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter) | ||
74 | { | ||
75 | if (emitter == Emitter) | ||
76 | return; | ||
77 | if (Emitter) | ||
78 | Emitter->drop(); | ||
79 | |||
80 | Emitter = emitter; | ||
81 | |||
82 | if (Emitter) | ||
83 | Emitter->grab(); | ||
84 | } | ||
85 | |||
86 | |||
87 | //! Adds new particle effector to the particle system. | ||
88 | void CParticleSystemSceneNode::addAffector(IParticleAffector* affector) | ||
89 | { | ||
90 | affector->grab(); | ||
91 | AffectorList.push_back(affector); | ||
92 | } | ||
93 | |||
94 | //! Get a list of all particle affectors. | ||
95 | const core::list<IParticleAffector*>& CParticleSystemSceneNode::getAffectors() const | ||
96 | { | ||
97 | return AffectorList; | ||
98 | } | ||
99 | |||
100 | //! Removes all particle affectors in the particle system. | ||
101 | void CParticleSystemSceneNode::removeAllAffectors() | ||
102 | { | ||
103 | core::list<IParticleAffector*>::Iterator it = AffectorList.begin(); | ||
104 | while (it != AffectorList.end()) | ||
105 | { | ||
106 | (*it)->drop(); | ||
107 | it = AffectorList.erase(it); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | |||
112 | //! Returns the material based on the zero based index i. | ||
113 | video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i) | ||
114 | { | ||
115 | return Buffer->Material; | ||
116 | } | ||
117 | |||
118 | |||
119 | //! Returns amount of materials used by this scene node. | ||
120 | u32 CParticleSystemSceneNode::getMaterialCount() const | ||
121 | { | ||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | |||
126 | //! Creates a particle emitter for an animated mesh scene node | ||
127 | IParticleAnimatedMeshSceneNodeEmitter* | ||
128 | CParticleSystemSceneNode::createAnimatedMeshSceneNodeEmitter( | ||
129 | scene::IAnimatedMeshSceneNode* node, bool useNormalDirection, | ||
130 | const core::vector3df& direction, f32 normalDirectionModifier, | ||
131 | s32 mbNumber, bool everyMeshVertex, | ||
132 | u32 minParticlesPerSecond, u32 maxParticlesPerSecond, | ||
133 | const video::SColor& minStartColor, const video::SColor& maxStartColor, | ||
134 | u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, | ||
135 | const core::dimension2df& minStartSize, | ||
136 | const core::dimension2df& maxStartSize ) | ||
137 | { | ||
138 | return new CParticleAnimatedMeshSceneNodeEmitter( node, | ||
139 | useNormalDirection, direction, normalDirectionModifier, | ||
140 | mbNumber, everyMeshVertex, | ||
141 | minParticlesPerSecond, maxParticlesPerSecond, | ||
142 | minStartColor, maxStartColor, | ||
143 | lifeTimeMin, lifeTimeMax, maxAngleDegrees, | ||
144 | minStartSize, maxStartSize ); | ||
145 | } | ||
146 | |||
147 | |||
148 | //! Creates a box particle emitter. | ||
149 | IParticleBoxEmitter* CParticleSystemSceneNode::createBoxEmitter( | ||
150 | const core::aabbox3df& box, const core::vector3df& direction, | ||
151 | u32 minParticlesPerSecond, u32 maxParticlesPerSecond, | ||
152 | const video::SColor& minStartColor, const video::SColor& maxStartColor, | ||
153 | u32 lifeTimeMin, u32 lifeTimeMax, | ||
154 | s32 maxAngleDegrees, const core::dimension2df& minStartSize, | ||
155 | const core::dimension2df& maxStartSize ) | ||
156 | { | ||
157 | return new CParticleBoxEmitter(box, direction, minParticlesPerSecond, | ||
158 | maxParticlesPerSecond, minStartColor, maxStartColor, | ||
159 | lifeTimeMin, lifeTimeMax, maxAngleDegrees, | ||
160 | minStartSize, maxStartSize ); | ||
161 | } | ||
162 | |||
163 | |||
164 | //! Creates a particle emitter for emitting from a cylinder | ||
165 | IParticleCylinderEmitter* CParticleSystemSceneNode::createCylinderEmitter( | ||
166 | const core::vector3df& center, f32 radius, | ||
167 | const core::vector3df& normal, f32 length, | ||
168 | bool outlineOnly, const core::vector3df& direction, | ||
169 | u32 minParticlesPerSecond, u32 maxParticlesPerSecond, | ||
170 | const video::SColor& minStartColor, const video::SColor& maxStartColor, | ||
171 | u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, | ||
172 | const core::dimension2df& minStartSize, | ||
173 | const core::dimension2df& maxStartSize ) | ||
174 | { | ||
175 | return new CParticleCylinderEmitter( center, radius, normal, length, | ||
176 | outlineOnly, direction, | ||
177 | minParticlesPerSecond, maxParticlesPerSecond, | ||
178 | minStartColor, maxStartColor, | ||
179 | lifeTimeMin, lifeTimeMax, maxAngleDegrees, | ||
180 | minStartSize, maxStartSize ); | ||
181 | } | ||
182 | |||
183 | |||
184 | //! Creates a mesh particle emitter. | ||
185 | IParticleMeshEmitter* CParticleSystemSceneNode::createMeshEmitter( | ||
186 | scene::IMesh* mesh, bool useNormalDirection, | ||
187 | const core::vector3df& direction, f32 normalDirectionModifier, | ||
188 | s32 mbNumber, bool everyMeshVertex, | ||
189 | u32 minParticlesPerSecond, u32 maxParticlesPerSecond, | ||
190 | const video::SColor& minStartColor, const video::SColor& maxStartColor, | ||
191 | u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, | ||
192 | const core::dimension2df& minStartSize, | ||
193 | const core::dimension2df& maxStartSize) | ||
194 | { | ||
195 | return new CParticleMeshEmitter( mesh, useNormalDirection, direction, | ||
196 | normalDirectionModifier, mbNumber, everyMeshVertex, | ||
197 | minParticlesPerSecond, maxParticlesPerSecond, | ||
198 | minStartColor, maxStartColor, | ||
199 | lifeTimeMin, lifeTimeMax, maxAngleDegrees, | ||
200 | minStartSize, maxStartSize ); | ||
201 | } | ||
202 | |||
203 | |||
204 | //! Creates a point particle emitter. | ||
205 | IParticlePointEmitter* CParticleSystemSceneNode::createPointEmitter( | ||
206 | const core::vector3df& direction, u32 minParticlesPerSecond, | ||
207 | u32 maxParticlesPerSecond, const video::SColor& minStartColor, | ||
208 | const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, | ||
209 | s32 maxAngleDegrees, const core::dimension2df& minStartSize, | ||
210 | const core::dimension2df& maxStartSize ) | ||
211 | { | ||
212 | return new CParticlePointEmitter(direction, minParticlesPerSecond, | ||
213 | maxParticlesPerSecond, minStartColor, maxStartColor, | ||
214 | lifeTimeMin, lifeTimeMax, maxAngleDegrees, | ||
215 | minStartSize, maxStartSize ); | ||
216 | } | ||
217 | |||
218 | |||
219 | //! Creates a ring particle emitter. | ||
220 | IParticleRingEmitter* CParticleSystemSceneNode::createRingEmitter( | ||
221 | const core::vector3df& center, f32 radius, f32 ringThickness, | ||
222 | const core::vector3df& direction, | ||
223 | u32 minParticlesPerSecond, u32 maxParticlesPerSecond, | ||
224 | const video::SColor& minStartColor, const video::SColor& maxStartColor, | ||
225 | u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, | ||
226 | const core::dimension2df& minStartSize, const core::dimension2df& maxStartSize ) | ||
227 | { | ||
228 | return new CParticleRingEmitter( center, radius, ringThickness, direction, | ||
229 | minParticlesPerSecond, maxParticlesPerSecond, minStartColor, | ||
230 | maxStartColor, lifeTimeMin, lifeTimeMax, maxAngleDegrees, | ||
231 | minStartSize, maxStartSize ); | ||
232 | } | ||
233 | |||
234 | |||
235 | //! Creates a sphere particle emitter. | ||
236 | IParticleSphereEmitter* CParticleSystemSceneNode::createSphereEmitter( | ||
237 | const core::vector3df& center, f32 radius, const core::vector3df& direction, | ||
238 | u32 minParticlesPerSecond, u32 maxParticlesPerSecond, | ||
239 | const video::SColor& minStartColor, const video::SColor& maxStartColor, | ||
240 | u32 lifeTimeMin, u32 lifeTimeMax, | ||
241 | s32 maxAngleDegrees, const core::dimension2df& minStartSize, | ||
242 | const core::dimension2df& maxStartSize ) | ||
243 | { | ||
244 | return new CParticleSphereEmitter(center, radius, direction, | ||
245 | minParticlesPerSecond, maxParticlesPerSecond, | ||
246 | minStartColor, maxStartColor, | ||
247 | lifeTimeMin, lifeTimeMax, maxAngleDegrees, | ||
248 | minStartSize, maxStartSize ); | ||
249 | } | ||
250 | |||
251 | |||
252 | //! Creates a point attraction affector. This affector modifies the positions of the | ||
253 | //! particles and attracts them to a specified point at a specified speed per second. | ||
254 | IParticleAttractionAffector* CParticleSystemSceneNode::createAttractionAffector( | ||
255 | const core::vector3df& point, f32 speed, bool attract, | ||
256 | bool affectX, bool affectY, bool affectZ ) | ||
257 | { | ||
258 | return new CParticleAttractionAffector( point, speed, attract, affectX, affectY, affectZ ); | ||
259 | } | ||
260 | |||
261 | //! Creates a scale particle affector. | ||
262 | IParticleAffector* CParticleSystemSceneNode::createScaleParticleAffector(const core::dimension2df& scaleTo) | ||
263 | { | ||
264 | return new CParticleScaleAffector(scaleTo); | ||
265 | } | ||
266 | |||
267 | |||
268 | //! Creates a fade out particle affector. | ||
269 | IParticleFadeOutAffector* CParticleSystemSceneNode::createFadeOutParticleAffector( | ||
270 | const video::SColor& targetColor, u32 timeNeededToFadeOut) | ||
271 | { | ||
272 | return new CParticleFadeOutAffector(targetColor, timeNeededToFadeOut); | ||
273 | } | ||
274 | |||
275 | |||
276 | //! Creates a gravity affector. | ||
277 | IParticleGravityAffector* CParticleSystemSceneNode::createGravityAffector( | ||
278 | const core::vector3df& gravity, u32 timeForceLost) | ||
279 | { | ||
280 | return new CParticleGravityAffector(gravity, timeForceLost); | ||
281 | } | ||
282 | |||
283 | |||
284 | //! Creates a rotation affector. This affector rotates the particles around a specified pivot | ||
285 | //! point. The speed represents Degrees of rotation per second. | ||
286 | IParticleRotationAffector* CParticleSystemSceneNode::createRotationAffector( | ||
287 | const core::vector3df& speed, const core::vector3df& pivotPoint ) | ||
288 | { | ||
289 | return new CParticleRotationAffector( speed, pivotPoint ); | ||
290 | } | ||
291 | |||
292 | |||
293 | //! pre render event | ||
294 | void CParticleSystemSceneNode::OnRegisterSceneNode() | ||
295 | { | ||
296 | doParticleSystem(os::Timer::getTime()); | ||
297 | |||
298 | if (IsVisible && (Particles.size() != 0)) | ||
299 | { | ||
300 | SceneManager->registerNodeForRendering(this); | ||
301 | ISceneNode::OnRegisterSceneNode(); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | |||
306 | //! render | ||
307 | void CParticleSystemSceneNode::render() | ||
308 | { | ||
309 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | ||
310 | ICameraSceneNode* camera = SceneManager->getActiveCamera(); | ||
311 | |||
312 | if (!camera || !driver) | ||
313 | return; | ||
314 | |||
315 | |||
316 | #if 0 | ||
317 | // calculate vectors for letting particles look to camera | ||
318 | core::vector3df view(camera->getTarget() - camera->getAbsolutePosition()); | ||
319 | view.normalize(); | ||
320 | |||
321 | view *= -1.0f; | ||
322 | |||
323 | #else | ||
324 | |||
325 | const core::matrix4 &m = camera->getViewFrustum()->getTransform( video::ETS_VIEW ); | ||
326 | |||
327 | const core::vector3df view ( -m[2], -m[6] , -m[10] ); | ||
328 | |||
329 | #endif | ||
330 | |||
331 | // reallocate arrays, if they are too small | ||
332 | reallocateBuffers(); | ||
333 | |||
334 | // create particle vertex data | ||
335 | s32 idx = 0; | ||
336 | for (u32 i=0; i<Particles.size(); ++i) | ||
337 | { | ||
338 | const SParticle& particle = Particles[i]; | ||
339 | |||
340 | #if 0 | ||
341 | core::vector3df horizontal = camera->getUpVector().crossProduct(view); | ||
342 | horizontal.normalize(); | ||
343 | horizontal *= 0.5f * particle.size.Width; | ||
344 | |||
345 | core::vector3df vertical = horizontal.crossProduct(view); | ||
346 | vertical.normalize(); | ||
347 | vertical *= 0.5f * particle.size.Height; | ||
348 | |||
349 | #else | ||
350 | f32 f; | ||
351 | |||
352 | f = 0.5f * particle.size.Width; | ||
353 | const core::vector3df horizontal ( m[0] * f, m[4] * f, m[8] * f ); | ||
354 | |||
355 | f = -0.5f * particle.size.Height; | ||
356 | const core::vector3df vertical ( m[1] * f, m[5] * f, m[9] * f ); | ||
357 | #endif | ||
358 | |||
359 | Buffer->Vertices[0+idx].Pos = particle.pos + horizontal + vertical; | ||
360 | Buffer->Vertices[0+idx].Color = particle.color; | ||
361 | Buffer->Vertices[0+idx].Normal = view; | ||
362 | |||
363 | Buffer->Vertices[1+idx].Pos = particle.pos + horizontal - vertical; | ||
364 | Buffer->Vertices[1+idx].Color = particle.color; | ||
365 | Buffer->Vertices[1+idx].Normal = view; | ||
366 | |||
367 | Buffer->Vertices[2+idx].Pos = particle.pos - horizontal - vertical; | ||
368 | Buffer->Vertices[2+idx].Color = particle.color; | ||
369 | Buffer->Vertices[2+idx].Normal = view; | ||
370 | |||
371 | Buffer->Vertices[3+idx].Pos = particle.pos - horizontal + vertical; | ||
372 | Buffer->Vertices[3+idx].Color = particle.color; | ||
373 | Buffer->Vertices[3+idx].Normal = view; | ||
374 | |||
375 | idx +=4; | ||
376 | } | ||
377 | |||
378 | // render all | ||
379 | core::matrix4 mat; | ||
380 | if (!ParticlesAreGlobal) | ||
381 | mat.setTranslation(AbsoluteTransformation.getTranslation()); | ||
382 | driver->setTransform(video::ETS_WORLD, mat); | ||
383 | |||
384 | driver->setMaterial(Buffer->Material); | ||
385 | |||
386 | driver->drawVertexPrimitiveList(Buffer->getVertices(), Particles.size()*4, | ||
387 | Buffer->getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES,Buffer->getIndexType()); | ||
388 | |||
389 | // for debug purposes only: | ||
390 | if ( DebugDataVisible & scene::EDS_BBOX ) | ||
391 | { | ||
392 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); | ||
393 | video::SMaterial deb_m; | ||
394 | deb_m.Lighting = false; | ||
395 | driver->setMaterial(deb_m); | ||
396 | driver->draw3DBox(Buffer->BoundingBox, video::SColor(0,255,255,255)); | ||
397 | } | ||
398 | } | ||
399 | |||
400 | |||
401 | //! returns the axis aligned bounding box of this node | ||
402 | const core::aabbox3d<f32>& CParticleSystemSceneNode::getBoundingBox() const | ||
403 | { | ||
404 | return Buffer->getBoundingBox(); | ||
405 | } | ||
406 | |||
407 | |||
408 | void CParticleSystemSceneNode::doParticleSystem(u32 time) | ||
409 | { | ||
410 | if (LastEmitTime==0) | ||
411 | { | ||
412 | LastEmitTime = time; | ||
413 | return; | ||
414 | } | ||
415 | |||
416 | u32 now = time; | ||
417 | u32 timediff = time - LastEmitTime; | ||
418 | LastEmitTime = time; | ||
419 | |||
420 | // run emitter | ||
421 | |||
422 | if (Emitter && IsVisible) | ||
423 | { | ||
424 | SParticle* array = 0; | ||
425 | s32 newParticles = Emitter->emitt(now, timediff, array); | ||
426 | |||
427 | if (newParticles && array) | ||
428 | { | ||
429 | s32 j=Particles.size(); | ||
430 | if (newParticles > 16250-j) | ||
431 | newParticles=16250-j; | ||
432 | Particles.set_used(j+newParticles); | ||
433 | for (s32 i=j; i<j+newParticles; ++i) | ||
434 | { | ||
435 | Particles[i]=array[i-j]; | ||
436 | AbsoluteTransformation.rotateVect(Particles[i].startVector); | ||
437 | if (ParticlesAreGlobal) | ||
438 | AbsoluteTransformation.transformVect(Particles[i].pos); | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | |||
443 | // run affectors | ||
444 | core::list<IParticleAffector*>::Iterator ait = AffectorList.begin(); | ||
445 | for (; ait != AffectorList.end(); ++ait) | ||
446 | (*ait)->affect(now, Particles.pointer(), Particles.size()); | ||
447 | |||
448 | if (ParticlesAreGlobal) | ||
449 | Buffer->BoundingBox.reset(AbsoluteTransformation.getTranslation()); | ||
450 | else | ||
451 | Buffer->BoundingBox.reset(core::vector3df(0,0,0)); | ||
452 | |||
453 | // animate all particles | ||
454 | f32 scale = (f32)timediff; | ||
455 | |||
456 | for (u32 i=0; i<Particles.size();) | ||
457 | { | ||
458 | // erase is pretty expensive! | ||
459 | if (now > Particles[i].endTime) | ||
460 | { | ||
461 | // Particle order does not seem to matter. | ||
462 | // So we can delete by switching with last particle and deleting that one. | ||
463 | // This is a lot faster and speed is very important here as the erase otherwise | ||
464 | // can cause noticable freezes. | ||
465 | Particles[i] = Particles[Particles.size()-1]; | ||
466 | Particles.erase( Particles.size()-1 ); | ||
467 | } | ||
468 | else | ||
469 | { | ||
470 | Particles[i].pos += (Particles[i].vector * scale); | ||
471 | Buffer->BoundingBox.addInternalPoint(Particles[i].pos); | ||
472 | ++i; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | const f32 m = (ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height) * 0.5f; | ||
477 | Buffer->BoundingBox.MaxEdge.X += m; | ||
478 | Buffer->BoundingBox.MaxEdge.Y += m; | ||
479 | Buffer->BoundingBox.MaxEdge.Z += m; | ||
480 | |||
481 | Buffer->BoundingBox.MinEdge.X -= m; | ||
482 | Buffer->BoundingBox.MinEdge.Y -= m; | ||
483 | Buffer->BoundingBox.MinEdge.Z -= m; | ||
484 | |||
485 | if (ParticlesAreGlobal) | ||
486 | { | ||
487 | core::matrix4 absinv( AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE ); | ||
488 | absinv.transformBoxEx(Buffer->BoundingBox); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | |||
493 | //! Sets if the particles should be global. If it is, the particles are affected by | ||
494 | //! the movement of the particle system scene node too, otherwise they completely | ||
495 | //! ignore it. Default is true. | ||
496 | void CParticleSystemSceneNode::setParticlesAreGlobal(bool global) | ||
497 | { | ||
498 | ParticlesAreGlobal = global; | ||
499 | } | ||
500 | |||
501 | //! Remove all currently visible particles | ||
502 | void CParticleSystemSceneNode::clearParticles() | ||
503 | { | ||
504 | Particles.set_used(0); | ||
505 | } | ||
506 | |||
507 | //! Sets the size of all particles. | ||
508 | void CParticleSystemSceneNode::setParticleSize(const core::dimension2d<f32> &size) | ||
509 | { | ||
510 | os::Printer::log("setParticleSize is deprecated, use setMinStartSize/setMaxStartSize in emitter.", irr::ELL_WARNING); | ||
511 | //A bit of a hack, but better here than in the particle code | ||
512 | if (Emitter) | ||
513 | { | ||
514 | Emitter->setMinStartSize(size); | ||
515 | Emitter->setMaxStartSize(size); | ||
516 | } | ||
517 | ParticleSize = size; | ||
518 | } | ||
519 | |||
520 | |||
521 | void CParticleSystemSceneNode::reallocateBuffers() | ||
522 | { | ||
523 | if (Particles.size() * 4 > Buffer->getVertexCount() || | ||
524 | Particles.size() * 6 > Buffer->getIndexCount()) | ||
525 | { | ||
526 | u32 oldSize = Buffer->getVertexCount(); | ||
527 | Buffer->Vertices.set_used(Particles.size() * 4); | ||
528 | |||
529 | u32 i; | ||
530 | |||
531 | // fill remaining vertices | ||
532 | for (i=oldSize; i<Buffer->Vertices.size(); i+=4) | ||
533 | { | ||
534 | Buffer->Vertices[0+i].TCoords.set(0.0f, 0.0f); | ||
535 | Buffer->Vertices[1+i].TCoords.set(0.0f, 1.0f); | ||
536 | Buffer->Vertices[2+i].TCoords.set(1.0f, 1.0f); | ||
537 | Buffer->Vertices[3+i].TCoords.set(1.0f, 0.0f); | ||
538 | } | ||
539 | |||
540 | // fill remaining indices | ||
541 | u32 oldIdxSize = Buffer->getIndexCount(); | ||
542 | u32 oldvertices = oldSize; | ||
543 | Buffer->Indices.set_used(Particles.size() * 6); | ||
544 | |||
545 | for (i=oldIdxSize; i<Buffer->Indices.size(); i+=6) | ||
546 | { | ||
547 | Buffer->Indices[0+i] = (u16)0+oldvertices; | ||
548 | Buffer->Indices[1+i] = (u16)2+oldvertices; | ||
549 | Buffer->Indices[2+i] = (u16)1+oldvertices; | ||
550 | Buffer->Indices[3+i] = (u16)0+oldvertices; | ||
551 | Buffer->Indices[4+i] = (u16)3+oldvertices; | ||
552 | Buffer->Indices[5+i] = (u16)2+oldvertices; | ||
553 | oldvertices += 4; | ||
554 | } | ||
555 | } | ||
556 | } | ||
557 | |||
558 | |||
559 | //! Writes attributes of the scene node. | ||
560 | void CParticleSystemSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const | ||
561 | { | ||
562 | IParticleSystemSceneNode::serializeAttributes(out, options); | ||
563 | |||
564 | out->addBool("GlobalParticles", ParticlesAreGlobal); | ||
565 | out->addFloat("ParticleWidth", ParticleSize.Width); | ||
566 | out->addFloat("ParticleHeight", ParticleSize.Height); | ||
567 | |||
568 | // write emitter | ||
569 | |||
570 | E_PARTICLE_EMITTER_TYPE type = EPET_COUNT; | ||
571 | if (Emitter) | ||
572 | type = Emitter->getType(); | ||
573 | |||
574 | out->addEnum("Emitter", (s32)type, ParticleEmitterTypeNames); | ||
575 | |||
576 | if (Emitter) | ||
577 | Emitter->serializeAttributes(out, options); | ||
578 | |||
579 | // write affectors | ||
580 | |||
581 | E_PARTICLE_AFFECTOR_TYPE atype = EPAT_NONE; | ||
582 | |||
583 | for (core::list<IParticleAffector*>::ConstIterator it = AffectorList.begin(); | ||
584 | it != AffectorList.end(); ++it) | ||
585 | { | ||
586 | atype = (*it)->getType(); | ||
587 | |||
588 | out->addEnum("Affector", (s32)atype, ParticleAffectorTypeNames); | ||
589 | |||
590 | (*it)->serializeAttributes(out); | ||
591 | } | ||
592 | |||
593 | // add empty affector to make it possible to add further affectors | ||
594 | |||
595 | if (options && options->Flags & io::EARWF_FOR_EDITOR) | ||
596 | out->addEnum("Affector", EPAT_NONE, ParticleAffectorTypeNames); | ||
597 | } | ||
598 | |||
599 | |||
600 | //! Reads attributes of the scene node. | ||
601 | void CParticleSystemSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) | ||
602 | { | ||
603 | IParticleSystemSceneNode::deserializeAttributes(in, options); | ||
604 | |||
605 | ParticlesAreGlobal = in->getAttributeAsBool("GlobalParticles"); | ||
606 | ParticleSize.Width = in->getAttributeAsFloat("ParticleWidth"); | ||
607 | ParticleSize.Height = in->getAttributeAsFloat("ParticleHeight"); | ||
608 | |||
609 | // read emitter | ||
610 | |||
611 | int emitterIdx = in->findAttribute("Emitter"); | ||
612 | if (emitterIdx == -1) | ||
613 | return; | ||
614 | |||
615 | if (Emitter) | ||
616 | Emitter->drop(); | ||
617 | Emitter = 0; | ||
618 | |||
619 | E_PARTICLE_EMITTER_TYPE type = (E_PARTICLE_EMITTER_TYPE) | ||
620 | in->getAttributeAsEnumeration("Emitter", ParticleEmitterTypeNames); | ||
621 | |||
622 | switch(type) | ||
623 | { | ||
624 | case EPET_POINT: | ||
625 | Emitter = createPointEmitter(); | ||
626 | break; | ||
627 | case EPET_ANIMATED_MESH: | ||
628 | Emitter = createAnimatedMeshSceneNodeEmitter(NULL); // we can't set the node - the user will have to do this | ||
629 | break; | ||
630 | case EPET_BOX: | ||
631 | Emitter = createBoxEmitter(); | ||
632 | break; | ||
633 | case EPET_CYLINDER: | ||
634 | Emitter = createCylinderEmitter(core::vector3df(0,0,0), 10.f, core::vector3df(0,1,0), 10.f); // (values here don't matter) | ||
635 | break; | ||
636 | case EPET_MESH: | ||
637 | Emitter = createMeshEmitter(NULL); // we can't set the mesh - the user will have to do this | ||
638 | break; | ||
639 | case EPET_RING: | ||
640 | Emitter = createRingEmitter(core::vector3df(0,0,0), 10.f, 10.f); // (values here don't matter) | ||
641 | break; | ||
642 | case EPET_SPHERE: | ||
643 | Emitter = createSphereEmitter(core::vector3df(0,0,0), 10.f); // (values here don't matter) | ||
644 | break; | ||
645 | default: | ||
646 | break; | ||
647 | } | ||
648 | |||
649 | u32 idx = 0; | ||
650 | |||
651 | #if 0 | ||
652 | if (Emitter) | ||
653 | idx = Emitter->deserializeAttributes(idx, in); | ||
654 | |||
655 | ++idx; | ||
656 | #else | ||
657 | if (Emitter) | ||
658 | Emitter->deserializeAttributes(in); | ||
659 | #endif | ||
660 | |||
661 | // read affectors | ||
662 | |||
663 | removeAllAffectors(); | ||
664 | u32 cnt = in->getAttributeCount(); | ||
665 | |||
666 | while(idx < cnt) | ||
667 | { | ||
668 | const char* name = in->getAttributeName(idx); | ||
669 | |||
670 | if (!name || strcmp("Affector", name)) | ||
671 | return; | ||
672 | |||
673 | E_PARTICLE_AFFECTOR_TYPE atype = | ||
674 | (E_PARTICLE_AFFECTOR_TYPE)in->getAttributeAsEnumeration(idx, ParticleAffectorTypeNames); | ||
675 | |||
676 | IParticleAffector* aff = 0; | ||
677 | |||
678 | switch(atype) | ||
679 | { | ||
680 | case EPAT_ATTRACT: | ||
681 | aff = createAttractionAffector(core::vector3df(0,0,0)); | ||
682 | break; | ||
683 | case EPAT_FADE_OUT: | ||
684 | aff = createFadeOutParticleAffector(); | ||
685 | break; | ||
686 | case EPAT_GRAVITY: | ||
687 | aff = createGravityAffector(); | ||
688 | break; | ||
689 | case EPAT_ROTATE: | ||
690 | aff = createRotationAffector(); | ||
691 | break; | ||
692 | case EPAT_SCALE: | ||
693 | aff = createScaleParticleAffector(); | ||
694 | break; | ||
695 | case EPAT_NONE: | ||
696 | default: | ||
697 | break; | ||
698 | } | ||
699 | |||
700 | ++idx; | ||
701 | |||
702 | if (aff) | ||
703 | { | ||
704 | #if 0 | ||
705 | idx = aff->deserializeAttributes(idx, in, options); | ||
706 | ++idx; | ||
707 | #else | ||
708 | aff->deserializeAttributes(in, options); | ||
709 | #endif | ||
710 | |||
711 | addAffector(aff); | ||
712 | aff->drop(); | ||
713 | } | ||
714 | } | ||
715 | } | ||
716 | |||
717 | |||
718 | } // end namespace scene | ||
719 | } // end namespace irr | ||
720 | |||
721 | |||