NL3D::CInstanceLighter Class Reference

#include <instance_lighter.h>


Detailed Description

A class to precompute "StaticSetup" lighting for instances in an InstanceGroup. Class "inspired" from CZoneLighter :)
Author:
Lionel Berenguier

Nevrax France

Date:
2001

Definition at line 55 of file instance_lighter.h.

Cell Iteration. ie iteration on _IGRetrieverGridMap cells and _IGSurfaceLightBuild cells

void beginCell ()
CSurfaceLightGrid::CCellCornergetCurrentCell ()
CIGSurfaceLightBuild::CCellCornergetCurrentCellInfo ()
uint getCurrentCellNumber () const
CSurfaceLightGrid::CCellCornergetCurrentNeighborCell (sint xnb, sint ynb)
CIGSurfaceLightBuild::CCellCornergetCurrentNeighborCellInfo (sint xnb, sint ynb)
uint getTotalCellNumber () const
bool isCurrentNeighborCellInSurface (sint xnb, sint ynb)
bool isEndCell ()
void nextCell ()
void progressCell (const char *message)
bool _IsEndCell
uint _ItCellId
uint _ItCurrentCellNumber
CIGSurfaceLight::ItRetrieverGridMap _ItRetriever
CIGSurfaceLightBuild::ItRetrieverGridMap _ItRetrieverInfo
uint _ItSurfId
float _LastCellProgress
uint _TotalCellNumber

Public Types

enum  { MaxOverSamples = 16 }

Public Member Functions

 CInstanceLighter ()
 Constructor.

void init ()
void light (const CInstanceGroup &igIn, CInstanceGroup &igOut, const CLightDesc &lightDesc, std::vector< CTriangle > &obstacles, CLandscape *landscape=NULL, CIGSurfaceLightBuild *igSurfaceLightBuild=NULL)
virtual void progress (const char *message, float progress)
virtual ~CInstanceLighter ()
 Destructor.

Static PointLights mgt.
void addStaticPointLight (const CPointLightNamed &pln, const char *igName)

Static Public Member Functions

void addTriangles (const IShape &shape, const NLMISC::CMatrix &modelMT, std::vector< CTriangle > &triangleArray, sint instanceId)
void addTriangles (CLandscape &landscape, std::vector< uint > &listZone, uint order, std::vector< CTriangle > &triangleArray)
void lightIgSimple (CInstanceLighter &instLighter, const CInstanceGroup &igIn, CInstanceGroup &igOut, const CLightDesc &lightDesc, const char *igName)

Private Member Functions

void compilePointLightRT (uint gridSize, float gridCellSize, std::vector< CTriangle > &obstacles, bool doShadow)
 Fill CubeGrid, and set PointLightRT in _StaticPointLightQuadGrid.

void computeSunContribution (const CLightDesc &lightDesc, std::vector< CTriangle > &obstacles, CLandscape *landscape)
void dilateLightingOnSurfaceCells ()
void processIGPointLightRT (std::vector< CPointLightNamed > &listPointLight)

Static Private Member Functions

void addTriangles (const CMeshMRMGeom &meshGeom, const NLMISC::CMatrix &modelMT, std::vector< CTriangle > &triangleArray, sint instanceId)
void addTriangles (const CMeshGeom &meshGeom, const NLMISC::CMatrix &modelMT, std::vector< CTriangle > &triangleArray, sint instanceId)
void excludeAllPatchFromRefineAll (CLandscape &landscape, std::vector< uint > &listZone, bool exclude)

Private Attributes

sint _CurrentInstanceComputed
CIGSurfaceLight::TRetrieverGridMap _IGRetrieverGridMap
CIGSurfaceLightBuild_IGSurfaceLightBuild
std::vector< CInstanceInfo_InstanceInfos
std::vector< CInstanceGroup::CInstance_Instances
CQuadGrid< CPointLightRT * > _StaticPointLightQuadGrid
 QuadGrid of PointLights. Builded from _StaticPointLights.

std::vector< CPointLightRT_StaticPointLights
 List of PointLights.


Member Enumeration Documentation

anonymous enum
 

Enumeration values:
MaxOverSamples 

Definition at line 59 of file instance_lighter.h.

00059 {MaxOverSamples= 16};


Constructor & Destructor Documentation

NL3D::CInstanceLighter::CInstanceLighter  ) 
 

Constructor.

Definition at line 66 of file instance_lighter.cpp.

References _IGSurfaceLightBuild.

00067 {
00068         _IGSurfaceLightBuild= NULL;
00069 }

virtual NL3D::CInstanceLighter::~CInstanceLighter  )  [inline, virtual]
 

Destructor.

Definition at line 131 of file instance_lighter.h.

00131 {}


Member Function Documentation

void NL3D::CInstanceLighter::addStaticPointLight const CPointLightNamed pln,
const char *  igName
 

Append a static point light to compute. call at setup stage (before light() ). NB: you must append all PointLights of intersets, even ones from the IG to compute.

Definition at line 999 of file instance_lighter.cpp.

References _StaticPointLights, NL3D::CInstanceLighter::CPointLightRT::BSphere, NLMISC::CBSphere::Center, NL3D::CPointLight::getAttenuationBegin(), NL3D::CPointLight::getAttenuationEnd(), NL3D::CPointLight::getPosition(), NL3D::CInstanceLighter::CPointLightRT::OODeltaAttenuation, NL3D::CInstanceLighter::CPointLightRT::PointLight, and NLMISC::CBSphere::Radius.

Referenced by lightIgSimple().

01000 {
01001         // NB: adding light more than 255 is allowed here, since the important thig is to not overflow really usefull lights
01002 
01003         // build the plRT.
01004         CPointLightRT   plRT;
01005         plRT.PointLight= pln;
01006         // compute plRT.OODeltaAttenuation
01007         plRT.OODeltaAttenuation= pln.getAttenuationEnd() - pln.getAttenuationBegin();
01008         if(plRT.OODeltaAttenuation <=0 )
01009                 plRT.OODeltaAttenuation= 1e10f;
01010         else
01011                 plRT.OODeltaAttenuation= 1.0f / plRT.OODeltaAttenuation;
01012         // compute plRT.BSphere
01013         plRT.BSphere.Center= pln.getPosition();
01014         plRT.BSphere.Radius= pln.getAttenuationEnd();
01015         // NB: FaceCubeGrid will be computed during light()
01016 
01017         // add the plRT
01018         _StaticPointLights.push_back(plRT);
01019 }

void NL3D::CInstanceLighter::addTriangles const CMeshMRMGeom meshGeom,
const NLMISC::CMatrix modelMT,
std::vector< CTriangle > &  triangleArray,
sint  instanceId
[static, private]
 

Definition at line 231 of file instance_lighter.cpp.

References NL3D::CMeshMRMGeom::getNbRdrPass(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CPrimitiveBlock::getQuadPointer(), NL3D::CMeshMRMGeom::getRdrPassPrimitiveBlock(), NL3D::CPrimitiveBlock::getTriPointer(), NL3D::CMeshMRMGeom::getVertexBuffer(), NL3D::CVertexBuffer::getVertexCoordPointer(), sint, uint, and uint32.

00232 {
00233         // Get the vertex buffer
00234         const CVertexBuffer &vb=meshGeom.getVertexBuffer();
00235 
00236         // For each render pass
00237         uint numRenderPass=meshGeom.getNbRdrPass(0);
00238         for (uint pass=0; pass<numRenderPass; pass++)
00239         {
00240                 // Get the primitive block
00241                 const CPrimitiveBlock &primitive=meshGeom.getRdrPassPrimitiveBlock ( 0, pass);
00242 
00243                 // Dump triangles
00244                 const uint32* triIndex=primitive.getTriPointer ();
00245                 uint numTri=primitive.getNumTri ();
00246                 uint tri;
00247                 for (tri=0; tri<numTri; tri++)
00248                 {
00249                         // Vertex
00250                         CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3]));
00251                         CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+1]));
00252                         CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+2]));
00253 
00254                         // Make a triangle
00255                         triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), instanceId));
00256                 }
00257 
00258                 // Dump quad
00259                 triIndex=primitive.getQuadPointer ();
00260                 numTri=primitive.getNumQuad ();
00261                 for (tri=0; tri<numTri; tri++)
00262                 {
00263                         // Vertex
00264                         CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4]));
00265                         CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+1]));
00266                         CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+2]));
00267                         CVector v3=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+3]));
00268 
00269                         // Make 2 triangles
00270                         triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), instanceId));
00271                         triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v2, v3), instanceId));
00272                 }
00273         }
00274 }

void NL3D::CInstanceLighter::addTriangles const CMeshGeom meshGeom,
const NLMISC::CMatrix modelMT,
std::vector< CTriangle > &  triangleArray,
sint  instanceId
[static, private]
 

Definition at line 179 of file instance_lighter.cpp.

References NL3D::CMeshGeom::getNbMatrixBlock(), NL3D::CMeshGeom::getNbRdrPass(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CPrimitiveBlock::getQuadPointer(), NL3D::CMeshGeom::getRdrPassPrimitiveBlock(), NL3D::CPrimitiveBlock::getTriPointer(), NL3D::CMeshGeom::getVertexBuffer(), NL3D::CVertexBuffer::getVertexCoordPointer(), sint, uint, and uint32.

00180 {
00181         // Get the vertex buffer
00182         const CVertexBuffer &vb=meshGeom.getVertexBuffer();
00183 
00184         // For each matrix block
00185         uint numBlock=meshGeom.getNbMatrixBlock();
00186         for (uint block=0; block<numBlock; block++)
00187         {
00188                 // For each render pass
00189                 uint numRenderPass=meshGeom.getNbRdrPass(block);
00190                 for (uint pass=0; pass<numRenderPass; pass++)
00191                 {
00192                         // Get the primitive block
00193                         const CPrimitiveBlock &primitive=meshGeom.getRdrPassPrimitiveBlock ( block, pass);
00194 
00195                         // Dump triangles
00196                         const uint32* triIndex=primitive.getTriPointer ();
00197                         uint numTri=primitive.getNumTri ();
00198                         uint tri;
00199                         for (tri=0; tri<numTri; tri++)
00200                         {
00201                                 // Vertex
00202                                 CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3]));
00203                                 CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+1]));
00204                                 CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+2]));
00205 
00206                                 // Make a triangle
00207                                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), instanceId));
00208                         }
00209 
00210                         // Dump quad
00211                         triIndex=primitive.getQuadPointer ();
00212                         numTri=primitive.getNumQuad ();
00213                         for (tri=0; tri<numTri; tri++)
00214                         {
00215                                 // Vertex
00216                                 CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4]));
00217                                 CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+1]));
00218                                 CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+2]));
00219                                 CVector v3=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+3]));
00220 
00221                                 // Make 2 triangles
00222                                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), instanceId));
00223                                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v2, v3), instanceId));
00224                         }
00225                 }
00226         }
00227 }

void NL3D::CInstanceLighter::addTriangles const IShape shape,
const NLMISC::CMatrix modelMT,
std::vector< CTriangle > &  triangleArray,
sint  instanceId
[static]
 

Add triangles from a transform shape. Work only for CMesh, CMultiMesh and CMeshMRM all without skinning. Give An instanceId!=-1 only for instances of the IG to compute. This is to avoid auto-shadowing.

Definition at line 129 of file instance_lighter.cpp.

References addTriangles(), NL3D::CMeshMRM::getMeshGeom(), NL3D::CMeshMultiLod::getMeshGeom(), NL3D::CMesh::getMeshGeom(), and sint.

