NL3D::CShadowPolyReceiver Class Reference

#include <shadow_poly_receiver.h>


Detailed Description

A class used to append/remove triangles that will be rendered for ShadowMap Additionally it can be used also for Camera collision for instance.
Author:
Lionel Berenguier

Nevrax France

Date:
2003

Definition at line 57 of file shadow_poly_receiver.h.

Public Member Functions

uint addTriangle (const NLMISC::CTriangle &tri)
 Append a triangle to the poly receiver.

 CShadowPolyReceiver (uint quadGridSize=32, float quadGridCellSize=4.f)
 Constructor.

float getCameraCollision (const CVector &start, const CVector &end, float radius, bool cone)
void removeTriangle (uint id)
 remove a triangle from the poly receiver.

void render (IDriver *drv, CMaterial &shadowMat, const CShadowMap *shadowMap, const CVector &casterPos, const CVector &vertDelta)

Private Types

typedef CQuadGrid< CTriangleIdTTriangleGrid
typedef std::map< CVector,
uint
TVertexMap

Private Member Functions

uint allocateVertex (const CVector &v)
void incVertexRefCount (uint id)
void releaseVertex (uint id)

Private Attributes

std::vector< uint_FreeTriangles
std::vector< uint_FreeVertices
std::vector< uint32_RenderTriangles
TTriangleGrid _TriangleGrid
std::vector< TTriangleGrid::CIterator > _Triangles
CVertexBuffer _VB
TVertexMap _VertexMap
std::vector< CVectorId_Vertices


Member Typedef Documentation

typedef CQuadGrid<CTriangleId> NL3D::CShadowPolyReceiver::TTriangleGrid [private]
 

Definition at line 105 of file shadow_poly_receiver.h.

typedef std::map<CVector, uint> NL3D::CShadowPolyReceiver::TVertexMap [private]
 

Definition at line 97 of file shadow_poly_receiver.h.


Constructor & Destructor Documentation

NL3D::CShadowPolyReceiver::CShadowPolyReceiver uint  quadGridSize = 32,
float  quadGridCellSize = 4.f
 

Constructor.

Definition at line 43 of file shadow_poly_receiver.cpp.

References _FreeTriangles, _FreeVertices, _TriangleGrid, NL3D::CQuadGrid< T >::create(), NL3D::CVertexBuffer::setVertexFormat(), and uint.

00044 {
00045         _Vertices.reserve(64);
00046         _FreeVertices.reserve(64);
00047         _FreeTriangles.reserve(64);
00048         _Triangles.reserve(64);
00049 
00050         _TriangleGrid.create(quadGridSize, quadGridCellSize);
00051 
00052         _VB.setVertexFormat(CVertexBuffer::PositionFlag);
00053 }


Member Function Documentation

uint NL3D::CShadowPolyReceiver::addTriangle const NLMISC::CTriangle tri  ) 
 

Append a triangle to the poly receiver.

Definition at line 57 of file shadow_poly_receiver.cpp.

References _FreeTriangles, _RenderTriangles, _TriangleGrid, _VertexMap, allocateVertex(), NLMISC::CAABBox::extend(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), incVertexRefCount(), NL3D::CQuadGrid< T >::insert(), NLMISC::CAABBox::setCenter(), uint, v, NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, and NL3D::CShadowPolyReceiver::CTriangleId::Vertex.

Referenced by NL3D::CLandscape::appendToShadowPolyReceiver().

00058 {
00059         uint    id;
00060 
00061         // Look for a free triangle entry.
00062         if(_FreeTriangles.empty())
00063         {
00064                 _Triangles.push_back(TTriangleGrid::CIterator());
00065                 id= _Triangles.size()-1;
00066                 // enlarge render size.
00067                 _RenderTriangles.resize(_Triangles.size() * 3);
00068         }
00069         else
00070         {
00071                 id= _FreeTriangles.back();
00072                 _FreeTriangles.pop_back();
00073         }
00074 
00075         // Allocate vertices, reusing same ones.
00076         CTriangleId             triId;
00077         CVector                 v[3];
00078         v[0]= tri.V0;
00079         v[1]= tri.V1;
00080         v[2]= tri.V2;
00081         for(uint i=0;i<3;i++)
00082         {
00083                 // Find the vertex in the map.
00084                 TVertexMap::iterator    it;
00085                 it= _VertexMap.find(v[i]);
00086                 // if not found, allocate it
00087                 if(it==_VertexMap.end())
00088                 {
00089                         triId.Vertex[i]= allocateVertex(v[i]);
00090                 }
00091                 // else get its id
00092                 else
00093                 {
00094                         triId.Vertex[i]= it->second;
00095                 }
00096 
00097                 // increment the reference of this vertex
00098                 incVertexRefCount(triId.Vertex[i]);
00099         }
00100         
00101         // Insert the triangle in the quadGrid.
00102         CAABBox         bb;
00103         bb.setCenter(tri.V0);
00104         bb.extend(tri.V1);
00105         bb.extend(tri.V2);
00106         // insert in QuadGrid and store iterator for future remove
00107         _Triangles[id]= _TriangleGrid.insert(bb.getMin(), bb.getMax(), triId);
00108 
00109         return id;
00110 }

