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/tess_block.h"
00029 #include "3d/patch_rdr_pass.h"
00030 #include "3d/landscape_face_vector_manager.h"
00031
00032
00033 namespace NL3D
00034 {
00035
00036
00037 CPlane CTessBlock::CurrentPyramid[NL3D_TESSBLOCK_NUM_CLIP_PLANE];
00038
00039
00040
00041
00042 CTessBlock::CTessBlock()
00043 {
00044 _Patch= NULL;
00045
00046
00047 Empty= true;
00048
00049 Clipped= true;
00050 FullFar1= false;
00051 EmptyFar1= false;
00052
00053
00054 for(sint i=0;i<NL3D_TESSBLOCK_TILESIZE;i++)
00055 {
00056 RdrTileRoot[i]=NULL;
00057 }
00058
00059
00060 LightMapRefCount= 0;
00061
00062 Far0FaceVector= NULL;
00063 Far1FaceVector= NULL;
00064
00065 _PrecToModify= NULL;
00066 _NextToModify= NULL;
00067
00068 FaceTileMaterialRefCount= 0;
00069 TileMaterialRefCount= 0;
00070
00071
00072 VegetableBlock= NULL;
00073 }
00074
00075
00076
00077 CTessBlock::~CTessBlock()
00078 {
00079 if(isInModifyList())
00080 {
00081 removeFromModifyList();
00082 }
00083
00084
00085 nlassert(LightMapRefCount==0);
00086 }
00087
00088
00089 void CTessBlock::init(CPatch *patch)
00090 {
00091 _Patch= patch;
00092 }
00093
00094 CPatch *CTessBlock::getPatch()
00095 {
00096 return _Patch;
00097 }
00098
00099
00100
00101
00102 void CTessBlock::extendSphereFirst(const CVector &vec)
00103 {
00104 if(Empty)
00105 {
00106 Empty= false;
00107 BBox.setCenter(vec);
00108 BBox.setHalfSize(CVector::Null);
00109 }
00110 else
00111 extendSphereAdd(vec);
00112 }
00113
00114
00115 void CTessBlock::extendSphereAdd(const CVector &vec)
00116 {
00117 if( !BBox.include(vec) )
00118 BBox.extend(vec);
00119 }
00120
00121
00122 void CTessBlock::extendSphereCompile()
00123 {
00124 BSphere.Center= BBox.getCenter();
00125 BSphere.Radius= BBox.getRadius();
00126 }
00127
00128
00129
00130 void CTessBlock::resetClip()
00131 {
00132 Clipped= false;
00133 FullFar1= false;
00134 EmptyFar1= false;
00135 }
00136
00137
00138
00139 void CTessBlock::forceClip()
00140 {
00141 Clipped= true;
00142 }
00143
00144
00145
00146 void CTessBlock::clip()
00147 {
00148 Clipped= false;
00149 for(sint i=0;i<NL3D_TESSBLOCK_NUM_CLIP_PLANE;i++)
00150 {
00151
00152 if(!BSphere.clipBack( CTessBlock::CurrentPyramid[i] ))
00153 {
00154 Clipped= true;
00155 break;
00156 }
00157 }
00158 }
00159
00160 void CTessBlock::clipFar(const CVector &refineCenter, float tileDistNear, float farTransition)
00161 {
00162 float r= (refineCenter-BSphere.Center).norm();
00163 if( (r-BSphere.Radius) > tileDistNear)
00164 {
00165 FullFar1= true;
00166 }
00167 else
00168 {
00169 if( (r+BSphere.Radius) < (tileDistNear-farTransition) )
00170 EmptyFar1= true;
00171 }
00172 }
00173
00174
00175
00176
00177 void CTessBlock::refillFaceVectorFar0()
00178 {
00179
00180 if(FarFaceList.size()>0)
00181 {
00182 nlassert(Far0FaceVector!=NULL);
00183
00184
00185 CTessFace *pFace;
00186 uint32 *dest= Far0FaceVector->TriPtr;
00187 for(pFace= FarFaceList.begin(); pFace; pFace= (CTessFace*)pFace->Next)
00188 {
00189 *(dest++)= pFace->FVBase->Index0;
00190 *(dest++)= pFace->FVLeft->Index0;
00191 *(dest++)= pFace->FVRight->Index0;
00192 }
00193 }
00194 }
00195
00196
00197
00198 void CTessBlock::createFaceVectorFar0(CLandscapeFaceVectorManager &mgr)
00199 {
00200 nlassert(Far0FaceVector==NULL);
00201
00202 if(FarFaceList.size()>0)
00203 {
00204
00205 Far0FaceVector= mgr.createFaceVector(FarFaceList.size());
00206
00207
00208 refillFaceVectorFar0();
00209 }
00210
00211 }
00212
00213 void CTessBlock::deleteFaceVectorFar0(CLandscapeFaceVectorManager &mgr)
00214 {
00215 if(Far0FaceVector)
00216 {
00217 mgr.deleteFaceVector(Far0FaceVector);
00218 Far0FaceVector= NULL;
00219 }
00220 }
00221
00222
00223 void CTessBlock::refillFaceVectorFar1()
00224 {
00225
00226 if(FarFaceList.size()>0)
00227 {
00228 nlassert(Far1FaceVector!=NULL);
00229
00230 CTessFace *pFace;
00231 uint32 *dest= Far1FaceVector->TriPtr;
00232 for(pFace= FarFaceList.begin(); pFace; pFace= (CTessFace*)pFace->Next)
00233 {
00234 *(dest++)= pFace->FVBase->Index1;
00235 *(dest++)= pFace->FVLeft->Index1;
00236 *(dest++)= pFace->FVRight->Index1;
00237 }
00238 }
00239 }
00240
00241
00242 void CTessBlock::createFaceVectorFar1(CLandscapeFaceVectorManager &mgr)
00243 {
00244 nlassert(Far1FaceVector==NULL);
00245
00246 if(FarFaceList.size()>0)
00247 {
00248
00249 Far1FaceVector= mgr.createFaceVector(FarFaceList.size());
00250
00251
00252 refillFaceVectorFar1();
00253 }
00254 }
00255
00256 void CTessBlock::deleteFaceVectorFar1(CLandscapeFaceVectorManager &mgr)
00257 {
00258 if(Far1FaceVector)
00259 {
00260 mgr.deleteFaceVector(Far1FaceVector);
00261 Far1FaceVector= NULL;
00262 }
00263 }
00264
00265
00266
00267 void CTessBlock::refillFaceVectorTile()
00268 {
00269
00270 for(uint tileId=0; tileId<NL3D_TESSBLOCK_TILESIZE; tileId++)
00271 {
00272
00273 if(RdrTileRoot[tileId])
00274 {
00275
00276 for(uint facePass=0; facePass<NL3D_MAX_TILE_FACE; facePass++)
00277 {
00278 CTessList<CTileFace> &faceList= RdrTileRoot[tileId]->TileFaceList[facePass];
00279 CLandscapeFaceVector *faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
00280
00281 if(faceList.size()>0)
00282 {
00283 nlassert( faceVector!=NULL );
00284
00285
00286 CTileFace *pFace;
00287 uint32 *dest= faceVector->TriPtr;
00288 for(pFace= faceList.begin(); pFace; pFace= (CTileFace*)pFace->Next)
00289 {
00290 *(dest++)= pFace->V[CTessFace::IdUvBase]->Index;
00291 *(dest++)= pFace->V[CTessFace::IdUvLeft]->Index;
00292 *(dest++)= pFace->V[CTessFace::IdUvRight]->Index;
00293 }
00294 }
00295 }
00296 }
00297 }
00298 }
00299
00300
00301
00302 void CTessBlock::createFaceVectorTile(CLandscapeFaceVectorManager &mgr)
00303 {
00304
00305 for(uint tileId=0; tileId<NL3D_TESSBLOCK_TILESIZE; tileId++)
00306 {
00307
00308 if(RdrTileRoot[tileId])
00309 {
00310
00311 for(uint facePass=0; facePass<NL3D_MAX_TILE_FACE; facePass++)
00312 {
00313 CTessList<CTileFace> &faceList= RdrTileRoot[tileId]->TileFaceList[facePass];
00314 CLandscapeFaceVector *&faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
00315
00316 if(faceList.size()>0)
00317 {
00318
00319 faceVector= mgr.createFaceVector(faceList.size());
00320 }
00321 }
00322 }
00323 }
00324
00325
00326 refillFaceVectorTile();
00327 }
00328
00329 void CTessBlock::deleteFaceVectorTile(CLandscapeFaceVectorManager &mgr)
00330 {
00331
00332 for(uint tileId=0; tileId<NL3D_TESSBLOCK_TILESIZE; tileId++)
00333 {
00334
00335 if(RdrTileRoot[tileId])
00336 {
00337
00338 for(uint facePass=0; facePass<NL3D_MAX_TILE_FACE; facePass++)
00339 {
00340 CLandscapeFaceVector *&faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
00341
00342 if(faceVector)
00343 {
00344 mgr.deleteFaceVector(faceVector);
00345 faceVector= NULL;
00346 }
00347 }
00348 }
00349 }
00350 }
00351
00352
00353
00354 void CTessBlock::appendToModifyListAndDeleteFaceVector(CTessBlock &root, CLandscapeFaceVectorManager &mgr)
00355 {
00356
00357 if(isInModifyList())
00358 return;
00359
00360
00361 _PrecToModify= &root;
00362 _NextToModify= root._NextToModify;
00363 if(root._NextToModify)
00364 root._NextToModify->_PrecToModify= this;
00365 root._NextToModify= this;
00366
00367
00368 deleteFaceVectorFar0(mgr);
00369 deleteFaceVectorFar1(mgr);
00370 deleteFaceVectorTile(mgr);
00371 }
00372
00373 void CTessBlock::removeFromModifyList()
00374 {
00375
00376
00377 if(!isInModifyList())
00378 return;
00379
00380
00381 _PrecToModify->_NextToModify= _NextToModify;
00382 if(_NextToModify)
00383 _NextToModify->_PrecToModify= _PrecToModify;
00384 _PrecToModify= NULL;
00385 _NextToModify= NULL;
00386 }
00387
00388
00389 }