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

patch_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 
+00029 #include "3d/patch.h"
+00030 #include "3d/vegetable.h"
+00031 #include "3d/vegetable_manager.h"
+00032 #include "3d/landscape_vegetable_block.h"
+00033 #include "3d/landscape.h"
+00034 #include "nel/misc/vector.h"
+00035 #include "nel/misc/common.h"
+00036 #include "3d/fast_floor.h"
+00037 #include "3d/tile_vegetable_desc.h"
+00038 #include "3d/vegetable_light_ex.h"
+00039 #include "3d/patchdlm_context.h"
+00040 
+00041 
+00042 using namespace std;
+00043 using namespace NLMISC;
+00044 
+00045 namespace NL3D 
+00046 {
+00047 
+00048 
+00049 // ***************************************************************************
+00050 void            CPatch::generateTileVegetable(CVegetableInstanceGroup *vegetIg, uint distType, uint ts, uint tt,
+00051         CLandscapeVegetableBlockCreateContext &vbCreateCtx)
+00052 {
+00053         uint    i;
+00054 
+00055         // Get tile infos for vegetable
+00056         // =========================
+00057 
+00058         // Get the state for this vegetable tile
+00059         CTileElement::TVegetableInfo    vegetWaterState= Tiles[tt * OrderS + ts].getVegetableState();
+00060         // If vegetable disabled, skip!
+00061         if(vegetWaterState == CTileElement::VegetableDisabled)
+00062                 return;
+00063 
+00064         // get the tileId under this tile (<=> the tile material)
+00065         uint    tileId= Tiles[tt * OrderS + ts].Tile[0];
+00066 
+00067         // get list of vegetable for this tile, and for hist distanceType category.
+00068         const CTileVegetableDesc                &tileVegetDesc= getLandscape()->getTileVegetableDesc(tileId);
+00069         const std::vector<CVegetable>   &vegetableList= tileVegetDesc.getVegetableList(distType);
+00070         uint                                                    distAddSeed= tileVegetDesc.getVegetableSeed(distType);
+00071         uint                                                    numVegetable= vegetableList.size();
+00072         
+00073         // If no vegetables at all, skip.
+00074         if(numVegetable==0)
+00075                 return;
+00076 
+00077         // compute approximate tile position and normal: get the middle
+00078         float   tileU= (ts + 0.5f) / (float)OrderS;
+00079         float   tileV= (tt + 0.5f) / (float)OrderT;
+00080         CBezierPatch    *bpatch= unpackIntoCache();
+00081         // Get approximate position for the tile (usefull for noise). NB: eval() is faster than computeVertex().
+00082         CVector         tilePos= bpatch->eval(tileU, tileV);
+00083         // Get also the normal used for all instances on this tile (not precise, 
+00084         // don't take noise into account, but faster).
+00085         CVector         tileNormal= bpatch->evalNormal(tileU, tileV);
+00086 
+00087         // Compute also position on middle of 4 edges of this tile, for generateGroupBiLinear().
+00088         CVector         tilePosBiLinear[4];
+00089         float           OOos= 1.0f / OrderS;
+00090         float           OOot= 1.0f / OrderT;
+00091         tilePosBiLinear[0]= bpatch->eval( (ts + 0.0f) * OOos, (tt + 0.5f) * OOot);
+00092         tilePosBiLinear[1]= bpatch->eval( (ts + 1.0f) * OOos, (tt + 0.5f) * OOot);
+00093         tilePosBiLinear[2]= bpatch->eval( (ts + 0.5f) * OOos, (tt + 0.0f) * OOot);
+00094         tilePosBiLinear[3]= bpatch->eval( (ts + 0.5f) * OOos, (tt + 1.0f) * OOot);
+00095 
+00096 
+00097         // compute a rotation matrix with the normal
+00098         CMatrix         matInstance;
+00099         matInstance.setRot(CVector::I, CVector::J, tileNormal);
+00100         // must normalize the matrix. use the vector which is the most orthogonal to tileNormal
+00101         // If tileNormal is much more a J vector, then use plane (I,tileNormal), and vice-versa
+00102         if(fabs(tileNormal.y) > fabs(tileNormal.x))
+00103                 matInstance.normalize(CMatrix::ZXY);
+00104         else
+00105                 matInstance.normalize(CMatrix::ZYX);
+00106 
+00107 
+00108         // prepare color / lighting
+00109         // =========================
+00110 
+00111         // say that ambient never change. VegetableManager handle the ambient and diffuse itself (for precomputeLighting)
+00112         CRGBAF  ambientF= CRGBAF(1,1,1,1);
+00113 
+00114         // Compute the tileLightmap (not modified by tileColor).
+00115         static  uint8   tileLumelmap[NL_LUMEL_BY_TILE * NL_LUMEL_BY_TILE];
+00116         getTileLumelmapPrecomputed(ts, tt, tileLumelmap, NL_LUMEL_BY_TILE);
+00117         // compute diffuse color by substracting from ambient.
+00118         CRGBAF  diffuseColorF[NL_LUMEL_BY_TILE * NL_LUMEL_BY_TILE];
+00119         // TODO_VEGET_OPTIM: optimize this.
+00120         // For all lumel of this tile.
+00121         for(i= 0; i<NL_LUMEL_BY_TILE*NL_LUMEL_BY_TILE; i++)
+00122         {
+00123                 // mul by 2, because shade is done twice here: by vertex, and by landscape.
+00124                 sint    tileLumel= 2*tileLumelmap[i];
+00125                 tileLumel= min(tileLumel, 255);
+00126                 float   tlf= tileLumel / 255.f;
+00127                 diffuseColorF[i].R= tlf;
+00128                 diffuseColorF[i].G= tlf;
+00129                 diffuseColorF[i].B= tlf;
+00130                 diffuseColorF[i].A= 1;
+00131         }
+00132 
+00133         // Compute The CVegetableLightEx, adding pointLight effect to vegetation
+00134         // First get pointLight at this tiles.
+00135         static  vector<CPointLightInfluence>    lightList;
+00136         lightList.clear();
+00137         appendTileLightInfluences( CUV(tileU, tileV), lightList);
+00138         // for each light, modulate the factor of influence
+00139         for(i=0; i<lightList.size();i++)
+00140         {
+00141                 CPointLight     *pl= lightList[i].PointLight;
+00142                 // compute the attenuation to the pos of the tile
+00143                 float   att= pl->computeLinearAttenuation(tilePos);
+00144                 // modulate the influence with this factor
+00145                 lightList[i].BkupInfluence= lightList[i].Influence;
+00146                 lightList[i].Influence*= att;
+00147         }
+00148         // sort the light by influence
+00149         sort(lightList.begin(), lightList.end());
+00150         // Setup the vegetLex directly in the ig. 
+00151         CVegetableLightEx       &vegetLex= vegetIg->VegetableLightEx;
+00152         // take only 2 first, computing direction to tilePos and computing attenuation.
+00153         vegetLex.NumLights= min((uint)CVegetableLightEx::MaxNumLight, lightList.size());
+00154         for(i=0;i<vegetLex.NumLights;i++)
+00155         {
+00156                 CPointLight     *pl= lightList[i].PointLight;
+00157                 // copy to vegetLex.
+00158                 vegetLex.PointLight[i]= pl;
+00159                 // get the attenuation
+00160                 vegetLex.PointLightFactor[i]= (uint)(256* lightList[i].Influence);
+00161                 // Setup the direction from pointLight.
+00162                 vegetLex.Direction[i]= tilePos - pl->getPosition();
+00163                 vegetLex.Direction[i].normalize();
+00164         }
+00165         // compute now the current colors of the vegetLex.
+00166         vegetLex.computeCurrentColors();
+00167 
+00168 
+00169         // Compute Dynamic Lightmap UV for this tile.
+00170         nlassert(_DLMContext);
+00171         CUV             dlmUV;
+00172         // get coordinate in 0..1 in texture.
+00173         dlmUV.U= _DLMContext->DLMUBias + _DLMContext->DLMUScale * tileU;
+00174         dlmUV.V= _DLMContext->DLMVBias + _DLMContext->DLMVScale * tileV;
+00175         // get coordinate in 0..255.
+00176         CVegetableUV8   dlmUV8;
+00177         dlmUV8.U= (uint8)OptFastFloor(dlmUV.U * 255 + 0.5f);
+00178         dlmUV8.V= (uint8)OptFastFloor(dlmUV.V * 255 + 0.5f);
+00179         // bound them, ensuring 8Bits UV "uncompressed" by driver are in the lightmap area.
+00180         clamp(dlmUV8.U, _DLMContext->MinU8, _DLMContext->MaxU8);
+00181         clamp(dlmUV8.V, _DLMContext->MinV8, _DLMContext->MaxV8);
+00182 
+00183 
+00184         // for all vegetable of this list, generate instances.
+00185         // =========================
+00186 
+00187         // Get an array for each vegetable (static for speed).
+00188         typedef         std::vector<NLMISC::CVector2f>  TPositionVector;
+00189         static  std::vector<TPositionVector>    instanceUVArray;
+00190         // realloc if necessary.
+00191         if(instanceUVArray.size() < numVegetable)
+00192         {
+00193                 // clean.
+00194                 contReset(instanceUVArray);
+00195                 // realloc.
+00196                 instanceUVArray.resize(numVegetable);
+00197         }
+00198 
+00199         // First, for each vegetable, generate the number of instance to create, and their relative position.
+00200         for(i= 0; i<numVegetable; i++)
+00201         {
+00202                 // get the vegetable
+00203                 const CVegetable        &veget= vegetableList[i];
+00204 
+00205                 // generate instance for this vegetable.
+00206                 veget.generateGroupBiLinear(tilePos, tilePosBiLinear, tileNormal, NL3D_PATCH_TILE_AREA, i + distAddSeed, instanceUVArray[i]);
+00207         }
+00208 
+00209         // Then, now that we kno how many instance to generate for each vegetable, reserve space.
+00210         CVegetableInstanceGroupReserve  vegetIgReserve;
+00211         for(i= 0; i<numVegetable; i++)
+00212         {
+00213                 // get the vegetable
+00214                 const CVegetable        &veget= vegetableList[i];
+00215 
+00216                 // reseve instance space for this vegetable.
+00217                 // instanceUVArray[i].size() is the number of instances to create.
+00218                 veget.reserveIgAddInstances(vegetIgReserve, (CVegetable::TVegetableWater)vegetWaterState, instanceUVArray[i].size());
+00219         }
+00220         // actual reseve memory of the ig.
+00221         getLandscape()->_VegetableManager->reserveIgCompile(vegetIg, vegetIgReserve);
+00222 
+00223 
+00224         // generate the instances for all the vegetables.
+00225         for(i= 0; i<numVegetable; i++)
+00226         {
+00227                 // get the vegetable
+00228                 const CVegetable        &veget= vegetableList[i];
+00229 
+00230                 // get the relatives position of the instances
+00231                 std::vector<CVector2f>  &instanceUV= instanceUVArray[i];
+00232 
+00233                 // For all instance, generate the real instances.
+00234                 for(uint j=0; j<instanceUV.size(); j++)
+00235                 {
+00236                         // generate the position in world Space.
+00237                         // instanceUV is in [0..1] interval, which maps to a tile, so explode to the patch
+00238                         CVector         instancePos;
+00239                         vbCreateCtx.eval(ts, tt, instanceUV[j].x, instanceUV[j].y, instancePos);
+00240                         // NB: use same normal for rotation for all instances in a same tile.
+00241                         matInstance.setPos( instancePos );
+00242 
+00243                         // peek color into the lightmap.
+00244                         sint    lumelS= OptFastFloor(instanceUV[j].x * NL_LUMEL_BY_TILE);
+00245                         sint    lumelT= OptFastFloor(instanceUV[j].y * NL_LUMEL_BY_TILE);
+00246                         clamp(lumelS, 0, NL_LUMEL_BY_TILE-1);
+00247                         clamp(lumelT, 0, NL_LUMEL_BY_TILE-1);
+00248 
+00249                         // generate the instance of the vegetable
+00250                         veget.generateInstance(vegetIg, matInstance, ambientF, 
+00251                                 diffuseColorF[ (lumelT<<NL_LUMEL_BY_TILE_SHIFT) + lumelS ],
+00252                                 (distType+1) * NL3D_VEGETABLE_BLOCK_ELTDIST, (CVegetable::TVegetableWater)vegetWaterState, dlmUV8);
+00253                 }
+00254         }
+00255 }
+00256 
+00257 
+00258 // ***************************************************************************
+00259 void    CPatch::recreateAllVegetableIgs()
+00260 {
+00261         // For all TessBlocks, try to release their VegetableBlock
+00262         for(uint numtb=0; numtb<TessBlocks.size(); numtb++)
+00263         {
+00264                 // if the vegetableBlock is deleted, and if there is at least one Material in the tessBlock, and if possible
+00265                 if( TessBlocks[numtb].VegetableBlock==NULL && TessBlocks[numtb].TileMaterialRefCount>0
+00266                         && getLandscape()->isVegetableActive())
+00267                 {
+00268                         // compute tessBlock coordinate
+00269                         uint tbWidth= OrderS>>1;
+00270                         uint ts= numtb&(tbWidth-1);
+00271                         uint tt= numtb/tbWidth;
+00272                         // crate the vegetable with tilecooridante (ie tessBlock coord *2);
+00273                         createVegetableBlock(numtb, ts*2, tt*2);
+00274                 }
+00275         }
+00276 
+00277 }
+00278 
+00279 
+00280 // ***************************************************************************
+00281 void    CPatch::deleteAllVegetableIgs()
+00282 {
+00283         // For all TessBlocks, try to release their VegetableBlock
+00284         for(uint i=0; i<TessBlocks.size(); i++)
+00285         {
+00286                 releaseVegetableBlock(i);
+00287         }
+00288 
+00289 }
+00290 
+00291 
+00292 // ***************************************************************************
+00293 void            CPatch::createVegetableBlock(uint numTb, uint ts, uint tt)
+00294 {
+00295         // TessBlock width
+00296         uint    tbWidth= OrderS >> 1;
+00297         // clipBlock width
+00298         uint    nTbPerCb= NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK;
+00299         uint    cbWidth= (tbWidth + nTbPerCb-1) >> NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK_SHIFT;
+00300 
+00301         // compute tessBlock coordinate.
+00302         uint    tbs ,tbt;
+00303         tbs= ts >> 1;
+00304         tbt= tt >> 1;
+00305         // compute clipBlock coordinate.
+00306         uint    cbs,cbt;
+00307         cbs= tbs >> NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK_SHIFT;
+00308         cbt= tbt >> NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK_SHIFT;
+00309 
+00310         // create the vegetable block.
+00311         CLandscapeVegetableBlock                *vegetBlock= new CLandscapeVegetableBlock;
+00312         // Init / append to list.
+00313         // compute center of the vegetableBlock (approx).
+00314         CBezierPatch    *bpatch= unpackIntoCache();
+00315         CVector         center= bpatch->eval( (float)(tbs*2+1)/OrderS, (float)(tbt*2+1)/OrderT );
+00316         // Lower-Left tile is (tbs*2, tbt*2)
+00317         vegetBlock->init(center, getLandscape()->_VegetableManager, VegetableClipBlocks[cbt *cbWidth + cbs], this, tbs*2, tbt*2, getLandscape()->_VegetableBlockList);
+00318 
+00319         // set in the tessBlock
+00320         TessBlocks[numTb].VegetableBlock= vegetBlock;
+00321 }
+00322 
+00323 
+00324 // ***************************************************************************
+00325 void            CPatch::releaseVegetableBlock(uint numTb)
+00326 {
+00327         // if exist, must delete the VegetableBlock.
+00328         if(TessBlocks[numTb].VegetableBlock)
+00329         {
+00330                 // delete Igs, and remove from list.
+00331                 TessBlocks[numTb].VegetableBlock->release(getLandscape()->_VegetableManager, getLandscape()->_VegetableBlockList);
+00332                 // delete.
+00333                 delete TessBlocks[numTb].VegetableBlock;
+00334                 TessBlocks[numTb].VegetableBlock= NULL;
+00335         }
+00336 }
+00337 
+00338 
+00339 
+00340 
+00341 
+00342 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1