Merge branch 'ryzom/ark-features' into main/gingo-test
[ryzomcore.git] / nel / src / 3d / tess_block.cpp
blob917e06a23b5bbbbc5554f1378b59093957d3f0ae
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
19 #include "nel/3d/tess_block.h"
20 #include "nel/3d/patch_rdr_pass.h"
21 #include "nel/3d/landscape_face_vector_manager.h"
23 #ifdef DEBUG_NEW
24 #define new DEBUG_NEW
25 #endif
27 namespace NL3D
31 CPlane CTessBlock::CurrentPyramid[NL3D_TESSBLOCK_NUM_CLIP_PLANE];
35 // ***************************************************************************
36 CTessBlock::CTessBlock()
38 _Patch= NULL;
40 // init bounding info.
41 Empty= true;
42 // By default, the tessBlock is clipped.
43 Clipped= true;
44 FullFar1= false;
45 EmptyFar1= false;
47 // init vert/face list.
48 for(sint i=0;i<NL3D_TESSBLOCK_TILESIZE;i++)
50 RdrTileRoot[i]=NULL;
53 // init LightMap.
54 LightMapRefCount= 0;
56 Far0FaceVector= NULL;
57 Far1FaceVector= NULL;
59 _PrecToModify= NULL;
60 _NextToModify= NULL;
62 FaceTileMaterialRefCount= 0;
63 TileMaterialRefCount= 0;
65 // Micro-vegetation.
66 VegetableBlock= NULL;
70 // ***************************************************************************
71 CTessBlock::~CTessBlock()
73 if(isInModifyList())
75 removeFromModifyList();
78 // LightMap should be released
79 nlassert(LightMapRefCount==0);
82 // ***************************************************************************
83 void CTessBlock::init(CPatch *patch)
85 _Patch= patch;
87 // ***************************************************************************
88 CPatch *CTessBlock::getPatch()
90 return _Patch;
95 // ***************************************************************************
96 void CTessBlock::extendSphereFirst(const CVector &vec)
98 if(Empty)
100 Empty= false;
101 BBox.setCenter(vec);
102 BBox.setHalfSize(CVector::Null);
104 else
105 extendSphereAdd(vec);
108 // ***************************************************************************
109 void CTessBlock::extendSphereAdd(const CVector &vec)
111 if( !BBox.include(vec) )
112 BBox.extend(vec);
115 // ***************************************************************************
116 void CTessBlock::extendSphereCompile()
118 BSphere.Center= BBox.getCenter();
119 BSphere.Radius= BBox.getRadius();
123 // ***************************************************************************
124 void CTessBlock::resetClip()
126 Clipped= false;
127 FullFar1= false;
128 EmptyFar1= false;
132 // ***************************************************************************
133 void CTessBlock::forceClip()
135 Clipped= true;
139 // ***************************************************************************
140 void CTessBlock::clip()
142 Clipped= false;
143 for(sint i=0;i<NL3D_TESSBLOCK_NUM_CLIP_PLANE;i++)
145 // If entirely out.
146 if(!BSphere.clipBack( CTessBlock::CurrentPyramid[i] ))
148 Clipped= true;
149 break;
153 // ***************************************************************************
154 void CTessBlock::clipFar(const CVector &refineCenter, float tileDistNear, float farTransition)
156 float r= (refineCenter-BSphere.Center).norm();
157 if( (r-BSphere.Radius) > tileDistNear)
159 FullFar1= true;
161 else
163 if( (r+BSphere.Radius) < (tileDistNear-farTransition) )
164 EmptyFar1= true;
170 // ***************************************************************************
171 void CTessBlock::refillFaceVectorFar0()
173 // If size is not 0.
174 if(FarFaceList.size()>0)
176 nlassert(Far0FaceVector!=NULL);
178 // Fill this faceVector, with FarFaceList
179 CTessFace *pFace;
180 TLandscapeIndexType *dest= Far0FaceVector+1;
181 for(pFace= FarFaceList.begin(); pFace; pFace= (CTessFace*)pFace->Next)
183 #if defined(NL_DEBUG) && defined(NL_LANDSCAPE_INDEX16)
184 nlassert(pFace->FVBase->Index0 <= 0xffff);
185 nlassert(pFace->FVLeft->Index0 <= 0xffff);
186 nlassert(pFace->FVRight->Index0 <= 0xffff);
187 #endif
188 *(dest++)= (TLandscapeIndexType) pFace->FVBase->Index0;
189 *(dest++)= (TLandscapeIndexType) pFace->FVLeft->Index0;
190 *(dest++)= (TLandscapeIndexType) pFace->FVRight->Index0;
196 // ***************************************************************************
197 void CTessBlock::createFaceVectorFar0(CLandscapeFaceVectorManager &mgr)
199 nlassert(Far0FaceVector==NULL);
200 // If size is not 0.
201 if(FarFaceList.size()>0)
203 // Create a faceVector of the wanted triangles size.
204 Far0FaceVector= mgr.createFaceVector(FarFaceList.size());
206 // init.
207 refillFaceVectorFar0();
211 // ***************************************************************************
212 void CTessBlock::deleteFaceVectorFar0(CLandscapeFaceVectorManager &mgr)
214 if(Far0FaceVector)
216 mgr.deleteFaceVector(Far0FaceVector);
217 Far0FaceVector= NULL;
221 // ***************************************************************************
222 void CTessBlock::refillFaceVectorFar1()
224 // If size is not 0.
225 if(FarFaceList.size()>0)
227 nlassert(Far1FaceVector!=NULL);
228 // Fill this faceVector, with FarFaceList
229 CTessFace *pFace;
230 TLandscapeIndexType *dest= Far1FaceVector+1;
231 for(pFace= FarFaceList.begin(); pFace; pFace= (CTessFace*)pFace->Next)
233 #if defined(NL_DEBUG) && defined(NL_LANDSCAPE_INDEX16)
234 nlassert(pFace->FVBase->Index1 <= 0xffff);
235 nlassert(pFace->FVLeft->Index1 <= 0xffff);
236 nlassert(pFace->FVRight->Index1 <= 0xffff);
237 #endif
238 *(dest++)= (TLandscapeIndexType) pFace->FVBase->Index1;
239 *(dest++)= (TLandscapeIndexType) pFace->FVLeft->Index1;
240 *(dest++)= (TLandscapeIndexType) pFace->FVRight->Index1;
245 // ***************************************************************************
246 void CTessBlock::createFaceVectorFar1(CLandscapeFaceVectorManager &mgr)
248 nlassert(Far1FaceVector==NULL);
249 // If size is not 0.
250 if(FarFaceList.size()>0)
252 // Create a faceVector of the wanted triangles size.
253 Far1FaceVector= mgr.createFaceVector(FarFaceList.size());
255 // init.
256 refillFaceVectorFar1();
259 // ***************************************************************************
260 void CTessBlock::deleteFaceVectorFar1(CLandscapeFaceVectorManager &mgr)
262 if(Far1FaceVector)
264 mgr.deleteFaceVector(Far1FaceVector);
265 Far1FaceVector= NULL;
270 // ***************************************************************************
271 void CTessBlock::refillFaceVectorTile()
273 // For all tiles existing, and for all facePass existing, fill the faceVector.
274 for(uint tileId=0; tileId<NL3D_TESSBLOCK_TILESIZE; tileId++)
276 // if tile exist.
277 if(RdrTileRoot[tileId])
279 // For all Pass faces of the tile.
280 for(uint facePass=0; facePass<NL3D_MAX_TILE_FACE; facePass++)
282 CTessList<CTileFace> &faceList= RdrTileRoot[tileId]->TileFaceList[facePass];
283 TLandscapeIndexType *faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
284 // If some triangles create them.
285 if(faceList.size()>0)
287 nlassert( faceVector!=NULL );
289 // Fill this faceVector, with the TileFaceList
290 CTileFace *pFace;
291 TLandscapeIndexType *dest= faceVector+1;
292 for(pFace= faceList.begin(); pFace; pFace= (CTileFace*)pFace->Next)
294 #if defined(NL_DEBUG) && defined(NL_LANDSCAPE_INDEX16)
295 nlassert(pFace->V[CTessFace::IdUvBase]->Index <= 0xffff);
296 nlassert(pFace->V[CTessFace::IdUvLeft]->Index <= 0xffff);
297 nlassert(pFace->V[CTessFace::IdUvRight]->Index <= 0xffff);
298 #endif
299 *(dest++)= (TLandscapeIndexType) pFace->V[CTessFace::IdUvBase]->Index;
300 *(dest++)= (TLandscapeIndexType) pFace->V[CTessFace::IdUvLeft]->Index;
301 *(dest++)= (TLandscapeIndexType) pFace->V[CTessFace::IdUvRight]->Index;
310 // ***************************************************************************
311 void CTessBlock::createFaceVectorTile(CLandscapeFaceVectorManager &mgr)
313 // For all tiles existing, and for all facePass existing, create the faceVector.
314 for(uint tileId=0; tileId<NL3D_TESSBLOCK_TILESIZE; tileId++)
316 // if tile exist.
317 if(RdrTileRoot[tileId])
319 // For all Pass faces of the tile.
320 for(uint facePass=0; facePass<NL3D_MAX_TILE_FACE; facePass++)
322 CTessList<CTileFace> &faceList= RdrTileRoot[tileId]->TileFaceList[facePass];
323 TLandscapeIndexType *&faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
324 // If some triangles create them.
325 if(faceList.size()>0)
327 // Create a faceVector of the wanted triangles size.
328 faceVector= mgr.createFaceVector(faceList.size());
334 // init.
335 refillFaceVectorTile();
337 // ***************************************************************************
338 void CTessBlock::deleteFaceVectorTile(CLandscapeFaceVectorManager &mgr)
340 // For all tiles existing, and for all facePass existing, delete the faceVector.
341 for(uint tileId=0; tileId<NL3D_TESSBLOCK_TILESIZE; tileId++)
343 // if tile exist.
344 if(RdrTileRoot[tileId])
346 // For all Pass faces of the tile.
347 for(uint facePass=0; facePass<NL3D_MAX_TILE_FACE; facePass++)
349 TLandscapeIndexType *&faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
350 // If the faceVector exist, delete it.
351 if(faceVector)
353 mgr.deleteFaceVector(faceVector);
354 faceVector= NULL;
362 // ***************************************************************************
363 void CTessBlock::appendToModifyListAndDeleteFaceVector(CTessBlock &root, CLandscapeFaceVectorManager &mgr)
365 // If already appened, return.
366 if(isInModifyList())
367 return;
369 // append to root.
370 _PrecToModify= &root;
371 _NextToModify= root._NextToModify;
372 if(root._NextToModify)
373 root._NextToModify->_PrecToModify= this;
374 root._NextToModify= this;
376 // Then delete All faceVector that may exist.
377 deleteFaceVectorFar0(mgr);
378 deleteFaceVectorFar1(mgr);
379 deleteFaceVectorTile(mgr);
381 // ***************************************************************************
382 void CTessBlock::removeFromModifyList()
384 // If already removed, return.
385 // _PrecToModify must be !NULL
386 if(!isInModifyList())
387 return;
389 // unlink.
390 _PrecToModify->_NextToModify= _NextToModify;
391 if(_NextToModify)
392 _NextToModify->_PrecToModify= _PrecToModify;
393 _PrecToModify= NULL;
394 _NextToModify= NULL;
398 } // NL3D