Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
Lightning.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 "Lightning.h"
25
26namespace 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}}
Ogre::Real mWidthMultiplier
Width multiplier.
Definition Lightning.h:171
Ogre::Real mTimeMultiplier
Global time multiplier.
Definition Lightning.h:180
void _updateData(const Ogre::Real &alpha, const Ogre::Real &currentPos, const Ogre::Real &parentTime)
Update data.
Ogre::uint32 mRecursivity
Recursivity level.
Definition Lightning.h:169
void _updateRenderQueueGroup(const Ogre::uint8 &rqg)
Update render queue group.
Ogre::BillboardSet * mBillboardSet
Billboard set.
Definition Lightning.h:193
std::vector< Lightning * > mChildren
Children lightnings.
Definition Lightning.h:190
Ogre::Real mRealLength
Real ray length (total segments length amount)
Definition Lightning.h:165
Ogre::Real mLength
Ray length.
Definition Lightning.h:162
Ogre::Vector3 mDirection
Ray direction.
Definition Lightning.h:160
bool mCreated
Has been create() already called?
Definition Lightning.h:200
Ogre::Real mIntensity
Lightning intensity.
Definition Lightning.h:185
Ogre::SceneNode * mSceneNode
Scene node.
Definition Lightning.h:197
Ogre::uint32 mDivisions
Number of divisions.
Definition Lightning.h:167
std::vector< Segment > mSegments
Segments.
Definition Lightning.h:188
Ogre::Vector3 mTimeMultipliers
Per step time multipliers.
Definition Lightning.h:182
void update(Ogre::Real timeSinceLastFrame)
Update.
Ogre::Real mTime
Current elapsed time.
Definition Lightning.h:178
Ogre::Vector3 mOrigin
Ray origin.
Definition Lightning.h:158
bool mFinished
Has the ray finished?
Definition Lightning.h:202
Ogre::Vector2 mBounds
Ray bounds (for internal visual calculations)
Definition Lightning.h:173
Ogre::SceneManager * mSceneManager
Scene manager.
Definition Lightning.h:195
Ogre::Vector2 mAngleRange
Angle range (Little values -> Less derivations, bigger values -> More derivations)
Definition Lightning.h:175
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