1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "Components/BsCParticleSystem.h"
4#include "Scene/BsSceneObject.h"
5#include "Utility/BsTime.h"
6#include "Private/RTTI/BsCParticleSystemRTTI.h"
7#include "Scene/BsSceneManager.h"
8
9using namespace std::placeholders;
10
11namespace bs
12{
13 CParticleSystem::CParticleSystem()
14 {
15 setName("ParticleSystem");
16 setFlag(ComponentFlag::AlwaysRun, true);
17 }
18
19 CParticleSystem::CParticleSystem(const HSceneObject& parent)
20 : Component(parent)
21 {
22 setName("ParticleSystem");
23 setFlag(ComponentFlag::AlwaysRun, true);
24 }
25
26 void CParticleSystem::setSettings(const ParticleSystemSettings& settings)
27 {
28 mSettings = settings;
29
30 if(mInternal)
31 mInternal->setSettings(settings);
32 }
33
34 void CParticleSystem::setGpuSimulationSettings(const ParticleGpuSimulationSettings& settings)
35 {
36 mGpuSimulationSettings = settings;
37
38 if(mInternal)
39 mInternal->setGpuSimulationSettings(settings);
40 }
41
42 void CParticleSystem::setEvolvers(const Vector<SPtr<ParticleEvolver>>& evolvers)
43 {
44 mEvolvers = evolvers;
45
46 if(mInternal)
47 mInternal->setEvolvers(evolvers);
48 }
49
50 void CParticleSystem::setEmitters(const Vector<SPtr<ParticleEmitter>>& emitters)
51 {
52 mEmitters = emitters;
53
54 if(mInternal)
55 mInternal->setEmitters(emitters);
56 }
57
58 void CParticleSystem::setLayer(UINT64 layer)
59 {
60 mLayer = layer;
61
62 if(mInternal)
63 mInternal->setLayer(layer);
64 }
65
66 void CParticleSystem::onDestroyed()
67 {
68 destroyInternal();
69 }
70
71 void CParticleSystem::onDisabled()
72 {
73 destroyInternal();
74 }
75
76 void CParticleSystem::onEnabled()
77 {
78 if(mPreviewMode)
79 {
80 destroyInternal();
81 mPreviewMode = false;
82 }
83
84 if(SceneManager::instance().isRunning())
85 {
86 restoreInternal();
87 mInternal->play();
88 }
89 }
90
91 void CParticleSystem::restoreInternal()
92 {
93 if (mInternal == nullptr)
94 {
95 mInternal = ParticleSystem::create();
96 gSceneManager()._bindActor(mInternal, sceneObject());
97 }
98
99 mInternal->setSettings(mSettings);
100 mInternal->setGpuSimulationSettings(mGpuSimulationSettings);
101 mInternal->setEmitters(mEmitters);
102 mInternal->setEvolvers(mEvolvers);
103 mInternal->setLayer(mLayer);
104 }
105
106 void CParticleSystem::destroyInternal()
107 {
108 if(mInternal)
109 {
110 mEmitters = mInternal->getEmitters();
111 mEvolvers = mInternal->getEvolvers();
112
113 gSceneManager()._unbindActor(mInternal);
114 }
115
116 // This should release the last reference and destroy the internal object
117 mInternal = nullptr;
118 }
119
120 bool CParticleSystem::_togglePreviewMode(bool enabled)
121 {
122 bool isRunning = SceneManager::instance().isRunning();
123
124 if(enabled)
125 {
126 // Cannot enable preview while running
127 if (isRunning)
128 return false;
129
130 if(!mPreviewMode)
131 {
132 restoreInternal();
133 mInternal->play();
134 mPreviewMode = true;
135 }
136
137 return true;
138 }
139 else
140 {
141 if (!isRunning)
142 destroyInternal();
143
144 mPreviewMode = false;
145 return false;
146 }
147 }
148
149 RTTITypeBase* CParticleSystem::getRTTIStatic()
150 {
151 return CParticleSystemRTTI::instance();
152 }
153
154 RTTITypeBase* CParticleSystem::getRTTI() const
155 {
156 return CParticleSystem::getRTTIStatic();
157 }
158}