00130 {
00131         // Lamed from CZoneLighter.
00132 
00133         // Cast to CMesh
00134         const CMesh *mesh=dynamic_cast<const CMesh*>(&shape);
00135 
00136         // Cast to CMeshMultiLod
00137         const CMeshMultiLod *meshMulti=dynamic_cast<const CMeshMultiLod*>(&shape);
00138 
00139         // Cast to CMeshMultiLod
00140         const CMeshMRM *meshMRM=dynamic_cast<const CMeshMRM*>(&shape);
00141 
00142         // It is a mesh ?
00143         if (mesh)
00144         {
00145                 // Add its triangles
00146                 addTriangles (mesh->getMeshGeom (), modelMT, triangleArray, instanceId);
00147         }
00148         // It is a CMeshMultiLod ?
00149         else if (meshMulti)
00150         {
00151                 // Get the first geommesh
00152                 const IMeshGeom *meshGeom=&meshMulti->getMeshGeom (0);
00153 
00154                 // Dynamic cast
00155                 const CMeshGeom *geomMesh=dynamic_cast<const CMeshGeom*>(meshGeom);
00156                 if (geomMesh)
00157                 {
00158                         addTriangles (*geomMesh, modelMT, triangleArray, instanceId);
00159                 }
00160 
00161                 // Dynamic cast
00162                 const CMeshMRMGeom *mrmGeomMesh=dynamic_cast<const CMeshMRMGeom*>(meshGeom);
00163                 if (mrmGeomMesh)
00164                 {
00165                         addTriangles (*mrmGeomMesh, modelMT, triangleArray, instanceId);
00166                 }
00167         }
00168         // It is a CMeshMultiLod ?
00169         else if (meshMRM)
00170         {
00171                 // Get the first lod mesh geom
00172                 addTriangles (meshMRM->getMeshGeom (), modelMT, triangleArray, instanceId);
00173         }
00174 }

void NL3D::CInstanceLighter::addTriangles CLandscape landscape,
std::vector< uint > &  listZone,
uint  order,
std::vector< CTriangle > &  triangleArray
[static]
 

Definition at line 77 of file instance_lighter.cpp.

References NL3D::CTessVertex::EndPos, excludeAllPatchFromRefineAll(), NL3D::CLandscape::getTessellationLeaves(), NL3D::CLandscape::refineAll(), NL3D::CLandscape::setThreshold(), NL3D::CLandscape::setTileMaxSubdivision(), uint, NL3D::CTessFace::VBase, NL3D::CTessFace::VLeft, and NL3D::CTessFace::VRight.

Referenced by addTriangles().

00078 {
00079         // Lamed from CZoneLighter.
00080         // Set all to refine
00081         excludeAllPatchFromRefineAll (landscape, listZone, false);
00082 
00083         // Setup the landscape
00084         landscape.setThreshold (0);
00085         landscape.setTileMaxSubdivision (order);
00086 
00087         // Refine it
00088         landscape.refineAll (CVector (0, 0, 0));
00089 
00090         // Dump tesselated triangles
00091         std::vector<const CTessFace*> leaves;
00092         landscape.getTessellationLeaves(leaves);
00093 
00094         // Number of leaves
00095         uint leavesCount=leaves.size();
00096 
00097         // Reserve the array
00098         triangleArray.reserve (triangleArray.size()+leavesCount);
00099 
00100         // Scan each leaves
00101         for (uint leave=0; leave<leavesCount; leave++)
00102         {
00103                 // Leave
00104                 const CTessFace *face=leaves[leave];
00105 
00106                 // Add a triangle. -1 because not an instance from an IG
00107                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (face->VBase->EndPos, face->VLeft->EndPos, face->VRight->EndPos), -1 ));
00108         }
00109 
00110         // Setup the landscape
00111         landscape.setThreshold (1000);
00112         landscape.setTileMaxSubdivision (0);
00113 
00114         // Remove all triangles
00115         landscape.refineAll (CVector (0, 0, 0));
00116         landscape.refineAll (CVector (0, 0, 0));
00117         landscape.refineAll (CVector (0, 0, 0));
00118         landscape.refineAll (CVector (0, 0, 0));
00119         landscape.refineAll (CVector (0, 0, 0));
00120         landscape.refineAll (CVector (0, 0, 0));
00121         landscape.refineAll (CVector (0, 0, 0));
00122         landscape.refineAll (CVector (0, 0, 0));
00123         landscape.refineAll (CVector (0, 0, 0));
00124         landscape.refineAll (CVector (0, 0, 0));
00125 
00126 }

void NL3D::CInstanceLighter::beginCell  )  [private]
 

Definition at line 1635 of file instance_lighter.cpp.

References _IGRetrieverGridMap, _IGSurfaceLightBuild, _IsEndCell, _ItCellId, _ItCurrentCellNumber, _ItRetriever, _ItRetrieverInfo, _ItSurfId, _LastCellProgress, nlassert, and NL3D::CIGSurfaceLightBuild::RetrieverGridMap.

Referenced by computeSunContribution(), dilateLightingOnSurfaceCells(), and processIGPointLightRT().

01636 {
01637         if(_IGSurfaceLightBuild)
01638         {
01639                 _ItRetriever= _IGRetrieverGridMap.begin();
01640                 if(_ItRetriever != _IGRetrieverGridMap.end() )
01641                 {
01642                         _ItRetrieverInfo= _IGSurfaceLightBuild->RetrieverGridMap.find(_ItRetriever->first);
01643                         nlassert(_ItRetrieverInfo != _IGSurfaceLightBuild->RetrieverGridMap.end() );
01644                         // We are suze here that the retriever is not empty, and that the grid herself is not empty too
01645                         _ItSurfId= 0;
01646                         _ItCellId= 0;
01647                         _ItCurrentCellNumber= 0;
01648                         _IsEndCell= false;
01649                         _LastCellProgress= 0;
01650                 }
01651                 else
01652                 {
01653                         _IsEndCell= true;
01654                 }
01655         }
01656         else
01657         {
01658                 _IsEndCell= true;
01659         }
01660 }

void NL3D::CInstanceLighter::compilePointLightRT uint  gridSize,
float  gridCellSize,
std::vector< CTriangle > &  obstacles,
bool  doShadow
[private]
 

Fill CubeGrid, and set PointLightRT in _StaticPointLightQuadGrid.

Definition at line 1023 of file instance_lighter.cpp.