uint NL3D::CShadowPolyReceiver::allocateVertex const CVector v  )  [private]
 

Definition at line 134 of file shadow_poly_receiver.cpp.

References _FreeVertices, _VertexMap, NL3D::CVertexBuffer::setNumVertices(), uint, and v.

Referenced by addTriangle().

00135 {
00136         uint    id;
00137 
00138         // Look for a free vertex entry.
00139         if(_FreeVertices.empty())
00140         {
00141                 // Add the vertex, and init refCount to 0.
00142                 _Vertices.push_back(v);
00143                 id= _Vertices.size()-1;
00144 
00145                 // Resize the VBuffer at max possible
00146                 _VB.setNumVertices(_Vertices.size());
00147         }
00148         else
00149         {
00150                 id= _FreeVertices.back();
00151                 _FreeVertices.pop_back();
00152                 // init entry
00153                 _Vertices[id]= v;
00154                 _Vertices[id].RefCount= 0;
00155         }
00156 
00157         // insert in the map (should not be here)
00158         _VertexMap.insert( make_pair(v, id) );
00159 
00160         return id;
00161 }

float NL3D::CShadowPolyReceiver::getCameraCollision const CVector start,
const CVector end,
float  radius,
bool  cone
 

Use the triangles added for camera 3rd person collision return a [0,1] value. 0 => collision at start. 1 => no collision.

Parameters:
radius is the radius of the 'cylinder'
cone if true, the object tested is a cone (radius goes to end)

Definition at line 308 of file shadow_poly_receiver.cpp.

References _TriangleGrid, NL3D::CCameraCol::BBox, NL3D::CQuadGrid< T >::begin(), NL3D::CCameraCol::build(), NL3D::CQuadGrid< T >::end(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), min, NL3D::CCameraCol::minimizeDistanceAgainstTri(), NL3D::CQuadGrid< T >::select(), and NL3D::CShadowPolyReceiver::CTriangleId::Vertex.

Referenced by NL3D::CLandscape::getCameraCollision().

00309 {
00310         // **** build the camera collision info
00311         CCameraCol      camCol;
00312         camCol.build(start, end, radius, cone);
00313         
00314         // select with quadGrid
00315         _TriangleGrid.select(camCol.BBox.getMin(), camCol.BBox.getMax());
00316         
00317         // **** For all triangles, test if intersect the camera collision
00318         TTriangleGrid::CIterator        it;
00319         float           sqrMinDist= FLT_MAX;
00320         for(it=_TriangleGrid.begin();it!=_TriangleGrid.end();it++)
00321         {
00322                 CTriangleId             &triId= *it;
00323                 camCol.minimizeDistanceAgainstTri(
00324                         _Vertices[triId.Vertex[0]], 
00325                         _Vertices[triId.Vertex[1]],
00326                         _Vertices[triId.Vertex[2]],
00327                         sqrMinDist);
00328         }
00329 
00330         // **** return the collision found, between [0,1]
00331         if(sqrMinDist == FLT_MAX)
00332                 return 1;
00333         else
00334         {
00335                 float   f= 1;
00336                 float   d= (end-start).norm();
00337                 if(d>0)
00338                 {
00339                         f= sqrtf(sqrMinDist) / d;
00340                         f= min(f, 1.f);
00341                 }
00342                 return f;
00343         }
00344 
00345 }

void NL3D::CShadowPolyReceiver::incVertexRefCount uint  id  )  [private]
 

Definition at line 183 of file shadow_poly_receiver.cpp.

References NL3D_SPR_MAX_REF_COUNT, nlassert, and uint.

Referenced by addTriangle().

00184 {
00185         nlassert(id<_Vertices.size());
00186         nlassert(_Vertices[id].RefCount < NL3D_SPR_MAX_REF_COUNT);
00187         _Vertices[id].RefCount++;
00188 }

void NL3D::CShadowPolyReceiver::releaseVertex uint  id  )  [private]
 

Definition at line 164 of file shadow_poly_receiver.cpp.

References _FreeVertices, _VertexMap, nlassert, and uint.

Referenced by removeTriangle().

