aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp721
1 files changed, 721 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp
new file mode 100644
index 0000000..54bfcc7
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp
@@ -0,0 +1,721 @@
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
25namespace irr
26{
27namespace scene
28{
29
30//! constructor
31CParticleSystemSceneNode::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
54CParticleSystemSceneNode::~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.
66IParticleEmitter* CParticleSystemSceneNode::getEmitter()
67{
68 return Emitter;
69}
70
71
72//! Sets the particle emitter, which creates the particles.
73void 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.
88void CParticleSystemSceneNode::addAffector(IParticleAffector* affector)
89{
90 affector->grab();
91 AffectorList.push_back(affector);
92}
93
94//! Get a list of all particle affectors.
95const core::list<IParticleAffector*>& CParticleSystemSceneNode::getAffectors() const
96{
97 return AffectorList;
98}
99
100//! Removes all particle affectors in the particle system.
101void 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.
113video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i)
114{
115 return Buffer->Material;
116}
117
118
119//! Returns amount of materials used by this scene node.
120u32 CParticleSystemSceneNode::getMaterialCount() const
121{
122 return 1;
123}
124
125
126//! Creates a particle emitter for an animated mesh scene node
127IParticleAnimatedMeshSceneNodeEmitter*
128CParticleSystemSceneNode::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.
149IParticleBoxEmitter* 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
165IParticleCylinderEmitter* 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.
185IParticleMeshEmitter* 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.
205IParticlePointEmitter* 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.
220IParticleRingEmitter* 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.
236IParticleSphereEmitter* 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.
254IParticleAttractionAffector* 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.
262IParticleAffector* CParticleSystemSceneNode::createScaleParticleAffector(const core::dimension2df& scaleTo)
263{
264 return new CParticleScaleAffector(scaleTo);
265}
266
267
268//! Creates a fade out particle affector.
269IParticleFadeOutAffector* CParticleSystemSceneNode::createFadeOutParticleAffector(
270 const video::SColor& targetColor, u32 timeNeededToFadeOut)
271{
272 return new CParticleFadeOutAffector(targetColor, timeNeededToFadeOut);
273}
274
275
276//! Creates a gravity affector.
277IParticleGravityAffector* 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.
286IParticleRotationAffector* 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
294void 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
307void 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
402const core::aabbox3d<f32>& CParticleSystemSceneNode::getBoundingBox() const
403{
404 return Buffer->getBoundingBox();
405}
406
407
408void 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.
496void CParticleSystemSceneNode::setParticlesAreGlobal(bool global)
497{
498 ParticlesAreGlobal = global;
499}
500
501//! Remove all currently visible particles
502void CParticleSystemSceneNode::clearParticles()
503{
504 Particles.set_used(0);
505}
506
507//! Sets the size of all particles.
508void 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
521void 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.
560void 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.
601void 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