References _StaticPointLightQuadGrid, _StaticPointLights, NL3D::CQuadGrid< T >::begin(), NL3D::CInstanceLighter::CPointLightRT::BSphere, NLMISC::CBSphere::Center, NL3D::CCubeGrid< const CTriangle * >::compile(), NL3D::CCubeGrid< const CTriangle * >::create(), NL3D::CQuadGrid< T >::create(), NL3D::CQuadGrid< CPointLightRT * >::create(), NL3D::CQuadGrid< T >::end(), NLMISC::CAABBox::extend(), NL3D::CInstanceLighter::CPointLightRT::FaceCubeGrid, NL3D::CPointLight::getAttenuationEnd(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NL3D::CPointLight::getPosition(), NL3D::CPointLight::getType(), NL3D::CCubeGrid< const CTriangle * >::insert(), NL3D::CQuadGrid< T >::insert(), NL3D::CQuadGrid< CPointLightRT * >::insert(), NL3D_INSTANCE_LIGHTER_CUBE_GRID_SIZE, NL3D::CInstanceLighter::CPointLightRT::PointLight, progress(), NLMISC::CBSphere::Radius, NL3D::CInstanceLighter::CPointLightRT::RefCount, NL3D::CQuadGrid< T >::select(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), size, NL3D::CInstanceLighter::CTriangle::Triangle, and uint.

Referenced by light().

01024 {
01025         uint    i;
01026 
01027         // Fill the quadGrid of Lights.
01028         // ===========
01029         _StaticPointLightQuadGrid.create(gridSize, gridCellSize);
01030         for(i=0; i<_StaticPointLights.size();i++)
01031         {
01032                 CPointLightRT   &plRT= _StaticPointLights[i];
01033 
01034                 // Compute the bbox of the light
01035                 CAABBox         bbox;
01036                 bbox.setCenter(plRT.BSphere.Center);
01037                 float   hl= plRT.BSphere.Radius;
01038                 bbox.setHalfSize(CVector(hl,hl,hl));
01039 
01040                 // Insert the pointLight in the quadGrid.
01041                 _StaticPointLightQuadGrid.insert(bbox.getMin(), bbox.getMax(), &plRT);
01042         }
01043 
01044 
01045         // Append triangles to cubeGrid ??
01046         if(doShadow)
01047         {
01048                 // For all obstacles, Fill a quadGrid.
01049                 // ===========
01050                 CQuadGrid<CTriangle*>   obstacleGrid;
01051                 obstacleGrid.create(gridSize, gridCellSize);
01052                 uint    size= obstacles.size();
01053                 for(i=0; i<size; i++)
01054                 {
01055                         // bbox of triangle
01056                         CAABBox bbox;
01057                         bbox.setCenter(obstacles[i].Triangle.V0);
01058                         bbox.extend(obstacles[i].Triangle.V1);
01059                         bbox.extend(obstacles[i].Triangle.V2);
01060                         // insert triangle in quadGrid.
01061                         obstacleGrid.insert(bbox.getMin(), bbox.getMax(), &obstacles[i]);
01062                 }
01063 
01064 
01065                 // For all PointLights, fill his CubeGrid
01066                 // ===========
01067                 for(i=0; i<_StaticPointLights.size();i++)
01068                 {
01069                         // progress
01070                         progress ("Compute Influences of PointLights 1/2", i / (float)_StaticPointLights.size());
01071 
01072                         CPointLightRT   &plRT= _StaticPointLights[i];
01073                         // Create the cubeGrid
01074                         plRT.FaceCubeGrid.create(plRT.PointLight.getPosition(), NL3D_INSTANCE_LIGHTER_CUBE_GRID_SIZE);
01075 
01076                         // AmbiantLIghts: do nothing.
01077                         if(plRT.PointLight.getType()!=CPointLight::AmbientLight)
01078                         {
01079                                 // Select only obstacle Faces around the light. Other are not usefull
01080                                 CAABBox bbox;
01081                                 bbox.setCenter(plRT.PointLight.getPosition());
01082                                 float   hl= plRT.PointLight.getAttenuationEnd();
01083                                 bbox.setHalfSize(CVector(hl,hl,hl));
01084                                 obstacleGrid.select(bbox.getMin(), bbox.getMax());
01085 
01086                                 // For all faces, fill the cubeGrid.
01087                                 CQuadGrid<CTriangle*>::CIterator        itObstacle;
01088                                 itObstacle= obstacleGrid.begin();
01089                                 while( itObstacle!=obstacleGrid.end() )
01090                                 {
01091                                         CTriangle       &tri= *(*itObstacle);
01092                                         /* Don't Test BackFace culling Here (unlike in CZoneLighter !!).
01093                                            For objects:
01094                                                 AutoOccluding problem is avoided with _CurrentInstanceComputed scheme.
01095                                                 Also, With pointLights, there is no multiSampling (since no factor stored)
01096                                                 Hence we are sure that no Object samples will lies under floor, and that the center of the 
01097                                                 object is far away.
01098                                            For IGSurface lighting:
01099                                                 notice that we already add 20cm in height because of "stairs problem" so
01100                                                 floor/surface auto_shadowing is not a problem here...
01101                                         */
01102                                         // Insert the triangle in the CubeGrid
01103                                         plRT.FaceCubeGrid.insert( tri.Triangle, &tri);
01104 
01105                                         itObstacle++;
01106                                 }
01107                         }
01108 
01109                         // Compile the CubeGrid.
01110                         plRT.FaceCubeGrid.compile();
01111 
01112                         // And Reset RefCount.
01113                         plRT.RefCount= 0;
01114                 }
01115         }
01116         // else, just build empty grid
01117         else
01118         {
01119                 for(i=0; i<_StaticPointLights.size();i++)
01120                 {
01121                         // progress
01122                         progress ("Compute Influences of PointLights 1/2", i / (float)_StaticPointLights.size());
01123 
01124                         CPointLightRT   &plRT= _StaticPointLights[i];
01125                         // Create a dummy empty cubeGrid => no rayTrace :)
01126                         plRT.FaceCubeGrid.create(plRT.PointLight.getPosition(), 4);
01127 
01128                         // Compile the CubeGrid.
01129                         plRT.FaceCubeGrid.compile();
01130 
01131                         // And Reset RefCount.
01132                         plRT.RefCount= 0;
01133                 }
01134         }
01135 
01136 }

void NL3D::CInstanceLighter::computeSunContribution const CLightDesc lightDesc,
std::vector< CTriangle > &  obstacles,
CLandscape landscape
[private]
 

Definition at line 633 of file instance_lighter.cpp.

References _CurrentInstanceComputed, _IGSurfaceLightBuild, _InstanceInfos, NL3D::CQuadGrid< T >::begin(), beginCell(), NL3D::CQuadGrid< T >::changeBase(), NL3D::CQuadGrid< T >::create(), NL3D::CVisualCollisionManager::createEntity(), NL3D::CVisualCollisionManager::deleteEntity(), NL3D::CInstanceLighter::CLightDesc::DisableSunContribution, NL3D::CQuadGrid< T >::end(), NLMISC::CAABBox::extend(), getCurrentCell(), getCurrentCellInfo(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NL3D::CVisualCollisionEntity::getStaticLightSetup(), NL3D::CInstanceLighter::CLightDesc::GridCellSize, NL3D::CInstanceLighter::CLightDesc::GridSize, NL3D::CQuadGrid< T >::insert(), NL3D::CInstanceLighter::CTriangle::InstanceId, NL3D::CIGSurfaceLightBuild::CCellCorner::InSurface, NLMISC::CTriangle::intersect(), NLMISC::CMatrix::inverted(), isEndCell(), NL3D::CInstanceLighter::CLightDesc::LightDirection, NL3D::NEL3DCalcBase(), nextCell(), nlassert, NLMISC::CVector::normalize(), NL3D::CIGSurfaceLightBuild::CCellCorner::NumOverSamples, NL3D::CIGSurfaceLightBuild::CCellCorner::OverSamples, NL3D::CInstanceLighter::CLightDesc::OverSampling, NL3D::CInstanceLighter::CTriangle::Plane, progress(), progressCell(), NL3D::CQuadGrid< T >::select(), NLMISC::CAABBox::setCenter(), NL3D::CVisualCollisionManager::setLandscape(), NL3D::CInstanceLighter::CLightDesc::Shadow, sint, NL3D::CIGSurfaceLightBuild::CCellCorner::SunContribution, NL3D::CSurfaceLightGrid::CCellCorner::SunContribution, NL3D::CInstanceLighter::CTriangle::Triangle, uint, and uint8.

Referenced by light().

00634 {
00635         sint    i;
00636         // Use precoputed landscape SunContribution
00637         CVisualCollisionManager         *VCM= NULL;
00638         CVisualCollisionEntity          *VCE= NULL;
00639         if(landscape)
00640         {
00641                 // create a CVisualCollisionManager and a CVisualCollisionEntity
00642                 VCM= new CVisualCollisionManager;
00643                 VCM->setLandscape(landscape);
00644                 VCE= VCM->createEntity();
00645         }
00646         std::vector<CPointLightInfluence>       dummyPointLightFromLandscape;
00647         dummyPointLightFromLandscape.reserve(1024);
00648 
00649 
00650         // If DisableSunContribution, easy, 
00651         if(lightDesc.DisableSunContribution)
00652         {
00653                 // Light all instances.
00654                 //==========
00655                 for(i=0; i<(sint)_Instances.size(); i++)
00656                 {
00657                         // If staticLight not enabled, skip.
00658                         if( !_Instances[i].StaticLightEnabled )
00659                                 continue;
00660 
00661                         // fill SunContribution to 0
00662                         _Instances[i].SunContribution= 0;
00663                 }
00664 
00665                 // Light SurfaceGrid Cells.
00666                 //==========
00667                 if(_IGSurfaceLightBuild)
00668                 {
00669                         // Begin cell iteration
00670                         beginCell();
00671                         // For all surface cell corners
00672                         while( !isEndCell() )
00673                         {
00674                                 // get the current cell and cellInfo iterated.
00675                                 CIGSurfaceLightBuild::CCellCorner       &cellInfo= getCurrentCellInfo();
00676                                 CSurfaceLightGrid::CCellCorner          &cell= getCurrentCell();
00677 
00678                                 // if the cell corner lies in the polygon surface.
00679                                 if(cellInfo.InSurface)
00680                                 {
00681                                         // fill SunContribution to 0
00682                                         cell.SunContribution= 0;
00683                                         // copy it to cellInfo
00684                                         cellInfo.SunContribution= cell.SunContribution;
00685                                 }
00686 
00687                                 // next cell
00688                                 nextCell();
00689                         }
00690                 }
00691         }
00692         // If no Raytrace Shadow, easy, 
00693         else if(!lightDesc.Shadow)
00694         {
00695                 // Light all instances.
00696                 //==========
00697                 for(i=0; i<(sint)_Instances.size(); i++)
00698                 {
00699                         progress ("Compute SunContribution on Instances", i / float(_Instances.size()) );
00700 
00701                         // If staticLight not enabled, skip.
00702                         if( !_Instances[i].StaticLightEnabled )
00703                                 continue;
00704 
00705                         // by default, fill SunContribution to 255
00706                         _Instances[i].SunContribution= 255;
00707                         // Try to get landscape SunContribution (better)
00708                         if(landscape)
00709                         {
00710                                 CVector         pos= _InstanceInfos[i].CenterPos;
00711                                 uint8   landSunContribution;
00712                                 dummyPointLightFromLandscape.clear();
00713                                 // If find faces under me
00714                                 NLMISC::CRGBA   dummyAmbient;
00715                                 if(VCE->getStaticLightSetup(pos, dummyPointLightFromLandscape, landSunContribution, dummyAmbient) )
00716                                 {
00717                                         _Instances[i].SunContribution= landSunContribution;
00718                                 }
00719                         }
00720                 }
00721 
00722                 // Light SurfaceGrid Cells.
00723                 //==========
00724                 if(_IGSurfaceLightBuild)
00725                 {
00726                         // Begin cell iteration
00727                         beginCell();
00728                         // For all surface cell corners
00729                         while( !isEndCell() )
00730                         {
00731                                 progressCell("Compute SunContribution on Surfaces");
00732 
00733                                 // get the current cell and cellInfo iterated.
00734                                 CIGSurfaceLightBuild::CCellCorner       &cellInfo= getCurrentCellInfo();
00735                                 CSurfaceLightGrid::CCellCorner          &cell= getCurrentCell();
00736 
00737                                 // if the cell corner lies in the polygon surface.
00738                                 if(cellInfo.InSurface)
00739                                 {
00740                                         // Just init SunContribution to 255, since no shadowing.
00741                                         cell.SunContribution= 255;
00742                                         // copy it to cellInfo
00743                                         cellInfo.SunContribution= cell.SunContribution;
00744                                 }
00745 
00746                                 // next cell
00747                                 nextCell();
00748                         }
00749                 }
00750         }
00751         else
00752         {
00753                 // Compute rayBasis
00754                 CVector rayDir= lightDesc.LightDirection;
00755                 CMatrix rayBasis;
00756                 rayDir.normalize();
00757                 NEL3DCalcBase(rayDir, rayBasis);
00758                 CMatrix invRayBasis;
00759                 invRayBasis= rayBasis.inverted();
00760 
00761                 // Build QuadGrid of obstacles.
00762                 //=========
00763                 // setup quadGrid
00764                 CQuadGrid<const CTriangle*>             quadGrid;
00765                 quadGrid.changeBase (invRayBasis);
00766                 quadGrid.create(lightDesc.GridSize, lightDesc.GridCellSize);
00767                 // Insert all obstacles in quadGrid
00768                 for(i=0; i<(sint)obstacles.size(); i++)
00769                 {
00770                         CAABBox triBBox;
00771                         // Compute the bbox in rayBasis.
00772                         triBBox.setCenter(invRayBasis * obstacles[i].Triangle.V0);
00773                         triBBox.extend(invRayBasis * obstacles[i].Triangle.V1);
00774                         triBBox.extend(invRayBasis * obstacles[i].Triangle.V2);
00775                         // And set the coord in our world, because will be multiplied with invRayBasis in insert()
00776                         quadGrid.insert(rayBasis * triBBox.getMin(), rayBasis * triBBox.getMax(), &obstacles[i]);
00777                 }
00778 
00779                 // For all instances, light them.
00780                 //=========
00781                 for(i=0; i<(sint)_Instances.size(); i++)
00782                 {
00783                         progress ("Compute SunContribution on Instances", i / float(_Instances.size()) );
00784 
00785                         // If staticLight not enabled, skip.
00786                         if( !_Instances[i].StaticLightEnabled )
00787                                 continue;
00788 
00789                         // try to use landscape SunContribution.
00790                         bool    landUsed= false;
00791                         if(landscape)
00792                         {
00793                                 CVector         pos= _InstanceInfos[i].CenterPos;
00794                                 uint8   landSunContribution;
00795                                 dummyPointLightFromLandscape.clear();
00796                                 // If find faces under me
00797                                 NLMISC::CRGBA   dummyAmbient;
00798                                 if(VCE->getStaticLightSetup(pos, dummyPointLightFromLandscape, landSunContribution, dummyAmbient) )
00799                                 {
00800                                         _Instances[i].SunContribution= landSunContribution;
00801                                         landUsed= true;
00802                                 }
00803                         }
00804 
00805                         // If failed to use landscape SunContribution, rayTrace
00806                         if(!landUsed)
00807                         {
00808                                 // number of samples (1 if no overSampling)
00809                                 uint    nSamples= max(1U, lightDesc.OverSampling);
00810 
00811                                 // Default is full lighted.
00812                                 uint    sunAccum= 255*nSamples;
00813 
00814                                 // For all samples
00815                                 for(uint sample=0; sample<nSamples; sample++)
00816                                 {
00817                                         // pos to rayTrace against
00818                                         CVector         pos= _InstanceInfos[i].OverSamples[sample];
00819 
00820                                         // rayTrace from this pos.
00821                                         CVector         lightPos= pos-(rayDir*1000.f);
00822                                         // Select an element with the X axis as a 3d ray
00823                                         quadGrid.select (lightPos, lightPos);
00824                                         // For each triangle selected
00825                                         CQuadGrid<const CTriangle*>::CIterator  it=quadGrid.begin();
00826                                         while (it!=quadGrid.end())
00827                                         {
00828                                                 const CTriangle *tri= *it;
00829 
00830                                                 // If same instanceId, skip
00831                                                 if(tri->InstanceId != i)
00832                                                 {
00833                                                         CVector         hit;
00834                                                         // If triangle occlude the ray, no sun Contribution
00835                                                         if(tri->Triangle.intersect(lightPos, pos, hit, tri->Plane))
00836                                                         {
00837                                                                 // The sample is not touched by sun. sub his contribution
00838                                                                 sunAccum-= 255;
00839                                                                 // End
00840                                                                 break;
00841                                                         }
00842                                                 }
00843                                                 
00844                                                 it++;
00845                                         }
00846                                 }
00847 
00848                                 // Average samples
00849                                 _Instances[i].SunContribution= sunAccum / nSamples;
00850                         }
00851 
00852                 }
00853 
00854 
00855                 // Light SurfaceGrid Cells.
00856                 //==========
00857                 if(_IGSurfaceLightBuild)
00858                 {
00859                         // No instance currenlty computed, since we compute surface cells.
00860                         _CurrentInstanceComputed= -1;
00861 
00862                         // Begin cell iteration
00863                         beginCell();
00864                         // For all surface cell corners
00865                         while( !isEndCell() )
00866                         {
00867                                 progressCell("Compute SunContribution on Surfaces");
00868 
00869                                 // get the current cell and cellInfo iterated.
00870                                 CIGSurfaceLightBuild::CCellCorner       &cellInfo= getCurrentCellInfo();
00871                                 CSurfaceLightGrid::CCellCorner          &cell= getCurrentCell();
00872 
00873                                 // if the cell corner lies in the polygon surface.
00874                                 if(cellInfo.InSurface)
00875                                 {
00876                                         // number of samples (at least 1 if no overSampling)
00877                                         uint    nSamples= cellInfo.NumOverSamples;
00878                                         nlassert(nSamples>=1);
00879 
00880                                         // Default is full lighted.
00881                                         uint    sunAccum= 255*nSamples;
00882 
00883                                         // For all samples
00884                                         for(uint sample=0; sample<nSamples; sample++)
00885                                         {
00886                                                 // Get pos to rayTrace.
00887                                                 CVector pos= cellInfo.OverSamples[sample];
00888 
00889                                                 // rayTrace from the pos of this Cell sample.
00890                                                 CVector         lightPos= pos-(rayDir*1000.f);
00891                                                 // Select an element with the X axis as a 3d ray
00892                                                 quadGrid.select (lightPos, lightPos);
00893                                                 // For each triangle selected
00894                                                 CQuadGrid<const CTriangle*>::CIterator  it=quadGrid.begin();
00895                                                 while (it!=quadGrid.end())
00896                                                 {
00897                                                         const CTriangle *tri= *it;
00898 
00899                                                         CVector         hit;
00900                                                         // If triangle occlude the ray, no sun Contribution
00901                                                         if(tri->Triangle.intersect(lightPos, pos, hit, tri->Plane))
00902                                                         {
00903                                                                 // The cell sample is not touched by sun. sub his contribution
00904                                                                 sunAccum-= 255;
00905                                                                 // End
00906                                                                 break;
00907                                                         }
00908                                                         
00909                                                         it++;
00910                                                 }
00911                                         }
00912 
00913                                         // Average SunContribution
00914                                         cell.SunContribution= sunAccum / nSamples;
00915 
00916                                         // copy it to cellInfo
00917                                         cellInfo.SunContribution= cell.SunContribution;
00918                                 }
00919 
00920                                 // next cell
00921                                 nextCell();
00922                         }
00923                 }
00924         }
00925 
00926 
00927         // Clean VCM and VCE
00928         if(landscape)
00929         {
00930                 // delete CVisualCollisionManager and CVisualCollisionEntity
00931                 VCM->deleteEntity(VCE);
00932                 delete VCM;
00933         }
00934 
00935 }

void NL3D::CInstanceLighter::dilateLightingOnSurfaceCells  )  [private]
 

Definition at line 1801 of file instance_lighter.cpp.

References beginCell(), NL3D::CIGSurfaceLightBuild::CCellCorner::CenterPos, NL3D::CIGSurfaceLightBuild::CCellCorner::Dilated, getCurrentCell(), getCurrentCellInfo(), getCurrentNeighborCell(), getCurrentNeighborCellInfo(), NL3D::CIGSurfaceLightBuild::CCellCorner::InSurface, isCurrentNeighborCellInSurface(), isEndCell(), NL3D::CSurfaceLightGrid::CCellCorner::Light, NL3D::CSurfaceLightGrid::CCellCorner::LocalAmbientId, nextCell(), progressCell(), sint, NL3D::CIGSurfaceLightBuild::CCellCorner::SunContribution, NL3D::CSurfaceLightGrid::CCellCorner::SunContribution, uint, and NLMISC::CVector::z.

Referenced by light().

01802 {
01803         // Begin cell iteration
01804         beginCell();
01805         // For all surface cell corners
01806         while( !isEndCell() )
01807         {
01808                 progressCell("Dilate Surfaces grids");
01809 
01810                 // get the current cell and cellInfo iterated.
01811                 CIGSurfaceLightBuild::CCellCorner       &cellInfo= getCurrentCellInfo();
01812                 CSurfaceLightGrid::CCellCorner          &cell= getCurrentCell();
01813 
01814                 // if the cell is not in the polygon surface, try to get from his neighbors.
01815                 if(!cellInfo.InSurface)
01816                 {
01817                         // Add Weighted influence of SunContribution, and get one of the PointLightContribution (random).
01818                         uint    wgtSunContribution= 0;
01819                         uint    wgtSunCount= 0;
01820                         // search if one of 8 neighbors is InSurface.
01821                         for(sint ynb= -1; ynb<= 1; ynb++)
01822                         {
01823                                 for(sint xnb= -1; xnb<= 1; xnb++)
01824                                 {
01825                                         // center => skip.
01826                                         if( xnb==0 && ynb==0 )
01827                                                 continue;
01828                                         // If the neighbor point is not out of the grid, and if in Surface.
01829                                         if( isCurrentNeighborCellInSurface(xnb, ynb) )
01830                                         {
01831                                                 // get the neighbor cell
01832                                                 CIGSurfaceLightBuild::CCellCorner       &nbCellInfo= getCurrentNeighborCellInfo(xnb, ynb);
01833                                                 CSurfaceLightGrid::CCellCorner          &nbCell= getCurrentNeighborCell(xnb, ynb);
01834                                                 // Add SunContribution.
01835                                                 wgtSunContribution+= nbCell.SunContribution;
01836                                                 wgtSunCount++;
01837                                                 // Just Copy PointLight info.
01838                                                 for(uint lightId= 0; lightId<CSurfaceLightGrid::NumLightPerCorner; lightId++)
01839                                                         cell.Light[lightId]= nbCell.Light[lightId];
01840                                                 // Just Copy AmbientLight info.
01841                                                 cell.LocalAmbientId= nbCell.LocalAmbientId;
01842 
01843 
01844                                                 // For debug mesh only, copy z from nb cellInfo
01845                                                 cellInfo.CenterPos.z= nbCellInfo.CenterPos.z;
01846                                         }
01847                                 }
01848                         }
01849                         // average SunContribution.
01850                         if(wgtSunCount>0)
01851                         {
01852                                 cell.SunContribution= wgtSunContribution / wgtSunCount;
01853 
01854                                 // For debug mesh only, copy SunContribution into cellInfo
01855                                 cellInfo.SunContribution= cell.SunContribution;
01856                                 cellInfo.Dilated= true;
01857                         }
01858                 }
01859 
01860                 // next cell
01861                 nextCell();
01862         }
01863 }

void NL3D::CInstanceLighter::excludeAllPatchFromRefineAll CLandscape landscape,
std::vector< uint > &  listZone,
bool  exclude
[static, private]
 

Definition at line 278 of file instance_lighter.cpp.

References NL3D::CLandscape::excludePatchFromRefineAll(), NL3D::CZone::getNumPatchs(), NL3D::CLandscape::getZone(), and uint.

Referenced by addTriangles().

00279 {
00280         // For each zone
00281         for (uint zone=0; zone<listZone.size(); zone++)
00282         {
00283                 // Get num patches
00284                 uint patchCount=landscape.getZone(listZone[zone])->getNumPatchs();
00285 
00286                 // For each patches
00287                 for (uint patch=0; patch<patchCount; patch++)
00288                 {
00289                         // Exclude all the patches from refine all
00290                         landscape.excludePatchFromRefineAll (listZone[zone], patch, exclude);
00291                 }
00292         }
00293 }

CSurfaceLightGrid::CCellCorner & NL3D::CInstanceLighter::getCurrentCell  )  [private]
 