00165 {
00166         nlassert(id<_Vertices.size());
00167         // dec ref
00168         nlassert(_Vertices[id].RefCount>0);
00169         _Vertices[id].RefCount--;
00170         // no more used?
00171         if(_Vertices[id].RefCount==0)
00172         {
00173                 // Free it.
00174                 _FreeVertices.push_back(id);
00175                 // Remove it from map.
00176                 TVertexMap::iterator    it= _VertexMap.find(_Vertices[id]);
00177                 nlassert(it!=_VertexMap.end());
00178                 _VertexMap.erase(it);
00179         }
00180 }

void NL3D::CShadowPolyReceiver::removeTriangle uint  id  ) 
 

remove a triangle from the poly receiver.

Definition at line 113 of file shadow_poly_receiver.cpp.

References _FreeTriangles, _TriangleGrid, NL3D::CQuadGrid< T >::end(), NL3D::CQuadGrid< T >::erase(), nlassert, releaseVertex(), uint, and NL3D::CShadowPolyReceiver::CTriangleId::Vertex.

Referenced by NL3D::CLandscape::removeFromShadowPolyReceiver().

00114 {
00115         nlassert(id<_Triangles.size());
00116         // Must not be NULL iterator.
00117         nlassert(_Triangles[id]!=_TriangleGrid.end());
00118 
00119         // Release Vertices
00120         const CTriangleId               &triId= *_Triangles[id];
00121         releaseVertex(triId.Vertex[0]);
00122         releaseVertex(triId.Vertex[1]);
00123         releaseVertex(triId.Vertex[2]);
00124 
00125         // Delete Triangle.
00126         _TriangleGrid.erase(_Triangles[id]);
00127         _Triangles[id]= _TriangleGrid.end();
00128         // Append to free list.
00129         _FreeTriangles.push_back(id);
00130 }

void NL3D::CShadowPolyReceiver::render IDriver drv,
CMaterial shadowMat,
const CShadowMap shadowMap,
const CVector casterPos,
const CVector vertDelta
 

clip, and render with a shadow map. Matrix setup should be OK.

Parameters:
vertDelta (for landscape). add this value from vertices before rendering.

Definition at line 192 of file shadow_poly_receiver.cpp.

