1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
19 #include "nel/3d/tess_block.h"
20 #include "nel/3d/patch_rdr_pass.h"
21 #include "nel/3d/landscape_face_vector_manager.h"
31 CPlane
CTessBlock::CurrentPyramid
[NL3D_TESSBLOCK_NUM_CLIP_PLANE
];
35 // ***************************************************************************
36 CTessBlock::CTessBlock()
40 // init bounding info.
42 // By default, the tessBlock is clipped.
47 // init vert/face list.
48 for(sint i
=0;i
<NL3D_TESSBLOCK_TILESIZE
;i
++)
62 FaceTileMaterialRefCount
= 0;
63 TileMaterialRefCount
= 0;
70 // ***************************************************************************
71 CTessBlock::~CTessBlock()
75 removeFromModifyList();
78 // LightMap should be released
79 nlassert(LightMapRefCount
==0);
82 // ***************************************************************************
83 void CTessBlock::init(CPatch
*patch
)
87 // ***************************************************************************
88 CPatch
*CTessBlock::getPatch()
95 // ***************************************************************************
96 void CTessBlock::extendSphereFirst(const CVector
&vec
)
102 BBox
.setHalfSize(CVector::Null
);
105 extendSphereAdd(vec
);
108 // ***************************************************************************
109 void CTessBlock::extendSphereAdd(const CVector
&vec
)
111 if( !BBox
.include(vec
) )
115 // ***************************************************************************
116 void CTessBlock::extendSphereCompile()
118 BSphere
.Center
= BBox
.getCenter();
119 BSphere
.Radius
= BBox
.getRadius();
123 // ***************************************************************************
124 void CTessBlock::resetClip()
132 // ***************************************************************************
133 void CTessBlock::forceClip()
139 // ***************************************************************************
140 void CTessBlock::clip()
143 for(sint i
=0;i
<NL3D_TESSBLOCK_NUM_CLIP_PLANE
;i
++)
146 if(!BSphere
.clipBack( CTessBlock::CurrentPyramid
[i
] ))
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
)
163 if( (r
+BSphere
.Radius
) < (tileDistNear
-farTransition
) )
170 // ***************************************************************************
171 void CTessBlock::refillFaceVectorFar0()
174 if(FarFaceList
.size()>0)
176 nlassert(Far0FaceVector
!=NULL
);
178 // Fill this faceVector, with FarFaceList
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);
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
);
201 if(FarFaceList
.size()>0)
203 // Create a faceVector of the wanted triangles size.
204 Far0FaceVector
= mgr
.createFaceVector(FarFaceList
.size());
207 refillFaceVectorFar0();
211 // ***************************************************************************
212 void CTessBlock::deleteFaceVectorFar0(CLandscapeFaceVectorManager
&mgr
)
216 mgr
.deleteFaceVector(Far0FaceVector
);
217 Far0FaceVector
= NULL
;
221 // ***************************************************************************
222 void CTessBlock::refillFaceVectorFar1()
225 if(FarFaceList
.size()>0)
227 nlassert(Far1FaceVector
!=NULL
);
228 // Fill this faceVector, with FarFaceList
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);
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
);
250 if(FarFaceList
.size()>0)
252 // Create a faceVector of the wanted triangles size.
253 Far1FaceVector
= mgr
.createFaceVector(FarFaceList
.size());
256 refillFaceVectorFar1();
259 // ***************************************************************************
260 void CTessBlock::deleteFaceVectorFar1(CLandscapeFaceVectorManager
&mgr
)
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
++)
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
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);
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
++)
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());
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
++)
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.
353 mgr
.deleteFaceVector(faceVector
);
362 // ***************************************************************************
363 void CTessBlock::appendToModifyListAndDeleteFaceVector(CTessBlock
&root
, CLandscapeFaceVectorManager
&mgr
)
365 // If already appened, return.
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())
390 _PrecToModify
->_NextToModify
= _NextToModify
;
392 _NextToModify
->_PrecToModify
= _PrecToModify
;