Otclient  14/8/2020
particlesystem.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "particle.h"
24 #include "particlesystem.h"
25 #include <framework/core/clock.h>
26 
28 {
29  m_finished = false;
30  m_lastUpdateTime = g_clock.seconds();
31 }
32 
34 {
35  for(const OTMLNodePtr& childNode : node->children()) {
36  if(childNode->tag() == "Emitter") {
38  emitter->load(childNode);
39  m_emitters.push_back(emitter);
40  }
41  else if(childNode->tag().find("Affector") != std::string::npos) {
42  ParticleAffectorPtr affector;
43 
44  if(childNode->tag() == "GravityAffector")
45  affector = ParticleAffectorPtr(new GravityAffector);
46  else if(childNode->tag() == "AttractionAffector")
48 
49  if(affector) {
50  affector->load(childNode);
51  m_affectors.push_back(affector);
52  }
53  }
54  }
55 }
56 
58 {
59  m_particles.push_back(particle);
60 }
61 
63 {
64  for(auto &particle: m_particles)
65  particle->render();
67 }
68 
70 {
71  static const float delay = 0.0166; // 60 updates/s
72 
73  // check time
74  float elapsedTime = g_clock.seconds() - m_lastUpdateTime;
75  if(elapsedTime < delay)
76  return;
77 
78  // check if finished
79  if(m_particles.empty() && m_emitters.empty()) {
80  m_finished = true;
81  return;
82  }
83 
84  m_lastUpdateTime = g_clock.seconds() - std::fmod(elapsedTime, delay);
85 
86  auto self = static_self_cast<ParticleSystem>();
87  for(int i = 0; i < std::floor(elapsedTime / delay); ++i) {
88 
89  // update emitters
90  for(auto it = m_emitters.begin(); it != m_emitters.end();) {
91  const ParticleEmitterPtr& emitter = *it;
92  if(emitter->hasFinished()) {
93  it = m_emitters.erase(it);
94  } else {
95  emitter->update(delay, self);
96  ++it;
97  }
98  }
99 
100  // update affectors
101  for(auto it = m_affectors.begin(); it != m_affectors.end();) {
102  const ParticleAffectorPtr& affector = *it;
103  if(affector->hasFinished()) {
104  it = m_affectors.erase(it);
105  } else {
106  affector->update(delay);
107  ++it;
108  }
109  }
110 
111  // update particles
112  for(auto it = m_particles.begin(); it != m_particles.end();) {
113  const ParticlePtr& particle = *it;
114  if(particle->hasFinished()) {
115  it = m_particles.erase(it);
116  } else {
117  // pass particles through affectors
118  for(const ParticleAffectorPtr& particleAffector : m_affectors)
119  particleAffector->updateParticle(particle, delay);
120 
121  particle->update(delay);
122  ++it;
123  }
124  }
125  }
126 }
particlesystem.h
ParticleAffectorPtr
stdext::shared_object_ptr< ParticleAffector > ParticleAffectorPtr
Definition: declarations.h:60
AttractionAffector
Definition: particleaffector.h:55
ParticleSystem::render
void render()
Definition: particlesystem.cpp:62
ParticleEmitter
Definition: particleemitter.h:32
OTMLNode::children
OTMLNodeList children()
Definition: otmlnode.cpp:170
ParticleSystem::load
void load(const OTMLNodePtr &node)
Definition: particlesystem.cpp:33
clock.h
ParticleSystem::ParticleSystem
ParticleSystem()
Definition: particlesystem.cpp:27
ParticleEmitterPtr
stdext::shared_object_ptr< ParticleEmitter > ParticleEmitterPtr
Definition: declarations.h:59
ParticleSystem::update
void update()
Definition: particlesystem.cpp:69
GravityAffector
Definition: particleaffector.h:46
particle.h
stdext::shared_object_ptr< OTMLNode >
g_painter
Painter * g_painter
Definition: painter.cpp:28
g_clock
Clock g_clock
Definition: clock.cpp:25
ParticleSystem::addParticle
void addParticle(const ParticlePtr &particle)
Definition: particlesystem.cpp:57
Clock::seconds
float seconds()
Definition: clock.h:38
Painter::resetCompositionMode
void resetCompositionMode()
Definition: painter.h:107