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/vegetable_8cpp-source.html | 465 ++++++++++++++++++++++++++++ 1 file changed, 465 insertions(+) create mode 100644 docs/doxygen/nel/vegetable_8cpp-source.html (limited to 'docs/doxygen/nel/vegetable_8cpp-source.html') diff --git a/docs/doxygen/nel/vegetable_8cpp-source.html b/docs/doxygen/nel/vegetable_8cpp-source.html new file mode 100644 index 00000000..18e75e4a --- /dev/null +++ b/docs/doxygen/nel/vegetable_8cpp-source.html @@ -0,0 +1,465 @@ + + + + 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  
+

vegetable.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 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 
+00028 #include "3d/vegetable.h"
+00029 #include "nel/misc/common.h"
+00030 #include "3d/vegetable_manager.h"
+00031 #include "3d/fast_floor.h"
+00032 
+00033 
+00034 using namespace std;
+00035 using namespace NLMISC;
+00036 
+00037 
+00038 namespace NL3D 
+00039 {
+00040 
+00041 
+00042 // ***************************************************************************
+00043 // Generate random value, but seed is spacial. Take a high frequency, so it gets more the aspect of random.
+00044 static  CNoiseValue             RandomGenerator(0,1, 7.68f);
+00045 
+00046 
+00047 // ***************************************************************************
+00048 CVegetable::CVegetable()
+00049 {
+00050         // Ground style density.
+00051         setAngleGround(0);
+00052 
+00053         // Density not maximised.
+00054         MaxDensity= -1;
+00055 
+00056         // No scale.
+00057         Sxy.Abs= Sz.Abs= 1;
+00058         Sxy.Rand= Sz.Rand= 0;
+00059         // No rotation.
+00060         Rx.Abs= Ry.Abs= Rz.Abs= 0;
+00061         Rx.Rand= Ry.Rand= Rz.Rand= 0;
+00062         // No BendFactor.
+00063         BendFactor.Abs= 1;
+00064         BendFactor.Rand= 0;
+00065         BendFrequencyFactor= 1;
+00066 
+00067         // Appear at 0.
+00068         DistType= 0;
+00069 
+00070         _Manager= NULL;
+00071 }
+00072 
+00073 
+00074 // ***************************************************************************
+00075 void    CVegetable::setAngleGround(float cosAngleMin)
+00076 {
+00077         _AngleType= AngleGround;
+00078 
+00079         _CosAngleMin= cosAngleMin;
+00080         // We must be at densityFactor==1, when cosAngle==1, keeping the same formula.
+00081         _CosAngleMax= 1 + (1-cosAngleMin);
+00082 
+00083         // precalc
+00084         _CosAngleMiddle= (_CosAngleMin + _CosAngleMax)/2;
+00085         _OOCosAngleDist= _CosAngleMax - _CosAngleMiddle;
+00086         if(_OOCosAngleDist)
+00087                 _OOCosAngleDist= 1.0f / _OOCosAngleDist;
+00088 }
+00089 
+00090 // ***************************************************************************
+00091 void    CVegetable::setAngleCeiling(float cosAngleMax)
+00092 {
+00093         _AngleType= AngleCeiling;
+00094 
+00095         _CosAngleMax= cosAngleMax;
+00096         // We must be at densityFactor==1, when cosAngle==-1, keeping the same formula.
+00097         _CosAngleMin= -1 - (cosAngleMax-(-1));
+00098         
+00099         // precalc
+00100         _CosAngleMiddle= (_CosAngleMin + _CosAngleMax)/2;
+00101         _OOCosAngleDist= _CosAngleMax - _CosAngleMiddle;
+00102         if(_OOCosAngleDist)
+00103                 _OOCosAngleDist= 1.0f / _OOCosAngleDist;
+00104 }
+00105 
+00106 // ***************************************************************************
+00107 void    CVegetable::setAngleWall(float cosAngleMin, float cosAngleMax)
+00108 {
+00109         _AngleType= AngleWall;
+00110 
+00111         _CosAngleMin= cosAngleMin;
+00112         _CosAngleMax= cosAngleMax;
+00113 
+00114         // precalc
+00115         _CosAngleMiddle= (_CosAngleMin + _CosAngleMax)/2;
+00116         _OOCosAngleDist= _CosAngleMax - _CosAngleMiddle;
+00117         if(_OOCosAngleDist)
+00118                 _OOCosAngleDist= 1.0f / _OOCosAngleDist;
+00119 }
+00120 
+00121 
+00122 // ***************************************************************************
+00123 void    CVegetable::registerToManager(CVegetableManager *manager)
+00124 {
+00125         nlassert(manager);
+00126         _Manager= manager;
+00127         _VegetableShape= _Manager->getVegetableShape(ShapeName);
+00128 }
+00129 
+00130 
+00131 // ***************************************************************************
+00132 void    CVegetable::generateGroupEx(float nbInst, const CVector &posInWorld, const CVector &surfaceNormal, uint vegetSeed, std::vector<CVector2f> &instances) const
+00133 {
+00134 
+00135         // Density modulation.
+00136         //===================
+00137 
+00138         // compute cos of angle between surfaceNormal and K(0,0,1).
+00139         float   cosAngle= surfaceNormal.z;
+00140         // compute angleFactor density. Use a quadratic, because f'(_CosAngleMiddle)==0.
+00141         float   angleFact= 1 - sqr((cosAngle - _CosAngleMiddle) * _OOCosAngleDist);
+00142         angleFact= max(0.f, angleFact);
+00143         // modulate density with angleFactor.
+00144         nbInst*= angleFact;
+00145 
+00146         // Now, 0<=nbInst<+oo. If we have 0.1, it means that we have 10% chance to spawn an instance.
+00147         // So add a "random" value (with help of a noise with High frequency)
+00148         // if nbInst==0, we should never have any instance (which may arise if evalOneLevelRandom()==1).
+00149         // hence the 0.99f* which ensure that we do nbInst+= [0..1[.
+00150         nbInst+= 0.99f * RandomGenerator.evalOneLevelRandom(posInWorld);
+00151 
+00152         // and then get only the integral part.
+00153         sint    nbInstances= OptFastFloor(nbInst);
+00154         nbInstances= max(0, nbInstances);
+00155 
+00156         // resize the instances
+00157         instances.resize(nbInstances);
+00158 
+00159         // Position generation.
+00160         //===================
+00161         // For now, generate them randomly.
+00162         static CVector2f        dSeed(0.513f, 0.267f);  // random values.
+00163         CVector                         seed= posInWorld;
+00164         seed.z+= vegetSeed * 0.723f;    // 0.723f is a random value.
+00165         for(sint i=0; i<nbInstances; i++)
+00166         {
+00167                 instances[i].x= RandomGenerator.evalOneLevelRandom(seed);
+00168                 seed.x+= dSeed.x;
+00169                 instances[i].y= RandomGenerator.evalOneLevelRandom(seed);
+00170                 seed.y+= dSeed.y;
+00171         }
+00172 }
+00173 
+00174 
+00175 // ***************************************************************************
+00176 void    CVegetable::generateGroup(const CVector &posInWorld, const CVector &surfaceNormal, float area, uint vegetSeed, std::vector<CVector2f> &instances) const
+00177 {
+00178         // number of instances to generate
+00179         float   dens= Density.eval(posInWorld);
+00180         if(MaxDensity >= 0)
+00181                 dens= min(dens, MaxDensity);
+00182         float   nbInst= area * dens;
+00183 
+00184         // modulate by normal and generate them.
+00185         generateGroupEx(nbInst, posInWorld, surfaceNormal, vegetSeed, instances);
+00186 }
+00187 
+00188 
+00189 // ***************************************************************************
+00190 void    CVegetable::generateGroupBiLinear(const CVector &posInWorld, const CVector posInWorldBorder[4], const CVector &surfaceNormal, float area, uint vegetSeed, std::vector<CVector2f> &instances) const
+00191 {
+00192         sint    i;
+00193         const   float evenDistribFact= 12.25f;          // an arbitrary value to have a higher frequency for random.
+00194 
+00195         // compute how many instances to generate on borders of the patch
+00196         // ==================
+00197         float   edgeDensity[4];
+00198         for(i=0; i<4; i++)
+00199         {
+00200                 // Get number of instances generated on edges
+00201                 edgeDensity[i]= area * Density.eval(posInWorldBorder[i]);
+00202                 if(MaxDensity >= 0)
+00203                         edgeDensity[i]= min(edgeDensity[i], area * MaxDensity);
+00204                 edgeDensity[i]= max(0.f, edgeDensity[i]);
+00205         }
+00206         // Average on center of the patch for each direction.
+00207         float   edgeDensityCenterX;
+00208         float   edgeDensityCenterY;
+00209         edgeDensityCenterX= 0.5f * (edgeDensity[0] + edgeDensity[1]);
+00210         edgeDensityCenterY= 0.5f * (edgeDensity[2] + edgeDensity[3]);
+00211 
+00212         
+00213         // Average for all the patch
+00214         float   nbInstAverage= 0.5f * (edgeDensityCenterX + edgeDensityCenterY);
+00215 
+00216 
+00217         // generate instances on the patch
+00218         // ==================
+00219         generateGroupEx(nbInstAverage, posInWorld, surfaceNormal, vegetSeed, instances);
+00220 
+00221 
+00222 
+00223         // move instances x/y to follow edge repartition
+00224         // ==================
+00225         // If on a direction, both edges are 0 density, then must do a special formula
+00226         bool    middleX= edgeDensityCenterX<=1;
+00227         bool    middleY= edgeDensityCenterY<=1;
+00228         float   OOEdgeDCX=0.0;
+00229         float   OOEdgeDCY=0.0;
+00230         if(!middleX)    OOEdgeDCX= 1.0f / edgeDensityCenterX;
+00231         if(!middleY)    OOEdgeDCY= 1.0f / edgeDensityCenterY;
+00232         // for all instances
+00233         for(i=0; i<(sint)instances.size(); i++)
+00234         {
+00235                 float           x= instances[i].x;
+00236                 float           y= instances[i].y;
+00237                 // a seed for random.
+00238                 CVector         randSeed(x*evenDistribFact, y*evenDistribFact, 0);
+00239 
+00240                 // X change.
+00241                 if(middleX)
+00242                 {
+00243                         // instances are grouped at middle. this is the bijection of easeInEaseOut
+00244                         x= x+x - easeInEaseOut(x);
+00245                         x= x+x - easeInEaseOut(x);
+00246                         instances[i].x= x;
+00247                 }
+00248                 else
+00249                 {
+00250                         // Swap X, randomly. swap more on border
+00251                         // evaluate the density in X direction we have at this point.
+00252                         float   densX= edgeDensity[0]*(1-x) + edgeDensity[1]* x ;
+00253                         // If on the side of the lowest density
+00254                         if(densX < edgeDensityCenterX)
+00255                         {
+00256                                 // may swap the position 
+00257                                 float   rdSwap= (densX * OOEdgeDCX );
+00258                                 // (densX * OOEdgeDCX) E [0..1[. The more it is near 0, the more is has chance to be swapped.
+00259                                 rdSwap+= RandomGenerator.evalOneLevelRandom( randSeed );
+00260                                 if(rdSwap<1)
+00261                                         instances[i].x= 1 - instances[i].x;
+00262                         }
+00263                 }
+00264 
+00265                 // Y change.
+00266                 if(middleY)
+00267                 {
+00268                         // instances are grouped at middle. this is the bijection of easeInEaseOut
+00269                         y= y+y - easeInEaseOut(y);
+00270                         y= y+y - easeInEaseOut(y);
+00271                         instances[i].y= y;
+00272                 }
+00273                 else
+00274                 {
+00275                         // Swap Y, randomly. swap more on border
+00276                         // evaluate the density in Y direction we have at this point.
+00277                         float   densY= edgeDensity[2]*(1-y) + edgeDensity[3]* y ;
+00278                         // If on the side of the lowest density
+00279                         if(densY < edgeDensityCenterY)
+00280                         {
+00281                                 // may swap the position 
+00282                                 float   rdSwap= (densY * OOEdgeDCY);
+00283                                 // (densY * OOEdgeDCY) E [0..1[. The more it is near 0, the more is has chance to be swapped.
+00284                                 rdSwap+= RandomGenerator.evalOneLevelRandom( randSeed );
+00285                                 if(rdSwap<1)
+00286                                         instances[i].y= 1 - instances[i].y;
+00287                         }
+00288                 }
+00289 
+00290         }
+00291 
+00292 }
+00293 
+00294 
+00295 // ***************************************************************************
+00296 void    CVegetable::reserveIgAddInstances(CVegetableInstanceGroupReserve &vegetIgReserve, TVegetableWater vegetWaterState, uint numInstances) const
+00297 {
+00298         nlassert(_Manager);
+00299 
+00300         if (_VegetableShape)
+00301                 _Manager->reserveIgAddInstances(vegetIgReserve, _VegetableShape, (CVegetableManager::TVegetableWater)vegetWaterState, numInstances);
+00302 }
+00303 
+00304 
+00305 // ***************************************************************************
+00306 void    CVegetable::generateInstance(CVegetableInstanceGroup *ig, const NLMISC::CMatrix &posInWorld, 
+00307                 const NLMISC::CRGBAF &modulateAmbientColor, const NLMISC::CRGBAF &modulateDiffuseColor, float blendDistMax,
+00308                 TVegetableWater vegetWaterState, CVegetableUV8 dlmUV) const
+00309 {
+00310         nlassert(_Manager);
+00311 
+00312 
+00313         CVector         seed= posInWorld.getPos();
+00314 
+00315         // Generate Matrix.
+00316         // ===============
+00317 
+00318         // Generate a random Scale / Rotation matrix.
+00319         CMatrix         randomMat;
+00320         // setup rotation
+00321         CVector         rot;
+00322         rot.x= Rx.eval(seed);
+00323         rot.y= Ry.eval(seed);
+00324         rot.z= Rz.eval(seed);
+00325         randomMat.setRot(rot, CMatrix::ZXY);
+00326         // scale.
+00327         if(Sxy.Abs!=0 || Sxy.Rand!=0 || Sz.Abs!=0 || Sz.Rand!=0)
+00328         {
+00329                 CVector         scale;
+00330                 scale.x= scale.y= Sxy.eval(seed);
+00331                 scale.z= Sz.eval(seed);
+00332                 randomMat.scale(scale);
+00333         }
+00334 
+00335         // Final Matrix.
+00336         CMatrix         finalMatrix;
+00337         finalMatrix= posInWorld * randomMat;
+00338 
+00339         // Generate Color and factor
+00340         // ===============
+00341         CRGBAF          materialColor(1,1,1,1);
+00342         // evaluate gradients. If none, color not modified.
+00343         Color.eval(seed, materialColor);
+00344         // modulate with user
+00345         CRGBAF          ambient, diffuse;
+00346         ambient= modulateAmbientColor * materialColor;
+00347         diffuse= modulateDiffuseColor * materialColor;
+00348 
+00349         // Generate a bendFactor
+00350         float   bendFactor= BendFactor.eval(seed);
+00351         // Generate a bendPhase
+00352         float   bendPhase= BendPhase.eval(seed);
+00353 
+00354 
+00355         // Append to the vegetableManager
+00356         // ===============
+00357         if (_VegetableShape)
+00358         {
+00359                 _Manager->addInstance(ig, _VegetableShape, finalMatrix, ambient, diffuse, 
+00360                         bendFactor, bendPhase, BendFrequencyFactor, blendDistMax, 
+00361                         (CVegetableManager::TVegetableWater)vegetWaterState, dlmUV);
+00362         }
+00363 }
+00364 
+00365 
+00366 // ***************************************************************************
+00367 void    CVegetable::serial(NLMISC::IStream &f)
+00368 {
+00369         /*
+00370         Version 1:
+00371                 - add BendFrequencyFactor
+00372         Version 0:
+00373                 - base version
+00374         */
+00375         sint    ver= f.serialVersion(1);
+00376 
+00377         f.serial(ShapeName);
+00378         f.serial(Density);
+00379         f.serial(MaxDensity);
+00380         f.serial(_CosAngleMin, _CosAngleMax, _CosAngleMiddle, _OOCosAngleDist);
+00381         f.serialEnum(_AngleType);
+00382         f.serial(Sxy, Sz);
+00383         f.serial(Rx, Ry, Rz);
+00384         f.serial(BendFactor);
+00385         f.serial(BendPhase);
+00386         f.serial(Color);
+00387         f.serial(DistType);
+00388 
+00389         if(ver>=1)
+00390                 f.serial(BendFrequencyFactor);
+00391         else
+00392                 BendFrequencyFactor= 1;
+00393 }
+00394 
+00395 
+00396 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1