]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CParticleBoxEmitter.cpp
Fix some more problems with OSX build file.
[irrlicht.git] / source / Irrlicht / CParticleBoxEmitter.cpp
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #include "CParticleBoxEmitter.h"\r
6 \r
7 #ifdef _IRR_COMPILE_WITH_PARTICLES_\r
8 \r
9 #include "os.h"\r
10 #include "IAttributes.h"\r
11 #include "irrMath.h"\r
12 \r
13 namespace irr\r
14 {\r
15 namespace scene\r
16 {\r
17 \r
18 //! constructor\r
19 CParticleBoxEmitter::CParticleBoxEmitter(\r
20         const core::aabbox3df& box, const core::vector3df& direction,\r
21         u32 minParticlesPerSecond, u32 maxParticlesPerSecond,\r
22         video::SColor minStartColor, video::SColor maxStartColor,\r
23         u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees,\r
24         const core::dimension2df& minStartSize, const core::dimension2df& maxStartSize)\r
25  : Box(box), Direction(direction),\r
26         MaxStartSize(maxStartSize), MinStartSize(minStartSize),\r
27         MinParticlesPerSecond(minParticlesPerSecond),\r
28         MaxParticlesPerSecond(maxParticlesPerSecond),\r
29         MinStartColor(minStartColor), MaxStartColor(maxStartColor),\r
30         MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax),\r
31         Time(0), MaxAngleDegrees(maxAngleDegrees)\r
32 {\r
33         #ifdef _DEBUG\r
34         setDebugName("CParticleBoxEmitter");\r
35         #endif\r
36 }\r
37 \r
38 \r
39 //! Prepares an array with new particles to emitt into the system\r
40 //! and returns how much new particles there are.\r
41 s32 CParticleBoxEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray)\r
42 {\r
43         Time += timeSinceLastCall;\r
44 \r
45         const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond);\r
46         const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond;\r
47         const f32 everyWhatMillisecond = 1000.0f / perSecond;\r
48 \r
49         if (Time > everyWhatMillisecond)\r
50         {\r
51                 Particles.set_used(0);\r
52                 u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f);\r
53                 Time = 0;\r
54                 SParticle p;\r
55                 const core::vector3df& extent = Box.getExtent();\r
56 \r
57                 if (amount > MaxParticlesPerSecond*2)\r
58                         amount = MaxParticlesPerSecond * 2;\r
59 \r
60                 for (u32 i=0; i<amount; ++i)\r
61                 {\r
62                         p.pos.X = Box.MinEdge.X + os::Randomizer::frand() * extent.X;\r
63                         p.pos.Y = Box.MinEdge.Y + os::Randomizer::frand() * extent.Y;\r
64                         p.pos.Z = Box.MinEdge.Z + os::Randomizer::frand() * extent.Z;\r
65 \r
66                         p.startTime = now;\r
67                         p.vector = Direction;\r
68 \r
69                         if (MaxAngleDegrees)\r
70                         {\r
71                                 core::vector3df tgt = Direction;\r
72                                 tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees);\r
73                                 tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees);\r
74                                 tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees);\r
75                                 p.vector = tgt;\r
76                         }\r
77 \r
78                         p.endTime = now + MinLifeTime;\r
79                         if (MaxLifeTime != MinLifeTime)\r
80                                 p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime);\r
81 \r
82                         if (MinStartColor==MaxStartColor)\r
83                                 p.color=MinStartColor;\r
84                         else\r
85                                 p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand());\r
86 \r
87                         p.startColor = p.color;\r
88                         p.startVector = p.vector;\r
89 \r
90                         if (MinStartSize==MaxStartSize)\r
91                                 p.startSize = MinStartSize;\r
92                         else\r
93                                 p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand());\r
94                         p.size = p.startSize;\r
95 \r
96                         Particles.push_back(p);\r
97                 }\r
98 \r
99                 outArray = Particles.pointer();\r
100 \r
101                 return Particles.size();\r
102         }\r
103 \r
104         return 0;\r
105 }\r
106 \r
107 \r
108 //! Writes attributes of the object.\r
109 void CParticleBoxEmitter::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const\r
110 {\r
111         core::vector3df b = Box.getExtent();\r
112         b *= 0.5f;\r
113         out->addVector3d("Box", b);\r
114         out->addVector3d("Direction", Direction);\r
115         out->addFloat("MinStartSizeWidth", MinStartSize.Width);\r
116         out->addFloat("MinStartSizeHeight", MinStartSize.Height);\r
117         out->addFloat("MaxStartSizeWidth", MaxStartSize.Width);\r
118         out->addFloat("MaxStartSizeHeight", MaxStartSize.Height);\r
119         out->addInt("MinParticlesPerSecond", MinParticlesPerSecond);\r
120         out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond);\r
121         out->addColor("MinStartColor", MinStartColor);\r
122         out->addColor("MaxStartColor", MaxStartColor);\r
123         out->addInt("MinLifeTime", MinLifeTime);\r
124         out->addInt("MaxLifeTime", MaxLifeTime);\r
125         out->addInt("MaxAngleDegrees", MaxAngleDegrees);\r
126 }\r
127 \r
128 \r
129 //! Reads attributes of the object.\r
130 void CParticleBoxEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)\r
131 {\r
132         // read data and correct input values here\r
133 \r
134         core::vector3df b = in->getAttributeAsVector3d("Box");\r
135 \r
136         if (b.X <= 0)\r
137                 b.X = 1.0f;\r
138         if (b.Y <= 0)\r
139                 b.Y = 1.0f;\r
140         if (b.Z <= 0)\r
141                 b.Z = 1.0f;\r
142 \r
143         Box.MinEdge.X = -b.X;\r
144         Box.MinEdge.Y = -b.Y;\r
145         Box.MinEdge.Z = -b.Z;\r
146         Box.MaxEdge.X = b.X;\r
147         Box.MaxEdge.Y = b.Y;\r
148         Box.MaxEdge.Z = b.Z;\r
149 \r
150         Direction = in->getAttributeAsVector3d("Direction");\r
151         if (Direction.getLength() == 0)\r
152                 Direction.set(0,0.01f,0);\r
153 \r
154         int idx = -1;\r
155         idx = in->findAttribute("MinStartSizeWidth");\r
156         if ( idx >= 0 )\r
157                 MinStartSize.Width = in->getAttributeAsFloat(idx);\r
158         idx = in->findAttribute("MinStartSizeHeight");\r
159         if ( idx >= 0 )\r
160                 MinStartSize.Height = in->getAttributeAsFloat(idx);\r
161         idx = in->findAttribute("MaxStartSizeWidth");\r
162         if ( idx >= 0 )\r
163                 MaxStartSize.Width = in->getAttributeAsFloat(idx);\r
164         idx = in->findAttribute("MaxStartSizeHeight");\r
165         if ( idx >= 0 )\r
166                 MaxStartSize.Height = in->getAttributeAsFloat(idx);\r
167 \r
168         MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond");\r
169         MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond");\r
170 \r
171         MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond);\r
172         MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u);\r
173         MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u);\r
174         MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond);\r
175 \r
176         MinStartColor = in->getAttributeAsColor("MinStartColor");\r
177         MaxStartColor = in->getAttributeAsColor("MaxStartColor");\r
178         MinLifeTime = in->getAttributeAsInt("MinLifeTime");\r
179         MaxLifeTime = in->getAttributeAsInt("MaxLifeTime");\r
180         MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees");\r
181 \r
182         MinLifeTime = core::max_(0u, MinLifeTime);\r
183         MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime);\r
184         MinLifeTime = core::min_(MinLifeTime, MaxLifeTime);\r
185 \r
186 }\r
187 \r
188 \r
189 } // end namespace scene\r
190 } // end namespace irr\r
191 \r
192 #endif // _IRR_COMPILE_WITH_PARTICLES_\r