From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/cloud__scape_8cpp-source.html | 870 +++++++++++++++++++++++++ 1 file changed, 870 insertions(+) create mode 100644 docs/doxygen/nel/cloud__scape_8cpp-source.html (limited to 'docs/doxygen/nel/cloud__scape_8cpp-source.html') diff --git a/docs/doxygen/nel/cloud__scape_8cpp-source.html b/docs/doxygen/nel/cloud__scape_8cpp-source.html new file mode 100644 index 00000000..12f3e571 --- /dev/null +++ b/docs/doxygen/nel/cloud__scape_8cpp-source.html @@ -0,0 +1,870 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

cloud_scape.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2002 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "std3d.h"
+00027 #include "cloud_scape.h"
+00028 #include "3d/driver.h"
+00029 #include "nel/3d/scissor.h"
+00030 #include "nel/3d/viewport.h"
+00031 
+00032 // ------------------------------------------------------------------------------------------------
+00033 using namespace NLMISC;
+00034 
+00035 namespace NL3D
+00036 {
+00037 
+00038 // ------------------------------------------------------------------------------------------------
+00039 #define SQR(x) (x)*(x)
+00040 
+00041 #define MAX_DIST        400.0f
+00042 #define MAX_CLOUDS      256
+00043 // QUEUE_SIZE must be at least 2*MAX_CLOUDS
+00044 #define QUEUE_SIZE      512 
+00045 
+00046 // ------------------------------------------------------------------------------------------------
+00047 // SCloudTexture3D
+00048 // ------------------------------------------------------------------------------------------------
+00049 
+00050 // ------------------------------------------------------------------------------------------------
+00051 SCloudTexture3D::SCloudTexture3D ()
+00052 {
+00053         Mem = NULL;
+00054         ToLight.initUnlit();
+00055         ToLight.setShader (CMaterial::Normal);
+00056         //ToLight.setTexture (0, Tex);
+00057         ToLight.setZFunc (CMaterial::always);
+00058         ToLight.setZWrite (false);
+00059         ToLight.texEnvOpRGB (0, CMaterial::Replace);
+00060         ToLight.texEnvArg0RGB (0, CMaterial::Diffuse, CMaterial::SrcColor);
+00061         ToLight.texEnvOpAlpha (0, CMaterial::Replace);
+00062         ToLight.texEnvArg0Alpha (0, CMaterial::Texture, CMaterial::InvSrcAlpha);
+00063         ToLight.setBlend (true);
+00064         ToLight.setBlendFunc (CMaterial::invsrcalpha, CMaterial::srcalpha);
+00065         ToLight.setColor (CRGBA(0,0,0,255));
+00066 
+00067         ToBill.initUnlit();
+00068         ToBill.setZFunc (CMaterial::always);
+00069         ToBill.setZWrite (false);
+00070         ToBill.setDoubleSided(true);
+00071 
+00072         ToBill.texEnvOpRGB (0, CMaterial::Add);
+00073         ToBill.texEnvArg0RGB (0, CMaterial::Texture, CMaterial::SrcColor);
+00074         ToBill.texEnvArg1RGB (0, CMaterial::Diffuse, CMaterial::SrcColor);
+00075         ToBill.setColor (CRGBA(80,80,80,255));
+00076 
+00077         ToBill.texEnvOpAlpha (0, CMaterial::Replace);
+00078         ToBill.texEnvArg0Alpha (0, CMaterial::Texture, CMaterial::SrcAlpha);
+00079 
+00080         ToBill.texEnvOpRGB (1, CMaterial::Modulate);
+00081         ToBill.texEnvArg0RGB (1, CMaterial::Previous, CMaterial::SrcColor);
+00082         ToBill.texEnvArg1RGB (1, CMaterial::Previous, CMaterial::SrcAlpha);
+00083         ToBill.texEnvOpAlpha (1, CMaterial::Replace);
+00084         ToBill.texEnvArg0Alpha (1, CMaterial::Previous, CMaterial::SrcAlpha);
+00085 
+00086         ToBill.setBlendFunc (CMaterial::one, CMaterial::invsrcalpha);
+00087         ToBill.setBlend (true);
+00088 }
+00089 
+00090 // ------------------------------------------------------------------------------------------------
+00091 void SCloudTexture3D::init (uint32 nWidth, uint32 nHeight, uint32 nDepth)
+00092 {
+00093         if (Mem != NULL)
+00094                 return;
+00095 
+00096         Width = raiseToNextPowerOf2 (nWidth);
+00097         Height = raiseToNextPowerOf2 (nHeight);
+00098         Depth = raiseToNextPowerOf2 (nDepth);
+00099         uint32 vdpo2 = getPowerOf2(Depth);
+00100         NbW = 1 << (vdpo2 / 2);
+00101         if ((vdpo2 & 1) != 0)
+00102                 NbH = 2 << (vdpo2 / 2);
+00103         else
+00104                 NbH = 1 << (vdpo2 / 2);
+00105 
+00106         Mem = new uint8[4*NbW*Width*NbH*Height];
+00107         Tex = new CTextureMem (Mem, 4*NbW*Width*NbH*Height, true, false, NbW*Width, NbH*Height, CBitmap::RGBA);
+00108 
+00109         Tex->setWrapS (ITexture::Clamp);
+00110         Tex->setWrapT (ITexture::Clamp);
+00111         Tex->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
+00112         Tex->setReleasable (false);
+00113         Tex->generate ();
+00114 
+00115         ToLight.setTexture (0, Tex);
+00116 
+00117         ToBill.setTexture(0, Tex);
+00118         ToBill.setTexture(1, Tex);
+00119 }
+00120 
+00121 // ------------------------------------------------------------------------------------------------
+00122 // SCloudTextureClamp
+00123 // ------------------------------------------------------------------------------------------------
+00124 
+00125 // ------------------------------------------------------------------------------------------------
+00126 SCloudTextureClamp::SCloudTextureClamp ()
+00127 {
+00128         Mem = NULL;
+00129         ToClamp.initUnlit();
+00130         ToClamp.setShader (CMaterial::Normal);
+00131         ToClamp.texEnvOpAlpha (0, CMaterial::Add);
+00132         ToClamp.texEnvArg0Alpha (0, CMaterial::Texture, CMaterial::SrcAlpha);
+00133         ToClamp.texEnvArg1Alpha (0, CMaterial::Diffuse, CMaterial::SrcAlpha);
+00134         ToClamp.setColor (CRGBA(255,255,255,255));
+00135         ToClamp.setBlend (true);
+00136         ToClamp.setBlendFunc (CMaterial::one, CMaterial::one);
+00137         ToClamp.setZFunc (CMaterial::always);
+00138         ToClamp.setZWrite (false);
+00139 
+00140 }
+00141 
+00142 // ------------------------------------------------------------------------------------------------
+00143 void SCloudTextureClamp::init (uint32 nWidth, uint32 nHeight, uint32 nDepth, const std::string &filename)
+00144 {
+00145         if (Mem != NULL)
+00146                 return;
+00147         
+00148         Width = raiseToNextPowerOf2 (nWidth);
+00149         Height = raiseToNextPowerOf2 (nHeight);
+00150         Depth = raiseToNextPowerOf2 (nDepth);
+00151         uint32 vdpo2 = getPowerOf2(Depth);
+00152         NbW = 1 << (vdpo2 / 2);
+00153         if ((vdpo2 & 1) != 0)
+00154                 NbH = 2 << (vdpo2 / 2);
+00155         else
+00156                 NbH = 1 << (vdpo2 / 2);
+00157 
+00158         Mem = new uint8[NbW*Width*NbH*Height];
+00159         uint32 i, j;
+00160 
+00161         if (filename == "")
+00162         {
+00163                 // No filename so init with default
+00164                 for (i = 0; i < NbW; ++i)
+00165                 {
+00166                         for (j = 0; j < NbH; ++j)
+00167                         {
+00168                                 uint32 d = i+j*NbW;
+00169                                 uint32 k, l;
+00170                                 for (k = 0; k < Width; ++k)
+00171                                 for (l = 0; l < Height; ++l)
+00172                                 {
+00173                                         float x = k+0.5f;
+00174                                         float y = l+0.5f;
+00175                                         float z = d+0.5f;
+00176                                         float xc = Width/2.0f;
+00177                                         float yc = Height/2.0f;
+00178                                         float zc = Depth/2.0f;
+00179 
+00180                                         float r = (x-xc)*(x-xc)/(Width*Width/4.0f) + (y-yc)*(y-yc)/(Height*Height/4.0f) 
+00181                                                         + (z-zc)*(z-zc)/(Depth*Depth/4.0f);
+00182 
+00183                                         uint8 col = 255;
+00184                                         if (r < 1.0f)
+00185                                         {
+00186                                                 col = (uint8)((r)*223+32);
+00187                                         }
+00188                                         Mem[i*Width+k + (j*Height+l)*NbW*Width] = col;
+00189                                 }
+00190                         }
+00191                 }
+00192         }
+00193         else
+00194         {
+00195                 // Load file TODO !
+00196         }
+00197 
+00198         Tex = new CTextureMem (Mem, NbW*Width*NbH*Height, true, false, NbW*Width, NbH*Height, CBitmap::Alpha);
+00199         Tex->setWrapS (ITexture::Repeat);
+00200         Tex->setWrapT (ITexture::Repeat);
+00201         Tex->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
+00202 
+00203         Tex->touch();
+00204         Tex->setReleasable (false);
+00205         Tex->generate();
+00206 
+00207         ToClamp.setTexture(0, Tex);
+00208 
+00209 }
+00210 
+00211 
+00212 // ------------------------------------------------------------------------------------------------
+00213 // CCloudScape
+00214 // ------------------------------------------------------------------------------------------------
+00215 
+00216 // ------------------------------------------------------------------------------------------------
+00217 CCloudScape::CCloudScape (NL3D::IDriver *pDriver) : _Noise3D (pDriver)
+00218 {
+00219         _Driver = pDriver;
+00220         // Misc purpose VB
+00221         _VertexBuffer.setVertexFormat (CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag);
+00222         _VertexBuffer.setNumVertices (4);
+00223 
+00224         // Material used for cleaning
+00225         _MatClear.initUnlit();
+00226         _MatClear.setDoubleSided (true);
+00227         _MatClear.setZFunc (CMaterial::always);
+00228         _MatClear.setZWrite (false);
+00229         _MatClear.setBlend (false);
+00230 
+00231         _MatBill.initUnlit();
+00232         _MatBill.setShader (CMaterial::Normal); // not needed
+00233 
+00234         _MatBill.texEnvOpRGB (0, CMaterial::Replace);
+00235         _MatBill.texEnvArg0RGB (0, CMaterial::Texture, CMaterial::SrcColor);
+00236 
+00237         _MatBill.texEnvOpAlpha (0, CMaterial::Replace);
+00238         _MatBill.texEnvArg0Alpha (0, CMaterial::Texture, CMaterial::SrcAlpha);
+00239 
+00240         _MatBill.texEnvOpRGB (1, CMaterial::InterpolateDiffuse);
+00241         _MatBill.texEnvArg0RGB (1, CMaterial::Texture, CMaterial::SrcColor);
+00242         _MatBill.texEnvArg1RGB (1, CMaterial::Previous, CMaterial::SrcColor);
+00243 
+00244         _MatBill.texEnvOpAlpha (1, CMaterial::InterpolateDiffuse);
+00245         _MatBill.texEnvArg0Alpha (1, CMaterial::Texture, CMaterial::SrcAlpha);
+00246         _MatBill.texEnvArg1Alpha (1, CMaterial::Previous, CMaterial::SrcAlpha);
+00247 
+00248         _MatBill.setBlend (true);
+00249         _MatBill.setBlendFunc(CMaterial::one, CMaterial::invsrcalpha);
+00250         _MatBill.setZFunc (CMaterial::always);
+00251         _MatBill.setZWrite (false);
+00252         _MatBill.setDoubleSided (true);
+00253         _MatBill.setAlphaTest(true);
+00254         _MatBill.setAlphaTestThreshold(2.0f/256.0f);
+00255 
+00256         _LODQualityThreshold = 160.0f;
+00257         _IsIncomingCSS = false;
+00258         _DebugQuad = false;
+00259         _NbHalfCloudToUpdate = 1;
+00260 }
+00261 
+00262 // ------------------------------------------------------------------------------------------------
+00263 CCloudScape::~CCloudScape ()
+00264 {
+00265 }
+00266 
+00267 // ------------------------------------------------------------------------------------------------
+00268 void CCloudScape::init (SCloudScapeSetup *pCSS, NL3D::CCamera *pCamera)
+00269 {
+00270         _ViewerCam = pCamera;
+00271         
+00272         _Noise3D.init();
+00273 
+00274         _AllClouds.resize (MAX_CLOUDS, CCloud(this));
+00275         _CloudPower.resize (MAX_CLOUDS);
+00276         _ShouldProcessCloud.resize (MAX_CLOUDS);
+00277 
+00278         // For the moment only one clamp texture (generated)
+00279         Tex3DTemp.init (64, 32, 32);
+00280         TexClamp.init (64, 32, 32,"");
+00281 
+00282         if (pCSS != NULL)
+00283         {
+00284                 _CurrentCSS = *pCSS;
+00285                 _NewCSS = *pCSS;
+00286                 _OldCSS = *pCSS;
+00287         }
+00288         _IsIncomingCSS = false;
+00289         _TimeNewCSS = 60.0*60.0;
+00290 
+00291         uint32 i;
+00292         for (i = 0; i < MAX_CLOUDS; ++i)
+00293         {
+00294                 float newX, newY, newZ, newSizeX, newSizeY, newSizeZ;
+00295 
+00296                 CCloud &c = _AllClouds[i];
+00297 
+00298                 c.setTex3DTemp (Tex3DTemp);
+00299                 c.setTexClamp (TexClamp);
+00300 
+00301                 while (true)
+00302                 {
+00303                         bool bRecalc = false;
+00304                         newX = MAX_DIST*(1.0f-2.0f*(((float)rand())/RAND_MAX));
+00305                         newY = MAX_DIST*(1.0f-2.0f*(((float)rand())/RAND_MAX));
+00306                         newZ = 85.0f+40.0f*(1.0f-2.0f*(((float)rand())/RAND_MAX));
+00307 
+00308                         newSizeX = 60.0f+10.0f*(1.0f-2.0f*(((float)rand())/RAND_MAX));
+00309                         newSizeY = 30.0f+10.0f*(1.0f-2.0f*(((float)rand())/RAND_MAX));
+00310                         newSizeZ = 30.0f+10.0f*(1.0f-2.0f*(((float)rand())/RAND_MAX));
+00311                         float f = 0.7f+0.3f*((float)rand())/RAND_MAX;
+00312                         newSizeX *= 1.5f*f;
+00313                         newSizeY *= 1.5f*f;
+00314                         newSizeZ *= 1.5f*f;
+00315 
+00316                         float d = sqrtf(SQR(newX)+SQR(newY));
+00317                         if (d > MAX_DIST) bRecalc = true;
+00318 
+00319                         float r1 = sqrtf(SQR(newSizeX/2)+SQR(newSizeY/2)+SQR(newSizeZ/2));
+00320                         for (uint32 k = 0;k < i; ++k)
+00321                         {
+00322                                 CCloud &c2 = _AllClouds[k];
+00323 
+00324                                 if ((fabs(newX-c2.getX()) < (newSizeX/2+c2.getSizeX()/2)) && 
+00325                                         (fabs(newY-c2.getY()) < (newSizeY/2+c2.getSizeY()/2)) && 
+00326                                         (fabs(newZ-c2.getZ()) < (newSizeZ/2+c2.getSizeZ()/2)))
+00327                                         bRecalc = true;
+00328                         }
+00329                         if (!bRecalc) break;
+00330                 }
+00331 
+00332                 c.init (64, 32, 32, 0.122f, 4);
+00333                 c.setX (newX-newSizeX/2);
+00334                 c.setY (newY-newSizeY/2);
+00335                 c.setZ (newZ-newSizeZ/2);
+00336 
+00337                 c.setSizeX (newSizeX);
+00338                 c.setSizeY (newSizeY);
+00339                 c.setSizeZ (newSizeZ);
+00340 
+00341                 c.Time = 0;
+00342                 c.FuturTime = _CurrentCSS.NbCloud * 2 * (0.04/_NbHalfCloudToUpdate);
+00343                 if (i < _CurrentCSS.NbCloud)
+00344                 {
+00345                         _CloudPower[i] = 255;
+00346                         _ShouldProcessCloud[i] = true;
+00347                 }
+00348                 else
+00349                 {
+00350                         _CloudPower[i] = 0;
+00351                         _ShouldProcessCloud[i] = false;
+00352                 }
+00353         }
+00354 
+00355         _SortedClouds.resize (MAX_CLOUDS);
+00356 
+00357         _CloudSchedulerSize = _CurrentCSS.NbCloud;
+00358         _CloudSchedulerLastAdded.resize (MAX_CLOUDS);
+00359         _FrameCounter = 0;
+00360         _CloudScheduler.clear();
+00361         for (i = 0; i < MAX_CLOUDS; ++i)
+00362                 _CloudSchedulerLastAdded[i].ValidPos = false;
+00363 
+00364         for (i = 0; i < QUEUE_SIZE; ++i)
+00365         {
+00366                 sint32 nCloudNb = i%_CurrentCSS.NbCloud;
+00367                 SCloudSchedulerEntry cse;
+00368                 cse.CloudIndex = nCloudNb;
+00369                 if (_CloudSchedulerLastAdded[nCloudNb].ValidPos == true)
+00370                 {
+00371                         SCloudSchedulerEntry &lastCSE = *_CloudSchedulerLastAdded[nCloudNb].Pos;
+00372                         sint32 delta = _FrameCounter - lastCSE.Frame;
+00373                         lastCSE.DeltaNextCalc = delta;
+00374                 }
+00375                 cse.Frame = _FrameCounter;
+00376                 cse.Ambient = _CurrentCSS.Ambient;
+00377                 cse.Diffuse = _CurrentCSS.Diffuse;
+00378                 cse.Power = _CloudPower[cse.CloudIndex];
+00379                 _CloudSchedulerLastAdded[nCloudNb].Pos = _CloudScheduler.insert(_CloudScheduler.end(), cse);
+00380                 _CloudSchedulerLastAdded[nCloudNb].ValidPos = true;
+00381 //              _CloudSchedulerLastAdded[nCloudNb].Pos = _CloudScheduler.end()-1;
+00382                 ++_FrameCounter;
+00383         }
+00384         _GlobalTime = 0.0f;
+00385         _DTRest = 0.0f;
+00386         _Generate = true;
+00387         _AverageFrameRate.init(16);
+00388         for (i = 0; i < 16; ++i)
+00389                 _AverageFrameRate.addValue (40.0f/1000.0f);
+00390 
+00391         _ExtrapolatedPriorities.resize (MAX_CLOUDS);
+00392 
+00393         for (i = 0; i < QUEUE_SIZE; ++i)
+00394                 anim (41.0/1000.0, _ViewerCam);
+00395 }
+00396 
+00397 // ------------------------------------------------------------------------------------------------
+00398 void CCloudScape::set (SCloudScapeSetup &css)
+00399 {
+00400         _IncomingCSS = css;
+00401         _IsIncomingCSS = true;
+00402 }
+00403 
+00404 // ------------------------------------------------------------------------------------------------
+00405 void CCloudScape::anim (double dt, NL3D::CCamera *pCamera)
+00406 {
+00407         sint32 i;
+00408 
+00409         _ViewerCam = pCamera;
+00410 
+00411         // 10 fps -> 200 fps
+00412         if (dt > 0.1) dt = 0.1;
+00413         if (dt < 0.005) dt = 0.005;
+00414 
+00415         _DeltaTime = dt;
+00416         _GlobalTime += _DeltaTime;
+00417         _AverageFrameRate.addValue ((float)_DeltaTime);
+00418 
+00419         // Animate the CSS
+00420         if (_TimeNewCSS > _NewCSS.TimeToChange)
+00421         {
+00422                 _CurrentCSS = _NewCSS;
+00423                 _OldCSS = _NewCSS;
+00424                 if (_IsIncomingCSS)
+00425                 {
+00426                         _IsIncomingCSS = false;
+00427                         _NewCSS = _IncomingCSS;
+00428                         _TimeNewCSS = 0;
+00429                         if (_NewCSS.NbCloud > _OldCSS.NbCloud)
+00430                         for (i = 0; i < (sint32)(_NewCSS.NbCloud-_OldCSS.NbCloud); ++i)
+00431                         {
+00432                                 CCloud &c = _AllClouds[_OldCSS.NbCloud+i];
+00433                                 c.CloudPower = 0;
+00434                                 _CloudPower[_OldCSS.NbCloud+i] = 0;
+00435                         }
+00436                 }
+00437         }
+00438         else
+00439         {
+00440                 float inter = (float)(_TimeNewCSS / _NewCSS.TimeToChange);
+00441                 _CurrentCSS.WindSpeed = (_NewCSS.WindSpeed - _OldCSS.WindSpeed)*inter + _OldCSS.WindSpeed;
+00442                 _CurrentCSS.CloudSpeed = (_NewCSS.CloudSpeed - _OldCSS.CloudSpeed)*inter + _OldCSS.CloudSpeed;
+00443 
+00444                 _CurrentCSS.Ambient.R = (uint8)((_NewCSS.Ambient.R - _OldCSS.Ambient.R)*inter + _OldCSS.Ambient.R);
+00445                 _CurrentCSS.Ambient.G = (uint8)((_NewCSS.Ambient.G - _OldCSS.Ambient.G)*inter + _OldCSS.Ambient.G);
+00446                 _CurrentCSS.Ambient.B = (uint8)((_NewCSS.Ambient.B - _OldCSS.Ambient.B)*inter + _OldCSS.Ambient.B);
+00447                 _CurrentCSS.Ambient.A = (uint8)((_NewCSS.Ambient.A - _OldCSS.Ambient.A)*inter + _OldCSS.Ambient.A);
+00448 
+00449                 _CurrentCSS.Diffuse.R = (uint8)((_NewCSS.Diffuse.R - _OldCSS.Diffuse.R)*inter + _OldCSS.Diffuse.R);
+00450                 _CurrentCSS.Diffuse.G = (uint8)((_NewCSS.Diffuse.G - _OldCSS.Diffuse.G)*inter + _OldCSS.Diffuse.G);
+00451                 _CurrentCSS.Diffuse.B = (uint8)((_NewCSS.Diffuse.B - _OldCSS.Diffuse.B)*inter + _OldCSS.Diffuse.B);
+00452                 _CurrentCSS.Diffuse.A = (uint8)((_NewCSS.Diffuse.A - _OldCSS.Diffuse.A)*inter + _OldCSS.Diffuse.A);
+00453 
+00454                 if (_NewCSS.NbCloud > _OldCSS.NbCloud)
+00455                 {
+00456                         // Add some clouds
+00457                         float slice = (_NewCSS.TimeToChange/4) / (_NewCSS.NbCloud-_OldCSS.NbCloud);
+00458                         sint32 diffCloud = _NewCSS.NbCloud-_OldCSS.NbCloud;
+00459 
+00460                         _CurrentCSS.NbCloud = _OldCSS.NbCloud + (1+(uint32)(_TimeNewCSS/slice));
+00461                         if (_CurrentCSS.NbCloud > _NewCSS.NbCloud)
+00462                                 _CurrentCSS.NbCloud = _NewCSS.NbCloud;
+00463 
+00464                         for (i = 0; i < diffCloud; ++i)
+00465                         {
+00466                                 _ShouldProcessCloud[_OldCSS.NbCloud+i] = true;
+00467                                 if (_TimeNewCSS < i*slice)
+00468                                         _CloudPower[_OldCSS.NbCloud+i] = 1;
+00469                                 else if (_TimeNewCSS > (i*slice+3*_NewCSS.TimeToChange/4))
+00470                                         _CloudPower[_OldCSS.NbCloud+i] = 255;
+00471                                 else
+00472                                         _CloudPower[_OldCSS.NbCloud+i] = (uint8)(255*(_TimeNewCSS-i*slice)/(3*_NewCSS.TimeToChange/4));
+00473                         }
+00474                 }
+00475                 else
+00476                 {
+00477                         // Remove some clouds
+00478                         float slice = (_NewCSS.TimeToChange/4) / (_OldCSS.NbCloud-_NewCSS.NbCloud);
+00479                         sint32 diffCloud = _OldCSS.NbCloud-_NewCSS.NbCloud;
+00480 
+00481                         _CurrentCSS.NbCloud = _OldCSS.NbCloud;
+00482 
+00483                         for (i = 0; i < diffCloud; ++i)
+00484                         {
+00485                                 if (_TimeNewCSS < i*slice)
+00486                                         _CloudPower[_OldCSS.NbCloud-i-1] = 255;
+00487                                 else if (_TimeNewCSS > (i*slice+3*_NewCSS.TimeToChange/4))
+00488                                         _CloudPower[_OldCSS.NbCloud-i-1] = 0;
+00489                                 else
+00490                                         _CloudPower[_OldCSS.NbCloud-i-1] = (uint8)(255-255*(_TimeNewCSS-i*slice)/(3*_NewCSS.TimeToChange/4));
+00491                         }
+00492                 }
+00493         }
+00494 
+00495         // Make the right number of half cloud
+00496         _DTRest += dt;
+00497 
+00498         while (_DTRest > (0.04/_NbHalfCloudToUpdate))
+00499         {
+00500                 makeHalfCloud ();
+00501                 _DTRest -= 0.04/_NbHalfCloudToUpdate;
+00502 
+00503                 for (i = 0; i < MAX_CLOUDS; ++i)
+00504                 {
+00505                         CCloud &c = _AllClouds[i];
+00506                         c.Time += 0.04/_NbHalfCloudToUpdate;
+00507                 }
+00508 
+00509                 _TimeNewCSS += 0.04/_NbHalfCloudToUpdate;
+00510         }
+00511 }
+00512 
+00513 // ------------------------------------------------------------------------------------------------
+00514 void CCloudScape::makeHalfCloud ()
+00515 {
+00516         CVector Viewer = CVector(0,0,0); //_ViewerCam->getMatrix().getPos();
+00517 
+00518         if (_Generate)
+00519         {
+00520                 // Find the next cloud in the list
+00521                 SCloudSchedulerEntry FrontCSE;
+00522 
+00523                 FrontCSE = _CloudScheduler.front();
+00524 
+00525                 // Is the cloud do not have another reference in the list add it now because it should be processed
+00526                 sint32 CloudIndexToAdd = -1;
+00527                 if ((_ShouldProcessCloud[FrontCSE.CloudIndex] == true) && 
+00528                         (       (_CloudSchedulerLastAdded[FrontCSE.CloudIndex].ValidPos == false) ||
+00529                                 ((_CloudSchedulerLastAdded[FrontCSE.CloudIndex].ValidPos == true) &&
+00530                                 (_CloudSchedulerLastAdded[FrontCSE.CloudIndex].Pos == _CloudScheduler.begin()))
+00531                         ))
+00532                 {
+00533                         // It should be added now !
+00534                         CloudIndexToAdd = FrontCSE.CloudIndex;
+00535                         FrontCSE.DeltaNextCalc = QUEUE_SIZE;
+00536                 }
+00537                 else
+00538                 {
+00539                         // Choose a Cloud Index To Add at the end of the list
+00540                         uint32 nPeriodeMax = _CurrentCSS.NbCloud+_CurrentCSS.NbCloud/10;
+00541                         sint32 Priority = -10000;
+00542                         uint32 i;
+00543 
+00544                         float sumPrior = 0.0f;
+00545                         for (i = 0; i < MAX_CLOUDS; ++i)
+00546                         if (_ShouldProcessCloud[i])
+00547                         {
+00548                                 CCloud &rC = _AllClouds[i];
+00549                                 float ExtrapolatedTime = ((0.04f/_NbHalfCloudToUpdate) * QUEUE_SIZE * 2);
+00550                                 float x = rC.getLastX () + ExtrapolatedTime * _CurrentCSS.WindSpeed;
+00551                                 //float d = sqrtf(SQR(x+rC.getSizeX()/2-Viewer.x)+SQR(rC.getY()+rC.getSizeY()/2-Viewer.y)+
+00552                                 //              SQR(rC.getZ()+rC.getSizeZ()/2-Viewer.z));
+00553                                 float d = SQR(x+rC.getSizeX()/2-Viewer.x)+SQR(rC.getY()+rC.getSizeY()/2-Viewer.y)+
+00554                                                 SQR(rC.getZ()+rC.getSizeZ()/2-Viewer.z);
+00555                                 float d05 = sqrtf(d);
+00556                                 float d025 = sqrtf(d05);
+00557                                 float d075 = d05*d025;
+00558 
+00559                                 _ExtrapolatedPriorities[i] = 1.0f / d075;
+00560                                 sumPrior += _ExtrapolatedPriorities[i];
+00561                         }
+00562 
+00563                         sint32 sumJeton = 0;
+00564                         for (i = 0; i < MAX_CLOUDS; ++i)
+00565                         if (_ShouldProcessCloud[i])
+00566                         {
+00567                                 // Normalize priorities
+00568                                 float factor = ((float)QUEUE_SIZE) / sumPrior;
+00569                                 sint32 nbJeton = (sint32)(0.5f+(factor * _ExtrapolatedPriorities[i]));
+00570 
+00571                                 if (nbJeton < 1)
+00572                                         nbJeton = 1;
+00573 
+00574                                 _ExtrapolatedPriorities[i] = (float)nbJeton;
+00575                                 sumJeton += nbJeton;
+00576                         }
+00577 
+00578                         if (sumJeton > QUEUE_SIZE)
+00579                         {
+00580                                 do
+00581                                 {
+00582                                         for (i = 0; i < MAX_CLOUDS; ++i)
+00583                                         if (_ShouldProcessCloud[i])
+00584                                         {
+00585                                                 if (_ExtrapolatedPriorities[i] > 1)
+00586                                                 {
+00587                                                         _ExtrapolatedPriorities[i] -= 1;
+00588                                                         --sumJeton;
+00589                                                         if (sumJeton == QUEUE_SIZE) break;
+00590                                                 }
+00591                                         }
+00592                                 }
+00593                                 while (sumJeton > QUEUE_SIZE);
+00594                         }
+00595 
+00596                         for (i = 0; i < MAX_CLOUDS; ++i)
+00597                         if (_ShouldProcessCloud[i])
+00598                         {                               
+00599                                 // Cloud Period
+00600                                 sint32 newPriority = nPeriodeMax;
+00601                                 // Is there a last entry in array ?
+00602                                 if (_CloudSchedulerLastAdded[i].ValidPos == true)
+00603                                 {
+00604                                         SCloudSchedulerEntry &rLastCSE = *_CloudSchedulerLastAdded[i].Pos;
+00605                                         newPriority = (sint32)(QUEUE_SIZE/_ExtrapolatedPriorities[i]);
+00606                                         newPriority = (_FrameCounter -  rLastCSE.Frame) - newPriority;
+00607                                 }
+00608                                 else
+00609                                 {
+00610                                         newPriority = 10000;
+00611                                 }
+00612                                 if (newPriority > Priority)
+00613                                 {
+00614                                         Priority = newPriority;
+00615                                         CloudIndexToAdd = i;
+00616                                 }
+00617                         }
+00618                         nlassert (CloudIndexToAdd != -1);
+00619                 }
+00620 
+00621                 // Ok now we have a good cloud index to add so make the new cloud entry
+00622                 SCloudSchedulerEntry newCSE;
+00623 
+00624                 newCSE.CloudIndex = CloudIndexToAdd;
+00625                 newCSE.Frame = _FrameCounter;
+00626                 newCSE.Ambient = _CurrentCSS.Ambient;
+00627                 newCSE.Diffuse = _CurrentCSS.Diffuse;
+00628                 newCSE.Power = _CloudPower[CloudIndexToAdd];
+00629 
+00630                 // If the cloud where added previously to the list
+00631                 if (_CloudSchedulerLastAdded[CloudIndexToAdd].ValidPos == true)
+00632                 {
+00633                         // This means that the cloud were added from a long time ago
+00634                         SCloudSchedulerEntry &lastCSE = *_CloudSchedulerLastAdded[CloudIndexToAdd].Pos;
+00635                         sint32 delta = _FrameCounter - lastCSE.Frame;                   
+00636                         lastCSE.DeltaNextCalc = delta;
+00637 
+00638                         // But the cloud can be removed (if so we have to not process it anymore)
+00639                         if (newCSE.Power == 0)
+00640                                 _ShouldProcessCloud[CloudIndexToAdd] = false;
+00641                 }
+00642                 else
+00643                 {
+00644                         // No the cloud do not appear previously in the list... So its a new one
+00645                         _AllClouds[CloudIndexToAdd].reset (_ViewerCam);
+00646                 }
+00647 
+00648                 // If the last cloud occurence of the cloud appear at beginning so no more occurence in list
+00649                 if (_CloudSchedulerLastAdded[FrontCSE.CloudIndex].Pos == _CloudScheduler.begin())
+00650                         _CloudSchedulerLastAdded[FrontCSE.CloudIndex].ValidPos = false;
+00651 
+00652                 _CloudSchedulerLastAdded[CloudIndexToAdd].Pos = _CloudScheduler.insert(_CloudScheduler.end(), newCSE);
+00653                 _CloudSchedulerLastAdded[CloudIndexToAdd].ValidPos = true;
+00654 //              _CloudSchedulerLastAdded[CloudIndexToAdd].Pos = _CloudScheduler.end()-1;
+00655                 _CloudScheduler.pop_front ();
+00656                 ++_FrameCounter;
+00657                 // End of scheduling
+00658 
+00659                 // Get the cloud to process (this must be the next occurence of front cloud)
+00660                 std::list<SCloudSchedulerEntry>::iterator it = _CloudScheduler.begin();
+00661                 while (it != _CloudScheduler.end())
+00662                 {
+00663                         SCloudSchedulerEntry &rCSE = *it;
+00664                         if (rCSE.CloudIndex == FrontCSE.CloudIndex)
+00665                                 break;
+00666                         ++it;
+00667                 }
+00668 
+00669                 SCloudSchedulerEntry CSEToCalc;
+00670                 // The cloud is no more present in the list
+00671                 if (it == _CloudScheduler.end())
+00672                 {
+00673                         FrontCSE.DeltaNextCalc = 1;
+00674                         CSEToCalc = FrontCSE;
+00675                 }
+00676                 else
+00677                 {
+00678                         CSEToCalc = *it;
+00679                 }
+00680 
+00681                 _CurrentCloudInProcess = &_AllClouds[CSEToCalc.CloudIndex];
+00682                 CCloud &c = *_CurrentCloudInProcess;
+00683 
+00684                 // To go from Front cloud to CSEToCalc cloud we should take the front DeltaNextCalc
+00685 
+00686                 _CurrentCloudInProcessFuturTime = ((0.04/_NbHalfCloudToUpdate) * FrontCSE.DeltaNextCalc * 2);
+00687                 c.setX ((float)(c.getLastX() +  _CurrentCloudInProcessFuturTime * _CurrentCSS.WindSpeed));
+00688 
+00689                 float d2D = sqrtf(SQR(c.getX()+c.getSizeX()/2-Viewer.x)+SQR(c.getY()+c.getSizeY()/2-Viewer.y));
+00690 
+00691                 if (d2D > MAX_DIST)
+00692                         c.CloudDistAtt = 255;
+00693                 else if (d2D > (MAX_DIST-100.0f))
+00694                         c.CloudDistAtt = (uint8)(255*((d2D-(MAX_DIST-100.0f))/100.0f));
+00695                 else
+00696                         c.CloudDistAtt = 0;
+00697 
+00698                 c.LastCloudPower = c.CloudPower;
+00699                 c.CloudPower = CSEToCalc.Power;
+00700                 c.CloudDiffuse = CSEToCalc.Diffuse;
+00701                 c.CloudAmbient = CSEToCalc.Ambient;
+00702 
+00703                 c.anim (_CurrentCloudInProcessFuturTime*_CurrentCSS.CloudSpeed, 
+00704                                 _CurrentCloudInProcessFuturTime*_CurrentCSS.WindSpeed);
+00705 
+00706                 c.generate (_Noise3D);
+00707 
+00708         }
+00709         else
+00710         {
+00711                 CCloud &c = *_CurrentCloudInProcess;
+00712 
+00713                 c.Time = 0;
+00714                 c.FuturTime = _CurrentCloudInProcessFuturTime;
+00715                 c.light();
+00716 
+00717                 if (c.getX() > MAX_DIST)
+00718                 {
+00719                         c.setX (c.getX() - (2 * MAX_DIST));
+00720                         c.setLooping ();
+00721                 }
+00722                 
+00723                 float r = sqrtf(SQR(c.getSizeX()/2)+SQR(c.getSizeY()/2)+SQR(c.getSizeZ()/2));
+00724                 float d2D = sqrtf(SQR(c.getX()+c.getSizeX()/2-Viewer.x)+SQR(c.getY()+c.getSizeY()/2-Viewer.y));
+00725                 float d = sqrtf(SQR(c.getX()+c.getSizeX()/2-Viewer.x)+SQR(c.getY()+c.getSizeY()/2-Viewer.y)+
+00726                                                 SQR(c.getZ()+c.getSizeZ()/2-Viewer.z));
+00727                 uint32 lookAtSize = (uint32)(_LODQualityThreshold*r/d);
+00728                 lookAtSize = raiseToNextPowerOf2 (lookAtSize);
+00729                 if (lookAtSize > 128) lookAtSize = 128;
+00730 
+00731                 c.genBill (_ViewerCam, lookAtSize);
+00732         }
+00733         _Generate = !_Generate;
+00734 }
+00735 
+00736 // ------------------------------------------------------------------------------------------------
+00737 void CCloudScape::render ()
+00738 {
+00739         uint32 i, j;
+00740         
+00741         CVector Viewer = CVector (0,0,0);
+00742 
+00743         CMatrix viewMat;
+00744         viewMat = _ViewerCam->getMatrix ();
+00745         viewMat.setPos(CVector(0,0,0));
+00746         viewMat.invert ();
+00747         CScissor s;
+00748         s.initFullScreen ();
+00749         _Driver->setupScissor (s);
+00750         CViewport v;
+00751         _Driver->setupViewport (v);
+00752         CFrustum f = _ViewerCam->getFrustum();
+00753         _Driver->setFrustum (f.Left, f.Right, f.Bottom, f.Top, f.Near, f.Far, f.Perspective);
+00754         _Driver->setupViewMatrix (viewMat);
+00755         _Driver->setupModelMatrix (CMatrix::Identity);
+00756 
+00757         uint32 nNbCloudToRender = 0;
+00758 
+00759         for (i = 0; i < MAX_CLOUDS; ++i)
+00760         {
+00761                 CCloud &c = _AllClouds[i];
+00762                 SSortedCloudEntry &sce = _SortedClouds[nNbCloudToRender];
+00763                 sce.Cloud = &c;
+00764                 sce.Distance = sqrtf(SQR(c.getX()+c.getSizeX()/2-Viewer.x)+SQR(c.getY()+c.getSizeY()/2-Viewer.y)+
+00765                                                 SQR(c.getZ()+c.getSizeZ()/2-Viewer.z));
+00766                 nNbCloudToRender++;
+00767         }
+00768 
+00769         for (i = 0; i < nNbCloudToRender-1; ++i)
+00770         for (j = i+1; j < nNbCloudToRender; ++j)
+00771         {
+00772                 if (_SortedClouds[i].Distance < _SortedClouds[j].Distance)
+00773                 {
+00774                         SSortedCloudEntry sceTmp = _SortedClouds[i];
+00775                         _SortedClouds[i] = _SortedClouds[j];
+00776                         _SortedClouds[j] = sceTmp;
+00777                 }
+00778         }
+00779 
+00780         for (i = 0; i < nNbCloudToRender; ++i)
+00781         {
+00782                 CCloud *pC = _SortedClouds[i].Cloud;
+00783                 if ((pC->CloudPower > 0) || (pC->LastCloudPower > 0))
+00784                         pC->dispBill (_ViewerCam);
+00785         }
+00786 }
+00787 
+00788 // ------------------------------------------------------------------------------------------------
+00789 uint32 CCloudScape::getMemSize()
+00790 {
+00791         uint32 nMemSize = 0;
+00792         for (uint32 i = 0; i < MAX_CLOUDS; ++i)
+00793         {
+00794                 CCloud &c = _AllClouds[i];
+00795                 nMemSize += c.getMemSize();
+00796         }
+00797         return nMemSize;
+00798 }
+00799 
+00800 } // namespace NL3D
+00801 
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1