Definition at line 1705 of file instance_lighter.cpp.

References _ItCellId, _ItRetriever, _ItSurfId, isEndCell(), and nlassert.

Referenced by computeSunContribution(), dilateLightingOnSurfaceCells(), and processIGPointLightRT().

01706 {
01707         nlassert(!isEndCell());
01708 
01709         // return ref on Cell.
01710         return  _ItRetriever->second.Grids[_ItSurfId].Cells[_ItCellId];
01711 }

CIGSurfaceLightBuild::CCellCorner & NL3D::CInstanceLighter::getCurrentCellInfo  )  [private]
 

Definition at line 1714 of file instance_lighter.cpp.

References _ItCellId, _ItRetrieverInfo, _ItSurfId, isEndCell(), and nlassert.

Referenced by computeSunContribution(), dilateLightingOnSurfaceCells(), and processIGPointLightRT().

01715 {
01716         nlassert(!isEndCell());
01717 
01718         // return ref on CellInfo.
01719         return _ItRetrieverInfo->second.Grids[_ItSurfId].Cells[_ItCellId];
01720 }

uint NL3D::CInstanceLighter::getCurrentCellNumber  )  const [inline, private]
 

Definition at line 284 of file instance_lighter.h.

References _ItCurrentCellNumber, and uint.

Referenced by progressCell().

00284 {return _ItCurrentCellNumber;}

CSurfaceLightGrid::CCellCorner & NL3D::CInstanceLighter::getCurrentNeighborCell sint  xnb,
sint  ynb
[private]
 

Definition at line 1757 of file instance_lighter.cpp.

References _ItCellId, _ItRetriever, _ItSurfId, NL3D::CSurfaceLightGrid::Cells, isCurrentNeighborCellInSurface(), nlassert, sint, uint, and NL3D::CSurfaceLightGrid::Width.

Referenced by dilateLightingOnSurfaceCells().

01758 {
01759         nlassert(isCurrentNeighborCellInSurface(xnb, ynb));
01760 
01761         // get a ref on the current grid.
01762         CSurfaceLightGrid       &surfGrid= _ItRetriever->second.Grids[_ItSurfId];
01763         // copute coordinate of the current cellCorner.
01764         sint    xCell, yCell;
01765         xCell= _ItCellId%surfGrid.Width;
01766         yCell= _ItCellId/surfGrid.Width;
01767         // compute coordinate of the neighbor cell corner
01768         xCell+= xnb;
01769         yCell+= ynb;
01770         // compute the neighbor id
01771         uint    nbId= yCell*surfGrid.Width + xCell;
01772 
01773         // then return a ref on it
01774         return surfGrid.Cells[nbId];
01775 }

CIGSurfaceLightBuild::CCellCorner & NL3D::CInstanceLighter::getCurrentNeighborCellInfo sint  xnb,
sint  ynb
[private]
 

Definition at line 1779 of file instance_lighter.cpp.

References _ItCellId, _ItRetrieverInfo, _ItSurfId, NL3D::CIGSurfaceLightBuild::CSurface::Cells, isCurrentNeighborCellInSurface(), nlassert, sint, uint, and NL3D::CIGSurfaceLightBuild::CSurface::Width.

Referenced by dilateLightingOnSurfaceCells().

