diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CParticleMeshEmitter.cpp | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CParticleMeshEmitter.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CParticleMeshEmitter.cpp new file mode 100644 index 0000000..74d5af1 --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/CParticleMeshEmitter.cpp | |||
@@ -0,0 +1,190 @@ | |||
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 "IrrCompileConfig.h" | ||
6 | #include "CParticleMeshEmitter.h" | ||
7 | #include "os.h" | ||
8 | |||
9 | namespace irr | ||
10 | { | ||
11 | namespace scene | ||
12 | { | ||
13 | |||
14 | //! constructor | ||
15 | CParticleMeshEmitter::CParticleMeshEmitter( | ||
16 | IMesh* mesh, bool useNormalDirection, | ||
17 | const core::vector3df& direction, f32 normalDirectionModifier, | ||
18 | s32 mbNumber, bool everyMeshVertex, | ||
19 | u32 minParticlesPerSecond, u32 maxParticlesPerSecond, | ||
20 | const video::SColor& minStartColor, const video::SColor& maxStartColor, | ||
21 | u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, | ||
22 | const core::dimension2df& minStartSize, | ||
23 | const core::dimension2df& maxStartSize ) | ||
24 | : Mesh(0), TotalVertices(0), MBCount(0), MBNumber(mbNumber), | ||
25 | NormalDirectionModifier(normalDirectionModifier), Direction(direction), | ||
26 | MaxStartSize(maxStartSize), MinStartSize(minStartSize), | ||
27 | MinParticlesPerSecond(minParticlesPerSecond), MaxParticlesPerSecond(maxParticlesPerSecond), | ||
28 | MinStartColor(minStartColor), MaxStartColor(maxStartColor), | ||
29 | MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), | ||
30 | Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees), | ||
31 | EveryMeshVertex(everyMeshVertex), UseNormalDirection(useNormalDirection) | ||
32 | { | ||
33 | #ifdef _DEBUG | ||
34 | setDebugName("CParticleMeshEmitter"); | ||
35 | #endif | ||
36 | setMesh(mesh); | ||
37 | } | ||
38 | |||
39 | |||
40 | //! Prepares an array with new particles to emitt into the system | ||
41 | //! and returns how much new particles there are. | ||
42 | s32 CParticleMeshEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) | ||
43 | { | ||
44 | Time += timeSinceLastCall; | ||
45 | |||
46 | const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); | ||
47 | const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; | ||
48 | const f32 everyWhatMillisecond = 1000.0f / perSecond; | ||
49 | |||
50 | if(Time > everyWhatMillisecond) | ||
51 | { | ||
52 | Particles.set_used(0); | ||
53 | u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); | ||
54 | Time = 0; | ||
55 | SParticle p; | ||
56 | |||
57 | if(amount > MaxParticlesPerSecond * 2) | ||
58 | amount = MaxParticlesPerSecond * 2; | ||
59 | |||
60 | for(u32 i=0; i<amount; ++i) | ||
61 | { | ||
62 | if( EveryMeshVertex ) | ||
63 | { | ||
64 | for( u32 j=0; j<Mesh->getMeshBufferCount(); ++j ) | ||
65 | { | ||
66 | for( u32 k=0; k<Mesh->getMeshBuffer(j)->getVertexCount(); ++k ) | ||
67 | { | ||
68 | p.pos = Mesh->getMeshBuffer(j)->getPosition(k); | ||
69 | if( UseNormalDirection ) | ||
70 | p.vector = Mesh->getMeshBuffer(j)->getNormal(k) / | ||
71 | NormalDirectionModifier; | ||
72 | else | ||
73 | p.vector = Direction; | ||
74 | |||
75 | p.startTime = now; | ||
76 | |||
77 | if( MaxAngleDegrees ) | ||
78 | { | ||
79 | core::vector3df tgt = p.vector; | ||
80 | tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees); | ||
81 | tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees); | ||
82 | tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees); | ||
83 | p.vector = tgt; | ||
84 | } | ||
85 | |||
86 | p.endTime = now + MinLifeTime; | ||
87 | if (MaxLifeTime != MinLifeTime) | ||
88 | p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime); | ||
89 | |||
90 | if (MinStartColor==MaxStartColor) | ||
91 | p.color=MinStartColor; | ||
92 | else | ||
93 | p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand()); | ||
94 | |||
95 | p.startColor = p.color; | ||
96 | p.startVector = p.vector; | ||
97 | |||
98 | if (MinStartSize==MaxStartSize) | ||
99 | p.startSize = MinStartSize; | ||
100 | else | ||
101 | p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand()); | ||
102 | p.size = p.startSize; | ||
103 | |||
104 | Particles.push_back(p); | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | const s32 randomMB = (MBNumber < 0) ? (os::Randomizer::rand() % MBCount) : MBNumber; | ||
111 | |||
112 | u32 vertexNumber = Mesh->getMeshBuffer(randomMB)->getVertexCount(); | ||
113 | if (!vertexNumber) | ||
114 | continue; | ||
115 | vertexNumber = os::Randomizer::rand() % vertexNumber; | ||
116 | |||
117 | p.pos = Mesh->getMeshBuffer(randomMB)->getPosition(vertexNumber); | ||
118 | if( UseNormalDirection ) | ||
119 | p.vector = Mesh->getMeshBuffer(randomMB)->getNormal(vertexNumber) / | ||
120 | NormalDirectionModifier; | ||
121 | else | ||
122 | p.vector = Direction; | ||
123 | |||
124 | p.startTime = now; | ||
125 | |||
126 | if( MaxAngleDegrees ) | ||
127 | { | ||
128 | core::vector3df tgt = Direction; | ||
129 | tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees); | ||
130 | tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees); | ||
131 | tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees); | ||
132 | p.vector = tgt; | ||
133 | } | ||
134 | |||
135 | p.endTime = now + MinLifeTime; | ||
136 | if (MaxLifeTime != MinLifeTime) | ||
137 | p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime); | ||
138 | |||
139 | if (MinStartColor==MaxStartColor) | ||
140 | p.color=MinStartColor; | ||
141 | else | ||
142 | p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand()); | ||
143 | |||
144 | p.startColor = p.color; | ||
145 | p.startVector = p.vector; | ||
146 | |||
147 | if (MinStartSize==MaxStartSize) | ||
148 | p.startSize = MinStartSize; | ||
149 | else | ||
150 | p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand()); | ||
151 | p.size = p.startSize; | ||
152 | |||
153 | Particles.push_back(p); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | outArray = Particles.pointer(); | ||
158 | |||
159 | return Particles.size(); | ||
160 | } | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | |||
166 | //! Set Mesh to emit particles from | ||
167 | void CParticleMeshEmitter::setMesh(IMesh* mesh) | ||
168 | { | ||
169 | Mesh = mesh; | ||
170 | |||
171 | TotalVertices = 0; | ||
172 | MBCount = 0; | ||
173 | VertexPerMeshBufferList.clear(); | ||
174 | |||
175 | if ( !Mesh ) | ||
176 | return; | ||
177 | |||
178 | MBCount = Mesh->getMeshBufferCount(); | ||
179 | VertexPerMeshBufferList.reallocate(MBCount); | ||
180 | for( u32 i = 0; i < MBCount; ++i ) | ||
181 | { | ||
182 | VertexPerMeshBufferList.push_back( Mesh->getMeshBuffer(i)->getVertexCount() ); | ||
183 | TotalVertices += Mesh->getMeshBuffer(i)->getVertexCount(); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | |||
188 | } // end namespace scene | ||
189 | } // end namespace irr | ||
190 | |||