Rigs of Rods 2023.09
Soft-body Physics Simulation
Loading...
Searching...
No Matches
LightningManager.cpp
Go to the documentation of this file.
1/*
2--------------------------------------------------------------------------------
3This source file is part of SkyX.
4Visit http://www.paradise-studios.net/products/skyx/
5
6Copyright (C) 2009-2012 Xavier Vergu�n Gonz�lez <xavyiy@gmail.com>
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt.
21--------------------------------------------------------------------------------
22*/
23
24#include "LightningManager.h"
25
26#include "VClouds.h"
27#include "skyx/Prerequisites.h"
28
29namespace SkyX { namespace VClouds
30{
31
33 : mVClouds(vc)
34 , mLightnings(std::vector<Lightning*>())
35 , mSceneNodes(std::vector<Ogre::SceneNode*>())
36 , mEnabled(false)
37 , mLightningColor(Ogre::Vector3(1,0.925f,0.85f))
38 , mLightningTimeMultiplier(2.0f)
39 , mAverageLightningApparitionTime(1.5f)
40 , mRemainingTime(1.5f)
41 , mVolCloudsLightningMaterial(Ogre::MaterialPtr())
42 , mLightningMaterial(Ogre::MaterialPtr())
43 , mListeners(std::vector<Listener*>())
44 , mCreated(false)
45 {
46 }
47
52
54 {
55 remove();
56
57 mVolCloudsLightningMaterial = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName("SkyX_VolClouds_Lightning"));
58 mLightningMaterial = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName("SkyX_Lightning"));
59
61 {
62 SkyXLOG("Error while creating SkyX::VClouds::LightningManager, material not found");
63 return;
64 }
65
66 if (mEnabled)
67 {
68 mVClouds->getGeometryManager()->_setMaterialName("SkyX_VolClouds_Lightning");
69 }
70 else
71 {
72 mVClouds->getGeometryManager()->_setMaterialName("SkyX_VolClouds");
73 }
74
75 mCreated = true;
76
78 }
79
81 {
82 if (!mCreated)
83 {
84 return;
85 }
86
87 for(Ogre::uint32 k = 0; k < mLightnings.size(); k++)
88 {
89 delete mLightnings.at(k);
90
91 mVClouds->getSceneManager()->destroySceneNode(mSceneNodes.at(k));
92 }
93
94 mLightnings.clear();
95 mSceneNodes.clear();
96
98
100 mLightningMaterial.reset();
101
102 mCreated = false;
103 }
104
105 void LightningManager::update(const Ogre::Real& timeSinceLastFrame)
106 {
107 if (!mCreated)
108 {
109 return;
110 }
111
112 if (mEnabled)
113 {
114 mRemainingTime -= timeSinceLastFrame;
115
116 if (mRemainingTime <= 0)
117 {
118 mRemainingTime = Ogre::Math::RangeRandom(0, 2*mAverageLightningApparitionTime);
119
120 // Select a random camera to place the lightning
121 if (!mVClouds->_getCamerasData().empty())
122 {
123 Ogre::Camera* c = mVClouds->_getCamerasData().at(mVClouds->_getCamerasData().size()*0.999).camera;
124
125 Ogre::Real prob = Ogre::Math::RangeRandom(0,1);
126
127 // Cloud-to-ground
128 if (prob < 0.5)
129 {
131 // Ray position
132 Ogre::Vector3(c->getDerivedPosition().x + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5), mVClouds->getGeometrySettings().Height.x + 0.2*mVClouds->getGeometrySettings().Height.y, c->getDerivedPosition().z + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5)),
133 // Ray direction
134 Ogre::Vector3(0,-1,0),
135 // Ray length
137 }
138 // Cloud-to-cloud
139 else if (prob < 0.7)
140 {
142 // Ray position
143 Ogre::Vector3(c->getDerivedPosition().x + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5), mVClouds->getGeometrySettings().Height.x + 0.2*mVClouds->getGeometrySettings().Height.y, c->getDerivedPosition().z + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5)),
144 // Ray direction
145 Ogre::Vector3(Ogre::Math::RangeRandom(-1,1),Ogre::Math::RangeRandom(-0.1,0.1),Ogre::Math::RangeRandom(-1,1)).normalisedCopy(),
146 // Ray length
147 Ogre::Math::RangeRandom(0.5,1.5f)*0.2*mVClouds->getGeometrySettings().Height.y);
148 }
149 // Cloud-to-ground + cloud-to-cloud
150 else
151 {
153 // Ray position
154 Ogre::Vector3(c->getDerivedPosition().x + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5), mVClouds->getGeometrySettings().Height.x + 0.2*mVClouds->getGeometrySettings().Height.y, c->getDerivedPosition().z + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5)),
155 // Ray direction
156 Ogre::Vector3(0,-1,0),
157 // Ray length
159
161 // Ray position
162 Ogre::Vector3(c->getDerivedPosition().x + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5), mVClouds->getGeometrySettings().Height.x + 0.2*mVClouds->getGeometrySettings().Height.y, c->getDerivedPosition().z + Ogre::Math::RangeRandom(-c->getFarClipDistance()*0.5,c->getFarClipDistance()*0.5)/Ogre::Math::RangeRandom(1,5)),
163 // Ray direction
164 Ogre::Vector3(Ogre::Math::RangeRandom(-1,1),Ogre::Math::RangeRandom(-0.1,0.1),Ogre::Math::RangeRandom(-1,1)).normalisedCopy(),
165 // Ray length
166 Ogre::Math::RangeRandom(0.5,1.5f)*0.2*mVClouds->getGeometrySettings().Height.y);
167 }
168
170 }
171 }
172 }
173
174 for(std::vector<Lightning*>::iterator it = mLightnings.begin(); it != mLightnings.end();)
175 {
176 if ((*it)->isFinished())
177 {
178 Ogre::SceneNode* sn = (*it)->getSceneNode();
179
180 delete (*it);
181 it = mLightnings.erase(it);
182
183 // Remove the associated scene node
184 for(std::vector<Ogre::SceneNode*>::iterator it2 = mSceneNodes.begin(); it2 != mSceneNodes.end(); it2++)
185 {
186 if ((*it2) == sn)
187 {
188 sn->getParentSceneNode()->removeAndDestroyChild(sn);
189 mSceneNodes.erase(it2);
190 break;
191 }
192 }
193 }
194 else
195 {
196 (*it)->update(timeSinceLastFrame);
197 it++;
198 }
199 }
200 }
201
202 Lightning* LightningManager::addLightning(const Ogre::Vector3& p, const Ogre::Vector3& d, const Ogre::Real l, const Ogre::uint32& div)
203 {
204 if (!mCreated || mLightnings.size() == 3)
205 {
206 return static_cast<Lightning*>(NULL);
207 }
208
209 Ogre::SceneNode* sn = mVClouds->getSceneManager()->getRootSceneNode()->createChildSceneNode();
210 sn->setPosition(p);
211
212 Lightning* lightning = new Lightning(mVClouds->getSceneManager(), sn, Ogre::Vector3(0,0,0), d, l, div, 3, mLightningTimeMultiplier, mVClouds->getGeometrySettings().Radius/9500);
213 lightning->create();
214 lightning->_updateRenderQueueGroup(
217 lightning->getBillboardSet()->setVisible(mVClouds->isVisible());
218
219 mSceneNodes.push_back(sn);
220 mLightnings.push_back(lightning);
221
222 for(Ogre::uint32 k = 0; k < mListeners.size(); k++)
223 {
224 mListeners.at(k)->lightningAdded(lightning);
225 }
226
227 return lightning;
228 }
229
231 {
232 Ogre::Vector3 pos;
233
234 for(Ogre::uint32 k = 0; k < 3; k++)
235 {
236 if (k < mLightnings.size())
237 {
238 pos = mVClouds->getGeometryManager()->getSceneNode()->_getFullTransform().inverse() * mSceneNodes.at(k)->_getDerivedPosition();
239
241 getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("uLightning" + Ogre::StringConverter::toString(k),
242 Ogre::Vector4(pos.x, pos.y, pos.z, mLightnings.at(k)->getIntensity()));
243 }
244 else
245 {
247 getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("uLightning" + Ogre::StringConverter::toString(k),
248 Ogre::Vector4(0,0,0,0));
249 }
250 }
251 }
252
253 void LightningManager::setLightningColor(const Ogre::Vector3& c)
254 {
255 mLightningColor = c;
256
257 if (!mCreated)
258 {
259 return;
260 }
261
262 mVolCloudsLightningMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()
263 ->setNamedConstant("uLightningColor", mLightningColor);
264
265 mLightningMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()
266 ->setNamedConstant("uColor", mLightningColor);
267 }
268
270 {
271 for(std::vector<Listener*>::iterator it = mListeners.begin(); it != mListeners.end(); it++)
272 {
273 if ((*it) == listener)
274 {
275 mListeners.erase(it);
276 return;
277 }
278 }
279 }
280
281 void LightningManager::setEnabled(const bool& enable)
282 {
283 mEnabled = enable;
284
285 if (mCreated)
286 {
287 if (mEnabled)
288 {
289 mVClouds->getGeometryManager()->_setMaterialName("SkyX_VolClouds_Lightning");
290 }
291 else
292 {
293 mVClouds->getGeometryManager()->_setMaterialName("SkyX_VolClouds");
294 }
295 }
296 }
297
298 void LightningManager::_updateRenderQueueGroup(const Ogre::uint8& rqg)
299 {
300 for(Ogre::uint32 k = 0; k < mLightnings.size(); k++)
301 {
302 mLightnings.at(k)->_updateRenderQueueGroup(rqg);
303 }
304 }
305
307 {
308 for(Ogre::uint32 k = 0; k < mLightnings.size(); k++)
309 {
310 mLightnings.at(k)->getBillboardSet()->setVisible(v);
311 }
312 }
313
314}}
const Ogre::Vector2 getHeight() const
Get height (x = Altitude over the camera, y: Field height (both in world coordinates))
const Ogre::Vector3 _getCurrentDistance() const
Get current camera to cloud field distance.
void _setMaterialName(const Ogre::String &mn)
Set material name.
Ogre::SceneNode * getSceneNode()
Get scene node.
void _updateRenderQueueGroup(const Ogre::uint8 &rqg)
Update render queue group.
Ogre::BillboardSet * getBillboardSet() const
Get billboard set.
Definition Lightning.h:122
Ogre::MaterialPtr mLightningMaterial
Lightning material.
std::vector< Listener * > mListeners
Listeners.
bool mCreated
Has been create() already called?
void removeListener(Listener *listener)
Remove listener.
LightningManager(VClouds *vc)
Constructor.
VClouds * mVClouds
VClouds pointer.
void setLightningColor(const Ogre::Vector3 &c)
Set lightning color.
Ogre::Real mLightningTimeMultiplier
Lightning time multiplier.
bool mEnabled
Is the lightning system enabled?
Ogre::MaterialPtr mVolCloudsLightningMaterial
Vol. clouds + lightning material.
std::vector< Ogre::SceneNode * > mSceneNodes
Scene nodes.
std::vector< Lightning * > mLightnings
Lightnings.
void updateMaterial()
Update material.
void _updateRenderQueueGroup(const Ogre::uint8 &rqg)
Update render queue group.
Ogre::Real mAverageLightningApparitionTime
Average lightning apparition time (in seconds)
Ogre::Vector3 mLightningColor
Lightning color.
void setEnabled(const bool &enable)
Enable or disable the lightning system.
void removeListeners()
Remove listeners.
void update(const Ogre::Real &timeSinceLastFrame)
Update, to be invoked per frame.
Lightning * addLightning(const Ogre::Vector3 &p, const Ogre::Vector3 &d, const Ogre::Real l, const Ogre::uint32 &div=static_cast< Ogre::uint32 >(Ogre::Math::RangeRandom(12, 30)))
Add lightning.
void _setVisible(const bool &v)
Set visible.
Ogre::Real mRemainingTime
Remaining time for next lightning.
GeometryManager * getGeometryManager()
Get geometry manager.
Definition VClouds.h:483
const RenderQueueGroups & getRenderQueueGroups() const
Get render queue groups.
Definition VClouds.h:260
std::vector< CameraData > & _getCamerasData()
Get cameras data.
Definition VClouds.h:500
const bool & isVisible() const
Is VClouds visible?
Definition VClouds.h:451
const GeometrySettings & getGeometrySettings() const
Get geometry settings.
Definition VClouds.h:217
Ogre::SceneManager * getSceneManager()
Get scene manager.
Definition VClouds.h:459
#define SkyXLOG(msg)
Include external headers.
Ogre::Vector2 Height
Height: x = Altitude over the camera, y: Field height (both in world coordinates)
Definition VClouds.h:65
Ogre::uint8 vcloudsLightningsUnder
VClouds lightnings render queue group (when the camera is under the cloud field)
Definition VClouds.h:55
Ogre::uint8 vcloudsLightningsOver
VClouds lightnings render queue group (when the camera is over the cloud field)
Definition VClouds.h:57