01780 {
01781         nlassert(isCurrentNeighborCellInSurface(xnb, ynb));
01782 
01783         // get a ref on the current grid.
01784         CIGSurfaceLightBuild::CSurface  &surfGrid= _ItRetrieverInfo->second.Grids[_ItSurfId];
01785         // copute coordinate of the current cellCorner.
01786         sint    xCell, yCell;
01787         xCell= _ItCellId%surfGrid.Width;
01788         yCell= _ItCellId/surfGrid.Width;
01789         // compute coordinate of the neighbor cell corner
01790         xCell+= xnb;
01791         yCell+= ynb;
01792         // compute the neighbor id
01793         uint    nbId= yCell*surfGrid.Width + xCell;
01794 
01795         // then return a ref on it
01796         return surfGrid.Cells[nbId];
01797 }

uint NL3D::CInstanceLighter::getTotalCellNumber  )  const [inline, private]
 

Definition at line 285 of file instance_lighter.h.

References _TotalCellNumber, and uint.

Referenced by progressCell().

00285 {return _TotalCellNumber;}

void NL3D::CInstanceLighter::init  ) 
 

Definition at line 72 of file instance_lighter.cpp.

Referenced by lightIgSimple().

00073 {
00074 }

bool NL3D::CInstanceLighter::isCurrentNeighborCellInSurface sint  xnb,
sint  ynb
[private]
 

Definition at line 1724 of file instance_lighter.cpp.

References _ItCellId, _ItRetriever, _ItRetrieverInfo, _ItSurfId, NL3D::CSurfaceLightGrid::Height, isEndCell(), nlassert, sint, uint, and NL3D::CSurfaceLightGrid::Width.

Referenced by dilateLightingOnSurfaceCells(), getCurrentNeighborCell(), and getCurrentNeighborCellInfo().

01725 {
01726         nlassert(!isEndCell());
01727 
01728         // get a ref on the current grid.
01729         CSurfaceLightGrid       &surfGrid= _ItRetriever->second.Grids[_ItSurfId];
01730         // copute coordinate of the current cellCorner.
01731         sint    xCell, yCell;
01732         xCell= _ItCellId%surfGrid.Width;
01733         yCell= _ItCellId/surfGrid.Width;
01734         // compute coordinate of the neighbor cell corner
01735         xCell+= xnb;
01736         yCell+= ynb;
01737 
01738         // check if in the surfaceGrid
01739         if(xCell<0 || xCell>=(sint)surfGrid.Width)
01740                 return false;
01741         if(yCell<0 || yCell>=(sint)surfGrid.Height)
01742                 return false;
01743 
01744         // compute the neighbor id
01745         uint    nbId= yCell*surfGrid.Width + xCell;
01746 
01747         // Now check in the cellInfo if this cell is InSurface.
01748         if( !_ItRetrieverInfo->second.Grids[_ItSurfId].Cells[nbId].InSurface )
01749                 return false;
01750 
01751         // Ok, the neighbor cell is valid.
01752 
01753         return true;
01754 }

bool NL3D::CInstanceLighter::isEndCell  )  [private]
 

Definition at line 1699 of file instance_lighter.cpp.

References _IsEndCell.

Referenced by computeSunContribution(), dilateLightingOnSurfaceCells(), getCurrentCell(), getCurrentCellInfo(), isCurrentNeighborCellInSurface(), nextCell(), and processIGPointLightRT().

01700 {
01701         return _IsEndCell;
01702 }

void NL3D::CInstanceLighter::light const CInstanceGroup igIn,
CInstanceGroup igOut,
const CLightDesc lightDesc,
std::vector< CTriangle > &  obstacles,
CLandscape landscape = NULL,
CIGSurfaceLightBuild igSurfaceLightBuild = NULL
 

Light an InstanceGroup igOut has different PointLights than igIn. eg: if a pointLight do not light anything, then it is not present in igOut. NB: shapes are used to retrieve usefull info on them (center of AABBox ...) . They are taken from lightDesc.UserShapeMap, or loaded from lightDesc.ShapePath if not found.

Parameters:
landscape if !NULL use this Landscape SunContribution, looking landscape faces under each instance, for faster computing, and to get influence of Sky. NB: this landscape does not have to be tesselated, but all Zones that lies under igIn should be loaded in.
igSurfaceLightBuild if !NULL, light() will compute igOut.IGSurfaceLight, else it is just cleared.

Definition at line 305 of file instance_lighter.cpp.

References _IGRetrieverGridMap, _IGSurfaceLightBuild, _InstanceInfos, _IsEndCell, _TotalCellNumber, NL3D::CInstanceGroup::build(), NL3D::CIGSurfaceLightBuild::CSurface::Cells, NL3D::CSurfaceLightGrid::Cells, NL3D::CIGSurfaceLightBuild::CellSize, compilePointLightRT(), computeSunContribution(), dilateLightingOnSurfaceCells(), NLMISC::CObjectVector< CCellCorner >::fill(), NLMISC::CAABBox::getCenter(), NLMISC::CAABBox::getHalfSize(), NL3D::CShapeStream::getShapePointer(), NL3D::CInstanceLighter::CLightDesc::GridCellSize, NL3D::CIGSurfaceLight::CRetrieverLightGrid::Grids, NL3D::CInstanceLighter::CLightDesc::GridSize, NL3D::CIGSurfaceLightBuild::CSurface::Height, NL3D::CSurfaceLightGrid::Height, NL3D::CMeshBase::isLightable(), NL3D::CSurfaceLightGrid::CCellCorner::Light, NL3D::CSurfaceLightGrid::CCellCorner::LocalAmbientId, NLMISC::CPlane::make(), nlassert, nlwarning, NLMISC::CIFile::open(), NL3D::CIGSurfaceLightBuild::CSurface::Origin, NL3D::CSurfaceLightGrid::Origin, NL3D::CInstanceLighter::CLightDesc::OverSampling, NL3D::CInstanceLighter::CTriangle::Plane, processIGPointLightRT(), NLMISC::CObjectVector< CCellCorner >::resize(), NLMISC::CObjectVector< CSurfaceLightGrid >::resize(), NL3D::CInstanceGroup::retrieve(), NL3D::CIGSurfaceLightBuild::RetrieverGridMap, NLMISC::CMatrix::scale(), NL3D::CShapeStream::serial(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), NLMISC::CMatrix::setPos(), NLMISC::CMatrix::setRot(), NL3D::CInstanceLighter::CLightDesc::Shadow, sint, NLMISC::CObjectVector< CCellCorner >::size(), NL3D::CSurfaceLightGrid::CCellCorner::SunContribution, NL3D::CInstanceLighter::CTriangle::Triangle, uint, NL3D::CInstanceLighter::CLightDesc::UserShapeMap, NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, NL3D::CIGSurfaceLightBuild::CSurface::Width, NL3D::CSurfaceLightGrid::Width, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z.

Referenced by lightIgSimple().

