RigsofRods
Soft-body Physics Simulation
Lightning.cpp
Go to the documentation of this file.
1 /*
2 --------------------------------------------------------------------------------
3 This source file is part of SkyX.
4 Visit http://www.paradise-studios.net/products/skyx/
5 
6 Copyright (C) 2009-2012 Xavier Verguín González <xavyiy@gmail.com>
7 
8 This program is free software; you can redistribute it and/or modify it under
9 the terms of the GNU Lesser General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
12 
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20 http://www.gnu.org/copyleft/lesser.txt.
21 --------------------------------------------------------------------------------
22 */
23 
24 #include "Lightning.h"
25 
26 namespace SkyX { namespace VClouds
27 {
28  Lightning::Lightning(Ogre::SceneManager* sm, Ogre::SceneNode* sn, const Ogre::Vector3& orig, const Ogre::Vector3& dir,
29  const Ogre::Real& l, const Ogre::uint32& d, const Ogre::uint32& rec, const Ogre::Real& tm, const Ogre::Real& wm, const Ogre::Vector2& b)
30  : mOrigin(orig)
31  , mDirection(dir)
32  , mLength(l)
33  , mRealLength(0)
34  , mDivisions(d)
35  , mRecursivity(rec)
36  , mTime(0)
37  , mTimeMultiplier(tm)
38  , mIntensity(0)
39  , mWidthMultiplier(wm)
40  , mBounds(b)
41  , mAngleRange(Ogre::Vector2(Ogre::Math::RangeRandom(0.3,0.5), Ogre::Math::RangeRandom(0.6,0.8)))
42  , mTimeMultipliers(Ogre::Vector3(Ogre::Math::RangeRandom(1.75,4.25), Ogre::Math::RangeRandom(0.4,1.25f), Ogre::Math::RangeRandom(0.2,1.0f)))
43  , mSegments(std::vector<Lightning::Segment>())
44  , mChildren(std::vector<Lightning*>())
45  , mBillboardSet(0)
46  , mSceneManager(sm)
47  , mSceneNode(sn)
48  , mCreated(false)
49  , mFinished(false)
50  {
51  }
52 
54  {
55  remove();
56  }
57 
59  {
60  remove();
61 
62  Ogre::Vector3 current, last = mOrigin;
63 
64  // Create ray segments
65  for(Ogre::uint32 k = 1; k < mDivisions+1; k++)
66  {
67  Ogre::Vector3 current = mOrigin + mDirection*mLength*(static_cast<Ogre::Real>(k)/mDivisions);
68 
69  current += (mLength/(mDivisions*3))*Ogre::Vector3(
70  Ogre::Math::RangeRandom(-1, 1), Ogre::Math::RangeRandom(-1, 1), Ogre::Math::RangeRandom(-1, 1));
71 
72  mSegments.push_back(Segment(last, current));
73 
74  mRealLength += (current-last).length();
75 
76  last = current;
77  }
78 
79  // Create the associated billboard set
80  mBillboardSet = mSceneManager->createBillboardSet();
81  mBillboardSet->setMaterialName("SkyX_Lightning");
82  mBillboardSet->setBillboardType(Ogre::BBT_ORIENTED_SELF);
83 
84  Ogre::Real width = mWidthMultiplier*3*(static_cast<Ogre::Real>(mRecursivity)/4+1)*Ogre::Math::RangeRandom(0.5f, 2.5f-mRecursivity/3);
85 
86  // Create the associated billboard for each segment
87  Ogre::Real delta;
88  Ogre::Vector2 bounds;
89  Ogre::Billboard* bb;
90  for(Ogre::uint32 k = 0; k < mSegments.size(); k++)
91  {
92  delta = 1.0f / mSegments.size();
93  bounds = Ogre::Vector2(k*delta,(k+1)*delta);
94 
95  bounds = Ogre::Vector2(mBounds.x, mBounds.x) + bounds*(mBounds.y-mBounds.x);
96 
97  bb = mBillboardSet->createBillboard((mSegments.at(k).a+mSegments.at(k).b)/2);
98  bb->setDimensions(width, (mSegments.at(k).a-mSegments.at(k).b).length());
99  bb->setColour(Ogre::ColourValue(0,bounds.x,bounds.y));
100  bb->mDirection = (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy();
101 
102  bb = mBillboardSet->createBillboard(mSegments.at(k).a + (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy()*width/2);
103  bb->setDimensions(width, width);
104  bb->setColour(Ogre::ColourValue(1,bounds.x,bounds.x));
105  bb->mDirection = (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy();
106 
107  bb = mBillboardSet->createBillboard(mSegments.at(k).b - (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy()*width/2);
108  bb->setDimensions(width, width);
109  bb->setColour(Ogre::ColourValue(1,bounds.y,bounds.y));
110  bb->mDirection = -(mSegments.at(k).a-mSegments.at(k).b).normalisedCopy();
111 
112  width *= 1-(1.0f/(mRecursivity*mRecursivity+1.0f))*(1.0f/mSegments.size());
113  }
114 
115  mBillboardSet->_updateBounds();
116 
117  mSceneNode->attachObject(mBillboardSet);
118 
119  mBillboardSet->setCustomParameter(0, Ogre::Vector4(1,0,0,0));
120 
121  // Ramifications
122  if (mRecursivity > 0)
123  {
124  Ogre::Real angle;
125  Ogre::Vector3 dir;
126  Ogre::Real lengthMult;
127  for (Ogre::uint32 k = 0; k < mDivisions-1; k++)
128  {
129  angle = (mSegments.at(k).b-mSegments.at(k).a).normalisedCopy().dotProduct(
130  ((mSegments.at(k+1).b-mSegments.at(k+1).a).normalisedCopy()));
131 
132  if (angle < Ogre::Math::RangeRandom(mAngleRange.x, mAngleRange.y))
133  {
134  dir = (mSegments.at(k).b-mSegments.at(k).a).normalisedCopy();
135  dir.x *= Ogre::Math::RangeRandom(0.8f, 1.2f);
136  dir.y *= Ogre::Math::RangeRandom(0.8f, 1.2f);
137  dir.z *= Ogre::Math::RangeRandom(0.8f, 1.2f);
138  dir.normalise();
139 
140  delta = 1.0f / mSegments.size();
141  bounds = Ogre::Vector2(mBounds.x+(mBounds.y-mBounds.x)*(k+1)*delta,1);
142 
143  lengthMult = Ogre::Math::RangeRandom(0.1f, 0.7f);
144 
145  Lightning* lightning = new Lightning(mSceneManager, mSceneNode, mSegments.at(k).b, dir, lengthMult*mLength, 2+mDivisions*lengthMult, mRecursivity-1, mTimeMultiplier, mWidthMultiplier, bounds);
146  lightning->create();
147 
148  mChildren.push_back(lightning);
149  }
150  }
151  }
152 
153  mCreated = true;
154  }
155 
157  {
158  if (!mCreated)
159  {
160  return;
161  }
162 
163  mSceneNode->detachObject(mBillboardSet);
164  mSceneManager->destroyBillboardSet(mBillboardSet);
165 
166  mSegments.clear();
167 
168  for(Ogre::uint32 k = 0; k < mChildren.size(); k++)
169  {
170  delete mChildren.at(k);
171  }
172 
173  mChildren.clear();
174 
175  mFinished = false;
176 
177  mCreated = false;
178  }
179 
180  void Lightning::update(Ogre::Real timeSinceLastFrame)
181  {
182  if (!mCreated)
183  {
184  return;
185  }
186 
187  timeSinceLastFrame *= mTimeMultiplier;
188 
189  // mTime timeline: (Note: Time multipliers are random)
190  // 0.0 -> 1.2 : Ray creation(fordward effect) + Big flash
191  // 1.2 -> 2.0 : Sinus flashing pattern
192  // 2.0 -> 3.0 Ray fading
193 
194  Ogre::Real alpha = 0.5f;
195  Ogre::Real maxAlpha = 1.5f;
196 
197  if (mTime < 1)
198  {
199  mTime += timeSinceLastFrame*mTimeMultipliers.x;
200 
201  if (mTime > 2) mTime = 1.5f; // Prevent big changes
202 
203  if (mTime > 0.8f) // Big flash start
204  {
205  alpha += (mTime-0.8f)*(maxAlpha/0.2f);
206  }
207  }
208  else if (mTime > 1 && mTime < 2)
209  {
210  mTime += timeSinceLastFrame*mTimeMultipliers.y;
211 
212  if (mTime > 3) mTime = 2.5f; // Prevent big changes
213 
214  if (mTime < 1.2f) // Big flash end
215  {
216  alpha += (0.2f-(mTime-1.0f))*(maxAlpha/0.2f);
217  }
218  else // Sinus flashing pattern
219  {
220  alpha += Ogre::Math::Abs(Ogre::Math::Sin((mTime-1.2f)*1.5f*mTimeMultipliers.x));
221  }
222  }
223  else if (mTime > 2) // Ray fading
224  {
225  mTime += timeSinceLastFrame*mTimeMultipliers.z;
226 
227  if (mTime > 3)
228  {
229  mTime = 3; // Prevent big changes
230  mFinished = true;
231  }
232 
233  alpha += Ogre::Math::Abs(Ogre::Math::Sin((2-1.2f)*1.5f*mTimeMultipliers.x));
234  alpha *= 3.0f-mTime;
235  }
236 
237  mIntensity = alpha;
238 
239  _updateData(alpha, mTime > 1 ? 1 : mTime, mTime);
240  }
241 
242  void Lightning::_updateRenderQueueGroup(const Ogre::uint8& rqg)
243  {
244  mBillboardSet->setRenderQueueGroup(rqg);
245 
246  for(Ogre::uint32 k = 0; k < mChildren.size(); k++)
247  {
248  mChildren.at(k)->_updateRenderQueueGroup(rqg);
249  }
250  }
251 
252  void Lightning::_updateData(const Ogre::Real& alpha, const Ogre::Real& currentPos, const Ogre::Real& parentTime)
253  {
254  Ogre::Vector4 params = Ogre::Vector4(alpha,currentPos,(3-mRecursivity)*0.075f+(mBounds.x*1.5f+0.2f)*0.85f,0);
255 
256  if (parentTime > 1 && parentTime < 2.2f)
257  {
258  params.z *= Ogre::Math::Clamp<Ogre::Real>(1.5-parentTime,0.2f,1);
259  }
260  else if (parentTime > 2.2f)
261  {
262  params.z *= Ogre::Math::Clamp<Ogre::Real>((-2.2f+parentTime)*1.25f,0.2f,1);
263  }
264 
265  mBillboardSet->setCustomParameter(0, params);
266 
267  for(Ogre::uint32 k = 0; k < mChildren.size(); k++)
268  {
269  mChildren.at(k)->_updateData(alpha*0.75f, currentPos, parentTime);
270  }
271  }
272 }}
SkyX::VClouds::Lightning::update
void update(Ogre::Real timeSinceLastFrame)
Update.
Definition: Lightning.cpp:180
SkyX::VClouds::Lightning::mSceneManager
Ogre::SceneManager * mSceneManager
Scene manager.
Definition: Lightning.h:195
SkyX::VClouds::Lightning::remove
void remove()
Remove.
Definition: Lightning.cpp:156
SkyX::VClouds::Lightning::mIntensity
Ogre::Real mIntensity
Lightning intensity.
Definition: Lightning.h:185
SkyX
Definition: AtmosphereManager.cpp:30
SkyX::VClouds::Lightning::mTimeMultiplier
Ogre::Real mTimeMultiplier
Global time multiplier.
Definition: Lightning.h:180
SkyX::VClouds::Lightning::mRealLength
Ogre::Real mRealLength
Real ray length (total segments length amount)
Definition: Lightning.h:165
SkyX::VClouds::Lightning::mSceneNode
Ogre::SceneNode * mSceneNode
Scene node.
Definition: Lightning.h:197
SkyX::VClouds::Lightning::mTimeMultipliers
Ogre::Vector3 mTimeMultipliers
Per step time multipliers.
Definition: Lightning.h:182
SkyX::VClouds::Lightning::_updateData
void _updateData(const Ogre::Real &alpha, const Ogre::Real &currentPos, const Ogre::Real &parentTime)
Update data.
Definition: Lightning.cpp:252
SkyX::VClouds::Lightning::mWidthMultiplier
Ogre::Real mWidthMultiplier
Width multiplier.
Definition: Lightning.h:171
SkyX::VClouds::Lightning::mCreated
bool mCreated
Has been create() already called?
Definition: Lightning.h:200
SkyX::VClouds::Lightning::mFinished
bool mFinished
Has the ray finished?
Definition: Lightning.h:202
SkyX::VClouds::Lightning::mSegments
std::vector< Segment > mSegments
Segments.
Definition: Lightning.h:188
SkyX::VClouds::Lightning::mChildren
std::vector< Lightning * > mChildren
Children lightnings.
Definition: Lightning.h:190
SkyX::VClouds::Lightning::mRecursivity
Ogre::uint32 mRecursivity
Recursivity level.
Definition: Lightning.h:169
Lightning.h
SkyX::VClouds::Lightning::_updateRenderQueueGroup
void _updateRenderQueueGroup(const Ogre::uint8 &rqg)
Update render queue group.
Definition: Lightning.cpp:242
SkyX::VClouds::Lightning::mLength
Ogre::Real mLength
Ray length.
Definition: Lightning.h:162
SkyX::VClouds::Lightning::mDivisions
Ogre::uint32 mDivisions
Number of divisions.
Definition: Lightning.h:167
SkyX::VClouds::Lightning
Definition: Lightning.h:31
SkyX::VClouds::Lightning::~Lightning
~Lightning()
Destructor.
Definition: Lightning.cpp:53
SkyX::VClouds::Lightning::mBounds
Ogre::Vector2 mBounds
Ray bounds (for internal visual calculations)
Definition: Lightning.h:173
SkyX::VClouds::Lightning::mDirection
Ogre::Vector3 mDirection
Ray direction.
Definition: Lightning.h:160
SkyX::VClouds::Lightning::Lightning
Lightning(Ogre::SceneManager *sm, Ogre::SceneNode *sn, const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, const Ogre::Real &l, const Ogre::uint32 &d, const Ogre::uint32 &rec, const Ogre::Real &tm, const Ogre::Real &wm, const Ogre::Vector2 &b=Ogre::Vector2(0, 1))
Constructor.
Definition: Lightning.cpp:28
SkyX::VClouds::Lightning::create
void create()
Create.
Definition: Lightning.cpp:58
SkyX::VClouds::Lightning::mAngleRange
Ogre::Vector2 mAngleRange
Angle range (Little values -> Less derivations, bigger values -> More derivations)
Definition: Lightning.h:175
Ogre
Definition: ExtinguishableFireAffector.cpp:35
SkyX::VClouds::Lightning::mOrigin
Ogre::Vector3 mOrigin
Ray origin.
Definition: Lightning.h:158
SkyX::VClouds::Lightning::mTime
Ogre::Real mTime
Current elapsed time.
Definition: Lightning.h:178
SkyX::VClouds::Lightning::mBillboardSet
Ogre::BillboardSet * mBillboardSet
Billboard set.
Definition: Lightning.h:193
SkyX::VClouds::Lightning::Segment
Segment struct.
Definition: Lightning.h:36