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