References _RenderTriangles, _TriangleGrid, NL3D::IDriver::activeVertexBuffer(), NL3D::CQuadGrid< T >::begin(), NL3D::CQuadGrid< T >::end(), NLMISC::CAABBox::getCenter(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NL3D::CShadowMap::LocalBoundingBox, NL3D::CShadowMap::LocalClipPlanes, min, NL3D_SPR_NUM_CLIP_PLANE, NL3D_SPR_NUM_CLIP_PLANE_MASK, NL3D_SPR_NUM_CLIP_PLANE_SHIFT, NL3D::IDriver::renderTriangles(), NL3D::CQuadGrid< T >::select(), NLMISC::CAABBox::setCenter(), NLMISC::CMatrix::setPos(), NL3D::CVertexBuffer::setVertexCoord(), sint, uint, and NL3D::CShadowPolyReceiver::CTriangleId::Vertex.

Referenced by NL3D::CLandscape::receiveShadowMap().

00193 {
00194         uint    i, j;
00195 
00196         // **** Fill Triangles that are hit by the Caster
00197         // First select with quadGrid
00198         CAABBox         worldBB;
00199         worldBB= shadowMap->LocalBoundingBox;
00200         worldBB.setCenter(worldBB.getCenter() + casterPos);
00201         _TriangleGrid.select(worldBB.getMin(), worldBB.getMax());
00202 
00203         // For all triangles, reset vertices flags.
00204         TTriangleGrid::CIterator        it;
00205         for(it=_TriangleGrid.begin();it!=_TriangleGrid.end();it++)
00206         {
00207                 CTriangleId             &triId= *it;
00208                 for(i=0;i<3;i++)
00209                 {
00210                         _Vertices[triId.Vertex[i]].Flags= 0;
00211                         _Vertices[triId.Vertex[i]].VBIdx= -1;
00212                 }
00213         }
00214 
00215         // Copute the world Clip Volume
00216         static  std::vector<CPlane>             worldClipPlanes;
00217         CMatrix         worldMat;
00218         // set -casterPos, because to transform a plane, we must do plane * M-1
00219         worldMat.setPos(-casterPos);
00220         // Allow max bits of planes clip.
00221         worldClipPlanes.resize(min((uint)shadowMap->LocalClipPlanes.size(), (uint)NL3D_SPR_NUM_CLIP_PLANE));
00222         // Transform into world
00223         for(i=0;i<worldClipPlanes.size();i++)
00224         {
00225                 worldClipPlanes[i]= shadowMap->LocalClipPlanes[i] * worldMat;
00226         }
00227 
00228         // For All triangles, clip them.
00229         uint    currentTriIdx= 0;
00230         uint    currentVbIdx= 0;
00231         for(it=_TriangleGrid.begin();it!=_TriangleGrid.end();it++)
00232         {
00233                 CTriangleId             &triId= *it;
00234                 uint                    triFlag= NL3D_SPR_NUM_CLIP_PLANE_MASK;
00235 
00236                 // for all vertices, clip them
00237                 for(i=0;i<3;i++)
00238                 {
00239                         uint    vid= triId.Vertex[i];
00240                         uint    vertexFlags= _Vertices[vid].Flags;
00241 
00242                         // if this vertex is still not computed
00243                         if(!vertexFlags)
00244                         {
00245                                 // For all planes of the Clip Volume, clip this vertex.
00246                                 for(j=0;j<worldClipPlanes.size();j++)
00247                                 {
00248                                         // out if in front
00249                                         bool    out= worldClipPlanes[j]*_Vertices[vid] > 0;
00250 
00251                                         vertexFlags|= ((uint)out)<<j;
00252                                 }
00253 
00254                                 // add the bit flag to say "computed".
00255                                 vertexFlags|= NL3D_SPR_NUM_CLIP_PLANE_SHIFT;
00256 
00257                                 // store
00258                                 _Vertices[vid].Flags= vertexFlags;
00259                         }
00260 
00261                         // And all vertex bits.
00262                         triFlag&= vertexFlags;
00263                 }
00264 
00265                 // if triangle not clipped, add the triangle
00266                 if( (triFlag & NL3D_SPR_NUM_CLIP_PLANE_MASK)==0 )
00267                 {
00268                         // Add the 3 vertices to the VB, and to the index buffer.
00269                         for(i=0;i<3;i++)
00270                         {
00271                                 uint    vid= triId.Vertex[i];
00272                                 sint    vbId= _Vertices[vid].VBIdx;
00273 
00274                                 // if not yet inserted in the VB, do it.
00275                                 if(vbId==-1)
00276                                 {
00277                                         // allocate a new place in the VBuffer
00278                                         vbId= currentVbIdx++;
00279                                         _Vertices[vid].VBIdx= vbId;
00280                                         // set the coord
00281                                         _VB.setVertexCoord(vbId, _Vertices[vid]+vertDelta);
00282                                 }
00283 
00284                                 // add the index to the tri list.
00285                                 _RenderTriangles[currentTriIdx++]= vbId;
00286                         }
00287                 }
00288         }
00289 
00290 
00291         // **** Render
00292         drv->activeVertexBuffer(_VB);
00293         drv->renderTriangles(shadowMat, &_RenderTriangles[0], currentTriIdx/3);
00294         // TestYoyo. Show in Red triangles selected
00295         /*static        CMaterial       tam;
00296         tam.initUnlit();
00297         tam.setColor(CRGBA(255,0,0,128));
00298         tam.setZFunc(CMaterial::always);
00299         tam.setZWrite(false);
00300         tam.setBlend(true);
00301         tam.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha);
00302         tam.setDoubleSided(true);
00303         drv->renderTriangles(tam, &_RenderTriangles[0], currentTriIdx/3);*/
00304 }


Field Documentation

std::vector<uint> NL3D::CShadowPolyReceiver::_FreeTriangles [private]
 

Definition at line 108 of file shadow_poly_receiver.h.

Referenced by addTriangle(), CShadowPolyReceiver(), and removeTriangle().

std::vector<uint> NL3D::CShadowPolyReceiver::_FreeVertices [private]
 

Definition at line 96 of file shadow_poly_receiver.h.

Referenced by allocateVertex(), CShadowPolyReceiver(), and releaseVertex().

std::vector<uint32> NL3D::CShadowPolyReceiver::_RenderTriangles [private]
 

Definition at line 113 of file shadow_poly_receiver.h.

Referenced by addTriangle(), and render().

TTriangleGrid NL3D::CShadowPolyReceiver::_TriangleGrid [private]
 

Definition at line 106 of file shadow_poly_receiver.h.

Referenced by addTriangle(), CShadowPolyReceiver(), getCameraCollision(), removeTriangle(), and render().

std::vector<TTriangleGrid::CIterator> NL3D::CShadowPolyReceiver::_Triangles [private]
 

Definition at line 107 of file shadow_poly_receiver.h.

CVertexBuffer NL3D::CShadowPolyReceiver::_VB [private]
 

Definition at line 112 of file shadow_poly_receiver.h.

TVertexMap NL3D::CShadowPolyReceiver::_VertexMap [private]
 

Definition at line 98 of file shadow_poly_receiver.h.

Referenced by addTriangle(), allocateVertex(), and releaseVertex().

std::vector<CVectorId> NL3D::CShadowPolyReceiver::_Vertices [private]
 

Definition at line 95 of file shadow_poly_receiver.h.


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 07:43:27 2004 for NeL by doxygen 1.3.6