00307 {
00308         sint                                    i;
00309         CVector                                 outGlobalPos;
00310         std::vector<CCluster>   outClusters;
00311         std::vector<CPortal>    outPortals;
00312         std::vector<CPointLightNamed>   pointLightList;
00313 
00314         nlassert(lightDesc.OverSampling==0 || lightDesc.OverSampling==2 || lightDesc.OverSampling==4
00315                 || lightDesc.OverSampling==8 || lightDesc.OverSampling==16);
00316 
00317         // Setup.
00318         //========
00319 
00320         // Prepare IGSurfaceLight lighting
00321         //-----------
00322         // Bkup SurfaceLightBuild to know if must light the surfaces, in differents part of the process.
00323         _IGSurfaceLightBuild= igSurfaceLightBuild;
00324         // Prepare _IGRetrieverGridMap.
00325         _IGRetrieverGridMap.clear();
00326         if(_IGSurfaceLightBuild)
00327         {
00328                 _TotalCellNumber= 0;
00329                 CIGSurfaceLightBuild::ItRetrieverGridMap        itSrc;
00330                 itSrc= _IGSurfaceLightBuild->RetrieverGridMap.begin();
00331                 // For all retrievers Infos in _IGSurfaceLightBuild
00332                 while(itSrc!=_IGSurfaceLightBuild->RetrieverGridMap.end())
00333                 {
00334                         uint    numSurfaces= itSrc->second.Grids.size();
00335                         // If !empty retriever.
00336                         if(numSurfaces>0)
00337                         {
00338                                 // Add it to the map, 
00339                                 CIGSurfaceLight::CRetrieverLightGrid            &rlgDst= _IGRetrieverGridMap[itSrc->first];
00340                                 // resize Array of surfaces.
00341                                 rlgDst.Grids.resize(numSurfaces);
00342                                 // For all surfaces, init them in rlgDst.
00343                                 for(uint i=0; i<numSurfaces; i++)
00344                                 {
00345                                         CIGSurfaceLightBuild::CSurface          &surfSrc= itSrc->second.Grids[i];
00346                                         CSurfaceLightGrid                                       &surfDst= rlgDst.Grids[i];
00347                                         // Init Cells with a default CellCorner
00348                                         CSurfaceLightGrid::CCellCorner          defaultCellCorner;
00349                                         defaultCellCorner.SunContribution= 0;
00350                                         defaultCellCorner.Light[0]= 0xFF;
00351                                         defaultCellCorner.LocalAmbientId= 0xFF;
00352                                         
00353                                         // Init the grid.
00354                                         surfDst.Origin= surfSrc.Origin;
00355                                         surfDst.Width= surfSrc.Width;
00356                                         surfDst.Height= surfSrc.Height;
00357                                         surfDst.Cells.resize(surfSrc.Cells.size());
00358                                         surfDst.Cells.fill(defaultCellCorner);
00359                                         // The grid must be valid an not empty
00360                                         nlassert( surfDst.Cells.size() == surfDst.Width*surfDst.Height );
00361                                         nlassert( surfDst.Width>= 2 );
00362                                         nlassert( surfDst.Height>= 2 );
00363 
00364                                         _TotalCellNumber+= surfDst.Cells.size();
00365                                 }
00366                         }
00367 
00368                         // Next localRetriever info.
00369                         itSrc++;
00370                 }
00371         }
00372         // Reset cell iteration.
00373         _IsEndCell= true;
00374 
00375 
00376         // Retrieve info from igIn.
00377         //-----------
00378         igIn.retrieve (outGlobalPos, _Instances, outClusters, outPortals, pointLightList);
00379 
00380 
00381         // set All Instances StaticLightEnabled= true, and Build _InstanceInfos.
00382         //-----------
00383         // Map of shape
00384         std::map<string, IShape*> shapeMap;
00385         _InstanceInfos.resize(_Instances.size());
00386         for(i=0; i<(sint)_Instances.size();i++)
00387         {
00388                 // Avoid StaticLight precomputing??
00389                 if(_Instances[i].AvoidStaticLightPreCompute)
00390                 {
00391                         _Instances[i].StaticLightEnabled= false;
00392                         // Next instance.
00393                         continue;
00394                 }
00395 
00396                 // Else let's do it.
00397                 _Instances[i].StaticLightEnabled= true;
00398 
00399 
00400                 // Get the shape centerPos;
00401                 //------------
00402                 CVector shapeCenterPos;
00403                 CVector overSamples[MaxOverSamples];
00404 
00405                 // Get the instance shape name
00406                 string name= _Instances[i].Name;
00407                 bool    shapeFound= true;
00408 
00409                 // Try to find the shape in the UseShapeMap.
00410                 std::map<string, IShape*>::const_iterator iteMap= lightDesc.UserShapeMap.find (name);
00411 
00412                 // If not found in userShape map, try to load it from the temp loaded ShapeBank.
00413                 if( iteMap == lightDesc.UserShapeMap.end() )
00414                 {
00415                         // Add a .shape at the end ?
00416                         if (name.find('.') == std::string::npos)
00417                                 name += ".shape";
00418 
00419                         // Get the instance shape name
00420                         string nameLookup = CPath::lookup (name, false, false);
00421                         if (!nameLookup.empty())
00422                                 name = nameLookup;
00423 
00424                         // Find the shape in the bank
00425                         iteMap= shapeMap.find (name);
00426                         if (iteMap==shapeMap.end())
00427                         {
00428                                 // Input file
00429                                 CIFile inputFile;
00430 
00431                                 if (!name.empty() && inputFile.open (name))
00432                                 {
00433                                         // Load it
00434                                         CShapeStream stream;
00435                                         stream.serial (inputFile);
00436 
00437                                         // Get the pointer
00438                                         iteMap=shapeMap.insert (std::map<string, IShape*>::value_type (name, stream.getShapePointer ())).first;
00439                                 }
00440                                 else
00441                                 {
00442                                         // Error
00443                                         nlwarning ("WARNING can't load shape %s\n", name.c_str());
00444                                         shapeFound= false;
00445                                 }
00446                         }
00447                 }
00448 
00449 
00450                 // Last chance to skip it: fully LightMapped ??
00451                 //-----------
00452                 if(shapeFound)
00453                 {
00454                         CMeshBase       *mesh= dynamic_cast<CMeshBase*>(iteMap->second);
00455                         if(mesh)
00456                         {
00457                                 // If this mesh is not lightable (fully lightMapped)
00458                                 if(!mesh->isLightable())
00459                                 {
00460                                         // Force Avoid StaticLight precomputing
00461                                         _Instances[i].AvoidStaticLightPreCompute= true;
00462                                         // Disable static lighting.
00463                                         _Instances[i].StaticLightEnabled= false;
00464                                         // Next instance.
00465                                         continue;
00466                                 }
00467                         }
00468                 }
00469 
00470 
00471                 // Compute pos and OverSamples
00472                 //-----------
00473                 {
00474                         // Compute bbox, or default bbox
00475                         CAABBox         bbox;
00476                         if(!shapeFound)
00477                         {
00478                                 bbox.setCenter(CVector::Null);
00479                                 bbox.setHalfSize(CVector::Null);
00480                         }
00481                         else
00482                         {
00483                                 iteMap->second->getAABBox(bbox);
00484                         }
00485                         // get pos
00486                         shapeCenterPos= bbox.getCenter();
00487 
00488 
00489                         // Compute overSamples
00490                         float   qx= bbox.getHalfSize().x/2;
00491                         float   qy= bbox.getHalfSize().y/2;
00492                         float   qz= bbox.getHalfSize().z/2;
00493                         // No OverSampling => just copy.
00494                         if(lightDesc.OverSampling==0)
00495                                 overSamples[0]= shapeCenterPos;
00496                         else if(lightDesc.OverSampling==2)
00497                         {
00498                                 // Prefer Z Axis.
00499                                 overSamples[0]= shapeCenterPos + CVector(0, 0, qz);
00500                                 overSamples[1]= shapeCenterPos - CVector(0, 0, qz);
00501                         }
00502                         else if(lightDesc.OverSampling==4)
00503                         {
00504                                 // Apply an overSampling such that we see 4 points if we look on each side of the bbox.
00505                                 overSamples[0]= shapeCenterPos + CVector(-qx, -qy, -qz);
00506                                 overSamples[1]= shapeCenterPos + CVector(+qx, -qy, +qz);
00507                                 overSamples[2]= shapeCenterPos + CVector(-qx, +qy, +qz);
00508                                 overSamples[3]= shapeCenterPos + CVector(+qx, +qy, -qz);
00509                         }
00510                         else if(lightDesc.OverSampling==8 || lightDesc.OverSampling==16)
00511                         {
00512                                 // 8x is the best overSampling shceme for bbox
00513                                 overSamples[0]= shapeCenterPos + CVector(-qx, -qy, -qz);
00514                                 overSamples[1]= shapeCenterPos + CVector(+qx, -qy, -qz);
00515                                 overSamples[2]= shapeCenterPos + CVector(-qx, +qy, -qz);
00516                                 overSamples[3]= shapeCenterPos + CVector(+qx, +qy, -qz);
00517                                 overSamples[4]= shapeCenterPos + CVector(-qx, -qy, +qz);
00518                                 overSamples[5]= shapeCenterPos + CVector(+qx, -qy, +qz);
00519                                 overSamples[6]= shapeCenterPos + CVector(-qx, +qy, +qz);
00520                                 overSamples[7]= shapeCenterPos + CVector(+qx, +qy, +qz);
00521 
00522                                 // 16x => use this setup, and decal from 1/8
00523                                 if(lightDesc.OverSampling==16)
00524                                 {
00525                                         CVector         decal(qx/2, qy/2, qz/2);
00526                                         for(uint sample=0; sample<8; sample++)
00527                                         {
00528                                                 // Copy and decal
00529                                                 overSamples[sample+8]= overSamples[sample] + decal;
00530                                                 // neg decal me
00531                                                 overSamples[sample]-= decal;
00532                                         }
00533                                 }
00534                         }
00535                 }
00536 
00537 
00538                 // Compute pos of the instance
00539                 //------------
00540                 CMatrix         matInst;
00541                 matInst.setPos(_Instances[i].Pos);
00542                 matInst.setRot(_Instances[i].Rot);
00543                 matInst.scale(_Instances[i].Scale);
00544                 _InstanceInfos[i].CenterPos= matInst * shapeCenterPos;
00545                 // Apply matInst to samples.
00546                 uint    nSamples= max(1U, lightDesc.OverSampling);
00547                 for(uint sample=0; sample<nSamples; sample++)
00548                 {
00549                         _InstanceInfos[i].OverSamples[sample]= matInst * overSamples[sample];
00550                 }
00551         }
00552 
00553         // Clean Up shapes.
00554         //-----------
00555         std::map<string, IShape*>::iterator iteMap;
00556         iteMap= shapeMap.begin();
00557         while(iteMap!= shapeMap.end())
00558         {
00559                 // delte shape
00560                 delete  iteMap->second;
00561                 // delete entry in map
00562                 shapeMap.erase(iteMap);
00563                 // next
00564                 iteMap= shapeMap.begin();
00565         }
00566 
00567         // Build all obstacles plane.
00568         //-----------
00569         for(i=0; i<(sint)obstacles.size();i++)
00570         {
00571                 CInstanceLighter::CTriangle& triangle=obstacles[i];
00572                 // Calc the plane
00573                 triangle.Plane.make (triangle.Triangle.V0, triangle.Triangle.V1, triangle.Triangle.V2);
00574         }
00575 
00576 
00577         // Lighting
00578         //========
00579         // Light With Sun: build the grid, and do it on all _Instances, using _InstanceInfos
00580         // Compute also Lighting on surface.
00581         computeSunContribution(lightDesc, obstacles, landscape);
00582 
00583         // Light With PointLights
00584         // build the cubeGrids
00585         compilePointLightRT(lightDesc.GridSize, lightDesc.GridCellSize, obstacles, lightDesc.Shadow);
00586         // kill pointLightList, because will use mine.
00587         pointLightList.clear();
00588         // Light for all _Instances, using _InstanceInfos
00589         // Compute also Lighting on surface.
00590         processIGPointLightRT(pointLightList);
00591 
00592         // If _IGSurfaceLightBuild, then dilate lighting
00593         if(_IGSurfaceLightBuild)
00594         {
00595                 dilateLightingOnSurfaceCells();
00596         }
00597 
00598 
00599         // Build result.
00600         //========
00601         if(_IGSurfaceLightBuild)
00602         {
00603                 // build with IGSurfaceLight lighting
00604                 igOut.build(outGlobalPos, _Instances, outClusters, outPortals, pointLightList, 
00605                         &_IGRetrieverGridMap, _IGSurfaceLightBuild->CellSize);
00606         }
00607         else
00608         {
00609                 // build without IGSurfaceLight lighting
00610                 igOut.build(outGlobalPos, _Instances, outClusters, outPortals, pointLightList);
00611         }
00612 
00613 }

void NL3D::CInstanceLighter::lightIgSimple CInstanceLighter instLighter,
const CInstanceGroup igIn,
CInstanceGroup igOut,
const CLightDesc lightDesc,
const char *  igName
[static]
 

Tool method which take a single IG, and do all the god job to light this one, with no other dependencies NB: it uses instLighter passed, init() ing it. It use lightDesc.UserShapeMap or it load Shape in directory lightDesc.ShapePath

Definition at line 1502 of file instance_lighter.cpp.

References addStaticPointLight(), NL3D::CInstanceGroup::getInstance(), NL3D::CInstanceGroup::getInstancePos(), NL3D::CInstanceGroup::getInstanceRot(), NL3D::CInstanceGroup::getInstanceScale(), NL3D::CInstanceGroup::getNumInstance(), NL3D::CInstanceGroup::getPointLightList(), NL3D::CInstanceGroup::getShapeName(), NL3D::CShapeStream::getShapePointer(), init(), light(), nlwarning, NLMISC::CIFile::open(), progress(), NLMISC::CMatrix::scale(), NL3D::CShapeStream::serial(), NLMISC::CMatrix::setPos(), NLMISC::CMatrix::setRot(), NL3D::CInstanceLighter::CLightDesc::Shadow, sint, and NL3D::CInstanceLighter::CLightDesc::UserShapeMap.

01503 {
01504         sint                            i;
01505 
01506 
01507         // Setup.
01508         //=======
01509         // Init
01510         instLighter.init();
01511 
01512         // Add obstacles.
01513         std::vector<CInstanceLighter::CTriangle>        obstacles;
01514         // only if Shadowing On.
01515         if(lightDesc.Shadow)
01516         {
01517                 // Map of shape to load
01518                 std::map<string, IShape*> shapeMap;
01519 
01520                 // For all instances of igIn.
01521                 for(i=0; i<(sint)igIn.getNumInstance();i++)
01522                 {
01523                         // progress
01524                         instLighter.progress("Loading Shapes obstacles", float(i)/igIn.getNumInstance());
01525 
01526                         // Skip it??
01527                         if(igIn.getInstance(i).DontCastShadow)
01528                                 continue;
01529 
01530                         // Get the instance shape name
01531                         string name= igIn.getShapeName(i);
01532                         bool    shapeFound= true;
01533 
01534                         // Try to find the shape in the UseShapeMap.
01535                         std::map<string, IShape*>::const_iterator iteMap= lightDesc.UserShapeMap.find (name);
01536 
01537                         // If not found in userShape map, try to load it from the temp loaded ShapeBank.
01538                         if( iteMap == lightDesc.UserShapeMap.end() )
01539                         {
01540                                 // Add a .shape at the end ?
01541                                 if (name.find('.') == std::string::npos)
01542                                         name += ".shape";
01543 
01544                                 // Get the instance shape name
01545                                 string nameLookup = CPath::lookup (name, false, false);
01546                                 if (!nameLookup.empty())
01547                                         name = nameLookup;
01548 
01549                                 // Find the shape in the bank
01550                                 iteMap= shapeMap.find (name);
01551                                 if (iteMap==shapeMap.end())
01552                                 {
01553                                         // Input file
01554                                         CIFile inputFile;
01555 
01556                                         if (!name.empty() && inputFile.open (name))
01557                                         {
01558                                                 // Load it
01559                                                 CShapeStream stream;
01560                                                 stream.serial (inputFile);
01561 
01562                                                 // Get the pointer
01563                                                 iteMap=shapeMap.insert (std::map<string, IShape*>::value_type (name, stream.getShapePointer ())).first;
01564                                         }
01565                                         else
01566                                         {
01567                                                 // Error
01568                                                 nlwarning ("WARNING can't load shape %s\n", name.c_str());
01569                                                 shapeFound= false;
01570                                         }
01571                                 }
01572                         }
01573                         
01574                         if(shapeFound)
01575                         {
01576                                 CMatrix         matInst;
01577                                 matInst.setPos(igIn.getInstancePos(i));
01578                                 matInst.setRot(igIn.getInstanceRot(i));
01579                                 matInst.scale(igIn.getInstanceScale(i));
01580                                 // Add triangles of this shape
01581                                 CInstanceLighter::addTriangles(*iteMap->second, matInst, obstacles, i);
01582                         }
01583 
01584                 }
01585 
01586                 // Clean Up shapes.
01587                 //-----------
01588                 std::map<string, IShape*>::iterator iteMap;
01589                 iteMap= shapeMap.begin();
01590                 while(iteMap!= shapeMap.end())
01591                 {
01592                         // delte shape
01593                         delete  iteMap->second;
01594                         // delete entry in map
01595                         shapeMap.erase(iteMap);
01596                         // next
01597                         iteMap= shapeMap.begin();
01598                 }
01599         }
01600 
01601         // Add pointLights of the IG.
01602         for(i=0; i<(sint)igIn.getPointLightList().size();i++)
01603         {
01604                 instLighter.addStaticPointLight( igIn.getPointLightList()[i], igName );
01605         }
01606 
01607 
01608         // Run.
01609         //=======
01610         instLighter.light(igIn, igOut, lightDesc, obstacles);
01611 
01612 }

