00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/landscape_vegetable_block.h"
00029 #include "3d/vegetable_manager.h"
00030 #include "3d/vegetable_clip_block.h"
00031 #include "3d/vegetable_instance_group.h"
00032 #include "3d/patch.h"
00033 #include "3d/bezier_patch.h"
00034
00035
00036 using namespace std;
00037 using namespace NLMISC;
00038
00039
00040 namespace NL3D
00041 {
00042
00043
00044
00045
00046
00047
00048 class CLVBSqrDistLUT
00049 {
00050 public:
00051 static float Array[NL3D_VEGETABLE_BLOCK_NUMDIST+1];
00052
00053 CLVBSqrDistLUT()
00054 {
00055
00056 for(uint i=0;i<NL3D_VEGETABLE_BLOCK_NUMDIST+1;i++)
00057 {
00058 Array[i]= i*NL3D_VEGETABLE_BLOCK_ELTDIST;
00059 Array[i]= sqr(Array[i]);
00060 }
00061 }
00062
00063 };
00064
00065
00066 CLVBSqrDistLUT NL3D_InitSqrDistLUT;
00067 float CLVBSqrDistLUT::Array[NL3D_VEGETABLE_BLOCK_NUMDIST+1];
00068
00069
00070
00071 CLandscapeVegetableBlock::CLandscapeVegetableBlock()
00072 {
00073 _VegetableClipBlock= NULL;
00074 _CurDistType= NL3D_VEGETABLE_BLOCK_NUMDIST;
00075
00076 for(uint j=0;j<NL3D_TESSBLOCK_TILESIZE;j++)
00077 {
00078 _VegetableSortBlock[j]= NULL;
00079 for(uint i=0;i<NL3D_VEGETABLE_BLOCK_NUMDIST;i++)
00080 {
00081 _VegetableIG[j][i]= NULL;
00082 }
00083 }
00084 }
00085
00086
00087
00088
00089 void CLandscapeVegetableBlock::init(const CVector ¢er, CVegetableManager *vegetManager,
00090 CVegetableClipBlock *vegetableClipBlock, CPatch *patch, uint ts, uint tt, CTessList<CLandscapeVegetableBlock> &vblist)
00091 {
00092 nlassert(patch);
00093 _Center= center;
00094 _VegetableClipBlock= vegetableClipBlock;
00095 _Patch= patch;
00096 _Ts= ts;
00097 _Tt= tt;
00098
00099
00100 sint tms,tmt;
00101
00102 nlassert(NL3D_TESSBLOCK_TILESIZE==4);
00103 for(tmt= _Tt; tmt<_Tt+2; tmt++)
00104 {
00105 for(tms= _Ts; tms<_Ts+2; tms++)
00106 {
00107
00108 float s= (tms + 0.5f) / _Patch->getOrderS();
00109 float t= (tmt + 0.5f) / _Patch->getOrderT();
00110 CBezierPatch *bpatch= _Patch->unpackIntoCache();
00111 CVector center= bpatch->eval(s, t);
00112
00113
00114 _VegetableSortBlock[(tmt-_Tt)*2 + (tms-_Ts)]= vegetManager->createSortBlock(_VegetableClipBlock, center, NL3D_PATCH_TILE_RADIUS);
00115 }
00116 }
00117
00118
00119 vblist.append(this);
00120 }
00121
00122
00123
00124 void CLandscapeVegetableBlock::release(CVegetableManager *vegeManager, CTessList<CLandscapeVegetableBlock> &vblist)
00125 {
00126
00127 for(uint j=0;j<NL3D_TESSBLOCK_TILESIZE;j++)
00128 {
00129
00130 for(uint i=0;i<NL3D_VEGETABLE_BLOCK_NUMDIST;i++)
00131 {
00132 if(_VegetableIG[j][i])
00133 {
00134 vegeManager->deleteIg(_VegetableIG[j][i]);
00135 _VegetableIG[j][i]= NULL;
00136 }
00137 }
00138
00139
00140 if(_VegetableSortBlock[j])
00141 {
00142 vegeManager->deleteSortBlock(_VegetableSortBlock[j]);
00143 _VegetableSortBlock[j]= NULL;
00144 }
00145 }
00146
00147
00148 _CurDistType= NL3D_VEGETABLE_BLOCK_NUMDIST;
00149
00150
00151 vblist.remove(this);
00152 }
00153
00154
00155 void CLandscapeVegetableBlock::update(const CVector &viewCenter, CVegetableManager *vegeManager)
00156 {
00157 float sqrDist= (viewCenter-_Center).sqrnorm();
00158
00159
00160 uint newDistType= _CurDistType;
00161 while(sqrDist<CLVBSqrDistLUT::Array[newDistType])
00162 {
00163 newDistType--;
00164 }
00165 while(newDistType<NL3D_VEGETABLE_BLOCK_NUMDIST && sqrDist>CLVBSqrDistLUT::Array[newDistType+1])
00166 {
00167 newDistType++;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 if(newDistType!=_CurDistType)
00177 {
00178
00179 if(newDistType>_CurDistType)
00180 {
00181
00182 for(uint j=0;j<NL3D_TESSBLOCK_TILESIZE;j++)
00183 {
00184
00185 for(uint i=_CurDistType; i<newDistType; i++)
00186 {
00187 if(_VegetableIG[j][i])
00188 {
00189 vegeManager->deleteIg(_VegetableIG[j][i]);
00190 _VegetableIG[j][i]= NULL;
00191 }
00192 }
00193
00194
00195 _VegetableSortBlock[j]->updateSortBlock(*vegeManager);
00196 }
00197 }
00198 else
00199 {
00200
00201 CLandscapeVegetableBlockCreateContext ctx;
00202 ctx.init(_Patch, _Ts, _Tt);
00203
00204
00205 for(uint i=newDistType; i<_CurDistType; i++)
00206 {
00207 createVegetableIGForDistType(i, vegeManager, ctx);
00208 }
00209
00210
00211 for(uint j=0;j<NL3D_TESSBLOCK_TILESIZE;j++)
00212 {
00213
00214 _VegetableSortBlock[j]->updateSortBlock(*vegeManager);
00215 }
00216 }
00217
00218
00219 _CurDistType= newDistType;
00220 }
00221
00222
00223 }
00224
00225
00226
00227 void CLandscapeVegetableBlock::createVegetableIGForDistType(uint i, CVegetableManager *vegeManager,
00228 CLandscapeVegetableBlockCreateContext &vbCreateCtx)
00229 {
00230
00231 nlassert(NL3D_TESSBLOCK_TILESIZE==4);
00232 nlassert(_VegetableIG[0][i]==NULL);
00233 nlassert(_VegetableIG[1][i]==NULL);
00234 nlassert(_VegetableIG[2][i]==NULL);
00235 nlassert(_VegetableIG[3][i]==NULL);
00236
00237
00238 sint tms,tmt;
00239
00240 nlassert(NL3D_TESSBLOCK_TILESIZE==4);
00241 for(tmt= _Tt; tmt<_Tt+2; tmt++)
00242 {
00243 for(tms= _Ts; tms<_Ts+2; tms++)
00244 {
00245 uint tileId= tms-_Ts + (tmt-_Tt)*2;
00246
00247
00248 CVegetableInstanceGroup *vegetIg= vegeManager->createIg(_VegetableSortBlock[tileId]);
00249 _VegetableIG[tileId][i]= vegetIg;
00250
00251
00252 _Patch->generateTileVegetable(vegetIg, i, tms, tmt, vbCreateCtx);
00253
00254
00255
00256 if(vegetIg->isEmpty())
00257 {
00258 vegeManager->deleteIg(vegetIg);
00259 _VegetableIG[tileId][i]= NULL;
00260 }
00261
00262
00263 }
00264 }
00265
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 CLandscapeVegetableBlockCreateContext::CLandscapeVegetableBlockCreateContext()
00278 {
00279 _Patch= NULL;
00280 }
00281
00282
00283
00284 void CLandscapeVegetableBlockCreateContext::init(CPatch *patch, uint ts, uint tt)
00285 {
00286 nlassert(patch);
00287 _Empty= true;
00288 _Patch= patch;
00289 _Ts= ts;
00290 _Tt= tt;
00291 }
00292
00293
00294
00295 void CLandscapeVegetableBlockCreateContext::eval(uint ts, uint tt, float x, float y, CVector &pos)
00296 {
00297 nlassert(NL3D_TESSBLOCK_TILESIZE==4);
00298
00299
00300
00301 if(_Empty)
00302 {
00303
00304 for(uint j=0; j<3;j++)
00305 {
00306 float t= (float)(_Tt+j)/_Patch->getOrderT();
00307 for(uint i=0; i<3;i++)
00308 {
00309 float s= (float)(_Ts+i)/_Patch->getOrderS();
00310
00311
00312
00313 _Pos[j*3+i]= _Patch->computeVertex(s, t);
00314 }
00315 }
00316
00317
00318 _Empty= false;
00319 }
00320
00321
00322
00323
00324 nlassert(ts==_Ts || ts==_Ts+1);
00325 nlassert(tt==_Tt || tt==_Tt+1);
00326 uint ds= ts-_Ts;
00327 uint dt= tt-_Tt;
00328
00329 uint v00= dt*3 + ds;
00330 uint v10= v00 + 1;
00331 uint v01= v00 + 3;
00332 uint v11= v00 + 4;
00333
00334 float dxdy= (1-x)*(1-y);
00335 float dx2dy= x*(1-y);
00336 float dxdy2= (1-x)*y;
00337 float dx2dy2= x*y;
00338
00339
00340 pos = _Pos[v00] * dxdy;
00341 pos+= _Pos[v10] * dx2dy;
00342 pos+= _Pos[v01] * dxdy2;
00343 pos+= _Pos[v11] * dx2dy2;
00344 }
00345
00346
00347 }