TDME2  1.9.200
ObjectParticleSystemInternal.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <memory>
5 #include <string>
6 #include <vector>
7 
8 #include <tdme/tdme.h>
9 #include <tdme/engine/Color4.h>
16 #include <tdme/engine/Engine.h>
17 #include <tdme/engine/Entity.h>
18 #include <tdme/engine/Object.h>
19 #include <tdme/engine/Timing.h>
20 #include <tdme/engine/Transform.h>
21 #include <tdme/math/Math.h>
22 #include <tdme/math/Matrix4x4.h>
23 #include <tdme/math/Vector3.h>
24 
25 using std::make_unique;
26 using std::remove;
27 using std::string;
28 using std::to_string;
29 using std::unique_ptr;
30 using std::vector;
31 
45 using tdme::math::Math;
48 
49 ObjectParticleSystemInternal::ObjectParticleSystemInternal(const string& id, Model* model, const Vector3& scale, bool autoEmit, bool contributesShadows, bool receivesShadows, int32_t maxCount, ParticleEmitter* emitter)
50 {
51  this->id = id;
52  this->enabled = true;
53  this->model = model;
54  this->objectScale = scale;
55  this->autoEmit = autoEmit;
56  this->contributesShadows = contributesShadows;
57  this->receivesShadows = receivesShadows;
58  particles.resize(maxCount);
59  objects.resize(maxCount);
60  for (auto i = 0; i < objects.size(); i++) {
61  objects[i] = new Object(
62  "tdme.opse." +
63  id +
64  ":" +
65  to_string(i),
66  model
67  );
68  objects[i]->setEnabled(false);
69  objects[i]->setScale(objectScale);
70  objects[i]->setContributesShadows(contributesShadows);
71  objects[i]->setReceivesShadows(receivesShadows);
72  objects[i]->setPickable(false);
73  }
74  this->emitter = unique_ptr<ParticleEmitter>(emitter);
75  this->effectColorMul.set(1.0f, 1.0f, 1.0f, 1.0f);
76  this->effectColorAdd.set(0.0f, 0.0f, 0.0f, 0.0f);
77  this->pickable = false;
78  this->particlesToSpawnRemainder = 0.0f;
79 }
80 
82  for (auto i = 0; i < objects.size(); i++) delete objects[i];
83 }
84 
86 {
87  return id;
88 }
89 
91 {
92  this->engine = engine;
93  for (auto i = 0; i < objects.size(); i++) {
94  objects[i]->setEngine(engine);
95  }
96 }
97 
99 {
100  this->renderer = renderer;
101  for (auto i = 0; i < objects.size(); i++) {
102  objects[i]->setRenderer(renderer);
103  }
104 }
105 
107 {
109  //
110  auto entityTransform = parentTransform * (*this);
111  entityTransformMatrix = entityTransform.getTransformMatrix();
112  //
113  updateInternal();
114 }
115 
117 {
118  Transform::setTransform(transform);
119  //
120  auto entityTransform = parentTransform * (*this);
121  entityTransformMatrix = entityTransform.getTransformMatrix();
122  //
123  updateInternal();
124 }
125 
127 {
128  // particles to spawn
129  auto particlesToSpawn = 0;
130  {
131  auto particlesToSpawnWithFraction = emitter->getCount() * engine->getTiming()->getDeltaTime() / 1000.0f;
132  if (autoEmit == true) {
133  particlesToSpawn = static_cast<int32_t>(particlesToSpawnWithFraction);
134  particlesToSpawnRemainder += particlesToSpawnWithFraction - particlesToSpawn;
135  if (particlesToSpawnRemainder > 1.0f) {
136  particlesToSpawn++;
138  }
139  } else {
140  particlesToSpawn = emitter->getCount();
141  }
142  }
143  // skip if nothing to spawn
144  if (particlesToSpawn == 0) return 0;
145  // spawn
146  auto particlesSpawned = 0;
147  for (auto i = 0; i < particles.size(); i++) {
148  auto& particle = particles[i];
149  if (particle.active == true) continue;
150  // emit particle
151  emitter->emit(&particle);
152  // enable object
153  auto object = objects[i];
154  object->setTranslation(particle.position);
155  object->update();
156  object->setEnabled(true);
157  object->setEffectColorAdd(effectColorAdd);
158  object->setEffectColorMul(effectColorMul);
159  enabledObjects.push_back(object);
160  // all particles spawned?
161  particlesSpawned++;
162  if (particlesSpawned == particlesToSpawn) break;
163  }
164  // done
165  return particlesSpawned;
166 }
167 
169 {
170  //
171  Vector3 center;
172  auto& localTransformMatrix = localTransform.getTransformMatrix();
173  localTransformMatrix.getTranslation(center);
174  center.add(emitter->getCenter());
175  //
176  Vector3 point;
177  Vector3 velocityForTime;
178  auto first = true;
179  auto timeDelta = engine->getTiming()->getDeltaTime();
180  for (auto i = 0; i < particles.size(); i++) {
181  auto& particle = particles[i];
182  if (particle.active == false)
183  continue;
184 
185  auto object = objects[i];
186  // life time
187  particle.lifeTimeCurrent += timeDelta;
188  if (particle.lifeTimeCurrent >= particle.lifeTimeMax) {
189  particle.active = false;
190  object->setEnabled(false);
191  enabledObjects.erase(remove(enabledObjects.begin(), enabledObjects.end(), object), enabledObjects.end());
192  continue;
193  }
194  // add gravity if our particle have a noticable mass
195  if (particle.mass > Math::EPSILON)
196  particle.velocity.sub(Vector3(0.0f, 0.5f * Math::G * static_cast<float>(timeDelta) / 1000.0f, 0.0f));
197  // TODO:
198  // maybe take air resistance into account like a huge paper needs more time to fall than a sphere of paper
199  // or heat for smoke or fire, whereas having no mass for those particles works around this problem for now
200  // translation
201  particle.position.add(velocityForTime.set(particle.velocity).scale(static_cast<float>(timeDelta) / 1000.0f));
202  // update up effect colors
203  object->setEffectColorAdd(effectColorAdd);
204  object->setEffectColorMul(effectColorMul);
205  // translation
206  point = localTransformMatrix.multiply(particle.position);
207  point.add(center);
208  // transform particle according to its transform
209  point = entityTransformMatrix.multiply(point);
210  // apply to object
211  object->setTranslation(point);
212  object->update();
213  if (first == true) {
214  worldBoundingBox = *object->getWorldBoundingBox();
215  first = false;
216  } else {
217  worldBoundingBox.extend(object->getWorldBoundingBox());
218  }
219  }
220  // compute bounding boxes
223 }
224 
226 {
227  for (auto i = 0; i < objects.size(); i++) {
228  objects[i]->dispose();
229  }
230 }
231 
Color 4 definition class.
Definition: Color4.h:18
void set(float r, float g, float b, float a)
Sets this color by its components.
Definition: Color4.h:66
Engine main class.
Definition: Engine.h:131
Timing * getTiming()
Definition: Engine.h:1064
Engine entity.
Definition: Entity.h:30
Object to be used with engine class.
Definition: Object.h:60
Timing class.
Definition: Timing.h:16
int64_t getDeltaTime()
Gets the time passed between last and current frame.
Definition: Timing.h:85
Transform which contain scale, rotations and translation.
Definition: Transform.h:29
virtual void setTransform(const Transform &transform)
Set transform.
Definition: Transform.h:177
virtual void update()
Computes transform matrix.
Definition: Transform.cpp:33
const Matrix4x4 & getTransformMatrix() const
Definition: Transform.h:169
Representation of a 3D model.
Definition: Model.h:35
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Definition: BoundingBox.h:26
void extend(BoundingBox *boundingBox)
Extend bounding box with given bounding box.
Definition: BoundingBox.h:158
void fromBoundingVolumeWithTransformMatrix(BoundingBox *original, const Matrix4x4 &transformMatrix)
Create bounding volume from given original(of same type) with applied transform matrix.
Definition: BoundingBox.cpp:79
void update()
Updates this bounding box.
void setTransform(const Transform &transform) override
Set transform.
int emitParticles() override
Adds particles to this particle entity at given position.
Standard math functions.
Definition: Math.h:19
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Definition: Matrix4x4.h:225
void getTranslation(Vector3 &translation) const
Get translation.
Definition: Matrix4x4.h:433
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
Vector3 & add(float scalar)
Adds a scalar.
Definition: Vector3.h:153
Vector3 & scale(float scalar)
Scales by scalar.
Definition: Vector3.h:201
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Definition: Vector3.h:70