void NL3D::CInstanceLighter::nextCell  )  [private]
 

Definition at line 1663 of file instance_lighter.cpp.

References _IGRetrieverGridMap, _IGSurfaceLightBuild, _IsEndCell, _ItCellId, _ItCurrentCellNumber, _ItRetriever, _ItRetrieverInfo, _ItSurfId, isEndCell(), nlassert, and NL3D::CIGSurfaceLightBuild::RetrieverGridMap.

Referenced by computeSunContribution(), dilateLightingOnSurfaceCells(), and processIGPointLightRT().

01664 {
01665         nlassert(!isEndCell());
01666 
01667         // Next Cell.
01668         _ItCellId++;
01669         _ItCurrentCellNumber++;
01670 
01671         // If end of Cells, next surface.
01672         if(_ItCellId >= _ItRetriever->second.Grids[_ItSurfId].Cells.size() )
01673         {
01674                 _ItCellId= 0;
01675                 _ItSurfId ++;
01676         }
01677 
01678         // If end of surface, next retriever.
01679         if(_ItSurfId >= _ItRetriever->second.Grids.size() )
01680         {
01681                 _ItSurfId= 0;
01682                 _ItRetriever++;
01683                 if(_ItRetriever != _IGRetrieverGridMap.end())
01684                 {
01685                         // Get info.
01686                         _ItRetrieverInfo= _IGSurfaceLightBuild->RetrieverGridMap.find(_ItRetriever->first);
01687                         nlassert(_ItRetrieverInfo != _IGSurfaceLightBuild->RetrieverGridMap.end() );
01688                 }
01689         }
01690 
01691         // If end of retreiver, End.
01692         if(_ItRetriever == _IGRetrieverGridMap.end())
01693         {
01694                 _IsEndCell= true;
01695         }
01696 }

void NL3D::CInstanceLighter::processIGPointLightRT std::vector< CPointLightNamed > &  listPointLight  )  [private]
 

Process the IG, ie process _InstanceInfos. Also process SurfaceLightGrid MultiCPU: not done for now. Be aware of CPointLightRT::RefCount!!!!

Definition at line 1161 of file instance_lighter.cpp.

References _CurrentInstanceComputed, _IGSurfaceLightBuild, _InstanceInfos, _StaticPointLightQuadGrid, _StaticPointLights, NL3D::CQuadGrid< CPointLightRT * >::begin(), beginCell(), NL3D::CInstanceLighter::CPointLightRT::BSphere, NLMISC::CBSphere::Center, NL3D::CIGSurfaceLightBuild::CCellCorner::CenterPos, NL3D::CInstanceLighter::CInstanceInfo::CenterPos, NL3D::CInstanceLighter::CPointLightRT::DstId, NL3D::CQuadGrid< CPointLightRT * >::end(), getCurrentCell(), getCurrentCellInfo(), NL3D::CPointLight::getType(), NL3D::CIGSurfaceLightBuild::CCellCorner::InSurface, isEndCell(), NL3D::CSurfaceLightGrid::CCellCorner::Light, NL3D::CInstanceGroup::CInstance::Light, NL3D::CInstanceLighter::CInstanceInfo::Light, NL3D::CIGSurfaceLightBuild::CCellCorner::LightInfo, NL3D::CSurfaceLightGrid::CCellCorner::LocalAmbientId, NL3D::CInstanceGroup::CInstance::LocalAmbientId, NL3D::CIGSurfaceLightBuild::CCellCorner::LocalAmbientLight, NL3D::CInstanceLighter::CInstanceInfo::LocalAmbientLight, min, nextCell(), nlctassert, nlwarning, NL3D::CInstanceLighter::CPredPointLightToPoint::Point, NL3D::CInstanceLighter::CPointLightRT::PointLight, progress(), progressCell(), NLMISC::CBSphere::Radius, NL3D::CInstanceLighter::CPointLightRT::RefCount, NL3D::CQuadGrid< CPointLightRT * >::select(), NL3D::CInstanceLighter::CPointLightRT::testRaytrace(), and uint.

Referenced by light().

