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
DataManager.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 "DataManager.h"
25
26#include "VClouds.h"
27#include "Ellipsoid.h"
28
29namespace SkyX { namespace VClouds
30{
32 : mVClouds(vc)
33 , mCellsCurrent(0)
34 , mCellsTmp(0)
35 , mFFRandom(0)
36 , mNx(0), mNy(0), mNz(0)
37 , mCurrentTransition(0)
38 , mUpdateTime(10.0f)
39 , mStep(0), mXStart(0), mXEnd(0)
40 , mMaxNumberOfClouds(250)
41 , mVolTexToUpdate(true)
42 , mCreated(false)
43 {
44 for (int k = 0; k < 2; k++)
45 {
46 mVolTextures[k].reset();
47 }
48 }
49
54
56 {
57 if (!mCreated)
58 {
59 return;
60 }
61
62 for (int k = 0; k < 2; k++)
63 {
64 Ogre::TextureManager::getSingleton().remove(mVolTextures[k]->getName());
65 mVolTextures[k].reset();
66 }
67
70
71 delete mFFRandom;
72
73 mNx = mNy = mNz = 0;
74
75 mCreated = false;
76 }
77
78 void DataManager::update(const Ogre::Real &timeSinceLastFrame)
79 {
81 {
82 mCurrentTransition += timeSinceLastFrame;
83
84 mXEnd = static_cast<int>((mCurrentTransition / mUpdateTime)*4*mNx);
85 if (mXEnd > 4*mNx)
86 {
87 mXEnd = 4*mNx;
88 }
89
90 if (mXEnd/mNx != mXStart/mNx)
91 {
92 for (int k = mStep; k <= mXEnd/mNx; k++)
93 {
95 mXStart = 0;
96 }
97 }
98 else
99 {
100 if (mXStart != mXEnd)
101 {
103 }
104 }
105
106 mStep = mXEnd/mNx;
107 mXStart = mXEnd;
108
110 {
112
115 mStep = mXStart = mXEnd = 0;
116 }
117 }
118 else
119 {
120 mCurrentTransition -= timeSinceLastFrame;
121
122 mXEnd = static_cast<int>(((mUpdateTime-mCurrentTransition) / mUpdateTime)*4*mNx);
123 if (mXEnd < 0)
124 {
125 mXEnd = 0;
126 }
127
128 if (mXEnd/mNx != mXStart/mNx)
129 {
130 for (int k = mStep; k <= mXEnd/mNx; k++)
131 {
133 mXStart = 0;
134 }
135 }
136 else
137 {
138 if (mXStart != mXEnd)
139 {
141 }
142 }
143
144 mStep = mXEnd/mNx;
145 mXStart = mXEnd;
146
147 if (mCurrentTransition <= 0)
148 {
150
153 mStep = mXStart = mXEnd = 0;
154 }
155 }
156 }
157
158 void DataManager::create(const int &nx, const int &ny, const int &nz)
159 {
160 remove();
161
162 mNx = nx; mNy = ny; mNz = nz;
163
164 mFFRandom = new FastFakeRandom(1024, 0, 1);
165
166 _initData(nx, ny, nz);
167
168 for (int k = 0; k < 2; k++)
169 {
170 _createVolTexture(static_cast<VolTextureId>(k), nx, ny, nz);
171 }
172
175
176 mCreated = true;
177 }
178
180 {
181 // Finish current update process
183 for (int k = mStep+1; k < 4; k++)
184 {
186 }
187 mStep = mXStart = mXEnd = 0;
188
189 if (mVolTexToUpdate)
190 {
193 }
194 else
195 {
198 }
199
201 }
202
203 void DataManager::_initData(const int& nx, const int& ny, const int& nz)
204 {
205 mCellsCurrent = _create3DCellArray(nx, ny, nz);
206 mCellsTmp = _create3DCellArray(nx, ny, nz, false);
207 }
208
209 DataManager::Cell *** DataManager::_create3DCellArray(const int& nx, const int& ny, const int& nz, const bool& init)
210 {
211 Cell ***c = new Cell** [nx];
212
213 int u, v, w;
214
215 for (u = 0; u < nx; u++)
216 {
217 c[u] = new Cell* [ny];
218
219 for (v = 0; v < ny; v++)
220 {
221 c[u][v] = new Cell[nz];
222 }
223 }
224
225 if (!init)
226 {
227 return c;
228 }
229
230 for (u = 0; u < nx; u++)
231 {
232 for (v = 0; v < ny; v++)
233 {
234 for (w = 1; w < nz; w++)
235 {
236 c[u][v][w].act = false;
237 c[u][v][w].cld = false;
238 c[u][v][w].hum = false;
239
240 c[u][v][w].pact = 0;
241 c[u][v][w].pext = 1;
242 c[u][v][w].phum = 0;
243
244 c[u][v][w].dens = 0.0f;
245 c[u][v][w].light = 1.0f;
246 }
247 }
248 }
249
250 return c;
251 }
252
253 void DataManager::_delete3DCellArray(Cell ***c, const int& nx, const int& ny)
254 {
255 int u, v;
256
257 for (u = 0; u < nx; u++)
258 {
259 for (v = 0; v < ny; v++)
260 {
261 delete [] c[u][v];
262 }
263
264 delete [] c[u];
265 }
266
267 delete [] c;
268 }
269
270 void DataManager::_copy3DCellArraysData(Cell ***src, Cell ***dest, const int& nx, const int& ny, const int& nz)
271 {
272 int u, v, w;
273
274 for (u = 0; u < nx; u++)
275 {
276 for (v = 0; v < ny; v++)
277 {
278 for (w = 0; w < nz; w++)
279 {
280 dest[u][v][w].act = src[u][v][w].act;
281 dest[u][v][w].cld = src[u][v][w].cld;
282 dest[u][v][w].hum = src[u][v][w].hum;
283
284 dest[u][v][w].pact = src[u][v][w].pact;
285 dest[u][v][w].pext = src[u][v][w].pext;
286 dest[u][v][w].phum = src[u][v][w].phum;
287
288 dest[u][v][w].dens = src[u][v][w].dens;
289 dest[u][v][w].light = src[u][v][w].light;
290 }
291 }
292 }
293 }
294
295 void DataManager::setWheater(const float& Humidity, const float& AverageCloudsSize, const bool& delayedResponse)
296 {
297 int numberofclouds = static_cast<int>(Humidity * mMaxNumberOfClouds);
298 Ogre::Vector3 maxcloudsize = AverageCloudsSize*Ogre::Vector3(mNx/14, mNy/14, static_cast<int>(static_cast<float>(mNz)/2.75));
299
300 // Update old clouds with new parameters
301 Ogre::Vector3 currentdimensions, currentPosition;
302 std::vector<Ellipsoid*>::const_iterator mEllipsoidsIt;
303
304 for(mEllipsoidsIt = mEllipsoids.begin(); mEllipsoidsIt != mEllipsoids.end(); mEllipsoidsIt++)
305 {
306 // Update size
307 currentdimensions = (*mEllipsoidsIt)->getDimensions();
308
309 if (currentdimensions.x / maxcloudsize.x < 0.5 || currentdimensions.x / maxcloudsize.x > 2)
310 {
311 currentdimensions.x = maxcloudsize.x + Ogre::Math::RangeRandom(-0.2,0.2)*maxcloudsize.x;
312 }
313 if (currentdimensions.y / maxcloudsize.y < 0.5 || currentdimensions.y / maxcloudsize.y > 2)
314 {
315 currentdimensions.y = maxcloudsize.y + Ogre::Math::RangeRandom(-0.2,0.2)*maxcloudsize.y;
316 }
317 if (currentdimensions.z / maxcloudsize.z < 0.5 || currentdimensions.z / maxcloudsize.z > 2)
318 {
319 currentdimensions.z = maxcloudsize.z + Ogre::Math::RangeRandom(-0.2,0.15)*maxcloudsize.z;
320 }
321
322 (*mEllipsoidsIt)->setDimensions(currentdimensions);
323
324 // Update position
325 currentPosition = (*mEllipsoidsIt)->getPosition();
326 (*mEllipsoidsIt)->setPosition(Ogre::Vector3(currentPosition.x,currentPosition.y,static_cast<int>(Ogre::Math::RangeRandom(currentdimensions.z+2,mNz-currentdimensions.z-2))));
327 }
328
329 // Remove some clouds if needed
330 while (static_cast<unsigned int>(numberofclouds) < mEllipsoids.size())
331 {
332 mEllipsoids.pop_back();
333 }
334
335 // Add new clouds if needed
336 Ogre::Vector3 newclouddimensions;
337 while (static_cast<unsigned int>(numberofclouds) > mEllipsoids.size())
338 {
339 newclouddimensions = maxcloudsize*Ogre::Vector3(Ogre::Math::RangeRandom(0.5, 2), Ogre::Math::RangeRandom(0.5, 2), Ogre::Math::RangeRandom(0.75, 1));
340 addEllipsoid(new Ellipsoid(newclouddimensions.x, newclouddimensions.y, newclouddimensions.z, mNx, mNy, mNz, (int)Ogre::Math::RangeRandom(0, mNx), (int)Ogre::Math::RangeRandom(0, mNy), static_cast<int>(Ogre::Math::RangeRandom(newclouddimensions.z+2,mNz-newclouddimensions.z-2)), Ogre::Math::RangeRandom(1,5.0f)), false);
341 }
342
343 _updateProbabilities(mCellsCurrent, mNx, mNy, mNz, delayedResponse);
344
345 if (!delayedResponse)
346 {
347 for (int k = 0; k < 4; k++)
348 {
350 }
351 mStep = mXStart = mXEnd = 0;
352
355 }
356 }
357
358 void DataManager::addEllipsoid(Ellipsoid *e, const bool& UpdateProbabilities)
359 {
360 mEllipsoids.push_back(e);
361
362 if (UpdateProbabilities)
363 {
365 }
366 }
367
368 void DataManager::_clearProbabilities(Cell*** c, const int& nx, const int& ny, const int& nz, const bool& clearData)
369 {
370 int u, v, w;
371
372 for (u = 0; u < nx; u++)
373 {
374 for (v = 0; v < ny; v++)
375 {
376 for (w = 0; w < nz; w++)
377 {
378 c[u][v][w].pact = 0;
379 c[u][v][w].pext = 1;
380 c[u][v][w].phum = 0;
381
382 if (clearData)
383 {
384 c[u][v][w].act = false;
385 c[u][v][w].cld = false;
386 c[u][v][w].hum = false;
387
388 c[u][v][w].dens = 0;
389 c[u][v][w].light = 0;
390 }
391 }
392 }
393 }
394 }
395
396 void DataManager::_updateProbabilities(Cell*** c, const int& nx, const int& ny, const int& nz, const bool& delayedResponse)
397 {
398 _clearProbabilities(c,nx,ny,nz,!delayedResponse);
399
400 std::vector<Ellipsoid*>::const_iterator mEllipsoidsIt;
401
402 for(mEllipsoidsIt = mEllipsoids.begin(); mEllipsoidsIt != mEllipsoids.end(); mEllipsoidsIt++)
403 {
404 (*mEllipsoidsIt)->updateProbabilities(c,nx,ny,nz,delayedResponse);
405 }
406 }
407
408 const Ogre::Real DataManager::_getLightAbsorcionAt(Cell*** c, const int& nx, const int& ny, const int& nz, const int& x, const int& y, const int& z, const Ogre::Vector3& d, const float& att) const
409 {
410 Ogre::Real step = 1, factor = 1;
411 Ogre::Vector3 pos = Ogre::Vector3(x, y, z);
412 bool outOfBounds = false;
413 int u, v, uu, vv,
414 current_iteration = 0, max_iterations = 8;
415
416 while(!outOfBounds)
417 {
418 if ( (int)pos.z >= nz || (int)pos.z < 0 || factor <= 0 || current_iteration >= max_iterations)
419 {
420 outOfBounds = true;
421 }
422 else
423 {
424 u = (int)pos.x; v = (int)pos.y;
425
426 uu = (u<0) ? (u + nx) : u; if (u>=nx) { uu-= nx; }
427 vv = (v<0) ? (v + ny) : v; if (v>=ny) { vv-= ny; }
428
429 factor -= c[uu][vv][(int)pos.z].dens*att*(1-static_cast<float>(current_iteration)/max_iterations);
430 pos += step*(-d);
431
432 current_iteration++;
433 }
434 }
435
436 return Ogre::Math::Clamp<Ogre::Real>(factor,0,1);
437 }
438
439 void DataManager::_performCalculations(const int& nx, const int& ny, const int& nz, const int& step, const int& xStart, const int& xEnd)
440 {
441 int u, v, w;
442
443 switch (step)
444 {
445 case 0:
446 {
447 for (u = xStart; u < xEnd; u++)
448 {
449 for (v = 0; v < ny; v++)
450 {
451 for (w = 0; w < nz; w++)
452 {
453 // ti+1 ti
454 mCellsCurrent[u][v][w].hum = mCellsCurrent[u][v][w].hum || (mFFRandom->get() < mCellsCurrent[u][v][w].phum);
455 mCellsCurrent[u][v][w].cld = mCellsCurrent[u][v][w].cld && (mFFRandom->get() > mCellsCurrent[u][v][w].pext);
456 mCellsCurrent[u][v][w].act = mCellsCurrent[u][v][w].act || (mFFRandom->get() < mCellsCurrent[u][v][w].pact);
457
458 // Copy act in the temporal buffer, for _fact(...)
459 mCellsTmp[u][v][w].act = mCellsCurrent[u][v][w].act;
460 }
461 }
462 }
463 }
464 break;
465 case 1:
466 {
467 for (u = xStart; u < xEnd; u++)
468 {
469 for (v = 0; v < ny; v++)
470 {
471 for (w = 0; w < nz; w++)
472 {
473 // ti+1 ti
474 mCellsCurrent[u][v][w].hum = mCellsCurrent[u][v][w].hum && !mCellsCurrent[u][v][w].act;
475 mCellsCurrent[u][v][w].cld = mCellsCurrent[u][v][w].cld || mCellsCurrent[u][v][w].act;
476 mCellsCurrent[u][v][w].act = !mCellsCurrent[u][v][w].act && mCellsCurrent[u][v][w].hum && _fact(mCellsTmp, nx, ny, nz, u,v,w);
477 }
478 }
479 }
480 }
481 break;
482 case 2:
483 {
484 // Continous density
485 for (u = xStart; u < xEnd; u++)
486 {
487 for (v = 0; v < ny; v++)
488 {
489 for (w = 0; w < nz; w++)
490 {
491 mCellsCurrent[u][v][w].dens = _getDensityAt(mCellsCurrent, nx, ny, nz, u,v,w, 1/*TODOOOO!!!*/, 1.15f);
492 // mCellsCurrent[u][v][w].dens = _getDensityAt(mCellsCurrent,u,v,w);
493 }
494 }
495 }
496 }
497 break;
498 case 3:
499 {
500 // Light scattering
501 Ogre::Vector3 SunDir = Ogre::Vector3(mVClouds->getSunDirection().x, mVClouds->getSunDirection().z, mVClouds->getSunDirection().y);
502
503 for (u = xStart; u < xEnd; u++)
504 {
505 for (v = 0; v < ny; v++)
506 {
507 for (w = 0; w < nz; w++)
508 {
509 mCellsCurrent[u][v][w].light = _getLightAbsorcionAt(mCellsCurrent, nx, ny, nz, u,v,w, SunDir, 0.15f/*TODO!!!!*/);
510 }
511 }
512 }
513 }
514 break;
515 }
516 }
517
518 const bool DataManager::_fact(Cell ***c, const int& nx, const int& ny, const int& nz, const int& x, const int& y, const int& z) const
519 {
520 bool i1m, j1m, k1m,
521 i1r, j1r, k1r,
522 i2r, i2m, j2r, j2m, k2r;
523
524 i1m = ((x+1)>=nx) ? c[0][y][z].act : c[x+1][y][z].act;
525 j1m = ((y+1)>=ny) ? c[x][0][z].act : c[x][y+1][z].act;
526 k1m = ((z+1)>=nz) ? false : c[x][y][z+1].act;
527
528 i1r = ((x-1)<0) ? c[nx-1][y][z].act : c[x-1][y][z].act;
529 j1r = ((y-1)<0) ? c[x][ny-1][z].act : c[x][y-1][z].act;
530 k1r = ((z-1)<0) ? false : c[x][y][z-1].act;
531
532 i2r = ((x-2)<0) ? c[nx-2][y][z].act : c[x-2][y][z].act;
533 j2r = ((y-2)<0) ? c[x][ny-2][z].act : c[x][y-2][z].act;
534 k2r = ((z-2)<0) ? false : c[x][y][z-2].act;
535
536 i2m = ((x+2)>=nx) ? c[1][y][z].act : c[x+2][y][z].act;
537 j2m = ((y+2)>=ny) ? c[x][1][z].act : c[x][y+2][z].act;
538
539 return i1m || j1m || k1m || i1r || j1r || k1r || i2r || i2m || j2r || j2m || k2r;
540 }
541
542 const float DataManager::_getDensityAt(Cell ***c, const int& nx, const int& ny, const int& nz, const int& x, const int& y, const int& z, const int& r, const float& strength) const
543 {
544 int zr = ((z-r)<0) ? 0 : z-r,
545 zm = ((z+r)>=nz) ? nz : z+r,
546 u, uu, v, vv, w,
547 clouds = 0, div = 0;
548
549 for (u = x-r; u <= x+r; u++)
550 {
551 for (v = y-r; v <= y+r; v++)
552 {
553 for (w = zr; w < zm; w++)
554 {
555 // x/y Seamless!
556 uu = (u<0) ? (u + nx) : u; if (u>=nx) { uu-= nx; }
557 vv = (v<0) ? (v + ny) : v; if (v>=ny) { vv-= ny; }
558
559 clouds += c[uu][vv][w].cld ? 1 : 0;
560 div++;
561 }
562 }
563 }
564
565 return Ogre::Math::Clamp<float>(strength*((float)clouds)/div, 0, 1);
566 }
567
568 const float DataManager::_getDensityAt(Cell ***c, const int& x, const int& y, const int& z) const
569 {
570 return c[x][y][z].cld ? 1.0f : 0.0f;
571 }
572
573 void DataManager::_createVolTexture(const VolTextureId& TexId, const int& nx, const int& ny, const int& nz)
574 {
575 mVolTextures[static_cast<int>(TexId)]
576 = Ogre::TextureManager::getSingleton().
577 createManual("_SkyX_VolCloudsData"+Ogre::StringConverter::toString(TexId),
578 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
579 Ogre::TEX_TYPE_3D,
580 nx, ny, nz, 0,
581 Ogre::PF_BYTE_RGBA);
582
583 mVolTextures[static_cast<int>(TexId)]->load();
584
585 static_cast<Ogre::MaterialPtr>(
586 Ogre::MaterialManager::getSingleton().getByName("SkyX_VolClouds"))
587 ->getTechnique(0)->getPass(0)->getTextureUnitState(static_cast<int>(TexId))
588 ->setTextureName("_SkyX_VolCloudsData"+Ogre::StringConverter::toString(TexId), Ogre::TEX_TYPE_3D);
589 static_cast<Ogre::MaterialPtr>(
590 Ogre::MaterialManager::getSingleton().getByName("SkyX_VolClouds_Lightning"))
591 ->getTechnique(0)->getPass(0)->getTextureUnitState(static_cast<int>(TexId))
592 ->setTextureName("_SkyX_VolCloudsData"+Ogre::StringConverter::toString(TexId), Ogre::TEX_TYPE_3D);
593 }
594
595 void DataManager::_updateVolTextureData(Cell ***c, const VolTextureId& TexId, const int& nx, const int& ny, const int& nz)
596 {
597 Ogre::HardwarePixelBufferSharedPtr buffer = mVolTextures[TexId]->getBuffer(0,0);
598
599 buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
600 const Ogre::PixelBox &pb = buffer->getCurrentLock();
601
602 Ogre::uint32 *pbptr = reinterpret_cast<Ogre::uint32*>(pb.data);
603 size_t x, y, z;
604
605 for (z = pb.front; z < pb.back; z++)
606 {
607 for (y = pb.top; y < pb.bottom; y++)
608 {
609 for (x = pb.left; x < pb.right; x++)
610 {
611 Ogre::PixelUtil::packColour (c[x][y][z].dens/* TODO!!!! */, c[x][y][z].light, 0, 0, pb.format, &pbptr[x]);
612 }
613 pbptr += pb.rowPitch;
614 }
615 pbptr += pb.getSliceSkip ();
616 }
617
618 buffer->unlock();
619 }
620}}
VClouds * mVClouds
SkyX parent pointer.
int mMaxNumberOfClouds
Max number of clouds(Ellipsoids)
DataManager(VClouds *vc)
Constructor.
float mCurrentTransition
Current transition.
Cell *** mCellsCurrent
Simulation data.
void _updateProbabilities(Cell ***c, const int &nx, const int &ny, const int &nz, const bool &delayedResponse)
Update probabilities based from the Ellipsoid vector.
std::vector< Ellipsoid * > mEllipsoids
Ellipsoids.
const Ogre::Real _getLightAbsorcionAt(Cell ***c, const int &nx, const int &ny, const int &nz, const int &x, const int &y, const int &z, const Ogre::Vector3 &d, const float &att) const
Get light absorcion factor at a point.
void setWheater(const float &Humidity, const float &AverageCloudsSize, const bool &delayedResponse=true)
Set wheater parameters Use this funtion to update the cloud field parameters, you'll get a smart and ...
void addEllipsoid(Ellipsoid *e, const bool &UpdateProbabilities=true)
Add ellipsoid: clouds are modelled as ellipsoids in our simulation approach, so.
bool mVolTexToUpdate
Current texture.
void create(const int &nx, const int &ny, const int &nz)
Create.
FastFakeRandom * mFFRandom
Fast fake random.
void _updateVolTextureData(Cell ***c, const VolTextureId &TexId, const int &nx, const int &ny, const int &nz)
Update volumetric texture data.
void _initData(const int &nx, const int &ny, const int &nz)
Initialize data.
const float _getDensityAt(Cell ***c, const int &nx, const int &ny, const int &nz, const int &x, const int &y, const int &z, const int &r, const float &strength) const
Get continous density at a point.
int mStep
Current calculation state.
VolTextureId
Volumetric textures enumeration.
Definition DataManager.h:59
bool mCreated
Has been create(...) already called?
void forceToUpdateData()
Forces the data manager to calculate the next step right now.
const bool _fact(Cell ***c, const int &nx, const int &ny, const int &nz, const int &x, const int &y, const int &z) const
Fact funtion.
Cell *** _create3DCellArray(const int &nx, const int &ny, const int &nz, const bool &init=true)
Create tridimensional cell array.
Ogre::TexturePtr mVolTextures[2]
Volumetric textures array.
void _clearProbabilities(Cell ***c, const int &nx, const int &ny, const int &nz, const bool &clearData)
Clear probabilities.
void _createVolTexture(const VolTextureId &TexId, const int &nx, const int &ny, const int &nz)
Create volumetric texture.
float mUpdateTime
Update time.
void _delete3DCellArray(Cell ***c, const int &nx, const int &ny)
Delete tridimensional cell array.
void _performCalculations(const int &nx, const int &ny, const int &nz, const int &step, const int &xStart, const int &xEnd)
Perform celullar automata simulation.
void _copy3DCellArraysData(Cell ***src, Cell ***dest, const int &nx, const int &ny, const int &nz)
Copy 3d cells arrays data.
void update(const Ogre::Real &timeSinceLastFrame)
Update.
Ellipsoid class x^2 y^2 z^2 / + / + / = 1 a^2 b^2 c^2.
Definition Ellipsoid.h:39
void updateProbabilities(DataManager::Cell ***c, const int &nx, const int &ny, const int &nz, const bool &delayedResponse=true)
Update probabilities.
Definition Ellipsoid.cpp:82
float & get()
Get random number.
const Ogre::Vector3 & getSunDirection() const
Get sun direction.
Definition VClouds.h:316
float dens
Continous density.
Definition DataManager.h:50
float light
Light absorcion.
Definition DataManager.h:53
bool hum
Humidity, phase and cloud.
Definition DataManager.h:44