// NeL - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
#include "std3d.h"
#include "nel/3d/tess_block.h"
#include "nel/3d/patch_rdr_pass.h"
#include "nel/3d/landscape_face_vector_manager.h"
namespace NL3D
{
CPlane CTessBlock::CurrentPyramid[NL3D_TESSBLOCK_NUM_CLIP_PLANE];
// ***************************************************************************
CTessBlock::CTessBlock()
{
_Patch= NULL;
// init bounding info.
Empty= true;
// By default, the tessBlock is clipped.
Clipped= true;
FullFar1= false;
EmptyFar1= false;
// init vert/face list.
for(sint i=0;i tileDistNear)
{
FullFar1= true;
}
else
{
if( (r+BSphere.Radius) < (tileDistNear-farTransition) )
EmptyFar1= true;
}
}
// ***************************************************************************
void CTessBlock::refillFaceVectorFar0()
{
// If size is not 0.
if(FarFaceList.size()>0)
{
nlassert(Far0FaceVector!=NULL);
// Fill this faceVector, with FarFaceList
CTessFace *pFace;
TLandscapeIndexType *dest= Far0FaceVector+1;
for(pFace= FarFaceList.begin(); pFace; pFace= (CTessFace*)pFace->Next)
{
#if defined(NL_DEBUG) && defined(NL_LANDSCAPE_INDEX16)
nlassert(pFace->FVBase->Index0 <= 0xffff);
nlassert(pFace->FVLeft->Index0 <= 0xffff);
nlassert(pFace->FVRight->Index0 <= 0xffff);
#endif
*(dest++)= (TLandscapeIndexType) pFace->FVBase->Index0;
*(dest++)= (TLandscapeIndexType) pFace->FVLeft->Index0;
*(dest++)= (TLandscapeIndexType) pFace->FVRight->Index0;
}
}
}
// ***************************************************************************
void CTessBlock::createFaceVectorFar0(CLandscapeFaceVectorManager &mgr)
{
nlassert(Far0FaceVector==NULL);
// If size is not 0.
if(FarFaceList.size()>0)
{
// Create a faceVector of the wanted triangles size.
Far0FaceVector= mgr.createFaceVector(FarFaceList.size());
// init.
refillFaceVectorFar0();
}
}
// ***************************************************************************
void CTessBlock::deleteFaceVectorFar0(CLandscapeFaceVectorManager &mgr)
{
if(Far0FaceVector)
{
mgr.deleteFaceVector(Far0FaceVector);
Far0FaceVector= NULL;
}
}
// ***************************************************************************
void CTessBlock::refillFaceVectorFar1()
{
// If size is not 0.
if(FarFaceList.size()>0)
{
nlassert(Far1FaceVector!=NULL);
// Fill this faceVector, with FarFaceList
CTessFace *pFace;
TLandscapeIndexType *dest= Far1FaceVector+1;
for(pFace= FarFaceList.begin(); pFace; pFace= (CTessFace*)pFace->Next)
{
#if defined(NL_DEBUG) && defined(NL_LANDSCAPE_INDEX16)
nlassert(pFace->FVBase->Index1 <= 0xffff);
nlassert(pFace->FVLeft->Index1 <= 0xffff);
nlassert(pFace->FVRight->Index1 <= 0xffff);
#endif
*(dest++)= (TLandscapeIndexType) pFace->FVBase->Index1;
*(dest++)= (TLandscapeIndexType) pFace->FVLeft->Index1;
*(dest++)= (TLandscapeIndexType) pFace->FVRight->Index1;
}
}
}
// ***************************************************************************
void CTessBlock::createFaceVectorFar1(CLandscapeFaceVectorManager &mgr)
{
nlassert(Far1FaceVector==NULL);
// If size is not 0.
if(FarFaceList.size()>0)
{
// Create a faceVector of the wanted triangles size.
Far1FaceVector= mgr.createFaceVector(FarFaceList.size());
// init.
refillFaceVectorFar1();
}
}
// ***************************************************************************
void CTessBlock::deleteFaceVectorFar1(CLandscapeFaceVectorManager &mgr)
{
if(Far1FaceVector)
{
mgr.deleteFaceVector(Far1FaceVector);
Far1FaceVector= NULL;
}
}
// ***************************************************************************
void CTessBlock::refillFaceVectorTile()
{
// For all tiles existing, and for all facePass existing, fill the faceVector.
for(uint tileId=0; tileId &faceList= RdrTileRoot[tileId]->TileFaceList[facePass];
TLandscapeIndexType *faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
// If some triangles create them.
if(faceList.size()>0)
{
nlassert( faceVector!=NULL );
// Fill this faceVector, with the TileFaceList
CTileFace *pFace;
TLandscapeIndexType *dest= faceVector+1;
for(pFace= faceList.begin(); pFace; pFace= (CTileFace*)pFace->Next)
{
#if defined(NL_DEBUG) && defined(NL_LANDSCAPE_INDEX16)
nlassert(pFace->V[CTessFace::IdUvBase]->Index <= 0xffff);
nlassert(pFace->V[CTessFace::IdUvLeft]->Index <= 0xffff);
nlassert(pFace->V[CTessFace::IdUvRight]->Index <= 0xffff);
#endif
*(dest++)= (TLandscapeIndexType) pFace->V[CTessFace::IdUvBase]->Index;
*(dest++)= (TLandscapeIndexType) pFace->V[CTessFace::IdUvLeft]->Index;
*(dest++)= (TLandscapeIndexType) pFace->V[CTessFace::IdUvRight]->Index;
}
}
}
}
}
}
// ***************************************************************************
void CTessBlock::createFaceVectorTile(CLandscapeFaceVectorManager &mgr)
{
// For all tiles existing, and for all facePass existing, create the faceVector.
for(uint tileId=0; tileId &faceList= RdrTileRoot[tileId]->TileFaceList[facePass];
TLandscapeIndexType *&faceVector= RdrTileRoot[tileId]->TileFaceVectors[facePass];
// If some triangles create them.
if(faceList.size()>0)
{
// Create a faceVector of the wanted triangles size.
faceVector= mgr.createFaceVector(faceList.size());
}
}
}
}
// init.
refillFaceVectorTile();
}
// ***************************************************************************
void CTessBlock::deleteFaceVectorTile(CLandscapeFaceVectorManager &mgr)
{
// For all tiles existing, and for all facePass existing, delete the faceVector.
for(uint tileId=0; tileIdTileFaceVectors[facePass];
// If the faceVector exist, delete it.
if(faceVector)
{
mgr.deleteFaceVector(faceVector);
faceVector= NULL;
}
}
}
}
}
// ***************************************************************************
void CTessBlock::appendToModifyListAndDeleteFaceVector(CTessBlock &root, CLandscapeFaceVectorManager &mgr)
{
// If already appened, return.
if(isInModifyList())
return;
// append to root.
_PrecToModify= &root;
_NextToModify= root._NextToModify;
if(root._NextToModify)
root._NextToModify->_PrecToModify= this;
root._NextToModify= this;
// Then delete All faceVector that may exist.
deleteFaceVectorFar0(mgr);
deleteFaceVectorFar1(mgr);
deleteFaceVectorTile(mgr);
}
// ***************************************************************************
void CTessBlock::removeFromModifyList()
{
// If already removed, return.
// _PrecToModify must be !NULL
if(!isInModifyList())
return;
// unlink.
_PrecToModify->_NextToModify= _NextToModify;
if(_NextToModify)
_NextToModify->_PrecToModify= _PrecToModify;
_PrecToModify= NULL;
_NextToModify= NULL;
}
} // NL3D