36 , mNx(0), mNy(0), mNz(0)
37 , mCurrentTransition(0)
39 , mStep(0), mXStart(0), mXEnd(0)
40 , mMaxNumberOfClouds(250)
41 , mVolTexToUpdate(true)
44 for (
int k = 0; k < 2; k++)
62 for (
int k = 0; k < 2; k++)
64 Ogre::TextureManager::getSingleton().remove(
mVolTextures[k]->getName());
168 for (
int k = 0; k < 2; k++)
183 for (
int k =
mStep+1; k < 4; k++)
215 for (u = 0; u < nx; u++)
217 c[u] =
new Cell* [ny];
219 for (v = 0; v < ny; v++)
221 c[u][v] =
new Cell[nz];
230 for (u = 0; u < nx; u++)
232 for (v = 0; v < ny; v++)
234 for (
w = 1;
w < nz;
w++)
236 c[u][v][
w].
act =
false;
237 c[u][v][
w].
cld =
false;
238 c[u][v][
w].
hum =
false;
244 c[u][v][
w].
dens = 0.0f;
257 for (u = 0; u < nx; u++)
259 for (v = 0; v < ny; v++)
274 for (u = 0; u < nx; u++)
276 for (v = 0; v < ny; v++)
278 for (
w = 0;
w < nz;
w++)
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;
298 Ogre::Vector3 maxcloudsize = AverageCloudsSize*Ogre::Vector3(
mNx/14,
mNy/14,
static_cast<int>(
static_cast<float>(
mNz)/2.75));
301 Ogre::Vector3 currentdimensions, currentPosition;
302 std::vector<Ellipsoid*>::const_iterator mEllipsoidsIt;
307 currentdimensions = (*mEllipsoidsIt)->getDimensions();
309 if (currentdimensions.x / maxcloudsize.x < 0.5 || currentdimensions.x / maxcloudsize.x > 2)
311 currentdimensions.x = maxcloudsize.x + Ogre::Math::RangeRandom(-0.2,0.2)*maxcloudsize.x;
313 if (currentdimensions.y / maxcloudsize.y < 0.5 || currentdimensions.y / maxcloudsize.y > 2)
315 currentdimensions.y = maxcloudsize.y + Ogre::Math::RangeRandom(-0.2,0.2)*maxcloudsize.y;
317 if (currentdimensions.z / maxcloudsize.z < 0.5 || currentdimensions.z / maxcloudsize.z > 2)
319 currentdimensions.z = maxcloudsize.z + Ogre::Math::RangeRandom(-0.2,0.15)*maxcloudsize.z;
322 (*mEllipsoidsIt)->setDimensions(currentdimensions);
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))));
330 while (
static_cast<unsigned int>(numberofclouds) <
mEllipsoids.size())
336 Ogre::Vector3 newclouddimensions;
337 while (
static_cast<unsigned int>(numberofclouds) >
mEllipsoids.size())
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);
345 if (!delayedResponse)
347 for (
int k = 0; k < 4; k++)
362 if (UpdateProbabilities)
372 for (u = 0; u < nx; u++)
374 for (v = 0; v < ny; v++)
376 for (
w = 0;
w < nz;
w++)
384 c[u][v][
w].
act =
false;
385 c[u][v][
w].
cld =
false;
386 c[u][v][
w].
hum =
false;
400 std::vector<Ellipsoid*>::const_iterator mEllipsoidsIt;
404 (*mEllipsoidsIt)->updateProbabilities(c,nx,ny,nz,delayedResponse);
410 Ogre::Real step = 1, factor = 1;
411 Ogre::Vector3 pos = Ogre::Vector3(
x,
y,
z);
412 bool outOfBounds =
false;
414 current_iteration = 0, max_iterations = 8;
418 if ( (
int)pos.z >= nz || (
int)pos.z < 0 || factor <= 0 || current_iteration >= max_iterations)
424 u = (int)pos.x; v = (int)pos.y;
426 uu = (u<0) ? (u + nx) : u;
if (u>=nx) { uu-= nx; }
427 vv = (v<0) ? (v + ny) : v;
if (v>=ny) { vv-= ny; }
429 factor -= c[uu][vv][(int)pos.z].
dens*att*(1-
static_cast<float>(current_iteration)/max_iterations);
436 return Ogre::Math::Clamp<Ogre::Real>(factor,0,1);
447 for (u = xStart; u < xEnd; u++)
449 for (v = 0; v < ny; v++)
451 for (
w = 0;
w < nz;
w++)
467 for (u = xStart; u < xEnd; u++)
469 for (v = 0; v < ny; v++)
471 for (
w = 0;
w < nz;
w++)
485 for (u = xStart; u < xEnd; u++)
487 for (v = 0; v < ny; v++)
489 for (
w = 0;
w < nz;
w++)
503 for (u = xStart; u < xEnd; u++)
505 for (v = 0; v < ny; v++)
507 for (
w = 0;
w < nz;
w++)
522 i2r, i2m, j2r, j2m, k2r;
526 k1m = ((
z+1)>=nz) ? false : c[
x][
y][
z+1].
act;
530 k1r = ((
z-1)<0) ? false : c[
x][
y][
z-1].
act;
534 k2r = ((
z-2)<0) ? false : c[
x][
y][
z-2].
act;
539 return i1m || j1m || k1m || i1r || j1r || k1r || i2r || i2m || j2r || j2m || k2r;
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
544 int zr = ((
z-r)<0) ? 0 :
z-r,
545 zm = ((
z+r)>=nz) ? nz :
z+r,
549 for (u =
x-r; u <=
x+r; u++)
551 for (v =
y-r; v <=
y+r; v++)
553 for (
w = zr;
w < zm;
w++)
556 uu = (u<0) ? (u + nx) : u;
if (u>=nx) { uu-= nx; }
557 vv = (v<0) ? (v + ny) : v;
if (v>=ny) { vv-= ny; }
559 clouds += c[uu][vv][
w].
cld ? 1 : 0;
565 return Ogre::Math::Clamp<float>(strength*((
float)clouds)/div, 0, 1);
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 {
…}
570 return c[
x][
y][
z].
cld ? 1.0f : 0.0f;
576 = Ogre::TextureManager::getSingleton().
577 createManual(
"_SkyX_VolCloudsData"+Ogre::StringConverter::toString(TexId),
578 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
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);
597 Ogre::HardwarePixelBufferSharedPtr buffer =
mVolTextures[TexId]->getBuffer(0,0);
599 buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
600 const Ogre::PixelBox &pb = buffer->getCurrentLock();
602 Ogre::uint32 *pbptr =
reinterpret_cast<Ogre::uint32*
>(pb.data);
605 for (
z = pb.front;
z < pb.back;
z++)
607 for (
y = pb.top;
y < pb.bottom;
y++)
609 for (
x = pb.left;
x < pb.right;
x++)
611 Ogre::PixelUtil::packColour (c[
x][
y][
z].dens, c[
x][
y][
z].light, 0, 0, pb.format, &pbptr[
x]);
613 pbptr += pb.rowPitch;
615 pbptr += pb.getSliceSkip ();
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.
~DataManager()
Destructor.
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.
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.
void updateProbabilities(DataManager::Cell ***c, const int &nx, const int &ny, const int &nz, const bool &delayedResponse=true)
Update probabilities.
float & get()
Get random number.
const Ogre::Vector3 & getSunDirection() const
Get sun direction.
float dens
Continous density.
float light
Light absorcion.
bool hum
Humidity, phase and cloud.