01162 {
01163         uint    i;
01164         vector<CPointLightRT*>          lightInfs;
01165         lightInfs.reserve(1024);
01166 
01167         // clear result list
01168         listPointLight.clear();
01169 
01170 
01171         // Compute each Instance
01172         //===========
01173         for(i=0; i<_InstanceInfos.size(); i++)
01174         {
01175                 // If staticLight not enabled, skip.
01176                 if( !_Instances[i].StaticLightEnabled )
01177                         continue;
01178 
01179                 CInstanceInfo   &inst= _InstanceInfos[i];
01180                 // Avoid autoShadowing
01181                 _CurrentInstanceComputed= i;
01182 
01183                 // progress
01184                 progress ("Compute Influences of PointLights 2/2", i / (float)_InstanceInfos.size());
01185 
01186                 // get the point of the instance.
01187                 CVector         pos= inst.CenterPos;
01188                 
01189                 // Default: takes no LocalAmbientLight;
01190                 inst.LocalAmbientLight= NULL;
01191                 float   furtherAmbLight= 0;
01192 
01193                 // Compute Which light influences him.
01194                 //---------
01195                 lightInfs.clear();
01196                 // Search possible lights around the position.
01197                 _StaticPointLightQuadGrid.select(pos, pos);
01198                 // For all of them, get the ones which touch this point.
01199                 CQuadGrid<CPointLightRT*>::CIterator    it= _StaticPointLightQuadGrid.begin();
01200                 while(it != _StaticPointLightQuadGrid.end())
01201                 {
01202                         CPointLightRT   *pl= *it;
01203 
01204                         // Test if really in the radius of the light, no occlusion, not an ambient, and in Spot Angle setup
01205                         if( pl->testRaytrace(pos, _CurrentInstanceComputed) )
01206                         {
01207                                 // Ok, add the light to the lights which influence the instance
01208                                 lightInfs.push_back(pl);
01209                         }
01210 
01211                         // Ambient Light ??
01212                         if( pl->PointLight.getType() == CPointLight::AmbientLight )
01213                         {
01214                                 // If the instance is in radius of the ambiant light.
01215                                 float   dRadius= pl->BSphere.Radius - (pl->BSphere.Center - pos).norm();
01216                                 if(dRadius>0)
01217                                 {
01218                                         // Take the best ambient light: the one which is further from the circumference
01219                                         if(dRadius > furtherAmbLight)
01220                                         {
01221                                                 furtherAmbLight= dRadius;
01222                                                 inst.LocalAmbientLight= pl;
01223                                         }
01224                                 }
01225                         }
01226 
01227                         // next
01228                         it++;
01229                 }
01230 
01231                 // If ambientLight chosen, inc Ref count of it
01232                 if(inst.LocalAmbientLight)
01233                         inst.LocalAmbientLight->RefCount++;
01234 
01235                 // Choose the Best ones.
01236                 //---------
01237                 CPredPointLightToPoint  predPLTP;
01238                 predPLTP.Point= pos;
01239                 // sort.
01240                 sort(lightInfs.begin(), lightInfs.end(), predPLTP);
01241                 // truncate.
01242                 lightInfs.resize( min((uint)lightInfs.size(), (uint)CInstanceGroup::NumStaticLightPerInstance) );
01243 
01244 
01245                 // For each of them, fill instance
01246                 //---------
01247                 uint                                    lightInfId;
01248                 for(lightInfId=0; lightInfId<lightInfs.size(); lightInfId++)
01249                 {
01250                         CPointLightRT   *pl= lightInfs[lightInfId];
01251 
01252                         // copy light.
01253                         inst.Light[lightInfId]= pl;
01254 
01255                         // Inc RefCount of the light.
01256                         pl->RefCount++;
01257                 }
01258                 // Reset any empty slot to NULL.
01259                 for(; lightInfId<CInstanceGroup::NumStaticLightPerInstance; lightInfId++)
01260                 {
01261                         inst.Light[lightInfId]= NULL;
01262                 }
01263 
01264         }
01265 
01266 
01267         // Compute Lighting on SurfaceLightGrid
01268         //===========
01269         // Must do it before compression !!
01270         // NB: big copy/Past from above
01271         if(_IGSurfaceLightBuild)
01272         {
01273                 // No instance currenlty computed, since we compute surface cells.
01274                 _CurrentInstanceComputed= -1;
01275 
01276                 // Begin cell iteration
01277                 beginCell();
01278                 // For all surface cell corners
01279                 while( !isEndCell() )
01280                 {
01281                         progressCell("Compute PointLights on Surfaces");
01282 
01283                         // get the current cellInfo iterated.
01284                         CIGSurfaceLightBuild::CCellCorner       &cellInfo= getCurrentCellInfo();
01285 
01286                         // if the cell corner lies in the polygon surface.
01287                         if(cellInfo.InSurface)
01288                         {
01289                                 // get the point of the cell.
01290                                 CVector         pos= cellInfo.CenterPos;
01291                                 
01292                                 // Default: takes no LocalAmbientLight;
01293                                 cellInfo.LocalAmbientLight= NULL;
01294                                 float   furtherAmbLight= 0;
01295 
01296                                 // Compute Which light influences him.
01297                                 //---------
01298                                 lightInfs.clear();
01299                                 // Search possible lights around the position.
01300                                 _StaticPointLightQuadGrid.select(pos, pos);
01301                                 // For all of them, get the ones which touch this point.
01302                                 CQuadGrid<CPointLightRT*>::CIterator    it= _StaticPointLightQuadGrid.begin();
01303                                 while(it != _StaticPointLightQuadGrid.end())
01304                                 {
01305                                         CPointLightRT   *pl= *it;
01306 
01307                                         // Test if really in the radius of the light, no occlusion, not an ambient, and in Spot Angle setup
01308                                         if( pl->testRaytrace(pos, _CurrentInstanceComputed) )
01309                                         {
01310                                                 // Ok, add the light to the lights which influence the cell
01311                                                 lightInfs.push_back(pl);
01312                                         }
01313 
01314                                         // Ambient Light ??
01315                                         if( pl->PointLight.getType() == CPointLight::AmbientLight )
01316                                         {
01317                                                 // If the instance is in radius of the ambiant light.
01318                                                 float   dRadius= pl->BSphere.Radius - (pl->BSphere.Center - pos).norm();
01319                                                 if(dRadius>0)
01320                                                 {
01321                                                         // Take the best ambient light: the one which is further from the circumference
01322                                                         if(dRadius > furtherAmbLight)
01323                                                         {
01324                                                                 furtherAmbLight= dRadius;
01325                                                                 cellInfo.LocalAmbientLight= pl;
01326                                                         }
01327                                                 }
01328                                         }
01329 
01330                                         // next
01331                                         it++;
01332                                 }
01333 
01334                                 // If ambientLight chosen, inc Ref count of it
01335                                 if(cellInfo.LocalAmbientLight)
01336                                         ((CPointLightRT*)cellInfo.LocalAmbientLight)->RefCount++;
01337 
01338 
01339                                 // Choose the Best ones.
01340                                 //---------
01341                                 CPredPointLightToPoint  predPLTP;
01342                                 predPLTP.Point= pos;
01343                                 // sort.
01344                                 sort(lightInfs.begin(), lightInfs.end(), predPLTP);
01345                                 // truncate.
01346                                 lightInfs.resize( min((uint)lightInfs.size(), (uint)CSurfaceLightGrid::NumLightPerCorner) );
01347 
01348 
01349                                 // For each of them, fill cellInfo
01350                                 //---------
01351                                 uint                                    lightInfId;
01352                                 for(lightInfId=0; lightInfId<lightInfs.size(); lightInfId++)
01353                                 {
01354                                         CPointLightRT   *pl= lightInfs[lightInfId];
01355 
01356                                         // copy light.
01357                                         cellInfo.LightInfo[lightInfId]= pl;
01358 
01359                                         // Inc RefCount of the light.
01360                                         pl->RefCount++;
01361                                 }
01362                                 // Reset any empty slot to NULL.
01363                                 for(; lightInfId<CSurfaceLightGrid::NumLightPerCorner; lightInfId++)
01364                                 {
01365                                         cellInfo.LightInfo[lightInfId]= NULL;
01366                                 }
01367 
01368                         }
01369 
01370                         // next cell
01371                         nextCell();
01372                 }
01373         }
01374 
01375 
01376 
01377         // Compress and setup _Instances with compressed data.
01378         //===========
01379         uint    plId= 0;
01380         // Process each pointLights
01381         for(i=0; i<_StaticPointLights.size(); i++)
01382         {
01383                 CPointLightRT   &plRT= _StaticPointLights[i];
01384                 // If this light is used.
01385                 if(plRT.RefCount > 0)
01386                 {
01387                         // Valid light ?
01388                         if (plId <=0xFF)
01389                         {
01390                                 // Must Copy it into Ig.
01391                                 listPointLight.push_back(plRT.PointLight);
01392                                 plRT.DstId= plId++;
01393                                 // If index >= 255, too many lights (NB: => because 255 is a NULL code).
01394                         }
01395                         else
01396                         {
01397                                 nlwarning("ERROR: Too many Static Point Lights influence the IG!!");
01398                                 // Set 0xFF. Special code indicating that the light CAN'T BE USED => any instance using 
01399                                 // it is buggy (won't be lighted by this light).
01400                                 plRT.DstId= plId++;
01401                         }
01402                 }
01403         }
01404 
01405         // For each instance, compress Point light info
01406         for(i=0; i<_Instances.size(); i++)
01407         {
01408                 // If staticLight not enabled, skip.
01409                 if( !_Instances[i].StaticLightEnabled )
01410                         continue;
01411 
01412                 CInstanceInfo                           &instSrc= _InstanceInfos[i];
01413                 CInstanceGroup::CInstance       &instDst= _Instances[i];
01414 
01415                 // Do it for PointLights
01416                 for(uint lightId= 0; lightId<CInstanceGroup::NumStaticLightPerInstance; lightId++)
01417                 {
01418                         if(instSrc.Light[lightId] == NULL)
01419                         {
01420                                 // Mark as unused.
01421                                 instDst.Light[lightId]= 0xFF;
01422                         }
01423                         else
01424                         {
01425                                 // Get index. NB: may still be 0xFF if 'Too many static light' bug.
01426                                 instDst.Light[lightId]= instSrc.Light[lightId]->DstId;
01427                         }
01428                 }
01429 
01430                 // Ensure that all FF are at end of the list (possible because of the TooManyStaticLight bug).
01431                 // But don't do a full sort, to preserve order due to influence...
01432                 nlctassert(CInstanceGroup::NumStaticLightPerInstance==2);
01433                 if(instDst.Light[0] == 0xFF)    swap(instDst.Light[0], instDst.Light[1]);
01434 
01435                 // Do it for Ambientlight
01436                 if(instSrc.LocalAmbientLight == NULL)
01437                         instDst.LocalAmbientId= 0xFF;
01438                 else
01439                         // NB: may still be 0xFF if 'Too many static light' bug.
01440                         instDst.LocalAmbientId= instSrc.LocalAmbientLight->DstId;
01441         }
01442 
01443         // For each cell, compress Point light info
01444         if(_IGSurfaceLightBuild)
01445         {
01446                 // Begin cell iteration
01447                 beginCell();
01448                 // For all surface cell corners
01449                 while( !isEndCell() )
01450                 {
01451                         // get the current cell and cellInfo iterated.
01452                         CIGSurfaceLightBuild::CCellCorner       &cellInfo= getCurrentCellInfo();
01453                         CSurfaceLightGrid::CCellCorner          &cell= getCurrentCell();
01454 
01455                         if(cellInfo.InSurface)
01456                         {
01457                                 // Do it for PointLights
01458                                 for(uint lightId= 0; lightId<CSurfaceLightGrid::NumLightPerCorner; lightId++)
01459                                 {
01460                                         if(cellInfo.LightInfo[lightId] == NULL)
01461                                         {
01462                                                 // Mark as unused.
01463                                                 cell.Light[lightId]= 0xFF;
01464                                         }
01465                                         else
01466                                         {
01467                                                 // Get index. NB: may still be 0xFF if 'Too many static light' bug.
01468                                                 cell.Light[lightId]= reinterpret_cast<CPointLightRT*>(cellInfo.LightInfo[lightId])->DstId;
01469                                         }
01470                                 }
01471 
01472                                 // Ensure that all FF are at end of the list (possible because of the TooManyStaticLight bug).
01473                                 // But don't do a full sort, to preserve order due to influence...
01474                                 nlctassert(CInstanceGroup::NumStaticLightPerInstance==2);
01475                                 if(cell.Light[0] == 0xFF)       swap(cell.Light[0], cell.Light[1]);
01476 
01477                                 // Do it for Ambientlight
01478                                 if(cellInfo.LocalAmbientLight == NULL)
01479                                         cell.LocalAmbientId= 0xFF;
01480                                 else
01481                                         // NB: may still be 0xFF if 'Too many static light' bug.
01482                                         cell.LocalAmbientId= ((CPointLightRT*)cellInfo.LocalAmbientLight)->DstId;
01483                         }
01484 
01485                         // next cell
01486                         nextCell();
01487                 }
01488         }
01489 
01490 
01491 }

virtual void NL3D::CInstanceLighter::progress const char *  message,
float  progress
[inline, virtual]
 

Definition at line 159 of file instance_lighter.h.

Referenced by compilePointLightRT(), computeSunContribution(), lightIgSimple(), processIGPointLightRT(), and progressCell().

00159 {};

void NL3D::CInstanceLighter::progressCell const char *  message  )  [private]
 

Definition at line 1623 of file instance_lighter.cpp.

References _LastCellProgress, getCurrentCellNumber(), getTotalCellNumber(), and progress().

Referenced by computeSunContribution(), dilateLightingOnSurfaceCells(), and processIGPointLightRT().

01624 {
01625         float   cp= getCurrentCellNumber() / float(getTotalCellNumber());
01626         if( cp > _LastCellProgress+0.05f)
01627         {
01628                 progress(message, cp);
01629                 _LastCellProgress= cp;
01630         }
01631 }


Field Documentation

sint NL3D::CInstanceLighter::_CurrentInstanceComputed [private]
 

Definition at line 210 of file instance_lighter.h.

Referenced by computeSunContribution(), and processIGPointLightRT().

CIGSurfaceLight::TRetrieverGridMap NL3D::CInstanceLighter::_IGRetrieverGridMap [private]
 

Definition at line 214 of file instance_lighter.h.

Referenced by beginCell(), light(), and nextCell().

CIGSurfaceLightBuild* NL3D::CInstanceLighter::_IGSurfaceLightBuild [private]
 

Definition at line 212 of file instance_lighter.h.

Referenced by beginCell(), CInstanceLighter(), computeSunContribution(), light(), nextCell(), and processIGPointLightRT().

std::vector<CInstanceInfo> NL3D::CInstanceLighter::_InstanceInfos [private]
 

Definition at line 208 of file instance_lighter.h.

Referenced by computeSunContribution(), light(), and processIGPointLightRT().

std::vector<CInstanceGroup::CInstance> NL3D::CInstanceLighter::_Instances [private]
 

Definition at line 206 of file instance_lighter.h.

bool NL3D::CInstanceLighter::_IsEndCell [private]
 

Definition at line 293 of file instance_lighter.h.

Referenced by beginCell(), isEndCell(), light(), and nextCell().

uint NL3D::CInstanceLighter::_ItCellId [private]
 

Definition at line 292 of file instance_lighter.h.

Referenced by beginCell(), getCurrentCell(), getCurrentCellInfo(), getCurrentNeighborCell(), getCurrentNeighborCellInfo(), isCurrentNeighborCellInSurface(), and nextCell().

uint NL3D::CInstanceLighter::_ItCurrentCellNumber [private]
 

Definition at line 294 of file instance_lighter.h.

Referenced by beginCell(), getCurrentCellNumber(), and nextCell().

CIGSurfaceLight::ItRetrieverGridMap NL3D::CInstanceLighter::_ItRetriever [private]
 

Definition at line 289 of file instance_lighter.h.

Referenced by beginCell(), getCurrentCell(), getCurrentNeighborCell(), isCurrentNeighborCellInSurface(), and nextCell().

CIGSurfaceLightBuild::ItRetrieverGridMap NL3D::CInstanceLighter::_ItRetrieverInfo [private]
 

Definition at line 290 of file instance_lighter.h.

Referenced by beginCell(), getCurrentCellInfo(), getCurrentNeighborCellInfo(), isCurrentNeighborCellInSurface(), and nextCell().

uint NL3D::CInstanceLighter::_ItSurfId [private]
 

Definition at line 291 of file instance_lighter.h.

Referenced by beginCell(), getCurrentCell(), getCurrentCellInfo(), getCurrentNeighborCell(), getCurrentNeighborCellInfo(), isCurrentNeighborCellInSurface(), and nextCell().

float NL3D::CInstanceLighter::_LastCellProgress [private]
 

Definition at line 296 of file instance_lighter.h.

Referenced by beginCell(), and progressCell().

CQuadGrid<CPointLightRT*> NL3D::CInstanceLighter::_StaticPointLightQuadGrid [private]
 

QuadGrid of PointLights. Builded from _StaticPointLights.

Definition at line 255 of file instance_lighter.h.

Referenced by compilePointLightRT(), and processIGPointLightRT().

std::vector<CPointLightRT> NL3D::CInstanceLighter::_StaticPointLights [private]
 

List of PointLights.

Definition at line 253 of file instance_lighter.h.

Referenced by addStaticPointLight(), compilePointLightRT(), and processIGPointLightRT().

uint NL3D::CInstanceLighter::_TotalCellNumber [private]
 

Definition at line 295 of file instance_lighter.h.

Referenced by getTotalCellNumber(), and light().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 06:47:40 2004 for NeL by doxygen 1.3.6