From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/a03739.html | 5912 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5912 insertions(+) create mode 100644 docs/doxygen/nel/a03739.html (limited to 'docs/doxygen/nel/a03739.html') diff --git a/docs/doxygen/nel/a03739.html b/docs/doxygen/nel/a03739.html new file mode 100644 index 00000000..b0eb7236 --- /dev/null +++ b/docs/doxygen/nel/a03739.html @@ -0,0 +1,5912 @@ + + +NeL: NL3D::CZoneLighter class Reference + + + +
+

NL3D::CZoneLighter Class Reference

#include <zone_lighter.h> +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Static PointLights mgt.

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

void processZonePointLightRT (std::vector< CPointLightNamed > &listPointLight)
CQuadGrid< CPointLightRT * > _StaticPointLightQuadGrid
 QuadGrid of PointLights. Builded from _StaticPointLights.

std::vector< CPointLightRT_StaticPointLights
 List of PointLights.


Public Member Functions

void addLightableShape (IShape *shape, const NLMISC::CMatrix &modelMT)
void addTriangles (const IShape &shape, const NLMISC::CMatrix &modelMT, std::vector< CTriangle > &triangleArray)
void addTriangles (CLandscape &landscape, std::vector< uint > &listZone, uint order, std::vector< CTriangle > &triangleArray)
void addWaterShape (CWaterShape *shape, const NLMISC::CMatrix &MT)
 Add a water shape. This is needed to decide wether tiles are above / below water.

float attenuation (const CVector &pos, const CZoneLighter::CLightDesc &description)
 CZoneLighter ()
void init ()
void light (CLandscape &landscape, CZone &output, uint zoneToLight, const CLightDesc &description, std::vector< CTriangle > &obstacles, std::vector< uint > &listZone)
virtual void progress (const char *message, float progress)
virtual ~CZoneLighter ()
Static PointLights mgt.
void addStaticPointLight (const CPointLightNamed &pln)
 Append a static point light to compute. call at setup stage (before light() ).


Static Public Member Functions

bool isLightableShape (IShape &shape)
 check wether a shape is lightable.


Data Fields

std::vector< CZBuffer_ZBufferLandscape
CZBuffer _ZBufferObject

Private Types

typedef std::vector< CShapeInfoTShapeVect
 A vector of lightable shapes.

typedef CQuadGrid< CWaterShape * > TWaterShapeQuadGrid

Private Member Functions

void addTriangles (const CMeshBase &meshBase, const CMeshMRMGeom &meshGeom, const CMatrix &modelMT, std::vector< CTriangle > &triangleArray)
void addTriangles (const CMeshBase &meshBase, const CMeshGeom &meshGeom, const NLMISC::CMatrix &modelMT, std::vector< CTriangle > &triangleArray)
void buildZoneInformation (CLandscape &landscape, const std::vector< uint > &listZone, const CLightDesc &lightDesc)
float calcSkyContribution (sint s, sint t, float height, float skyIntensity, const CVector &normal) const
void computeTileFlagsForPositionTowardWater (const CLightDesc &lightDesc, std::vector< const CTessFace * > &tessFaces)
void excludeAllPatchFromRefineAll (CLandscape &landscape, std::vector< uint > &listZone, bool exclude)
uint getAPatch (uint process)
uint8 getMaxPhi (sint s, sint t, sint deltaS, sint deltaT, float heightPos) const
void getNormal (const NL3D::CPatch *pPatch, sint16 lumelS, sint16 lumelT, std::vector< NL3D::CPatchUVLocator > &locator, const std::vector< NL3D::CPatch::CBindInfo > &bindInfo, const std::vector< bool > &binded, std::set< uint64 > &visited, float deltaS, float deltaT, uint rotation, const NL3D::CBezierPatch &bezierPatch, uint lastEdge=5)
void getPatchNormalAndPositions (std::vector< CLumelDescriptor > &lumels, CLandscape &landscape, uint zoneToLight, uint patch, CPatchUVLocator *locator, bool *binded)
float getSkyContribution (const CVector &pos, const CVector &normal, float SkyIntensity) const
 compute the sky contribution at the given position

bool getTexture (const CMaterial &material, NLMISC::CBitmap *&result, bool &clampU, bool &clampV, uint8 &alphaTestThreshold, bool &doubleSided)
bool isLumelOnEdgeMustBeOversample (uint patch, uint edge, sint s, sint t, const std::vector< bool > &binded, const std::vector< bool > &oversampleEdges, std::vector< CPatchUVLocator > &locator, uint8 shadowed, std::vector< std::vector< uint8 > > &shadowBuffer)
void lightShapes (uint zoneID, const CLightDesc &description)
 Launch a set of threads to perform lighting of lightable shapes.

void lightSingleShape (CShapeInfo &lsi, const CLightDesc &description, uint cpu)
 Compute the lighting for a single lightable shape.

void lightWater (CWaterShape &ws, const CMatrix &MT, const CLightDesc &description, uint cpu)
 Compute the lighting for a water shape.

void makeQuadGridFromWaterShapes (NLMISC::CAABBox zoneBBox)
void processCalc (uint process, const CLightDesc &description)
void processLightableShapeCalc (uint process, TShapeVect *shapeToLit, uint firstShape, uint lastShape, const CLightDesc &description)
 Process lighting for a set of lightable shapes. This is called by the threads created by lightShapes().

void setTileFlagsToDefault (std::vector< const CTessFace * > &tessFaces)

Static Private Member Functions

void copyTileFlags (CZone &destZone, const CZone &srcZone)

Private Attributes

std::vector< std::vector<
+ CBezierPatch > > 
_BezierPatch
std::vector< std::vector<
+ std::vector< bool > > > 
_Binded
std::vector< std::vector<
+ std::vector< CPatch::CBindInfo > > > 
_BindInfo
std::map< std::string, NLMISC::CBitmap_Bitmaps
std::vector< CBorderVertex_BorderVertices
uint64 _CPUMask
NLMISC::CVector _GetNormalNormal
const NL3D::CPatch_GetNormalPatch
uint _GetNormalRadius
uint _GetNormalSqRadius
std::vector< float > _HeightField
sint _HeightFieldCellCount
float _HeightfieldCellSize
NLMISC::CVector _K [256][8]
NL3D::CLandscape_Landscape
std::vector< uint_LastPatchComputed
TShapeVect _LightableShapes
 lightable shapes

std::vector< std::vector<
+ std::vector< CPatchUVLocator > > > 
_Locator
std::vector< std::vector<
+ CLumelDescriptor > > 
_Lumels
NLMISC::CFastMutex _Mutex
uint _NumberOfPatchComputed
uint _NumLightableShapesProcessed
NLMISC::CVector _OrigineHeightField
std::vector< std::vector<
+ bool > > 
_OversampleEdges
NLMISC::CSynchronized< std::vector<
+ bool > > 
_PatchComputed
std::vector< CPatchInfo_PatchInfo
uint _ProcessCount
volatile uint _ProcessExited
CQuadGrid< const CTriangle * > _QuadGrid [10]
NLMISC::CRandom _Random
NLMISC::CMatrix _RayBasis
std::vector< std::vector<
+ uint8 > > 
_ShadowArray
float _ShadowBias
bool _Softshadow
NLMISC::CVector _SunDirection
TWaterShapeQuadGrid _WaterShapeQuadGrid
TShapeVect _WaterShapes
bool _ZBufferOverflow
std::map< uint, uint_ZoneId
uint _ZoneToLight

Static Private Attributes

sint16 _GetNormalDeltaS [4] = { -1, 0, 1, 0 }
sint16 _GetNormalDeltaT [4] = { 0, 1, 0, -1 }

Friends

class CCalcLightableShapeRunnable
class NL3D::CLightRunnable
class NL3D::CRenderZBuffer
+


Member Typedef Documentation

+

+ + + + +
+ + +
typedef std::vector<CShapeInfo> NL3D::CZoneLighter::TShapeVect [private] +
+
+ + + + + +
+   + + +

+A vector of lightable shapes. +

+ +

+Definition at line 403 of file zone_lighter.h. +

+Referenced by NL3D::CCalcLightableShapeRunnable::CCalcLightableShapeRunnable(), and processLightableShapeCalc().

+

+ + + + +
+ + +
typedef CQuadGrid<CWaterShape *> NL3D::CZoneLighter::TWaterShapeQuadGrid [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 605 of file zone_lighter.h.

+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
CZoneLighter::CZoneLighter  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 245 of file zone_lighter.cpp. +

+

00245                             : _PatchComputed ("PatchComputed")
+00246 {
+00247 }
+
+

+ + + + +
+ + + + + + + + + +
virtual NL3D::CZoneLighter::~CZoneLighter  )  [inline, virtual]
+
+ + + + + +
+   + + +

+ +

+Definition at line 70 of file zone_lighter.h. +

+

00070 {}
+
+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CZoneLighter::addLightableShape IShape shape,
const NLMISC::CMatrix modelMT
+
+ + + + + +
+   + + +

+Some shape (water shapes for now) can be lit. This add such a shape to the process of lighting.

See also:
isLightableShape()
+ +

+Definition at line 2773 of file zone_lighter.cpp. +

+References _LightableShapes, NL3D::CZoneLighter::CShapeInfo::MT, and NL3D::CZoneLighter::CShapeInfo::Shape. +

+

02774 {
+02775         CShapeInfo lsi;
+02776         lsi.MT = MT;
+02777         lsi.Shape = shape;
+02778         _LightableShapes.push_back(lsi);
+02779 }
+
+

+ + + + +
+ + + + + + + + + + +
void CZoneLighter::addStaticPointLight const CPointLightNamed pln  ) 
+
+ + + + + +
+   + + +

+Append a static point light to compute. call at setup stage (before light() ). +

+ +

+Definition at line 3179 of file zone_lighter.cpp. +

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

+

03180 {
+03181         // build the plRT.
+03182         CPointLightRT   plRT;
+03183         plRT.PointLight= pln;
+03184         // compute plRT.OODeltaAttenuation
+03185         plRT.OODeltaAttenuation= pln.getAttenuationEnd() - pln.getAttenuationBegin();
+03186         if(plRT.OODeltaAttenuation <=0 )
+03187                 plRT.OODeltaAttenuation= 0;
+03188         else
+03189                 plRT.OODeltaAttenuation= 1.0f / plRT.OODeltaAttenuation;
+03190         // compute plRT.BSphere
+03191         plRT.BSphere.Center= pln.getPosition();
+03192         plRT.BSphere.Radius= pln.getAttenuationEnd();
+03193         // NB: FaceCubeGrid will be computed during light()
+03194 
+03195         // add the plRT
+03196         _StaticPointLights.push_back(plRT);
+03197 
+03198 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::addTriangles const CMeshBase meshBase,
const CMeshMRMGeom meshGeom,
const CMatrix modelMT,
std::vector< CTriangle > &  triangleArray
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1887 of file zone_lighter.cpp. +

+References NL3D::CMeshBase::getMaterial(), NL3D::CMeshMRMGeom::getNbRdrPass(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CPrimitiveBlock::getQuadPointer(), NL3D::CMeshMRMGeom::getRdrPassMaterial(), NL3D::CMeshMRMGeom::getRdrPassPrimitiveBlock(), NL3D::CVertexBuffer::getTexCoordPointer(), getTexture(), NL3D::CPrimitiveBlock::getTriPointer(), NL3D::CMeshMRMGeom::getVertexBuffer(), NL3D::CVertexBuffer::getVertexCoordPointer(), uint, uint32, uint8, and v. +

+

01888 {
+01889         // Get the vertex buffer
+01890         const CVertexBuffer &vb=meshGeom.getVertexBuffer();
+01891 
+01892         // For each render pass
+01893         uint numRenderPass=meshGeom.getNbRdrPass(0);
+01894         for (uint pass=0; pass<numRenderPass; pass++)
+01895         {
+01896                 // Get the primitive block
+01897                 const CPrimitiveBlock &primitive=meshGeom.getRdrPassPrimitiveBlock ( 0, pass);
+01898 
+01899                 // Get the material
+01900                 const CMaterial &material = meshBase.getMaterial (meshGeom.getRdrPassMaterial (0, pass));
+01901 
+01902                 // ** Get the bitmap
+01903 
+01904                 // Texture informations, not NULL only if texture is used for alpha test
+01905                 CBitmap *texture;
+01906                 bool clampU;
+01907                 bool clampV;
+01908                 uint8 alphaTestThreshold;
+01909                 bool doubleSided;
+01910                 if (getTexture (material, texture, clampU, clampV, alphaTestThreshold, doubleSided))
+01911                 {
+01912                         // Dump triangles
+01913                         const uint32* triIndex=primitive.getTriPointer ();
+01914                         uint numTri=primitive.getNumTri ();
+01915                         uint tri;
+01916                         for (tri=0; tri<numTri; tri++)
+01917                         {
+01918                                 // Vertex
+01919                                 CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3]));
+01920                                 CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+1]));
+01921                                 CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+2]));
+01922 
+01923                                 // UV
+01924                                 float u[3];
+01925                                 float v[3];
+01926                                 for (uint i=0; i<3; i++)
+01927                                 {
+01928                                         // Get UV coordinates
+01929                                         float *uv = (float*)vb.getTexCoordPointer (triIndex[tri*3+i], 0);
+01930                                         if (uv)
+01931                                         {
+01932                                                 // Copy it
+01933                                                 u[i] = uv[0];
+01934                                                 v[i] = uv[1];
+01935                                         }
+01936                                 }
+01937 
+01938                                 // Make a triangle
+01939                                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), doubleSided, texture, clampU, clampV, u, v, 
+01940                                         alphaTestThreshold));
+01941                         }
+01942 
+01943                         // Dump quad
+01944                         triIndex=primitive.getQuadPointer ();
+01945                         numTri=primitive.getNumQuad ();
+01946                         for (tri=0; tri<numTri; tri++)
+01947                         {
+01948                                 // Vertex
+01949                                 CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4]));
+01950                                 CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+1]));
+01951                                 CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+2]));
+01952                                 CVector v3=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+3]));
+01953 
+01954                                 // UV
+01955                                 float u[4];
+01956                                 float v[4];
+01957                                 for (uint i=0; i<4; i++)
+01958                                 {
+01959                                         // Get UV coordinates
+01960                                         float *uv = (float*)vb.getTexCoordPointer (triIndex[tri*4+i], 0);
+01961                                         if (uv)
+01962                                         {
+01963                                                 // Copy it
+01964                                                 u[i] = uv[0];
+01965                                                 v[i] = uv[1];
+01966                                         }
+01967                                 }
+01968 
+01969                                 // Make 2 triangles
+01970                                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), doubleSided, texture, clampU, clampV, u, v, 
+01971                                         alphaTestThreshold));
+01972                                 u[1] = u[2];
+01973                                 u[2] = u[3];
+01974                                 v[1] = v[2];
+01975                                 v[2] = v[3];
+01976                                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v2, v3), doubleSided, texture, clampU, clampV, u, v, 
+01977                                         alphaTestThreshold));
+01978                         }
+01979                 }
+01980         }
+01981 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::addTriangles const CMeshBase meshBase,
const CMeshGeom meshGeom,
const NLMISC::CMatrix modelMT,
std::vector< CTriangle > &  triangleArray
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1717 of file zone_lighter.cpp. +

+References NL3D::CMeshBase::getMaterial(), NL3D::CMeshGeom::getNbMatrixBlock(), NL3D::CMeshGeom::getNbRdrPass(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CPrimitiveBlock::getQuadPointer(), NL3D::CMeshGeom::getRdrPassMaterial(), NL3D::CMeshGeom::getRdrPassPrimitiveBlock(), NL3D::CVertexBuffer::getTexCoordPointer(), getTexture(), NL3D::CPrimitiveBlock::getTriPointer(), NL3D::CMeshGeom::getVertexBuffer(), NL3D::CVertexBuffer::getVertexCoordPointer(), uint, uint32, uint8, and v. +

+

01718 {
+01719         // Get the vertex buffer
+01720         const CVertexBuffer &vb=meshGeom.getVertexBuffer();
+01721 
+01722         // For each matrix block
+01723         uint numBlock=meshGeom.getNbMatrixBlock();
+01724         for (uint block=0; block<numBlock; block++)
+01725         {
+01726                 // For each render pass
+01727                 uint numRenderPass=meshGeom.getNbRdrPass(block);
+01728                 for (uint pass=0; pass<numRenderPass; pass++)
+01729                 {
+01730                         // Get the primitive block
+01731                         const CPrimitiveBlock &primitive=meshGeom.getRdrPassPrimitiveBlock ( block, pass);
+01732 
+01733                         // Get the material
+01734                         const CMaterial &material = meshBase.getMaterial (meshGeom.getRdrPassMaterial ( block, pass));
+01735 
+01736                         // ** Get the bitmap
+01737 
+01738                         // Texture informations, not NULL only if texture is used for alpha test
+01739                         CBitmap *texture;
+01740                         bool clampU;
+01741                         bool clampV;
+01742                         uint8 alphaTestThreshold;
+01743                         bool doubleSided;
+01744                         if (getTexture (material, texture, clampU, clampV, alphaTestThreshold, doubleSided))
+01745                         {
+01746                                 // Dump triangles
+01747                                 const uint32* triIndex=primitive.getTriPointer ();
+01748                                 uint numTri=primitive.getNumTri ();
+01749                                 uint tri;
+01750                                 for (tri=0; tri<numTri; tri++)
+01751                                 {
+01752                                         // Vertex
+01753                                         CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3]));
+01754                                         CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+1]));
+01755                                         CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*3+2]));
+01756 
+01757                                         // UV
+01758                                         float u[3];
+01759                                         float v[3];
+01760                                         for (uint i=0; i<3; i++)
+01761                                         {
+01762                                                 // Get UV coordinates
+01763                                                 float *uv = (float*)vb.getTexCoordPointer (triIndex[tri*3+i], 0);
+01764                                                 if (uv)
+01765                                                 {
+01766                                                         // Copy it
+01767                                                         u[i] = uv[0];
+01768                                                         v[i] = uv[1];
+01769                                                 }
+01770                                         }
+01771 
+01772                                         // Make a triangle
+01773                                         triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), doubleSided, texture, clampU, clampV, u, v, 
+01774                                                 alphaTestThreshold));
+01775                                 }
+01776 
+01777                                 // Dump quad
+01778                                 triIndex=primitive.getQuadPointer ();
+01779                                 numTri=primitive.getNumQuad ();
+01780                                 for (tri=0; tri<numTri; tri++)
+01781                                 {
+01782                                         // Vertex
+01783                                         CVector v0=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4]));
+01784                                         CVector v1=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+1]));
+01785                                         CVector v2=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+2]));
+01786                                         CVector v3=modelMT*(*(CVector*)vb.getVertexCoordPointer (triIndex[tri*4+3]));
+01787 
+01788                                         // UV
+01789                                         float u[4];
+01790                                         float v[4];
+01791                                         for (uint i=0; i<4; i++)
+01792                                         {
+01793                                                 // Get UV coordinates
+01794                                                 float *uv = (float*)vb.getTexCoordPointer (triIndex[tri*4+i], 0);
+01795                                                 if (uv)
+01796                                                 {
+01797                                                         // Copy it
+01798                                                         u[i] = uv[0];
+01799                                                         v[i] = uv[1];
+01800                                                 }
+01801                                         }
+01802 
+01803                                         // Make 2 triangles
+01804                                         triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v1, v2), doubleSided, texture, clampU, clampV, u, v, 
+01805                                                 alphaTestThreshold));
+01806                                         u[1] = u[2];
+01807                                         u[2] = u[3];
+01808                                         v[1] = v[2];
+01809                                         v[2] = v[3];
+01810                                         triangleArray.push_back (CTriangle (NLMISC::CTriangle (v0, v2, v3), doubleSided, texture, clampU, clampV, u, v, 
+01811                                                 alphaTestThreshold));
+01812                                 }
+01813                         }
+01814                 }
+01815         }
+01816 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::addTriangles const IShape shape,
const NLMISC::CMatrix modelMT,
std::vector< CTriangle > &  triangleArray
+
+ + + + + +
+   + + +

+ +

+Definition at line 1670 of file zone_lighter.cpp. +

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

+

01671 {
+01672         // Cast to CMesh
+01673         const CMesh *mesh=dynamic_cast<const CMesh*>(&shape);
+01674 
+01675         // Cast to CMeshMultiLod
+01676         const CMeshMultiLod *meshMulti=dynamic_cast<const CMeshMultiLod*>(&shape);
+01677 
+01678         // Cast to CMeshMultiLod
+01679         const CMeshMRM *meshMRM=dynamic_cast<const CMeshMRM*>(&shape);
+01680 
+01681         // It is a mesh ?
+01682         if (mesh)
+01683         {
+01684                 // Add its triangles
+01685                 addTriangles (*mesh, mesh->getMeshGeom (), modelMT, triangleArray);
+01686         }
+01687         // It is a CMeshMultiLod ?
+01688         else if (meshMulti)
+01689         {
+01690                 // Get the first geommesh
+01691                 const IMeshGeom *meshGeom=&meshMulti->getMeshGeom (0);
+01692 
+01693                 // Dynamic cast
+01694                 const CMeshGeom *geomMesh=dynamic_cast<const CMeshGeom*>(meshGeom);
+01695                 if (geomMesh)
+01696                 {
+01697                         addTriangles (*meshMulti, *geomMesh, modelMT, triangleArray);
+01698                 }
+01699 
+01700                 // Dynamic cast
+01701                 const CMeshMRMGeom *mrmGeomMesh=dynamic_cast<const CMeshMRMGeom*>(meshGeom);
+01702                 if (mrmGeomMesh)
+01703                 {
+01704                         addTriangles (*meshMulti, *mrmGeomMesh, modelMT, triangleArray);
+01705                 }
+01706         }
+01707         // It is a CMeshMultiLod ?
+01708         else if (meshMRM)
+01709         {
+01710                 // Get the first lod mesh geom
+01711                 addTriangles (*meshMRM, meshMRM->getMeshGeom (), modelMT, triangleArray);
+01712         }
+01713 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::addTriangles CLandscape landscape,
std::vector< uint > &  listZone,
uint  order,
std::vector< CTriangle > &  triangleArray
+
+ + + + + +
+   + + +

+ +

+Definition at line 1613 of file zone_lighter.cpp. +

+References NL3D::CTessVertex::EndPos, excludeAllPatchFromRefineAll(), NL3D::CParamCoord::getS(), NL3D::CParamCoord::getT(), NL3D::CLandscape::getTessellationLeaves(), min, NL3D::CTessFace::PVBase, NL3D::CTessFace::PVLeft, NL3D::CTessFace::PVRight, NL3D::CLandscape::refineAll(), NL3D::CLandscape::setThreshold(), NL3D::CLandscape::setTileMaxSubdivision(), uint, NL3D::CTessFace::VBase, NL3D::CTessFace::VLeft, and NL3D::CTessFace::VRight. +

+Referenced by addTriangles(). +

+

01614 {
+01615         // Set all to refine
+01616         excludeAllPatchFromRefineAll (landscape, listZone, false);
+01617 
+01618         // Setup the landscape
+01619         landscape.setThreshold (0);
+01620         landscape.setTileMaxSubdivision (order);
+01621 
+01622         // Refine it
+01623         landscape.refineAll (CVector (0, 0, 0));
+01624 
+01625         // Dump tesselated triangles
+01626         std::vector<const CTessFace*> leaves;
+01627         landscape.getTessellationLeaves(leaves);
+01628 
+01629         // Number of leaves
+01630         uint leavesCount=leaves.size();
+01631 
+01632         // Reserve the array
+01633         triangleArray.reserve (triangleArray.size()+leavesCount);
+01634 
+01635         // Scan each leaves
+01636         for (uint leave=0; leave<leavesCount; leave++)
+01637         {
+01638                 // Leave
+01639                 const CTessFace *face=leaves[leave];
+01640 
+01641                 // Start and end coordinate
+01642                 float startS=min (min (face->PVBase.getS(), face->PVLeft.getS()), face->PVRight.getS());
+01643                 float endS=max (max (face->PVBase.getS(), face->PVLeft.getS()), face->PVRight.getS());
+01644                 float startT=min (min (face->PVBase.getT(), face->PVLeft.getT()), face->PVRight.getT());
+01645                 float endT=max (max (face->PVBase.getT(), face->PVLeft.getT()), face->PVRight.getT());
+01646 
+01647                 // Add a triangle
+01648                 triangleArray.push_back (CTriangle (NLMISC::CTriangle (face->VBase->EndPos, face->VLeft->EndPos, face->VRight->EndPos)));
+01649         }
+01650 
+01651         // Setup the landscape
+01652         landscape.setThreshold (1000);
+01653         landscape.setTileMaxSubdivision (0);
+01654 
+01655         // Remove all triangles
+01656         landscape.refineAll (CVector (0, 0, 0));
+01657         landscape.refineAll (CVector (0, 0, 0));
+01658         landscape.refineAll (CVector (0, 0, 0));
+01659         landscape.refineAll (CVector (0, 0, 0));
+01660         landscape.refineAll (CVector (0, 0, 0));
+01661         landscape.refineAll (CVector (0, 0, 0));
+01662         landscape.refineAll (CVector (0, 0, 0));
+01663         landscape.refineAll (CVector (0, 0, 0));
+01664         landscape.refineAll (CVector (0, 0, 0));
+01665         landscape.refineAll (CVector (0, 0, 0));
+01666 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CZoneLighter::addWaterShape CWaterShape shape,
const NLMISC::CMatrix MT
+
+ + + + + +
+   + + +

+Add a water shape. This is needed to decide wether tiles are above / below water. +

+make sure it hasn't been inserted twice +

+Definition at line 3057 of file zone_lighter.cpp. +

+References NL3D::CZoneLighter::CShapeInfo::MT, and NL3D::CZoneLighter::CShapeInfo::Shape. +

+

03058 {
+03060         CShapeInfo ci;
+03061         ci.Shape = shape;
+03062         ci.MT = MT;
+03063         _WaterShapes.push_back(ci);
+03064 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
float CZoneLighter::attenuation const CVector pos,
const CZoneLighter::CLightDesc description
+
+ + + + + +
+   + + +

+ +

+Definition at line 3767 of file zone_lighter.cpp. +

+References _Random, _ZBufferLandscape, _ZBufferObject, _ZBufferOverflow, NL3D::CZoneLighter::CZBuffer::LocalZBufferXMin, NL3D::CZoneLighter::CZBuffer::LocalZBufferYMin, min, NLMISC::CRandom::rand(), NLMISC::CRandom::RandMax, sint, NL3D::CZoneLighter::CLightDesc::SoftShadowJitter, NL3D::CZoneLighter::CLightDesc::SoftShadowSamplesSqrt, testZPercentageCloserFilter(), transformVectorToZBuffer(), uint, NLMISC::CVector::x, x, NLMISC::CVector::y, y, and NLMISC::CVector::z. +

+Referenced by lightWater(), and processCalc(). +

+

03768 {
+03769         // Clipped ?
+03770 
+03771         // *** Landscape attenuation
+03772 
+03773         // Current value
+03774         float averageAttenuation = 0;
+03775         float randomSum = 0;
+03776 
+03777         // For each sample
+03778         uint sample;
+03779         const uint samples = description.SoftShadowSamplesSqrt*description.SoftShadowSamplesSqrt;
+03780         for (sample=0; sample<samples; sample++)
+03781         {
+03782                 // The zbuffer
+03783                 CZBuffer &zbuffer = _ZBufferLandscape[sample];
+03784 
+03785                 // Get position in z buffer
+03786                 CVector zPos;
+03787                 transformVectorToZBuffer (zbuffer, pos, zPos);
+03788 
+03789                 sint x = (sint)floor (zPos.x);
+03790                 sint y = (sint)floor (zPos.y);
+03791 
+03792                 // Get the z
+03793                 float random = (float)_Random.rand () * description.SoftShadowJitter + _Random.RandMax * (1.f - description.SoftShadowJitter);
+03794                 averageAttenuation += random * testZPercentageCloserFilter (zPos.x-(float)zbuffer.LocalZBufferXMin, zPos.y-(float)zbuffer.LocalZBufferYMin, zPos.z, zbuffer, description, _ZBufferOverflow);
+03795                 randomSum += random;
+03796         }
+03797 
+03798         // Average landscape attenuation
+03799         averageAttenuation /= randomSum;
+03800 
+03801 
+03802         
+03803         // *** Attenuation in the object zbuffer
+03804 
+03805         // Get position in z buffer
+03806         CVector zPos;
+03807         transformVectorToZBuffer (_ZBufferObject, pos, zPos);
+03808 
+03809         const sint x = (sint)floor (zPos.x);
+03810         const sint y = (sint)floor (zPos.y);
+03811 
+03812         const float objectAttenuation = testZPercentageCloserFilter (zPos.x-(float)_ZBufferObject.LocalZBufferXMin, zPos.y-(float)_ZBufferObject.LocalZBufferYMin, zPos.z, _ZBufferObject, description, _ZBufferOverflow);
+03813 
+03814 
+03815         // *** Return the min of the both
+03816         return std::min (objectAttenuation, averageAttenuation);
+03817 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::buildZoneInformation CLandscape landscape,
const std::vector< uint > &  listZone,
const CLightDesc lightDesc
[private]
+
+ + + + + +
+   + + +

+make a quad grid of each water shape

+check for each tile if it is above / below water +

+Definition at line 2045 of file zone_lighter.cpp. +

+References _BezierPatch, _Binded, _BindInfo, _GetNormalNormal, _Locator, _Lumels, _OversampleEdges, _ZoneId, _ZoneToLight, BLUR_SIZE, computeTileFlagsForPositionTowardWater(), count, easineasout(), NL3D::CTessVertex::EndPos, NL3D::CBezierPatch::evalNormal(), NL3D::CLandscape::excludePatchFromRefineAll(), NLMISC::CAABBoxExt::getAABBox(), NL3D::CPatch::getBindNeighbor(), getNormal(), NLMISC::CPlane::getNormal(), NL3D::CZone::getNumPatchs(), NL3D::CPatch::getOrderS(), NL3D::CPatch::getOrderT(), NL3D::CPatch::getPatchId(), NLMISC::getPowerOf2(), NL3D::CParamCoord::getS(), NL3D::CParamCoord::getT(), NL3D::CLandscape::getTessellationLeaves(), NL3D::CPatch::getZone(), NL3D::CLandscape::getZone(), NL3D::CZone::getZoneBB(), NL3D::CZone::getZoneId(), index, NLMISC::isPowerOf2(), NLMISC::CPlane::make(), makeQuadGridFromWaterShapes(), NL_LUMEL_BY_TILE, NL_MAX_TILES_BY_PATCH_EDGE, nlassert, NL3D::CZoneLighter::CLumelDescriptor::Normal, NLMISC::CVector::normalize(), NL3D::CTessFace::Patch, NL3D::CZoneLighter::CLumelDescriptor::Position, progress(), NL3D::CTessFace::PVBase, NL3D::CTessFace::PVLeft, NL3D::CTessFace::PVRight, NL3D::CLandscape::refineAll(), s, NL3D::CZoneLighter::CLumelDescriptor::S, NLMISC::CVector::set(), NL3D::CLandscape::setThreshold(), setTileFlagsToDefault(), NL3D::CLandscape::setTileMaxSubdivision(), sint, t, NL3D::CZoneLighter::CLumelDescriptor::T, uint, NL3D::CPatch::unpackIntoCache(), value, NL3D::CTessFace::VBase, NL3D::CTessFace::VLeft, and NL3D::CTessFace::VRight. +

+Referenced by light(). +

+

02046 {
+02047         // Bool visit
+02048         vector<vector<uint> > visited;
+02049 
+02050         // Zone count
+02051         uint zoneCount=listZone.size();
+02052 
+02053         // Resize arries
+02054         _Locator.resize (zoneCount);
+02055         _Binded.resize (zoneCount);
+02056         _BindInfo.resize (zoneCount);
+02057         _BezierPatch.resize (zoneCount);
+02058 
+02059         // For each zone
+02060         for (uint zone=0; zone<zoneCount; zone++)
+02061         {
+02062                 // Get num patches
+02063                 uint patchCount=landscape.getZone(listZone[zone])->getNumPatchs();
+02064 
+02065                 // Insert zone id
+02066                 _ZoneId.insert (map<uint, uint>::value_type (listZone[zone], zone));
+02067 
+02068                 // This is the zone to light ?
+02069                 if (listZone[zone]==_ZoneToLight)
+02070                 {
+02071                         // Resize the arraies
+02072                         _Lumels.resize(patchCount);
+02073 //                      _LumelCorners.resize(patchCount);
+02074 //                      _BezierPatch.resize(patchCount);
+02075                         _OversampleEdges.resize(patchCount);
+02076                         visited.resize(patchCount);
+02077                 }
+02078 
+02079                 // Common arries
+02080                 _Locator[zone].resize(patchCount);
+02081                 _Binded[zone].resize(patchCount);
+02082                 _BindInfo[zone].resize(patchCount);
+02083                 _BezierPatch[zone].resize(patchCount);
+02084 
+02085                 // For each patch
+02086                 uint patch;
+02087                 for (patch=0; patch<patchCount; patch++)
+02088                 {
+02089                         // Get a patch pointer
+02090                         const CPatch* pPatch=(const_cast<const CZone*>(landscape.getZone(listZone[zone])))->getPatch (patch);
+02091 
+02092                         // Progress bar
+02093                         progress ("Scan all patches", (float)patch/(float)patchCount);
+02094 
+02095                         // Get pointer on arries
+02096                         vector<bool> &binded=_Binded[zone][patch];
+02097                         vector<CPatch::CBindInfo> &bindInfo=_BindInfo[zone][patch];
+02098                         vector<CPatchUVLocator> &locator=_Locator[zone][patch];
+02099                         CBezierPatch &bezierPatch=_BezierPatch[zone][patch];
+02100                         binded.resize (4, false);
+02101                         bindInfo.resize (4);
+02102                         locator.resize (4);
+02103 
+02104                         // Contruct the patch
+02105                         bezierPatch=*pPatch->unpackIntoCache();
+02106 
+02107                         // Same zone ?
+02108                         if (listZone[zone]==_ZoneToLight)
+02109                         {
+02110                                 // oversample this edge
+02111                                 _OversampleEdges[patch].resize (4, false);
+02112                         }
+02113 
+02114                         // *** Build bind info
+02115 
+02116                         // *** Build neighboorhood information
+02117                         uint edge;
+02118                         for (edge=0; edge<4; edge++)
+02119                         {
+02120                                 // Bond neighbor
+02121                                 pPatch->getBindNeighbor (edge, bindInfo[edge]);
+02122 
+02123                                 // Patch binded
+02124                                 if (bindInfo[edge].NPatchs>0)
+02125                                 {
+02126                                         // This edeg is binded
+02127                                         binded[edge]=true;
+02128 
+02129                                         // Same zone ?
+02130                                         if ((listZone[zone]==_ZoneToLight)&&(bindInfo[edge].Zone->getZoneId()!=_ZoneToLight))
+02131                                         {
+02132                                                 // oversample this edge
+02133                                                 _OversampleEdges[patch][edge]=true;
+02134                                         }
+02135                                         locator[edge].build (pPatch, edge, bindInfo[edge]);
+02136                                 }
+02137                                 else
+02138                                 {
+02139                                         if (listZone[zone]==_ZoneToLight)
+02140                                         {
+02141                                                 // oversample this edge
+02142                                                 _OversampleEdges[patch][edge]=true;
+02143                                         }
+02144                                 }
+02145                         }
+02146 
+02147                         // This is the zone to light ?
+02148                         if (listZone[zone]==_ZoneToLight)
+02149                         {
+02150                                 // *** Resize lumel array for this patch
+02151 
+02152                                 // Get patch order
+02153                                 uint orderS=pPatch->getOrderS();
+02154                                 uint orderT=pPatch->getOrderT();
+02155 
+02156                                 // Number of lumels
+02157                                 uint lumelCount = orderS*orderT*16;
+02158                                 uint lumelCornerCount = (orderS*4+1)*(orderT*4+1);
+02159 
+02160                                 // Resize the lumel descriptor
+02161                                 CLumelDescriptor descriptor;
+02162                                 descriptor.Normal.set (0,0,0);
+02163                                 descriptor.Position.set (0,0,0);
+02164                                 descriptor.S=0;
+02165                                 descriptor.T=0;
+02166                                 _Lumels[patch].resize (lumelCount, descriptor);
+02167                                 visited[patch].resize (lumelCount, 0);
+02168 //                              _LumelCorners[patch].resize (lumelCornerCount);
+02169 
+02170 
+02171                                 // *** Unexclude this patch
+02172 
+02173                                 // Exclude all the patches from refine all
+02174                                 landscape.excludePatchFromRefineAll (listZone[zone], patch, false);
+02175                         }
+02176                         else
+02177                         {
+02178                                 // Exclude all the patches from refine all
+02179                                 landscape.excludePatchFromRefineAll (listZone[zone], patch, true);
+02180                         }
+02181                 }
+02182         }
+02183 
+02184         // *** Now tesselate this zone to shadow casters accuracy
+02185 
+02186         // Setup the landscape
+02187         landscape.setThreshold (0);
+02188         landscape.setTileMaxSubdivision (0);
+02189 
+02190         // Refine all
+02191         progress ("Refine landscape to shadow accuracy", 0.5f);
+02192         landscape.refineAll (CVector (0, 0, 0));
+02193 
+02194         // Get tesselated faces
+02195         std::vector<const CTessFace*> leaves;
+02196         landscape.getTessellationLeaves(leaves);
+02197         
+02198 
+02199         
+02200         
+02201         if (_WaterShapes.size() != 0) // any water shape in this zone ?
+02202         {
+02204                 makeQuadGridFromWaterShapes(landscape.getZone(_ZoneToLight)->getZoneBB().getAABBox());
+02205 
+02207                 computeTileFlagsForPositionTowardWater(lightDesc, leaves);
+02208         }
+02209         else
+02210         {
+02211                 setTileFlagsToDefault(leaves);
+02212         }
+02213         
+02214 
+02215         // Id of this zone in the array
+02216         uint zoneNumber=_ZoneId[_ZoneToLight];
+02217 
+02218         // Scan each leaves
+02219         uint leavesCount=leaves.size();
+02220         uint leave;
+02221         for (leave=0; leave<leavesCount; leave++)
+02222         {
+02223                 // Progress bar
+02224                 if ( (leave&0xff) == 0)
+02225                         progress ("Precompute lumel position", (float)leave/(float)leavesCount);
+02226 
+02227                 // Leave
+02228                 const CTessFace *face=leaves[leave];
+02229 
+02230                 // Get zone id
+02231                 if (face->Patch->getZone()->getZoneId()==_ZoneToLight)
+02232                 {
+02233                         // Get a patch pointer
+02234                         const CPatch* pPatch=face->Patch;
+02235 
+02236                         // Get order
+02237                         uint orderS=pPatch->getOrderS();
+02238                         uint orderT=pPatch->getOrderT();
+02239 
+02240                         // *** Base Coordinates
+02241 
+02242                         CVector pos[15];
+02243                         pos[0]=face->VBase->EndPos;             // p0
+02244                         pos[1]=face->VRight->EndPos;
+02245                         pos[2]=face->VLeft->EndPos;             // p2
+02246                         pos[3]=(pos[1]+pos[2])/2;
+02247                         pos[4]=(pos[0]+pos[1])/2;                               // p4
+02248                         pos[5]=(pos[0]+pos[2])/2;
+02249                         pos[6]=(pos[0]+pos[3])/2;                               // p6
+02250                         pos[7]=(pos[2]+pos[3])/2;
+02251                         pos[8]=(pos[1]+pos[3])/2;                               // p8
+02252                         pos[9]=(pos[0]+pos[4])/2;
+02253                         pos[10]=(pos[1]+pos[4])/2;                              // p10
+02254                         pos[11]=(pos[0]+pos[5])/2;
+02255                         pos[12]=(pos[2]+pos[5])/2;                              // p12
+02256                         pos[13]=(pos[3]+pos[5])/2;
+02257                         pos[14]=(pos[3]+pos[4])/2;                              // p14
+02258 
+02259                         float s0=face->PVBase.getS();
+02260                         float s1=face->PVRight.getS();
+02261                         float s2=face->PVLeft.getS();
+02262                         float s3=(s1+s2)/2;
+02263                         float s4=(s0+s1)/2;
+02264                         float s5=(s0+s2)/2;
+02265                         float s6=(s4+s5)/2;
+02266                         float s7=(s2+s3)/2;
+02267                         float s8=(s1+s3)/2;
+02268 
+02269                         float t0=face->PVBase.getT();
+02270                         float t1=face->PVRight.getT();
+02271                         float t2=face->PVLeft.getT();
+02272                         float t3=(t1+t2)/2;
+02273                         float t4=(t0+t1)/2;
+02274                         float t5=(t0+t2)/2;
+02275                         float t6=(t4+t5)/2;
+02276                         float t7=(t2+t3)/2;
+02277                         float t8=(t1+t3)/2;
+02278 
+02279                         // *** Interpolated value
+02280                         CVector interpolatedP[10]=
+02281                         {
+02282                                 (pos[0]+pos[6])/2,
+02283                                 (pos[4]+pos[6])/2,
+02284                                 (pos[4]+pos[8])/2,
+02285                                 (pos[1]+pos[8])/2,
+02286                                 (pos[5]+pos[6])/2,
+02287                                 (pos[3]+pos[6])/2,
+02288                                 (pos[3]+pos[8])/2,
+02289                                 (pos[5]+pos[7])/2,
+02290                                 (pos[3]+pos[7])/2,
+02291                                 (pos[2]+pos[7])/2,
+02292                         };
+02293 
+02294                         // Does the border are snapped ?
+02295                         uint sBase = (uint)floor ((float)orderS * face->PVBase.getS() + 0.5);
+02296                         uint tBase = (uint)floor ((float)orderT * face->PVBase.getT() + 0.5);
+02297                         uint sLeft = (uint)floor ((float)orderS * face->PVLeft.getS() + 0.5);
+02298                         uint tLeft = (uint)floor ((float)orderT * face->PVLeft.getT() + 0.5);
+02299                         uint sRight = (uint)floor ((float)orderS * face->PVRight.getS() + 0.5);
+02300                         uint tRight = (uint)floor ((float)orderT * face->PVRight.getT() + 0.5);
+02301                         bool snapedLeft[2]=
+02302                         {
+02303                                 (sBase == 0) && (sRight == 0),
+02304                                 (sBase == 0) && (sLeft == 0),
+02305                         };
+02306                         bool snapedRight[2]=
+02307                         {
+02308                                 (sBase == orderS) && (sRight == orderS),
+02309                                 (sBase == orderS) && (sLeft == orderS),
+02310                         };
+02311                         bool snapedTop[2]=
+02312                         {
+02313                                 (tBase == 0) && (tRight == 0),
+02314                                 (tBase == 0) && (tLeft == 0),
+02315                         };
+02316                         bool snapedBottom[2]=
+02317                         {
+02318                                 (tBase == orderT) && (tRight == orderT),
+02319                                 (tBase == orderT) && (tLeft == orderT),
+02320                         };
+02321                         bool snapedBorder[2]=
+02322                         {
+02323                                 snapedLeft[0]||snapedRight[0]||snapedTop[0]||snapedBottom[0],
+02324                                 snapedLeft[1]||snapedRight[1]||snapedTop[1]||snapedBottom[1],
+02325                         };
+02326 
+02327                         bool snapedCorner[3]=
+02328                         {
+02329                                 ((sBase == 0) && ((tBase == 0) || (tBase == orderT))) || 
+02330                                 ((sBase == orderS) && ((tBase == 0) || (tBase == orderT))),
+02331                                 ((sRight == 0) && ((tRight == 0) || (tRight == orderT))) || 
+02332                                 ((sRight == orderS) && ((tRight == 0) || (tRight == orderT))),
+02333                                 ((sLeft == 0) && ((tLeft == 0) || (tLeft == orderT))) || 
+02334                                 ((sLeft == orderS) && ((tLeft == 0) || (tLeft == orderT))),
+02335                         };
+02336 
+02337                         // Snap on the border
+02338                         uint i;
+02339                         for (i=0; i<8; i++)
+02340                         {
+02341                                 // Snaped on left ?
+02342                                 if (snapedBorder[VertexThanCanBeSnappedOnABorder[i][1]])
+02343                                 {
+02344                                         // Compute the border vertex
+02345                                         interpolatedP[VertexThanCanBeSnappedOnABorder[i][0]] = (pos[VertexThanCanBeSnappedOnABorder[i][2]]
+02346                                                 + pos[VertexThanCanBeSnappedOnABorder[i][3]])/2;
+02347                                 }
+02348                         }
+02349 
+02350                         // Snap on the corner
+02351                         for (i=0; i<3; i++)
+02352                         {
+02353                                 // Snaped on a corner ?
+02354                                 uint tesselCornerIndex = VertexThanCanBeSnappedOnACorner[i][1];
+02355                                 if ( snapedCorner[tesselCornerIndex] )
+02356                                 {
+02357                                         // Compute the border vertex
+02358                                         interpolatedP[VertexThanCanBeSnappedOnACorner[i][0]] = pos[tesselCornerIndex];
+02359                                 }
+02360                         }
+02361 
+02362                         float interpolatedS[10]=
+02363                         {
+02364                                 (s0+s6)/2,
+02365                                 (s4+s6)/2,
+02366                                 (s4+s8)/2,
+02367                                 (s1+s8)/2,
+02368                                 (s5+s6)/2,
+02369                                 (s3+s6)/2,
+02370                                 (s3+s8)/2,
+02371                                 (s5+s7)/2,
+02372                                 (s3+s7)/2,
+02373                                 (s2+s7)/2,
+02374                         };
+02375                         
+02376                         float interpolatedT[10]=
+02377                         {
+02378                                 (t0+t6)/2,
+02379                                 (t4+t6)/2,
+02380                                 (t4+t8)/2,
+02381                                 (t1+t8)/2,
+02382                                 (t5+t6)/2,
+02383                                 (t3+t6)/2,
+02384                                 (t3+t8)/2,
+02385                                 (t5+t7)/2,
+02386                                 (t3+t7)/2,
+02387                                 (t2+t7)/2,
+02388                         };
+02389 
+02390                         for (i=0; i<10; i++)
+02391                         {
+02392                                 sint s=(sint)((float)orderS*4*interpolatedS[i]);
+02393                                 sint t=(sint)((float)orderT*4*interpolatedT[i]);
+02394 
+02395                                 if ((s>=0)&&(s<(sint)orderS*4)&&(t>=0)&&(t<(sint)orderT*4))
+02396                                 {
+02397                                         // Triangle index
+02398                                         uint index=s+t*orderS*4;
+02399 
+02400                                         // Ge tthe patch id
+02401                                         uint patchId=pPatch->getPatchId();
+02402 
+02403                                         // Get lumel array
+02404                                         vector<CLumelDescriptor> &lumels=_Lumels[patchId];
+02405 
+02406                                         // Visited
+02407                                         visited[patchId][index]++;
+02408 
+02409                                         // Position
+02410                                         lumels[index].Position+=interpolatedP[i];
+02411                                 }
+02412                         }
+02413                 }
+02414         }
+02415 
+02416         // *** Now, finalise patch informations for shadow source positions
+02417 
+02418         // For each patches
+02419         uint patchCount=landscape.getZone(_ZoneToLight)->getNumPatchs();
+02420         uint patch;
+02421         for (patch=0; patch<patchCount; patch++)
+02422         {
+02423                 // Info
+02424                 progress ("Finalize lumel positions", (float)patch/(float)patchCount);
+02425 
+02426                 // *** Resize lumel array for this patch
+02427 
+02428                 // Get a patch pointer
+02429                 const CPatch* pPatch=(const_cast<const CZone*>(landscape.getZone(_ZoneToLight)))->getPatch (patch);
+02430                 uint orderS=pPatch->getOrderS();
+02431                 uint orderT=pPatch->getOrderT();
+02432 
+02433                 // Get lumel array
+02434                 vector<CLumelDescriptor> &lumels=_Lumels[patch];
+02435 
+02436                 // *** Average position
+02437 
+02438                 // Renormalize
+02439                 nlassert (isPowerOf2 (orderS));
+02440                 nlassert (isPowerOf2 (orderT));
+02441                 uint lumelS=4<<getPowerOf2 (orderS);
+02442                 uint lumelT=4<<getPowerOf2 (orderT);
+02443 
+02444                 for (uint t=0; t<lumelT; t++)
+02445                 for (uint s=0; s<lumelS; s++)
+02446                 {
+02447                         // Lumel index
+02448                         uint lumelIndex=s+t*lumelS;
+02449 
+02450                         // *** Number of visit
+02451                         uint visitedCount=visited[patch][lumelIndex];
+02452                         
+02453                         // If visited, renormalise other values
+02454                         if (visitedCount)
+02455                         {
+02456                                 // Normalise position
+02457                                 lumels[lumelIndex].Position/=(float)visitedCount;
+02458                         }
+02459 
+02460                         // Not visited for next pass
+02461                         visited[patch][lumelIndex]=false;
+02462                 }
+02463         }
+02464         
+02465         // *** Now tesselate this zone to shadow receivers accuracy
+02466 
+02467         // Setup the landscape
+02468         landscape.setThreshold (0);
+02469         landscape.setTileMaxSubdivision (4);
+02470 
+02471         // Refine all
+02472         progress ("Refine landscape to lumels", 0.5f);
+02473         landscape.refineAll (CVector (0, 0, 0));
+02474 
+02475         // Get tesselated faces
+02476         leaves.clear ();
+02477         landscape.getTessellationLeaves(leaves);
+02478 
+02479         // Scan each leaves
+02480         leavesCount=leaves.size();
+02481         for (leave=0; leave<leavesCount; leave++)
+02482         {
+02483                 // Progress bar
+02484                 if ( (leave&0xff) == 0)
+02485                         progress ("Precompute tesselation", (float)leave/(float)leavesCount);
+02486 
+02487                 // Leave
+02488                 const CTessFace *face=leaves[leave];
+02489 
+02490                 // Get zone id
+02491                 if (face->Patch->getZone()->getZoneId()==_ZoneToLight)
+02492                 {
+02493                         // Get a patch pointer
+02494                         const CPatch* pPatch=face->Patch;
+02495 
+02496                         // Get order
+02497                         uint orderS=pPatch->getOrderS();
+02498                         uint orderT=pPatch->getOrderT();
+02499 
+02500                         // Coordinates
+02501                         float fS=(face->PVBase.getS()+face->PVLeft.getS()+face->PVRight.getS())/3.f;
+02502                         float fT=(face->PVBase.getT()+face->PVLeft.getT()+face->PVRight.getT())/3.f;
+02503                         uint s=(uint)((float)orderS*4*fS);
+02504                         uint t=(uint)((float)orderT*4*fT);
+02505                         nlassert (s>=0);
+02506                         nlassert (s<orderS*4);
+02507                         nlassert (t>=0);
+02508                         nlassert (t<orderT*4);
+02509 
+02510                         // Triangle index
+02511                         uint index=s+t*orderS*4;
+02512 
+02513                         // Ge tthe patch id
+02514                         uint patchId=pPatch->getPatchId();
+02515 
+02516                         // Get lumel array
+02517                         vector<CLumelDescriptor> &lumels=_Lumels[patchId];
+02518 
+02519                         // Visited
+02520                         visited[patchId][index]++;
+02521 
+02522                         // Lumel s and t
+02523                         lumels[index].S+=fS;
+02524                         lumels[index].T+=fT;
+02525 
+02526                         // Normal
+02527                         CPlane plane;
+02528                         plane.make (face->VBase->EndPos, face->VLeft->EndPos, face->VRight->EndPos);
+02529                         lumels[index].Normal+=plane.getNormal();
+02530                 }
+02531         }
+02532 
+02533         // *** Now, finalise patch informations
+02534 
+02535         // For each patches
+02536         patchCount=landscape.getZone(_ZoneToLight)->getNumPatchs();
+02537         for (patch=0; patch<patchCount; patch++)
+02538         {
+02539                 // Info
+02540                 progress ("Finalize patches", (float)patch/(float)patchCount);
+02541 
+02542                 // *** Resize lumel array for this patch
+02543 
+02544                 // Get a patch pointer
+02545                 const CPatch* pPatch=(const_cast<const CZone*>(landscape.getZone(_ZoneToLight)))->getPatch (patch);
+02546                 uint orderS=pPatch->getOrderS();
+02547                 uint orderT=pPatch->getOrderT();
+02548 
+02549                 // Get lumel array
+02550                 vector<CLumelDescriptor> &lumels=_Lumels[patch];
+02551 
+02552                 // *** Compute an interpolated normal
+02553 
+02554                 // Get pointer on arries
+02555                 vector<bool> &binded=_Binded[zoneNumber][patch];
+02556                 vector<CPatchUVLocator> &locator=_Locator[zoneNumber][patch];
+02557                 vector<CPatch::CBindInfo> &bindInfo=_BindInfo[zoneNumber][patch];
+02558                 CBezierPatch &bezierPatch=_BezierPatch[zoneNumber][patch];
+02559 
+02560                 // Renormalize
+02561                 nlassert (isPowerOf2 (orderS));
+02562                 nlassert (isPowerOf2 (orderT));
+02563                 uint powerS=getPowerOf2 (orderS);
+02564                 uint powerT=getPowerOf2 (orderT);
+02565                 uint lumelS=4<<powerS;
+02566                 uint lumelT=4<<powerT;
+02567 
+02568                 // Sample edge normal
+02569                 CVector normals[NL_MAX_TILES_BY_PATCH_EDGE*NL_LUMEL_BY_TILE+1][4];
+02570                 uint sFixed[4] = { 0, 0xffffffff, lumelS-1, 0xffffffff };
+02571                 uint tFixed[4] = { 0xffffffff, lumelT-1, 0xffffffff, 0 };
+02572                 float sOri[4] = { 0, -1, (float)lumelS, -1 };
+02573                 float tOri[4] = { -1, (float)lumelT, -1, 0 };
+02574                 for (uint edge=0; edge<4; edge++)
+02575                 {
+02576                         // s and t
+02577                         uint count=(edge&1)?lumelS:lumelT;
+02578                         for (uint lumel=0; lumel<=count; lumel++)
+02579                         {
+02580                                 // Start coordinates
+02581                                 float origineS;
+02582                                 float origineT;
+02583                                 uint startS;
+02584                                 uint startT;
+02585                                 if (edge&1)
+02586                                 {
+02587                                         if (lumel==count)
+02588                                                 startS=count-1;
+02589                                         else
+02590                                                 startS=lumel;
+02591                                         startT=tFixed[edge];
+02592                                         origineS=(float)lumel;
+02593                                         origineT=tOri[edge];
+02594                                 }
+02595                                 else
+02596                                 {
+02597                                         if (lumel==count)
+02598                                                 startT=count-1;
+02599                                         else
+02600                                                 startT=lumel;
+02601                                         startS=sFixed[edge];
+02602                                         origineT=(float)lumel;
+02603                                         origineS=sOri[edge];
+02604                                 }
+02605                                 _GetNormalNormal=CVector::Null;
+02606                                 set<uint64> visitedLumels;
+02607                                 getNormal (pPatch, startS, startT, locator, bindInfo, binded, visitedLumels, 
+02608                                         startS+0.5f-origineS, startT+0.5f-origineT, 0, bezierPatch);
+02609                                 _GetNormalNormal.normalize ();
+02610                                 normals[lumel][edge]=_GetNormalNormal;
+02611                         }
+02612 
+02613                         // Smooth the corners
+02614 #define BLUR_SIZE 4
+02615                         for (uint i=1; i<BLUR_SIZE; i++)
+02616                         {
+02617                                 float value=(float)i/BLUR_SIZE;
+02618                                 value=easineasout(value);
+02619                                 normals[i][edge]=normals[0][edge]*(1-value)+normals[i][edge]*value;
+02620                                 normals[i][edge].normalize();
+02621                                 normals[count-i][edge]=normals[count][edge]*(1-value)+normals[count-i][edge]*value;
+02622                                 normals[count-i][edge].normalize();
+02623                         }
+02624                 }
+02625                 
+02626                 for (uint t=0; t<lumelT; t++)
+02627                 for (uint s=0; s<lumelS; s++)
+02628                 {
+02629                         // Lumel index
+02630                         uint lumelIndex=s+t*lumelS;
+02631 
+02632                         // *** Calc the smoothed normal
+02633                         
+02634                         // For each edge
+02635                         CVector normalS=bezierPatch.evalNormal (((float)s+0.5f)/(float)lumelS, ((float)t+0.5f)/(float)lumelT);
+02636                         float sFactor=0;
+02637                         CVector normalT=normalS;
+02638                         float tFactor=0;
+02639                         bool sGood=false, tGood=false;
+02640                         if (s<BLUR_SIZE)
+02641                         {
+02642                                 sGood=true;
+02643                                 // Average the two normals
+02644                                 CVector average=normals[t][0];
+02645                                 average+=normals[t+1][0];
+02646                                 average/=2;
+02647 
+02648                                 // Blend
+02649                                 float value=s+0.5f;
+02650                                 sFactor=BLUR_SIZE-value;
+02651                                 value/=BLUR_SIZE;
+02652                                 value=easineasout(value);
+02653                                 normalS=(normalS*value+average*(1-value));
+02654                                 normalS.normalize();
+02655                         }
+02656                         if (s>=lumelS-BLUR_SIZE)
+02657                         {
+02658                                 sGood=true;
+02659                                 // Average the two normals
+02660                                 CVector average=normals[t][2];
+02661                                 average+=normals[t+1][2];
+02662                                 average/=2;
+02663 
+02664                                 // Blend
+02665                                 float value=s+0.5f;
+02666                                 sFactor=BLUR_SIZE-(lumelS-value);
+02667                                 value=(lumelS-value)/BLUR_SIZE;
+02668                                 value=easineasout(value);
+02669                                 normalS=(normalS*value+average*(1-value));
+02670                                 normalS.normalize();
+02671                         }
+02672                         if (t<BLUR_SIZE)
+02673                         {
+02674                                 tGood=true;
+02675                                 // Average the two normals
+02676                                 CVector average=normals[s][3];
+02677                                 average+=normals[s+1][3];
+02678                                 average/=2;
+02679 
+02680                                 // Blend
+02681                                 float value=t+0.5f;
+02682                                 tFactor=BLUR_SIZE-value;
+02683                                 value/=BLUR_SIZE;
+02684                                 value=easineasout(value);
+02685                                 normalT=(normalT*value+average*(1-value));
+02686                                 normalT.normalize();
+02687                         }
+02688                         if (t>=lumelT-BLUR_SIZE)
+02689                         {
+02690                                 tGood=true;
+02691                                 // Average the two normals
+02692                                 CVector average=normals[s][1];
+02693                                 average+=normals[s+1][1];
+02694                                 average/=2;
+02695 
+02696                                 // Blend
+02697                                 float value=t+0.5f;
+02698                                 tFactor=BLUR_SIZE-(lumelT-value);
+02699                                 value=((lumelT)-value)/BLUR_SIZE;
+02700                                 value=easineasout(value);
+02701                                 normalT=(normalT*value+average*(1-value));
+02702                                 normalT.normalize();
+02703                         }
+02704 
+02705                         // The smooth normal
+02706                         CVector smoothNormal;
+02707 
+02708                         if ((sGood)&&(tGood))
+02709                         {
+02710                                 if ((sFactor!=BLUR_SIZE)||(tFactor!=BLUR_SIZE))
+02711                                         smoothNormal=normalS*(BLUR_SIZE-tFactor)+normalT*(BLUR_SIZE-sFactor);
+02712                                 else
+02713                                         smoothNormal=normalS+normalT;
+02714                         }
+02715                         else if (sGood)
+02716                                 smoothNormal=normalS;
+02717                         else
+02718                                 smoothNormal=normalT;
+02719 
+02720                         // Normalize it
+02721                         smoothNormal.normalize();
+02722 
+02723                         // The pure normal
+02724                         CVector purNormal=bezierPatch.evalNormal (((float)s+0.5f)/(float)lumelS, ((float)t+0.5f)/(float)lumelT);
+02725 
+02726                         // Normalize the noisy normal
+02727                         lumels[lumelIndex].Normal.normalize();
+02728 
+02729                         // Final normal
+02730                         lumels[lumelIndex].Normal=lumels[lumelIndex].Normal-purNormal+smoothNormal;
+02731                         lumels[lumelIndex].Normal.normalize ();
+02732 
+02733                         // *** Number of visit
+02734                         uint visitedCount=visited[patch][lumelIndex];
+02735                         
+02736                         // Some lumel have not been found in tesselation
+02737                         //nlassert (visitedCount==2);
+02738 
+02739                         // If visited, renormalise other values
+02740                         if (visitedCount)
+02741                         {
+02742                                 // Normalise position
+02743                                 lumels[lumelIndex].S/=(float)visitedCount;
+02744                                 lumels[lumelIndex].T/=(float)visitedCount;
+02745                         }
+02746                 }
+02747         }
+02748 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
float CZoneLighter::calcSkyContribution sint  s,
sint  t,
float  height,
float  skyIntensity,
const CVector normal
const [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 296 of file zone_lighter.cpp. +

+References NLMISC::clamp(), deltaDirection, getMaxPhi(), height, NLMISC::Pi, s, sint, t, uint, and uint8. +

+Referenced by getSkyContribution(). +

+

00297 {
+00298         // Sky contribution
+00299         float skyContribution;
+00300 
+00301         // Calc k
+00302         CVector k (0, 0, 0);
+00303 
+00304         // For the height direction
+00305         for (uint i=0; i<8; i++)
+00306         {
+00307                 // Get phi for this point
+00308                 uint8 phi=getMaxPhi (s, t, deltaDirection[i][0], deltaDirection[i][1], height);
+00309 
+00310                 // Add to k
+00311                 k+=_K[phi][i];
+00312         }
+00313 
+00314         // Finalize sky contribution
+00315         skyContribution=(float)(skyIntensity*(normal*k)/(2*Pi));
+00316         skyContribution=(float)(skyIntensity*(normal*k)/(2*Pi));
+00317         clamp (skyContribution, 0.f, 1.f);
+00318         return skyContribution;
+00319 }
+
+

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

+Fill CubeGrid, and set PointLightRT in _StaticPointLightQuadGrid. +

+ +

+Definition at line 3202 of file zone_lighter.cpp. +

+References NL3D::CQuadGrid< T >::begin(), NL3D::CZoneLighter::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::CZoneLighter::CPointLightRT::FaceCubeGrid, NL3D::CPointLight::getAttenuationEnd(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NL3D::CZoneLighter::CTriangle::getPlane(), NL3D::CPointLight::getPosition(), NL3D::CPointLight::getType(), NL3D::CCubeGrid< const CTriangle * >::insert(), NL3D::CQuadGrid< T >::insert(), NL3D::CQuadGrid< CPointLightRT * >::insert(), NLMISC::CAABBox::intersect(), NL3D_ZONE_LIGHTER_CUBE_GRID_SIZE, NL3D::CZoneLighter::CPointLightRT::PointLight, progress(), NLMISC::CBSphere::Radius, NL3D::CZoneLighter::CPointLightRT::RefCount, NL3D::CQuadGrid< T >::select(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), size, NL3D::CZoneLighter::CTriangle::Triangle, uint, NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, and NLMISC::CTriangle::V2. +

+Referenced by light(). +

+

03203 {
+03204         uint    i;
+03205 
+03206         // Fill the quadGrid of Lights.
+03207         // ===========
+03208         _StaticPointLightQuadGrid.create(gridSize, gridCellSize);
+03209         for(i=0; i<_StaticPointLights.size();i++)
+03210         {
+03211                 CPointLightRT   &plRT= _StaticPointLights[i];
+03212 
+03213                 // Compute the bbox of the light
+03214                 CAABBox         bbox;
+03215                 bbox.setCenter(plRT.BSphere.Center);
+03216                 float   hl= plRT.BSphere.Radius;
+03217                 bbox.setHalfSize(CVector(hl,hl,hl));
+03218 
+03219                 // Insert the pointLight in the quadGrid.
+03220                 _StaticPointLightQuadGrid.insert(bbox.getMin(), bbox.getMax(), &plRT);
+03221         }
+03222 
+03223 
+03224         // Append triangles to cubeGrid ??
+03225         if(doShadow)
+03226         {
+03227                 // Point lights ?
+03228                 if (!_StaticPointLights.empty ())
+03229                 {
+03230                         // For all obstacles, Fill a quadGrid.
+03231                         // ===========
+03232                         CQuadGrid<CTriangle*>   obstacleGrid;
+03233                         obstacleGrid.create(gridSize, gridCellSize);
+03234                         uint    size= obstacles.size();
+03235                         for(i=0; i<size; i++)
+03236                         {
+03237                                 // bbox of triangle
+03238                                 CAABBox bbox;
+03239                                 bbox.setCenter(obstacles[i].Triangle.V0);
+03240                                 bbox.extend(obstacles[i].Triangle.V1);
+03241                                 bbox.extend(obstacles[i].Triangle.V2);
+03242                                 // insert triangle in quadGrid.
+03243                                 obstacleGrid.insert(bbox.getMin(), bbox.getMax(), &obstacles[i]);
+03244                         }
+03245 
+03246 
+03247                         // For all PointLights, fill his CubeGrid
+03248                         // ===========
+03249                         for(i=0; i<_StaticPointLights.size();i++)
+03250                         {
+03251                                 // progress
+03252                                 progress ("Compute Influences of PointLights", 0.5f*i / (float)(_StaticPointLights.size()-1));
+03253 
+03254                                 CPointLightRT   &plRT= _StaticPointLights[i];
+03255                                 // Create the cubeGrid
+03256                                 plRT.FaceCubeGrid.create(plRT.PointLight.getPosition(), NL3D_ZONE_LIGHTER_CUBE_GRID_SIZE);
+03257 
+03258                                 // AmbiantLIghts: do nothing.
+03259                                 if(plRT.PointLight.getType()!=CPointLight::AmbientLight)
+03260                                 {
+03261                                         // Select only obstacle Faces around the light. Other are not usefull
+03262                                         CAABBox bbox;
+03263                                         bbox.setCenter(plRT.PointLight.getPosition());
+03264                                         float   hl= plRT.PointLight.getAttenuationEnd();
+03265                                         bbox.setHalfSize(CVector(hl,hl,hl));
+03266                                         obstacleGrid.select(bbox.getMin(), bbox.getMax());
+03267 
+03268                                         // For all faces, fill the cubeGrid.
+03269                                         CQuadGrid<CTriangle*>::CIterator        itObstacle;
+03270                                         itObstacle= obstacleGrid.begin();
+03271                                         while( itObstacle!=obstacleGrid.end() )
+03272                                         {
+03273                                                 CTriangle       &tri= *(*itObstacle);
+03274 
+03275                                                 // Triangle bounding box
+03276                                                 CAABBox triBbox;
+03277                                                 triBbox.setCenter (tri.Triangle.V0);
+03278                                                 triBbox.extend (tri.Triangle.V1);
+03279                                                 triBbox.extend (tri.Triangle.V2);
+03280 
+03281                                                 // Triangle in the light
+03282                                                 if (triBbox.intersect (bbox))
+03283                                                 {
+03284                                                         // Test BackFace culling. Only faces which are BackFace the point light are inserted.
+03285                                                         // This is to avoid AutoOccluding problems
+03286                                                         if( tri.getPlane() * plRT.BSphere.Center < 0)
+03287                                                         {
+03288                                                                 // Insert the triangle in the CubeGrid
+03289                                                                 plRT.FaceCubeGrid.insert( tri.Triangle, &tri);
+03290                                                         }
+03291                                                 }
+03292 
+03293                                                 itObstacle++;
+03294                                         }
+03295                                 }
+03296 
+03297                                 // Compile the CubeGrid.
+03298                                 plRT.FaceCubeGrid.compile();
+03299 
+03300                                 // And Reset RefCount.
+03301                                 plRT.RefCount= 0;
+03302                         }
+03303                 }
+03304         }
+03305         // else, just build empty grid
+03306         else
+03307         {
+03308                 for(i=0; i<_StaticPointLights.size();i++)
+03309                 {
+03310                         // progress
+03311                         progress ("Compute Influences of PointLights", 0.5f*i / (float)(_StaticPointLights.size()-1));
+03312 
+03313                         CPointLightRT   &plRT= _StaticPointLights[i];
+03314                         // Create a dummy empty cubeGrid => no rayTrace :)
+03315                         plRT.FaceCubeGrid.create(plRT.PointLight.getPosition(), 4);
+03316 
+03317                         // Compile the CubeGrid.
+03318                         plRT.FaceCubeGrid.compile();
+03319 
+03320                         // And Reset RefCount.
+03321                         plRT.RefCount= 0;
+03322                 }
+03323         }
+03324 
+03325 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CZoneLighter::computeTileFlagsForPositionTowardWater const CLightDesc lightDesc,
std::vector< const CTessFace * > &  tessFaces
[private]
+
+ + + + + +
+   + + +

+For each tile of the current zone, check wether it below or above water. The result is stored in the flags of the tile. The quadtree is removed then. +

+Definition at line 3563 of file zone_lighter.cpp. +

+References _WaterShapeQuadGrid, _ZoneToLight, NL3D::CQuadGrid< T >::begin(), NL3D::CQuadGrid< T >::clearSelection(), NLMISC::contReset(), NL3D::CQuadGrid< T >::end(), NLMISC::CAABBox::extend(), NLMISC::CAABBox::getMax(), NLMISC::CPolygon2D::intersect(), nlinfo, progress(), NL3D::CQuadGrid< T >::select(), NLMISC::CAABBox::setMinMax(), NL3D::CTileElement::setVegetableState(), TTileOfPatchMap, uint, NL3D::CZoneLighter::CLightDesc::VegetableHeight, NLMISC::CPolygon::Vertices, NLMISC::CPolygon2D::Vertices, NLMISC::CVector::x, NLMISC::CVector::y, z, and NLMISC::CVector::z. +

+Referenced by buildZoneInformation(). +

+

03566 {       
+03567         uint numTileAbove     = 0;
+03568         uint numTileBelow     = 0;
+03569         uint numTileIntersect = 0;
+03570         
+03572         TTileOfPatchMap tiles;
+03573 
+03575         //  First, build the bbox for all tiles  //
+03577 
+03578         uint triCount = 0, totalTriCount = tessFaces.size();    
+03579 
+03580         nlinfo("Dealing with %d tessFaces", tessFaces.size());
+03581         for (std::vector<const CTessFace*>::iterator it = tessFaces.begin(); it != tessFaces.end(); ++it, ++triCount)
+03582         {
+03584                 if ((*it)->Patch->getZone()->getZoneId() != _ZoneToLight) continue;
+03586                 if ((*it)->Patch->Tiles[(*it)->TileId].getVegetableState() == CTileElement::VegetableDisabled)
+03587                         continue;
+03588 
+03589                 CTileOfPatch top((*it)->TileId, (*it)->Patch);
+03590                 TTileOfPatchMap::iterator tileIt = tiles.find(top);
+03591 
+03593                 if (tileIt == tiles.end()) // first time ?
+03594                 {
+03596                         NLMISC::CAABBox b;
+03597                         b.setMinMax((*it)->VBase->EndPos, (*it)->VLeft->EndPos);
+03598                         b.extend((*it)->VRight->EndPos);
+03599                         b.extend(b.getMax() + lightDesc.VegetableHeight * NLMISC::CVector::K); // adds vegetable height                 
+03600                         tiles[top] = b;
+03601                 }
+03602                 else // extends the bbox with the given face
+03603                 {
+03604                         NLMISC::CAABBox &b = tileIt->second;                    
+03605                         b.extend((*it)->VBase->EndPos);
+03606                         b.extend((*it)->VRight->EndPos);
+03607                         b.extend((*it)->VLeft->EndPos);
+03608                 }
+03609 
+03610                 if ((triCount % 100) == 0)
+03611                 {
+03612                         progress("Building bbox from tiles", (float) triCount / totalTriCount);
+03613                 }
+03614         }
+03615 
+03616         progress("Building bbox from tiles", 1.f);
+03617 
+03618 
+03619 
+03621         // Now, check each tile bbox against water shapes //
+03623         NLMISC::CPolygon   waterPoly;
+03624         NLMISC::CPolygon2D tilePoly;
+03625         tilePoly.Vertices.resize(4);
+03626 
+03627         uint tileCount = 0, totalTileCount = tiles.size();      
+03628 
+03629         for (TTileOfPatchMap::iterator tileIt = tiles.begin(); tileIt != tiles.end(); ++tileIt, ++tileCount)
+03630         {
+03631                 const NLMISC::CVector v0 = tileIt->second.getMin();
+03632                 const NLMISC::CVector v1 = tileIt->second.getMax();
+03633 
+03635                 tilePoly.Vertices[0].set(v0.x, v0.y); 
+03636                 tilePoly.Vertices[1].set(v1.x, v0.y); 
+03637                 tilePoly.Vertices[2].set(v1.x, v1.y); 
+03638                 tilePoly.Vertices[3].set(v0.x, v1.y); 
+03639 
+03641                 _WaterShapeQuadGrid.clearSelection();
+03642                 _WaterShapeQuadGrid.select(tileIt->second.getMin(), tileIt->second.getMax());
+03643 
+03644                 CTileElement &te = tileIt->first.Patch->Tiles[tileIt->first.TileId]; // alias to the current tile element
+03645 
+03647                 TWaterShapeQuadGrid::CIterator qgIt;
+03648                 for (qgIt = _WaterShapeQuadGrid.begin(); qgIt != _WaterShapeQuadGrid.end(); ++qgIt)
+03649                 {
+03650                         
+03651                         (*qgIt)->getShapeInWorldSpace(waterPoly);
+03652                         NLMISC::CPolygon2D poly(waterPoly);
+03653                         if (poly.intersect(tilePoly)) // above or below a water surface ?               
+03654                         {
+03656                                 float waterHeight = waterPoly.Vertices[0].z;
+03657 
+03658                                 if (v1.z < waterHeight)
+03659                                 {
+03660                                         // below
+03661                                         te.setVegetableState(CTileElement::UnderWater);
+03662                                         //nlassert(te.getVegetableState() == CTileElement::UnderWater);
+03663                                         ++ numTileBelow;
+03664                                 }
+03665                                 else if (v0. z > waterHeight)
+03666                                 {
+03667                                         // above
+03668                                         te.setVegetableState(CTileElement::AboveWater);
+03669                                         //nlassert(te.getVegetableState() == CTileElement::AboveWater);
+03670                                         ++ numTileAbove;
+03671                                 }
+03672                                 else
+03673                                 {
+03674                                         // intersect water
+03675                                         te.setVegetableState(CTileElement::IntersectWater);
+03676                                         //nlassert(te.getVegetableState() == CTileElement::IntersectWater);
+03677                                         ++ numTileIntersect;
+03678                                 }
+03679                                 break;
+03680                         }
+03681                 }
+03682 
+03683                 if (qgIt == _WaterShapeQuadGrid.end()) // no intersection found ? if yes it's above water
+03684                 {
+03685                         te.setVegetableState(CTileElement::AboveWater); 
+03686                         //nlassert(te.getVegetableState() == CTileElement::AboveWater);
+03687                         ++ numTileAbove;
+03688                 }
+03689 
+03690                 if ((tileCount % 50) == 0)
+03691                 {
+03692                         progress("Computing tile position towards water", (float) tileCount / totalTileCount);
+03693                 }
+03694         }
+03695 
+03696         progress("Computing tile position towards water", 1.f);
+03697 
+03698         nlinfo(" %d tiles are above water.", numTileAbove);
+03699         nlinfo(" %d tiles are below water.", numTileBelow);
+03700         nlinfo(" %d tiles intersect water.", numTileIntersect);
+03701 
+03702 
+03703 
+03705         NLMISC::contReset(_WaterShapeQuadGrid);
+03706 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CZoneLighter::copyTileFlags CZone destZone,
const CZone srcZone
[static, private]
+
+ + + + + +
+   + + +

+This copy the flags of the tiles from the source zone to a dest zone (result of the lighting). This is needed beacuse these flags are updated to say wether a given tile is above / below water IMPORTANT : the source and destination zones must match of course... +

+Definition at line 1261 of file zone_lighter.cpp. +

+References NL3D::CZone::copyTilesFlags(), NL3D::CZone::getNumPatchs(), NL3D::CZone::getPatch(), NL3D::CZone::getZoneId(), nlassert, and sint. +

+Referenced by light(). +

+

01262 {
+01263         nlassert(destZone.getZoneId() == srcZone.getZoneId());
+01264         for (sint k = 0; k < srcZone.getNumPatchs(); ++k)
+01265         {
+01266                 destZone.copyTilesFlags(k, srcZone.getPatch(k));
+01267         }
+01268 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::excludeAllPatchFromRefineAll CLandscape landscape,
std::vector< uint > &  listZone,
bool  exclude
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1985 of file zone_lighter.cpp. +

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

+Referenced by addTriangles(). +

+

01986 {
+01987         // For each zone
+01988         for (uint zone=0; zone<listZone.size(); zone++)
+01989         {
+01990                 // Get num patches
+01991                 uint patchCount=landscape.getZone(listZone[zone])->getNumPatchs();
+01992 
+01993                 // For each patches
+01994                 for (uint patch=0; patch<patchCount; patch++)
+01995                 {
+01996                         // Exclude all the patches from refine all
+01997                         landscape.excludePatchFromRefineAll (listZone[zone], patch, exclude);
+01998                 }
+01999         }
+02000 }
+
+

+ + + + +
+ + + + + + + + + + +
uint CZoneLighter::getAPatch uint  process  )  [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 3726 of file zone_lighter.cpp. +

+References _LastPatchComputed, _NumberOfPatchComputed, _PatchComputed, _PatchInfo, index, and uint. +

+Referenced by processCalc(). +

+

03727 {
+03728         // Accessor
+03729         CSynchronized<std::vector<bool> >::CAccessor access (&_PatchComputed);
+03730 
+03731         // Current index
+03732         uint index = _LastPatchComputed[process];
+03733         uint firstIndex = index;
+03734 
+03735         if (access.value().size() == 0)
+03736                 // no more patches
+03737                 return 0xffffffff;
+03738 
+03739         while (access.value()[index])
+03740         {
+03741                 // Next patch
+03742                 index++;
+03743 
+03744                 // Last patch ?
+03745                 if (index == _PatchInfo.size())
+03746                         index = 0;
+03747 
+03748                 // First ?
+03749                 if (firstIndex == index)
+03750                         // no more patches
+03751                         return 0xffffffff;
+03752         }
+03753 
+03754         // Visited
+03755         access.value()[index] = true;
+03756 
+03757         // Last index
+03758         _LastPatchComputed[process] = index;
+03759         _NumberOfPatchComputed++;
+03760 
+03761         // Return the index
+03762         return index;
+03763 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint8 CZoneLighter::getMaxPhi sint  s,
sint  t,
sint  deltaS,
sint  deltaT,
float  heightPos
const [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1390 of file zone_lighter.cpp. +

+References _HeightFieldCellCount, _HeightfieldCellSize, NLMISC::clamp(), height, nlassert, NLMISC::Pi, res, s, sint, t, and uint8. +

+Referenced by calcSkyContribution(). +

+

01391 {
+01392         // Start position
+01393         s+=deltaS;
+01394         t+=deltaT;
+01395 
+01396         // Distance increment
+01397         float stepDistance=CVector (deltaS*_HeightfieldCellSize, deltaT*_HeightfieldCellSize,0).norm ();
+01398 
+01399         // Current distance
+01400         float distance=stepDistance;
+01401 
+01402         // Max height
+01403         float maxHeight=0;
+01404         float maxTanTeta=0;
+01405 
+01406         // For all the line
+01407         while ((s<_HeightFieldCellCount)&&(t<_HeightFieldCellCount)&&(s>=0)&&(t>=0))
+01408         {
+01409                 // Get height
+01410                 float height=_HeightField[s+t*_HeightFieldCellCount];
+01411                 height-=heightPos;
+01412 
+01413                 // Better ?
+01414                 if (height>maxHeight)
+01415                 {
+01416                         // Calc sin teta
+01417                         float tanTeta=height/distance;
+01418                         nlassert (tanTeta>=0);
+01419 
+01420                         // Better ?
+01421                         if (tanTeta>maxTanTeta)
+01422                         {
+01423                                 // New max height
+01424                                 maxHeight=height;
+01425                                 maxTanTeta=tanTeta;
+01426                         }
+01427                 }
+01428                 s+=deltaS;
+01429                 t+=deltaT;
+01430                 distance+=stepDistance;
+01431         }
+01432 
+01433         // return phi
+01434         float teta=(float)atan (maxTanTeta);
+01435         nlassert (teta>=0);
+01436         nlassert (teta<=Pi/2);
+01437         clamp (teta, 0.f, (float)Pi/2);
+01438         sint res=(sint)((Pi/2-teta)*256/(Pi/2));
+01439         clamp (res, 0, 255);
+01440         return (uint8)res;
+01441 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::getNormal const NL3D::CPatch pPatch,
sint16  lumelS,
sint16  lumelT,
std::vector< NL3D::CPatchUVLocator > &  locator,
const std::vector< NL3D::CPatch::CBindInfo > &  bindInfo,
const std::vector< bool > &  binded,
std::set< uint64 > &  visited,
float  deltaS,
float  deltaT,
uint  rotation,
const NL3D::CBezierPatch bezierPatch,
uint  lastEdge = 5
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1506 of file zone_lighter.cpp. +

+References _BezierPatch, _Binded, _BindInfo, _GetNormalDeltaS, _GetNormalDeltaT, _GetNormalNormal, _Locator, _ZoneId, NL3D::CBezierPatch::evalNormal(), NL3D::CPatch::getOrderS(), NL3D::CPatch::getOrderT(), NL3D::CPatch::getPatchId(), NL3D::CPatch::getSmoothFlag(), NL3D::CPatch::getZone(), NL3D::CZone::getZoneId(), nlassert, sint, sint16, uint, uint16, uint64, NLMISC::CVector2f::x, and NLMISC::CVector2f::y. +

+Referenced by buildZoneInformation(). +

+

01509 {
+01510         // Build a desc srructure
+01511         uint64 id=(uint64)lumelS|(((uint64)lumelT)<<16)|(((uint64)pPatch->getPatchId())<<32)|(((uint64)pPatch->getZone()->getZoneId())<<48);
+01512 
+01513         // Insert it
+01514         if (visited.insert (id).second)
+01515         {
+01516                 // Clip
+01517                 float sqDist=deltaS*deltaS+deltaT*deltaT;
+01518                 if ( sqDist < 1 )
+01519                 {
+01520                         // Continue...
+01521 
+01522                         sint orderSx4=pPatch->getOrderS()<<2;
+01523                         sint orderTx4=pPatch->getOrderT()<<2;
+01524 
+01525                         sint16 _GetNormalBorderS[4]={ 0, -10, 1, -10 };
+01526                         sint16 _GetNormalBorderT[4]={ -10, 1, -10, 0 };
+01527                         _GetNormalBorderS[2]=orderSx4-1;
+01528                         _GetNormalBorderT[1]=orderTx4-1;
+01529 
+01530                         // Add normal
+01531                         _GetNormalNormal+=bezierPatch.evalNormal ( ((float)lumelS+0.5f)/(float)orderSx4, ((float)lumelT+0.5f)/(float)orderTx4 );
+01532 
+01533                         // For the four neighbors
+01534                         for (uint edge=0; edge<4; edge++)
+01535                         {
+01536                                 // Not last edge ?
+01537                                 if (edge!=lastEdge)
+01538                                 {
+01539                                         // Direction
+01540                                         uint globalDirection=(edge+(4-rotation))&0x3;
+01541 
+01542                                         // Neighbor
+01543                                         if ( (lumelS==_GetNormalBorderS[edge]) || (lumelT==_GetNormalBorderT[edge]) )
+01544                                         {
+01545                                                 // Binded ?
+01546                                                 bool bind=binded[edge];
+01547                                                 bool smooth=pPatch->getSmoothFlag (edge);
+01548                                                 if (bind&&smooth)
+01549                                                 {
+01550                                                         // Lumel coord
+01551                                                         CVector2f lumelCoord ( ((float)(lumelS+_GetNormalDeltaS[edge])+0.5f)/4, 
+01552                                                                 ((float)(lumelT+_GetNormalDeltaT[edge])+0.5f)/4 );
+01553 
+01554                                                         // Get neighbor pixel
+01555                                                         uint otherPatch=locator[edge].selectPatch(lumelCoord);
+01556 
+01557                                                         // Get uv
+01558                                                         CVector2f neighborUV;
+01559                                                         CPatch *patchOut;
+01560                                                         locator[edge].locateUV (lumelCoord, otherPatch, patchOut, neighborUV);
+01561 
+01562                                                         // New coordinates
+01563                                                         sint16 newLumelS=(sint16)(4.f*neighborUV.x);
+01564                                                         sint16 newLumelT=(sint16)(4.f*neighborUV.y);
+01565 
+01566                                                         // Zone id
+01567                                                         uint16 patchId=patchOut->getPatchId();
+01568                                                         uint16 zoneId=_ZoneId[patchOut->getZone()->getZoneId ()];
+01569 
+01570                                                         // Get edge
+01571                                                         uint newEdge=0;
+01572                                                         uint i;
+01573                                                         for (i=0; i<=(uint)bindInfo[edge].NPatchs; i++)
+01574                                                         {
+01575                                                                 // Good patch ?
+01576                                                                 if (bindInfo[edge].Next[i]==patchOut)
+01577                                                                 {
+01578                                                                         // Get its edge
+01579                                                                         newEdge=bindInfo[edge].Edge[i];
+01580                                                                         break;
+01581                                                                 }
+01582                                                         }
+01583                                                         
+01584                                                         // Rotation 
+01585                                                         uint newRotation=(2-edge+rotation+newEdge)&0x3;
+01586 
+01587                                                         // Must found it
+01588                                                         nlassert (i!=(uint)bindInfo[edge].NPatchs);
+01589 
+01590                                                         // Get the bezier patch
+01591                                                         CBezierPatch &NewBezierPatch=_BezierPatch[zoneId][patchId];
+01592 
+01593                                                         // Next lumel
+01594                                                         getNormal (patchOut, newLumelS, newLumelT, _Locator[zoneId][patchId], _BindInfo[zoneId][patchId], 
+01595                                                                 _Binded[zoneId][patchId], visited, deltaS+_GetNormalDeltaS[globalDirection], 
+01596                                                                 deltaT+_GetNormalDeltaT[globalDirection], newRotation, NewBezierPatch, newEdge);
+01597                                                 }
+01598                                         }
+01599                                         else
+01600                                         {
+01601                                                 // Left internal
+01602                                                 getNormal (pPatch, lumelS+_GetNormalDeltaS[edge], lumelT+_GetNormalDeltaT[edge], locator, bindInfo, binded, visited, 
+01603                                                         deltaS+_GetNormalDeltaS[globalDirection], deltaT+_GetNormalDeltaT[globalDirection], rotation, bezierPatch, (edge+2)&0x3);
+01604                                         }
+01605                                 }
+01606                         }
+01607                 }
+01608         }
+01609 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CZoneLighter::getPatchNormalAndPositions std::vector< CLumelDescriptor > &  lumels,
CLandscape landscape,
uint  zoneToLight,
uint  patch,
CPatchUVLocator locator,
bool *  binded
[private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
float CZoneLighter::getSkyContribution const CVector pos,
const CVector normal,
float  SkyIntensity
const [private]
+
+ + + + + +
+   + + +

+compute the sky contribution at the given position +

+ +

+Definition at line 1271 of file zone_lighter.cpp. +

+References _HeightfieldCellSize, _OrigineHeightField, calcSkyContribution(), s, sint, t, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z. +

+Referenced by lightWater(), and processCalc(). +

+

01272 {       
+01273         float s=(pos.x-_OrigineHeightField.x)/_HeightfieldCellSize;
+01274         float t=(pos.y-_OrigineHeightField.y)/_HeightfieldCellSize;
+01275         sint sInt=(sint)(floor (s+0.5f));
+01276         sint tInt=(sint)(floor (t+0.5f));
+01277 
+01278         // Bilinear
+01279         float skyContributionTab[2][2];
+01280         skyContributionTab[0][0] = calcSkyContribution (sInt-1, tInt-1, pos.z, skyIntensity, normal);
+01281         skyContributionTab[1][0] = calcSkyContribution (sInt, tInt-1, pos.z, skyIntensity, normal);
+01282         skyContributionTab[1][1] = calcSkyContribution (sInt, tInt, pos.z, skyIntensity, normal);
+01283         skyContributionTab[0][1] = calcSkyContribution (sInt-1, tInt, pos.z, skyIntensity, normal);
+01284         
+01285         float sFact=s+0.5f-sInt;
+01286         float tFact=t+0.5f-tInt;
+01287         return (skyContributionTab[0][0]*(1.f-sFact) + skyContributionTab[1][0]*sFact)*(1.f-tFact) +
+01288                 (skyContributionTab[0][1]*(1.f-sFact) + skyContributionTab[1][1]*sFact)*tFact;  
+01289 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool CZoneLighter::getTexture const CMaterial material,
NLMISC::CBitmap *&  result,
bool &  clampU,
bool &  clampV,
uint8 alphaTestThreshold,
bool &  doubleSided
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1820 of file zone_lighter.cpp. +

+References _Bitmaps, NLMISC::clamp(), NLMISC::CBitmap::convertToType(), NL3D::ITexture::generate(), NL3D::CMaterial::getAlphaTest(), NL3D::CMaterial::getAlphaTestThreshold(), NL3D::CMaterial::getBlend(), NL3D::CMaterial::getDoubleSided(), NL3D::ITexture::getShareName(), NL3D::CMaterial::getTexture(), NL3D::ITexture::getWrapS(), NL3D::ITexture::getWrapT(), NL3D::ITexture::release(), NL3D::ITexture::supportSharing(), and uint8. +

+Referenced by addTriangles(). +

+

01821 {
+01822         // Texture informations, not NULL only if texture is used for alpha test
+01823         result = NULL;
+01824         clampU = false;
+01825         clampV = false;
+01826 
+01827         // Alpha test threashold
+01828         float alphaTestThresholdF = material.getAlphaTestThreshold () * 255;
+01829         clamp (alphaTestThresholdF, 0.f, 255.f);
+01830         alphaTestThreshold = (uint8)alphaTestThresholdF;
+01831 
+01832         // Drawable material ?
+01833         if (material.getBlend ())
+01834                 return false;
+01835 
+01836         // Use alpha test ?
+01837         if (material.getAlphaTest ())
+01838         {
+01839                 // Get the texture
+01840                 ITexture *texture = material.getTexture (0);
+01841 
+01842                 // Is texture shared ?
+01843                 if (texture && texture->supportSharing ())
+01844                 {
+01845                         // Share name
+01846                         string name = texture->getShareName();
+01847 
+01848                         // Texture exist ?
+01849                         std::map<string, NLMISC::CBitmap>::iterator ite = _Bitmaps.find (name);
+01850                         if (ite != _Bitmaps.end ())
+01851                         {
+01852                                 // Yes
+01853                                 result = &(ite->second);
+01854                         }
+01855                         else
+01856                         {
+01857                                 // No, add it
+01858                                 ite = _Bitmaps.insert (std::map<string, NLMISC::CBitmap>::value_type (name, CBitmap())).first;
+01859                                 result = &(ite->second);
+01860 
+01861                                 // Generate the texture
+01862                                 texture->generate ();
+01863 
+01864                                 // Convert to RGBA
+01865                                 texture->convertToType (CBitmap::RGBA);
+01866 
+01867                                 // Copy it
+01868                                 *result = *texture;
+01869 
+01870                                 // Release the texture
+01871                                 texture->release ();
+01872                         }
+01873 
+01874                         // Wrap flags
+01875                         clampU = texture->getWrapS () == ITexture::Clamp;
+01876                         clampV = texture->getWrapT () == ITexture::Clamp;
+01877                 }
+01878         }
+01879 
+01880         // Get double sided flag
+01881         doubleSided = material.getDoubleSided ();
+01882         return true;
+01883 }
+
+

+ + + + +
+ + + + + + + + + +
void CZoneLighter::init  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 251 of file zone_lighter.cpp. +

+References _Bitmaps, _ZBufferOverflow, NLMISC::Pi, NLMISC::CVector::set(), and uint. +

+

00252 {
+00253         // Precalc some values
+00254         for (uint i=0; i<8; i++)
+00255         {
+00256                 // Precalc sinP and cosP
+00257                 float sinP=(float)(sin((Pi/4)*(i+0.5))-sin((Pi/4)*(i-0.5)));
+00258                 float cosP=(float)(cos((Pi/4)*(i-0.5))-cos((Pi/4)*(i+0.5)));
+00259 
+00260                 for (uint phi=0; phi<256; phi++)
+00261                 {
+00262                         // Real phi
+00263                         float fPhi=(float)((Pi/2)*phi/256.0);
+00264 
+00265                         // Tmp result
+00266                         float tmp0=(float)(fPhi-sin(2*fPhi)/2);
+00267                         float tmp1=(float)sin(fPhi);
+00268 
+00269                         // Calc K
+00270                         _K[phi][i].set (tmp0*sinP, tmp0*cosP, (float)((Pi/4)*tmp1*tmp1));
+00271                 }
+00272         }
+00273 
+00274         // Init some containers
+00275         _ZBufferOverflow = false;
+00276         _Bitmaps.clear ();
+00277 }
+
+

+ + + + +
+ + + + + + + + + + +
bool CZoneLighter::isLightableShape IShape shape  )  [static]
+
+ + + + + +
+   + + +

+check wether a shape is lightable. +

+for now, the only shape that we lit are water shapes +

+Definition at line 2783 of file zone_lighter.cpp. +

+References NL3D::CWaterShape::getColorMap(), and NL3D::CWaterShape::isLightMappingEnabled(). +

+Referenced by processLightableShapeCalc(). +

+

02784 {
+02786         if (dynamic_cast<CWaterShape *>(&shape) != NULL)
+02787         {
+02788                 // check that this water surface has a diffuse map that is a CTextureFile (we must be able to save it !)
+02789                 CWaterShape *ws = static_cast<CWaterShape *>(&shape);
+02790                 const ITexture *tex = ws->getColorMap();
+02791                 if (dynamic_cast<const CTextureFile *>(tex) != NULL)
+02792                 {
+02793                         return ws->isLightMappingEnabled();
+02794                 }
+02795         }
+02796         return false;
+02797 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool CZoneLighter::isLumelOnEdgeMustBeOversample uint  patch,
uint  edge,
sint  s,
sint  t,
const std::vector< bool > &  binded,
const std::vector< bool > &  oversampleEdges,
std::vector< CPatchUVLocator > &  locator,
uint8  shadowed,
std::vector< std::vector< uint8 > > &  shadowBuffer
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1451 of file zone_lighter.cpp. +

+References _GetNormalDeltaS, _GetNormalDeltaT, NL3D::CPatch::getOrderS(), NL3D::CPatch::getPatchId(), s, sint, t, uint, uint8, NLMISC::CVector2f::x, and NLMISC::CVector2f::y. +

+

01454 {
+01455         // Must force oversampling of this edge ?
+01456         if (oversampleEdges[edge])
+01457                 return true;
+01458         else
+01459         {
+01460                 // binded ?
+01461                 if (binded[edge])
+01462                 {
+01463                         // Lumel coord
+01464                         CVector2f lumelCoord (((float)(s+_GetNormalDeltaS[edge])+0.5f)/4.f, ((float)(t+_GetNormalDeltaT[edge])+0.5f)/4.f);
+01465                         uint otherPatch=locator[edge].selectPatch(lumelCoord);
+01466 
+01467                         // Get uv
+01468                         CVector2f neighborUV;
+01469                         CPatch *patchOut;
+01470                         locator[edge].locateUV (lumelCoord, otherPatch, patchOut, neighborUV);
+01471                         
+01472                         // Is the same shadowed flag ?
+01473                         sint ss=(sint)(neighborUV.x*4.f);
+01474                         sint tt=(sint)(neighborUV.y*4.f);
+01475                         return (shadowBuffer[patchOut->getPatchId()][ss+(patchOut->getOrderS()<<2)*tt]!=shadowed);
+01476                 }
+01477                 else
+01478                 {
+01479                         // Not oversample if not binded
+01480                         return false;
+01481                 }
+01482         }
+01483 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::light CLandscape landscape,
CZone output,
uint  zoneToLight,
const CLightDesc description,
std::vector< CTriangle > &  obstacles,
std::vector< uint > &  listZone
+
+ + + + + +
+   + + +

+copy the tiles flags from the zone to light to the output zone

+Perform lightning of some ig's of the current zone (if any) +

+Definition at line 920 of file zone_lighter.cpp. +

+References _BorderVertices, _CPUMask, _HeightFieldCellCount, _HeightfieldCellSize, _LastPatchComputed, _NumberOfPatchComputed, _OrigineHeightField, _PatchComputed, _PatchInfo, NL3D::CZoneLighter::CTriangle::_Plane, _ProcessCount, _ProcessExited, _RayBasis, _ShadowArray, _ZBufferLandscape, _ZBufferObject, _ZBufferOverflow, _ZoneToLight, NL3D::CZoneInfo::BorderVertices, NL3D::CZone::build(), buildZoneInformation(), compilePointLightRT(), copyTileFlags(), FilterZBuffer(), NL3D::CZoneLighter::CTriangle::Flags, NLMISC::CAABBoxExt::getCenter(), NLMISC::IProcess::getCPUMask(), NLMISC::IThread::getCPUMask(), NLMISC::CMatrix::getI(), NLMISC::CMatrix::getJ(), NL3D::CZone::getZoneBB(), NL3D::CZoneLighter::CLightDesc::GridCellSize, NL3D::CZoneLighter::CLightDesc::GridSize, NL3D::CZoneLighter::CLightDesc::HeightfieldCellSize, NL3D::CZoneLighter::CLightDesc::HeightfieldSize, InitZBuffer(), NLMISC::CMatrix::invert(), lightShapes(), NL3D::CZoneLighter::CZBuffer::LocalZBufferHeight, NL3D::CZoneLighter::CZBuffer::LocalZBufferWidth, NLMISC::CPlane::make(), MAX_CPU_PROCESS, NLMISC::CVector::maxof(), min, NLMISC::CVector::minof(), NL3D::NEL3DCalcBase(), nlassert, NLMISC::nlSleep(), nlwarning, NL3D::CZoneLighter::CLightDesc::NumCPU, NL3D::CZoneInfo::Patchs, NL3D::CZoneInfo::PointLights, processZonePointLightRT(), progress(), NL3D::CZone::retrieve(), NLMISC::IThread::setCPUMask(), NL3D::CZoneLighter::CLightDesc::Shadow, sint, size, NL3D::CZoneLighter::CLightDesc::SoftShadowSamplesSqrt, NLMISC::IThread::start(), NL3D::CZoneLighter::CLightDesc::SunCenter, NL3D::CZoneLighter::CLightDesc::SunDirection, NL3D::CZoneLighter::CLightDesc::SunDistance, NL3D::CZoneLighter::CLightDesc::SunRadius, NL3D::CLightRunnable::Thread, NL3D::CRenderZBuffer::Thread, NLMISC::toString(), NL3D::CZoneLighter::CTriangle::Triangle, uint, uint64, NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, x, NLMISC::CVector::x, y, NLMISC::CVector::y, NLMISC::CVector::z, NL3D::CZoneLighter::CLightDesc::ZBufferLandscapeSize, NL3D::CZoneLighter::CLightDesc::ZBufferObjectSize, and NL3D::CZoneInfo::ZoneId. +

+

00921 {
+00922         /*
+00923          * Lighting algorithm
+00924          * ------------------
+00925          *
+00926          * - Create a quad grid to store shadow casting triangles
+00927          * - Create a heightfield used for global illumination. Cells are initialized with -FLT_MAX
+00928          * - Insert each shadow casting triangles in the quad grid and fill the heightfield's cells overlapped by the bounding box of the triangle with
+00929          * the max height of the triangle if its height is > than the current height in the heightfield's cell.
+00930          * - 
+00931          */
+00932 
+00933         // Backup thread mask
+00934         IThread *currentThread = IThread::getCurrentThread ();
+00935         uint64 threadMask = currentThread->getCPUMask();
+00936         currentThread->setCPUMask (1);
+00937 
+00938         // Calc the ray basis
+00939         _SunDirection=description.SunDirection;
+00940         NEL3DCalcBase (_SunDirection, _RayBasis);
+00941 
+00942         // Zone to light
+00943         _ZoneToLight=zoneToLight;
+00944 
+00945         // Landscape 
+00946         _Landscape=&landscape;
+00947 
+00948         // Process count
+00949         _ProcessCount=description.NumCPU;
+00950         if (_ProcessCount==0)
+00951         {
+00952                 // Create a doomy thread
+00953                 IProcess *pProcess=IProcess::getCurrentProcess ();
+00954                 _CPUMask = pProcess->getCPUMask();
+00955                 _ProcessCount = 0;
+00956                 uint64 i;
+00957                 for (i=0; i<64; i++)
+00958                 {
+00959                         if (_CPUMask&((uint64)1<<i))
+00960                                 _ProcessCount++;
+00961                 }
+00962         }
+00963         if (_ProcessCount>MAX_CPU_PROCESS)
+00964                 _ProcessCount=MAX_CPU_PROCESS;
+00965 
+00966         // Number of obstacle polygones
+00967         printf ("Obstacle polygones : %d\n", obstacles.size ());
+00968 
+00969         // Number of CPUS used
+00970         printf ("Number of CPU used: %d\n", _ProcessCount);
+00971 
+00972         // Zone pointer
+00973         CZone *pZone=landscape.getZone (_ZoneToLight);
+00974         if (pZone)
+00975         {
+00976                 // *** Compute center of the object
+00977 
+00978                 // Get the zone bounding box
+00979                 const CAABBoxExt &zoneBB=pZone->getZoneBB();
+00980 
+00981                 // Get the center
+00982                 CVector center = zoneBB.getCenter ();
+00983 
+00984                 // *** Compute planes
+00985                 const uint size=obstacles.size();
+00986                 uint triangleId;
+00987                 for (triangleId=0; triangleId<size; triangleId++)
+00988                 {
+00989                         // Triangle ref
+00990                         CZoneLighter::CTriangle& triangle=obstacles[triangleId];
+00991 
+00992                         // Calc the plane
+00993                         triangle._Plane.make (triangle.Triangle.V0, triangle.Triangle.V1, triangle.Triangle.V2);
+00994                 }
+00995 
+00996                 // Create landscape zbuffers
+00997                 _ZBufferLandscape.resize (description.SoftShadowSamplesSqrt*description.SoftShadowSamplesSqrt);
+00998 
+00999                 uint sampleX;
+01000                 uint sampleY;
+01001                 for (sampleY=0; sampleY<description.SoftShadowSamplesSqrt; sampleY++)
+01002                 for (sampleX=0; sampleX<description.SoftShadowSamplesSqrt; sampleX++)
+01003                 {
+01004                         // *** Render the light zbuffer
+01005                         CZBuffer &zbuffer = _ZBufferLandscape[sampleX + sampleY*description.SoftShadowSamplesSqrt];
+01006 
+01007                         // Delta pos for area light
+01008                         float deltaX = ( (float)sampleX + 0.5f  - (float)description.SoftShadowSamplesSqrt / 2.f) / (float)description.SoftShadowSamplesSqrt;
+01009                         float deltaY = ( (float)sampleY + 0.5f  - (float)description.SoftShadowSamplesSqrt / 2.f) / (float)description.SoftShadowSamplesSqrt;
+01010                         CVector lightPos = _RayBasis.getI () * ((float)description.SunRadius * deltaX) + _RayBasis.getJ () * ((float)description.SunRadius * deltaY);
+01011                         lightPos = description.SunCenter - (description.SunDirection * description.SunDistance) + lightPos;
+01012 
+01013                         InitZBuffer (zbuffer, lightPos, _RayBasis, zoneBB, description.ZBufferLandscapeSize, description);
+01014                         printf ("Zbuffer %d size : %d x %d\n", sampleX+sampleY*description.SoftShadowSamplesSqrt, zbuffer.LocalZBufferWidth, zbuffer.LocalZBufferHeight);
+01015                 }
+01016 
+01017 
+01018                 // *** Init the zbuffer for the vegetation
+01019                 CVector lightPos = description.SunCenter - (description.SunDirection * description.SunDistance);
+01020                 InitZBuffer (_ZBufferObject, lightPos, _RayBasis, zoneBB, description.ZBufferObjectSize, description);
+01021                 printf ("Zbuffer object size : %d x %d\n", _ZBufferObject.LocalZBufferWidth, _ZBufferObject.LocalZBufferHeight);
+01022                 
+01023                 
+01024                 // Compute the zbuffer in multi thread
+01025                 _ProcessExited = 0;
+01026 
+01027                 // Number of triangle to render per thread
+01028                 uint numTriangle = (obstacles.size () / _ProcessCount) + 1;
+01029 
+01030                 // First triangle for the thread
+01031                 uint firstTriangle = 0;
+01032 
+01033                 // Count
+01034                 _NumberOfPatchComputed = 0;
+01035 
+01036                 for (uint process=0; process<_ProcessCount; process++)
+01037                 {
+01038                         // Get list of triangles to render
+01039                         uint lastTriangle=firstTriangle+numTriangle;
+01040                         if (lastTriangle>obstacles.size ())
+01041                                 lastTriangle=obstacles.size ();
+01042 
+01043                         // Create a thread
+01044                         CRenderZBuffer *runnable = new CRenderZBuffer (process, this, &description, firstTriangle, lastTriangle - firstTriangle, &obstacles);
+01045                         IThread *pThread=IThread::create (runnable);
+01046                         runnable->Thread = pThread;
+01047                         
+01048                         // New first patch
+01049                         firstTriangle = lastTriangle;
+01050 
+01051                         // Launch
+01052                         pThread->start();
+01053                 }
+01054 
+01055                 // Wait for others processes
+01056                 while (_ProcessExited!=_ProcessCount)
+01057                 {
+01058                         nlSleep (1000);
+01059 
+01060                         // Call the progress callback
+01061                         progress ("Render triangles", (float)_NumberOfPatchComputed/(float)obstacles.size());
+01062                 }
+01063 
+01064                 // * Save the zbuffer
+01065                 uint sample;
+01066                 const uint samples = description.SoftShadowSamplesSqrt*description.SoftShadowSamplesSqrt;
+01067 #ifdef SAVE_ZBUFFER
+01068                 for (sample=0; sample<samples; sample++)
+01069                 {
+01070                         // *** The zbuffer
+01071                         CZBuffer &zbuffer = _ZBufferLandscape[sample];
+01072 
+01073                         string zbufferFilename = SAVE_ZBUFFER"/zbuffer_landscape_" + toString (sample) + ".jpg";
+01074 
+01075                         SaveZBuffer (zbuffer, zbufferFilename.c_str ());
+01076                 }
+01077 
+01078                 // Save the object zbuffer
+01079                 SaveZBuffer (_ZBufferObject, SAVE_ZBUFFER"/zbuffer_object.jpg");
+01080 #endif // SAVE_ZBUFFER
+01081 
+01082                 // *** Filter the zbuffer
+01083                 for (sample=0; sample<samples; sample++)
+01084                 {
+01085                         // For landscape zbuffer, expand the z to neighbor
+01086                         FilterZBuffer (_ZBufferLandscape[sample], 5);
+01087                 }
+01088 
+01089                 // Change the quadGrid basis
+01090                 CMatrix invRayBasis=_RayBasis;
+01091                 invRayBasis.invert ();
+01092                 
+01093                 // Init the heightfield
+01094                 _HeightfieldCellSize=description.HeightfieldCellSize;
+01095                 _HeightFieldCellCount=(sint)(description.HeightfieldSize/_HeightfieldCellSize);
+01096                 nlassert (_HeightFieldCellCount!=0);
+01097                 _OrigineHeightField=zoneBB.getCenter ()-CVector (description.HeightfieldSize/2, description.HeightfieldSize/2, 0);
+01098                 _HeightField.resize (_HeightFieldCellCount*_HeightFieldCellCount, -FLT_MAX);
+01099 
+01100                 // Fill the quadGrid and the heightField
+01101                 for (triangleId=0; triangleId<size; triangleId++)
+01102                 {
+01103                         // Progress bar
+01104                         if ( (triangleId&0xff) == 0)
+01105                                 progress ("Build quadtree and heightfield", (float)triangleId/(float)size);
+01106 
+01107                         // Triangle ref
+01108                         CZoneLighter::CTriangle& triangle=obstacles[triangleId];
+01109 
+01110                         // Look for the min coordinate, in World Basis
+01111                         CVector minv;
+01112                         minv.minof (triangle.Triangle.V0, triangle.Triangle.V1);
+01113                         minv.minof (minv, triangle.Triangle.V2);
+01114 
+01115                         // Look for the max coordinate, in World Basis
+01116                         CVector maxv;
+01117                         maxv.maxof (triangle.Triangle.V0, triangle.Triangle.V1);
+01118                         maxv.maxof (maxv, triangle.Triangle.V2);
+01119 
+01120                         // Lanscape tri ?
+01121                         if (triangle.Flags & CTriangle::Landscape)
+01122                         {
+01123                                 // Fill the heightfield
+01124                                 sint minX=std::max (0, (sint)floor (0.5f+(minv.x-_OrigineHeightField.x)/_HeightfieldCellSize));
+01125                                 sint maxX=std::min (_HeightFieldCellCount, (sint)floor (0.5f+(maxv.x-_OrigineHeightField.x)/_HeightfieldCellSize));
+01126                                 sint minY=std::max (0, (sint)floor (0.5f+(minv.y-_OrigineHeightField.y)/_HeightfieldCellSize));
+01127                                 sint maxY=std::min (_HeightFieldCellCount, (sint)floor (0.5f+(maxv.y-_OrigineHeightField.y)/_HeightfieldCellSize));
+01128 
+01129                                 // Calc position in the heightfield
+01130                                 for (sint y=minY; y<maxY; y++)
+01131                                 for (sint x=minX; x<maxX; x++)
+01132                                 {
+01133                                         // Valid position, try to insert it
+01134                                         if (maxv.z>_HeightField[x+y*_HeightFieldCellCount])
+01135                                         {
+01136                                                 // New height in this cell
+01137                                                 _HeightField[x+y*_HeightFieldCellCount]=maxv.z;
+01138                                         }
+01139                                 }
+01140                         }
+01141                 }
+01142 
+01143                 // Retrieve the zone to fill its shaded value
+01144                 pZone->retrieve (_PatchInfo, _BorderVertices);
+01145 
+01146                 // Number of patch
+01147                 uint patchCount=_PatchInfo.size();
+01148 
+01149                 // Bit array to know if the lumel is shadowed
+01150                 if (description.Shadow)
+01151                         _ShadowArray.resize (patchCount);
+01152 
+01153                 // A lumel vector by patch
+01154                 vector<vector<CLumelDescriptor> > lumels;
+01155                 lumels.resize (patchCount);
+01156 
+01157                 // Build zone informations
+01158                 buildZoneInformation (landscape,
+01159                                                           listZone,
+01160                                                           description);
+01161 
+01162         }
+01163 
+01164         // Number of patch
+01165         uint patchCount=_PatchInfo.size();
+01166 
+01167         // Reset patch count
+01168         {
+01169                 CSynchronized<std::vector<bool> >::CAccessor access (&_PatchComputed);
+01170                 access.value().resize (0);
+01171                 access.value().resize (patchCount, false);
+01172         }
+01173 
+01174         // Patch by thread
+01175         uint patchCountByThread = patchCount/_ProcessCount;
+01176         patchCountByThread++;
+01177 
+01178         // Patch to allocate
+01179         uint firstPatch=0;
+01180         _NumberOfPatchComputed = 0;
+01181 
+01182         // Reset exited process
+01183         _ProcessExited=0;
+01184 
+01185         // Set the thread state
+01186         _LastPatchComputed.resize (_ProcessCount);
+01187 
+01188         // Launch threads
+01189         uint process;
+01190         for (process=0; process<_ProcessCount; process++)
+01191         {
+01192                 // Last patch
+01193                 uint lastPatch=firstPatch+patchCountByThread;
+01194                 if (lastPatch>patchCount)
+01195                         lastPatch=patchCount;
+01196 
+01197                 // Last patch computed
+01198                 _LastPatchComputed[process] = firstPatch;
+01199 
+01200                 // Create a thread
+01201                 CLightRunnable *runnable = new CLightRunnable (process, this, &description);
+01202                 IThread *pThread=IThread::create (runnable);
+01203                 runnable->Thread = pThread;
+01204                 
+01205                 // New first patch
+01206                 firstPatch=lastPatch;
+01207 
+01208                 // Launch
+01209                 pThread->start();
+01210         }
+01211 
+01212         // Wait for others processes
+01213         while (_ProcessExited!=_ProcessCount)
+01214         {
+01215                 nlSleep (1000);
+01216 
+01217                 // Call the progress callback
+01218                 progress ("Lighting patches", (float)_NumberOfPatchComputed/(float)_PatchInfo.size());
+01219         }
+01220 
+01221         // Reset old thread mask
+01222         currentThread->setCPUMask (threadMask);
+01223         
+01224         // overflow ?
+01225         if (_ZBufferOverflow)
+01226                 nlwarning ("Error : zbuffer overflow");
+01227 
+01228         // Progress bar
+01229         progress ("Compute Influences of PointLights", 0.f);
+01230 
+01231         // Compute PointLight influences on zone.
+01232         // Some precalc.
+01233         compilePointLightRT(description.GridSize, description.GridCellSize, obstacles, description.Shadow);
+01234         // Influence patchs and get light list of interest
+01235         std::vector<CPointLightNamed>   listPointLight;
+01236         processZonePointLightRT(listPointLight);
+01237 
+01238 
+01239         // Rebuild the zone
+01240 
+01241         // Progress bar
+01242         progress ("Compress the lightmap", 0.6f);
+01243 
+01244         // Build, with list of lights.
+01245         CZoneInfo       zinfo;
+01246         zinfo.ZoneId= _ZoneToLight;
+01247         zinfo.Patchs= _PatchInfo;
+01248         zinfo.BorderVertices= _BorderVertices;
+01249         zinfo.PointLights= listPointLight;
+01250         output.build (zinfo);
+01251 
+01253         copyTileFlags(output, *(landscape.getZone(zoneToLight)));
+01254 
+01256         lightShapes(zoneToLight, description);
+01257 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CZoneLighter::lightShapes uint  zoneID,
const CLightDesc description
[private]
+
+ + + + + +
+   + + +

+Launch a set of threads to perform lighting of lightable shapes. +

+compute light for the lightable shapes in the given zone

+wait for other process +

+Definition at line 2800 of file zone_lighter.cpp. +

+References _LightableShapes, _NumLightableShapesProcessed, _ProcessCount, _ProcessExited, CCalcLightableShapeRunnable, min, NLMISC::nlSleep(), progress(), NLMISC::IThread::start(), and uint. +

+Referenced by light(). +

+

02801 {
+02803         if (_LightableShapes.size() == 0) return;       
+02804 
+02805         uint numShapePerThread = 1 + (_LightableShapes.size() / _ProcessCount);
+02806         uint currShapeIndex = 0;
+02807         uint process = 0;
+02808         _ProcessExited = 0;
+02809 
+02810         _NumLightableShapesProcessed = 0;
+02811 
+02812 
+02813         progress("Processing lightable shapes", 0);
+02814         
+02815         for (uint k = 0; k < _LightableShapes.size(); ++k, ++process)
+02816         {
+02817                 uint lastShapeIndex = currShapeIndex + numShapePerThread;
+02818                 lastShapeIndex = std::min((uint)_LightableShapes.size(), lastShapeIndex);               
+02819                 IThread *pThread = IThread::create (new CCalcLightableShapeRunnable(process, this, &description, &_LightableShapes, currShapeIndex, lastShapeIndex));
+02820                 pThread->start();
+02821                 currShapeIndex = lastShapeIndex;
+02822         }
+02823 
+02825         while (_ProcessExited != _ProcessCount)
+02826         {
+02827                 nlSleep (10);
+02828         }
+02829 
+02830 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::lightSingleShape CShapeInfo si,
const CLightDesc description,
uint  cpu
[private]
+
+ + + + + +
+   + + +

+Compute the lighting for a single lightable shape. +

+we compute the lighting for one single shape +

+Definition at line 2852 of file zone_lighter.cpp. +

+References _LightableShapes, _NumLightableShapesProcessed, lightWater(), NL3D::CZoneLighter::CShapeInfo::MT, progress(), NL3D::CZoneLighter::CShapeInfo::Shape, and uint. +

+Referenced by processLightableShapeCalc(). +

+

02853 {
+02855         if (dynamic_cast<CWaterShape *>(si.Shape))
+02856         {
+02857                 lightWater(* static_cast<CWaterShape *>(si.Shape), si.MT, description, cpu);
+02858         }
+02859         ++_NumLightableShapesProcessed;
+02860         progress("Processing lightable shapes", (float) _NumLightableShapesProcessed / _LightableShapes.size());
+02861         return; 
+02862 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::lightWater CWaterShape ws,
const CMatrix MT,
const CLightDesc description,
uint  cpu
[private]
+
+ + + + + +
+   + + +

+Compute the lighting for a water shape. +

+get the diffuse map

+build a matrix to convert from water space to uv space

+get min and max uvs

+raytrace each texel

+now, save the result +

+Definition at line 2927 of file zone_lighter.cpp. +

+References attenuation(), NLMISC::clamp(), NLMISC::COFile::close(), NL3D::ITexture::generate(), NL3D::CWaterShape::getColorMap(), NL3D::CWaterShape::getColorMapMat(), getExt(), NL3D::CTextureFile::getFileName(), NLMISC::CBitmap::getHeight(), NLMISC::CPolygon::getNumVertices(), NLMISC::CBitmap::getPixels(), NL3D::CWaterShape::getShapeInWorldSpace(), getSkyContribution(), NLMISC::CBitmap::getWidth(), height, NLMISC::CMatrix::inverted(), min, NLMISC::CRGBA::modulateFromColor(), NL3D::CZoneLighter::CLightDesc::ModulateWaterColor, nlwarning, NLMISC::COFile::open(), NLMISC::CMatrix::setPos(), NLMISC::CMatrix::setRot(), NL3D::CZoneLighter::CLightDesc::Shadow, sint, NL3D::CZoneLighter::CLightDesc::SkyContributionForWater, NL3D::CZoneLighter::CLightDesc::SkyIntensity, NL3D::CZoneLighter::CLightDesc::SunDirection, uint, uint8, NLMISC::CPolygon::Vertices, NL3D::CZoneLighter::CLightDesc::WaterAmbient, NL3D::CZoneLighter::CLightDesc::WaterDiffuse, NL3D::CZoneLighter::CLightDesc::WaterShadowBias, width, NLMISC::CBitmap::writeTGA(), x, NLMISC::CVector::x, NLMISC::CVector2f::x, y, NLMISC::CVector::y, and NLMISC::CVector2f::y. +

+Referenced by lightSingleShape(). +

+

02928 {       
+02929         try
+02930         {       
+02932                 CTextureFile *diffuseTex = NLMISC::safe_cast<CTextureFile *>(ws.getColorMap());
+02933                 std::string texFileName = CPath::lookup(diffuseTex->getFileName());
+02934                 diffuseTex->generate();
+02935                 const uint width = diffuseTex->getWidth();
+02936                 const uint height = diffuseTex->getHeight();    
+02937                 
+02939                 NLMISC::CMatrix worldSpaceToUVs;
+02940                 NLMISC::CVector2f col0, col1, pos;
+02941                 ws.getColorMapMat(col0, col1, pos);
+02942                 worldSpaceToUVs.setRot(NLMISC::CVector(col0.x * width, col0.y * height, 0),
+02943                                                            NLMISC::CVector(col1.x * width, col1.y * height, 0),
+02944                                                            NLMISC::CVector::K);
+02945                 worldSpaceToUVs.setPos(NLMISC::CVector(pos.x * width, pos.y * height, 0));              
+02946 
+02948                 NLMISC::CPolygon p;
+02949                 ws.getShapeInWorldSpace(p);
+02950 
+02951                 float minU, maxU;
+02952                 float minV, maxV;
+02953 
+02954                 NLMISC::CVector uvs = worldSpaceToUVs * p.Vertices[0];
+02955                 minU = maxU = uvs.x;
+02956                 minV = maxV = uvs.y;
+02957 
+02958 
+02959                 for (uint k = 1; k < (uint) p.getNumVertices(); ++k)
+02960                 {
+02961                         uvs = worldSpaceToUVs * p.Vertices[k];
+02962                         minU = std::min(uvs.x, minU);
+02963                         minV = std::min(uvs.y, minV);
+02964                         maxU = std::max(uvs.x, maxU);
+02965                         maxV = std::max(uvs.y, maxV);   
+02966                 }
+02967                 
+02968                 
+02969         
+02970 
+02971                 sint iMinU = (sint) minU;
+02972                 sint iMaxU = (sint) maxU;
+02973                 sint iMinV = (sint) minV;
+02974                 sint iMaxV = (sint) maxV;
+02975 
+02976                 NLMISC::clamp(iMinU, 0, (sint) width);
+02977                 NLMISC::clamp(iMaxU, 0, (sint) width);
+02978                 NLMISC::clamp(iMinV, 0, (sint) height);
+02979                 NLMISC::clamp(iMaxV, 0, (sint) height);
+02980 
+02981                 // matrix to go from uv space to worldspace
+02982                 NLMISC::CMatrix UVSpaceToWorldSpace = worldSpaceToUVs.inverted();
+02983 
+02984                 CObjectVector<uint8> &pixs8 = diffuseTex->getPixels();
+02985                 NLMISC::CRGBA *rgbPixs = (NLMISC::CRGBA *) &pixs8[0];
+02986 
+02987         
+02989                 for (sint x = iMinU; x < iMaxU; ++x)
+02990                 {
+02991                         for (sint y = iMinV; y < iMaxV; ++y)
+02992                         {
+02993                                 float factor;
+02994                                 NLMISC::CVector pos = UVSpaceToWorldSpace * NLMISC::CVector( x + 0.5f, y + 0.5f, 0 ) 
+02995                                         + description.WaterShadowBias * NLMISC::CVector::K;
+02996                                 if (description.Shadow)
+02997                                 {
+02998                                         factor = attenuation (pos, description);
+02999                                 }
+03000                                 else
+03001                                 {
+03002                                         factor = - NLMISC::CVector::K * description.SunDirection;
+03003                                 }
+03004                                 clamp(factor, 0.f, 1.f);
+03005                                 factor = factor * description.WaterDiffuse + description.WaterAmbient;
+03006                                 if (description.SkyContributionForWater)
+03007                                 {
+03008                                         factor += getSkyContribution(pos, NLMISC::CVector::K, description.SkyIntensity);
+03009                                 }
+03010                                 clamp(factor, 0.f, 1.f);
+03011                                 uint intensity = (uint8) (255 * factor);
+03012                                 NLMISC::CRGBA srcCol(intensity,
+03013                                                                          intensity,
+03014                                                                          intensity,
+03015                                                                           255);
+03016 
+03017                                 if (!description.ModulateWaterColor)
+03018                                 {
+03019                                         rgbPixs[x + y * width] = srcCol;
+03020                                 }
+03021                                 else
+03022                                 {
+03023                                         NLMISC::CRGBA &col = rgbPixs[x + y * width];
+03024                                         col.modulateFromColor(col, srcCol);
+03025                                 }
+03026                         }
+03027                 }
+03028         
+03030                 if (getExt(texFileName) != ".tga")
+03031                 {
+03032                         nlwarning("Zone lighter : error when lighting a water surface : input bitmap is not a tga file");
+03033                 }
+03034                 else
+03035                 {
+03036                         try
+03037                         {
+03038                                 COFile of;
+03039                                 of.open(texFileName);
+03040                                 diffuseTex->writeTGA(of, 24);
+03041                                 of.close();
+03042                         }
+03043                         catch (NLMISC::Exception &)
+03044                         {
+03045                                 nlwarning("Zone lighter : while lighting a water shape, writing %s failed! ", texFileName.c_str());
+03046                         }
+03047                 }
+03048         }
+03049         catch(NLMISC::Exception &e)
+03050         {
+03051                 nlwarning("Water shape lighting failed !");
+03052                 nlwarning(e.what());
+03053         }
+03054 }
+
+

+ + + + +
+ + + + + + + + + + +
void CZoneLighter::makeQuadGridFromWaterShapes NLMISC::CAABBox  zoneBBox  )  [private]
+
+ + + + + +
+   + + +

+Make a quad grid of all the water shapes that where registered by calling addWaterShape() The vector of water shapes is released then

Parameters:
+ + +
bbox the bbox of the zone containing the water shapes
+
+ +

+Definition at line 3067 of file zone_lighter.cpp. +

+References _WaterShapeQuadGrid, NLMISC::contReset(), count, NL3D::CQuadGrid< T >::create(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), height, NL3D::CQuadGrid< T >::insert(), NLMISC::CAABBox::intersect(), progress(), NLMISC::CAABBox::transformAABBox(), uint, width, NLMISC::CVector::x, and NLMISC::CVector::y. +

+Referenced by buildZoneInformation(). +

+

03068 {
+03069         if (!_WaterShapes.size()) return;
+03070 
+03071         NLMISC::CAABBox tmpBox;
+03072 
+03074         const uint numCells = 16;
+03075 
+03077         float width  = zoneBBox.getMax().x - zoneBBox.getMin().x;
+03078         float height = zoneBBox.getMax().y - zoneBBox.getMin().y;
+03079 
+03080         float dim = std::max(width, height);
+03081 
+03082 
+03084         _WaterShapeQuadGrid.create(numCells, dim / numCells);
+03085         
+03086 
+03087         uint count = 0, totalCount = _WaterShapes.size();
+03088 
+03090         for (TShapeVect::iterator it = _WaterShapes.begin(); it != _WaterShapes.end(); ++it, ++count)
+03091         {
+03093                 it->Shape->getAABBox(tmpBox);
+03094                 NLMISC::CAABBox currBB = NLMISC::CAABBox::transformAABBox(it->MT, tmpBox);
+03095 
+03097                 if (zoneBBox.intersect(currBB))
+03098                 {
+03099                         _WaterShapeQuadGrid.insert(currBB.getMin(), currBB.getMax(), NLMISC::safe_cast<CWaterShape *>(it->Shape));
+03100                 }
+03101                 progress("Building quadtree from water surfaces", (float) count / totalCount);
+03102         }
+03103 
+03105         NLMISC::contReset(_WaterShapes);
+03106 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CZoneLighter::processCalc uint  process,
const CLightDesc description
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1293 of file zone_lighter.cpp. +

+References _Lumels, _PatchInfo, _ShadowArray, _ZoneToLight, attenuation(), NLMISC::clamp(), getAPatch(), getSkyContribution(), NL3D::CLandscape::getZone(), NL3D::CPatchInfo::Lumels, nlassert, NL3D::CZoneLighter::CLightDesc::Shadow, sint, NL3D::CZoneLighter::CLightDesc::SkyContribution, NL3D::CZoneLighter::CLightDesc::SkyIntensity, NL3D::CZoneLighter::CLightDesc::SunContribution, and uint. +

+

01294 {
+01295         // *** Raytrace each patches
+01296 
+01297         // Pointer on the zone
+01298         CZone *pZone=_Landscape->getZone (_ZoneToLight);
+01299 
+01300         // Get a patch
+01301         uint patch = getAPatch (process);
+01302         while (patch != 0xffffffff)
+01303         {
+01304                 // For each patch
+01305                 if (description.Shadow)
+01306                 {
+01307                         // Lumels
+01308                         std::vector<CLumelDescriptor> &lumels=_Lumels[patch];
+01309                 
+01310                         // Lumel count
+01311                         uint lumelCount=lumels.size();
+01312                         CPatchInfo &patchInfo=_PatchInfo[patch];
+01313                         nlassert (patchInfo.Lumels.size()==lumelCount);
+01314 
+01315                         // Resize shadow array
+01316                         _ShadowArray[patch].resize (lumelCount);
+01317 
+01318                         // For each lumel
+01319                         for (uint lumel=0; lumel<lumelCount; lumel++)
+01320                         {
+01321                                 float factor=0;
+01322                                 factor = attenuation (lumels[lumel].Position, description);
+01323                                 patchInfo.Lumels[lumel]=(uint)(factor*255);
+01324                         }
+01325                 }
+01326                 else
+01327                 {
+01328                         // Lumels
+01329                         std::vector<CLumelDescriptor> &lumels=_Lumels[patch];
+01330                 
+01331                         // Lumel count
+01332                         uint lumelCount=lumels.size();
+01333                         CPatchInfo &patchInfo=_PatchInfo[patch];
+01334                         nlassert (patchInfo.Lumels.size()==lumelCount);
+01335 
+01336                         // For each lumel
+01337                         for (uint lumel=0; lumel<lumelCount; lumel++)
+01338                         {
+01339                                 // Not shadowed
+01340                                 patchInfo.Lumels[lumel]=255;
+01341                         }
+01342                 }
+01343 
+01344                 // *** Lighting
+01345                 
+01346                 // Get the patch info
+01347                 CPatchInfo &patchInfo=_PatchInfo[patch];
+01348 
+01349                 // ** Pointer on arries
+01350                 std::vector<CLumelDescriptor> &lumels=_Lumels[patch];
+01351 
+01352                 // Go for light each lumel
+01353                 for (uint lumel=0; lumel<lumels.size(); lumel++)
+01354                 {
+01355                         // Sky contribution
+01356                         float skyContribution;
+01357                         
+01358                         if (description.SkyContribution)
+01359                         {                                                               
+01360                                 skyContribution = getSkyContribution(lumels[lumel].Position, lumels[lumel].Normal, description.SkyIntensity);
+01361                         }
+01362                         else
+01363                         {
+01364                                 skyContribution = 0.f;
+01365                         }
+01366 
+01367                         // Sun contribution
+01368                         float sunContribution;
+01369                         if (description.SunContribution)
+01370                         {
+01371                                 sunContribution=(-lumels[lumel].Normal*_SunDirection)-skyContribution;
+01372                                 clamp (sunContribution, 0.f, 1.f);
+01373                         }
+01374                         else
+01375                                 sunContribution=0;
+01376 
+01377                         // Final lighting
+01378                         sint finalLighting=(sint)(255.f*(((float)patchInfo.Lumels[lumel])*sunContribution/255.f+skyContribution));
+01379                         clamp (finalLighting, 0, 255);
+01380                         patchInfo.Lumels[lumel]=finalLighting;
+01381                 }
+01382 
+01383                 // Next patch
+01384                 patch = getAPatch (process);
+01385         }
+01386 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void CZoneLighter::processLightableShapeCalc uint  process,
TShapeVect shapeToLit,
uint  firstShape,
uint  lastShape,
const CLightDesc description
[private]
+
+ + + + + +
+   + + +

+Process lighting for a set of lightable shapes. This is called by the threads created by lightShapes(). +

+ +

+Definition at line 2836 of file zone_lighter.cpp. +

+References isLightableShape(), lightSingleShape(), nlassert, TShapeVect, and uint. +

+

02841 {
+02842         // for each lightable shape
+02843         for (uint k = firstShape; k < lastShape; ++k)
+02844         {               
+02845                 nlassert(isLightableShape(* (*shapesToLit)[k].Shape)); // make sure it is a lightable shape             
+02846                 lightSingleShape((*shapesToLit)[k], description, process);      
+02847         }
+02848 }
+
+

+ + + + +
+ + + + + + + + + + +
void CZoneLighter::processZonePointLightRT std::vector< CPointLightNamed > &  listPointLight  )  [private]
+
+ + + + + +
+   + + +

+Process the zone, ie process _PatchInfo. MultiCPU: not done for now. Be aware of CPointLightRT::RefCount!!!! +

+Definition at line 3346 of file zone_lighter.cpp. +

+References _PatchInfo, _ZoneToLight, NL3D::CQuadGrid< CPointLightRT * >::begin(), NL3D::CZoneLighter::CPointLightRT::BSphere, NLMISC::CBSphere::Center, NLMISC::clamp(), NL3D::CPointLight::computeLinearAttenuation(), NL3D::CPatch::computeVertex(), NL3D::CZoneLighter::CPointLightRT::DstId, NL3D::CQuadGrid< CPointLightRT * >::end(), NL3D::CBezierPatch::evalNormal(), NL3D::CLandscape::getZone(), NL3D::CZoneLighter::CPatchForPL::HeightTLI, NL3D::CTileLightInfluence::Light, NL3D::CZoneLighter::CTileLightInfUnpack::Light, NL3D::CZoneLighter::CTileLightInfUnpack::LightFactor, min, NLMISC::CVector::normalize(), NL3D::CZoneLighter::CPredPointLightToPoint::Point, NL3D::CZoneLighter::CPointLightRT::PointLight, progress(), NL3D::CZoneLighter::CPointLightRT::RefCount, s, NL3D::CQuadGrid< CPointLightRT * >::select(), NL3D::CTileLightInfluence::setDiffuseLightFactor(), t, NL3D::CZoneLighter::CPointLightRT::testRaytrace(), NL3D::CPatchInfo::TileLightInfluences, NL3D::CZoneLighter::CPatchForPL::TileLightInfluences, uint, uint8, NL3D::CPatch::unpackIntoCache(), w, NL3D::CZoneLighter::CPatchForPL::WidthTLI, x, and y. +

+Referenced by light(). +

+

03347 {
+03348         uint    i;
+03349         vector<CPointLightRT*>          lightInfs;
+03350         lightInfs.reserve(1024);
+03351 
+03352         // clear result list
+03353         listPointLight.clear();
+03354 
+03355         // zoneToLight
+03356         CZone   *zoneToLight= _Landscape->getZone(_ZoneToLight);
+03357         if(!zoneToLight)
+03358                 return;
+03359 
+03360         // Build patchForPLs
+03361         //===========
+03362         vector<CPatchForPL>             patchForPLs;
+03363         patchForPLs.resize(_PatchInfo.size());
+03364         for(i=0; i<patchForPLs.size(); i++)
+03365         {
+03366                 // Get OrderS/OrderT
+03367                 patchForPLs[i].OrderS= _PatchInfo[i].OrderS;
+03368                 patchForPLs[i].OrderT= _PatchInfo[i].OrderT;
+03369                 // resize TileLightInfluences
+03370                 uint    w= patchForPLs[i].WidthTLI= patchForPLs[i].OrderS/2 +1 ;
+03371                 uint    h= patchForPLs[i].HeightTLI= patchForPLs[i].OrderT/2 +1;
+03372                 patchForPLs[i].TileLightInfluences.resize(w*h);
+03373         }
+03374 
+03375 
+03376         // compute each TileLightInfluence
+03377         //===========
+03378         for(i=0; i<patchForPLs.size(); i++)
+03379         {
+03380                 // progress
+03381                 progress ("Compute Influences of PointLights", 0.5f + 0.5f*i / (float)patchForPLs.size());
+03382 
+03383                 CPatchForPL             &pfpl= patchForPLs[i];
+03384                 const CPatch    *patch= const_cast<const CZone*>(zoneToLight)->getPatch(i);
+03385 
+03386                 uint    x, y;
+03387                 for(y= 0; y<pfpl.HeightTLI; y++)
+03388                 {
+03389                         for(x= 0; x<pfpl.WidthTLI; x++)
+03390                         {
+03391                                 // compute the point and normal (normalized) where the TLI lies.
+03392                                 //---------
+03393                                 CVector         pos, normal;
+03394                                 float           s, t;
+03395                                 s= (float)x / (pfpl.WidthTLI-1);
+03396                                 t= (float)y / (pfpl.HeightTLI-1);
+03397                                 // Compute the Vertex, with Noise information (important for accurate raytracing).
+03398                                 pos= patch->computeVertex(s, t);
+03399                                 // Use UnNoised normal from BezierPatch, because the lighting does not need to be so precise.
+03400                                 CBezierPatch    *bp= patch->unpackIntoCache();
+03401                                 normal= bp->evalNormal(s, t);
+03402                                 
+03403 
+03404                                 // Compute Which light influences him.
+03405                                 //---------
+03406                                 lightInfs.clear();
+03407                                 // Search possible lights around the position.
+03408                                 _StaticPointLightQuadGrid.select(pos, pos);
+03409                                 // For all of them, get the ones which touch this point.
+03410                                 CQuadGrid<CPointLightRT*>::CIterator    it= _StaticPointLightQuadGrid.begin();
+03411                                 while(it != _StaticPointLightQuadGrid.end())
+03412                                 {
+03413                                         CPointLightRT   *pl= *it;
+03414 
+03415                                         // a light influence a TLI only if this one is FrontFaced to the light !!
+03416                                         if( ( pl->BSphere.Center - pos ) * normal > 0)
+03417                                         {
+03418                                                 // Add 5cm else it fails in some case where ( pl->BSphere.Center - pos ) * normal is 
+03419                                                 // nearly 0 and the point should be occluded.
+03420                                                 const float     deltaY= 0.05f;
+03421                                                 CVector posToRT= pos + normal * deltaY;
+03422                                                 // Test if really in the radius of the light, if no occlusion, and if in SpotAngle
+03423                                                 if( pl->testRaytrace(posToRT) )
+03424                                                 {
+03425                                                         // Ok, add the light to the lights which influence the TLI 
+03426                                                         lightInfs.push_back(pl);
+03427                                                 }
+03428                                         }
+03429 
+03430                                         // next
+03431                                         it++;
+03432                                 }
+03433 
+03434                                 // Choose the Best ones.
+03435                                 //---------
+03436                                 CPredPointLightToPoint  predPLTP;
+03437                                 predPLTP.Point= pos;
+03438                                 // sort.
+03439                                 sort(lightInfs.begin(), lightInfs.end(), predPLTP);
+03440                                 // truncate.
+03441                                 lightInfs.resize( min((uint)lightInfs.size(), (uint)CTileLightInfluence::NumLightPerCorner) );
+03442 
+03443 
+03444                                 // For each of them, fill TLI
+03445                                 //---------
+03446                                 CTileLightInfUnpack             tli;
+03447                                 uint                                    lightInfId;
+03448                                 for(lightInfId=0; lightInfId<lightInfs.size(); lightInfId++)
+03449                                 {
+03450                                         CPointLightRT   *pl= lightInfs[lightInfId];
+03451 
+03452                                         // copy light.
+03453                                         tli.Light[lightInfId]= pl;
+03454                                         // Compute light Diffuse factor.
+03455                                         CVector         dir= pl->BSphere.Center - pos;
+03456                                         dir.normalize();
+03457                                         tli.LightFactor[lightInfId]= dir * normal;
+03458                                         clamp(tli.LightFactor[lightInfId], 0.f, 1.f);
+03459                                         // modulate by light attenuation.
+03460                                         tli.LightFactor[lightInfId]*= pl->PointLight.computeLinearAttenuation(pos);
+03461 
+03462                                         // Inc RefCount of the light.
+03463                                         pl->RefCount++;
+03464                                 }
+03465                                 // Reset any empty slot to NULL.
+03466                                 for(; lightInfId<CTileLightInfluence::NumLightPerCorner; lightInfId++)
+03467                                 {
+03468                                         tli.Light[lightInfId]= NULL;
+03469                                 }
+03470 
+03471 
+03472                                 // Set TLI in patch.
+03473                                 //---------
+03474                                 pfpl.TileLightInfluences[y*pfpl.WidthTLI + x]= tli;
+03475                         }
+03476                 }
+03477         }
+03478 
+03479 
+03480         // compress and setup _PatchInfo with compressed data.
+03481         //===========
+03482         uint    plId= 0;
+03483         // Process each pointLights
+03484         for(i=0; i<_StaticPointLights.size(); i++)
+03485         {
+03486                 CPointLightRT   &plRT= _StaticPointLights[i];
+03487                 // If this light is used.
+03488                 if(plRT.RefCount > 0)
+03489                 {
+03490                         // Must Copy it into Zone.
+03491                         listPointLight.push_back(plRT.PointLight);
+03492                         plRT.DstId= plId++;
+03493                         // If index >= 255, too many lights (NB: => because 255 is a NULL code).
+03494                         if(plId>=0xFF)
+03495                         {
+03496                                 throw Exception("Too many Static Point Lights influence the zone!!");
+03497                         }
+03498                 }
+03499         }
+03500 
+03501         // For each patch, compress TLI in PatchInfo.
+03502         for(i=0; i<patchForPLs.size(); i++)
+03503         {
+03504                 CPatchForPL             &pfpl= patchForPLs[i];
+03505                 CPatchInfo              &pInfo= _PatchInfo[i];
+03506 
+03507                 uint    w= pfpl.WidthTLI;
+03508                 uint    h= pfpl.HeightTLI;
+03509 
+03510                 // Fill  pInfo.TileLightInfluences
+03511                 pInfo.TileLightInfluences.resize(w*h);
+03512                 uint    x, y;
+03513                 for(y= 0; y<h; y++)
+03514                 {
+03515                         for(x= 0; x<w; x++)
+03516                         {
+03517                                 uint    tliId= y*w + x;
+03518                                 // For all light slot
+03519                                 for(uint lightId= 0; lightId<CTileLightInfluence::NumLightPerCorner; lightId++)
+03520                                 {
+03521                                         CTileLightInfUnpack             &tliSrc= pfpl.TileLightInfluences[tliId];
+03522                                         CTileLightInfluence             &tliDst= pInfo.TileLightInfluences[tliId];
+03523                                         if(tliSrc.Light[lightId] == NULL)
+03524                                         {
+03525                                                 // Mark as unused.
+03526                                                 tliDst.Light[lightId]= 0xFF;
+03527                                         }
+03528                                         else
+03529                                         {
+03530                                                 // Get index.
+03531                                                 tliDst.Light[lightId]= tliSrc.Light[lightId]->DstId;
+03532                                                 // Get Diffuse Factor.
+03533                                                 tliDst.setDiffuseLightFactor(lightId, (uint8)(tliSrc.LightFactor[lightId]*255));
+03534                                         }
+03535                                 }
+03536                         }
+03537                 }
+03538 
+03539         }
+03540 
+03541 }
+
+

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

+ +

+Definition at line 342 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), compilePointLightRT(), computeTileFlagsForPositionTowardWater(), light(), lightShapes(), lightSingleShape(), makeQuadGridFromWaterShapes(), and processZonePointLightRT(). +

+

00342 {};
+
+

+ + + + +
+ + + + + + + + + + +
void CZoneLighter::setTileFlagsToDefault std::vector< const CTessFace * > &  tessFaces  )  [private]
+
+ + + + + +
+   + + +

+If no water surface overlap the zone, so we set all the flags to 'AboveWater", or don't change them if they were set to 'DisableVegetable' +

+Definition at line 3710 of file zone_lighter.cpp. +

+References _ZoneToLight, NL3D::CTileElement::getVegetableState(), and NL3D::CTileElement::setVegetableState(). +

+Referenced by buildZoneInformation(). +

+

03711 {
+03713         for (std::vector<const CTessFace*>::iterator it = tessFaces.begin(); it != tessFaces.end(); ++it)
+03714         {
+03715                 if ((*it)->Patch->getZone()->getZoneId() != _ZoneToLight) continue;
+03716                 CTileElement &te = (*it)->Patch->Tiles[(*it)->TileId];
+03717                 if (te.getVegetableState() != CTileElement::VegetableDisabled)
+03718                 {
+03719                         te.setVegetableState(CTileElement::AboveWater);
+03720                 }
+03721         }
+03722 }
+
+


Friends And Related Function Documentation

+

+ + + + +
+ + +
friend class CCalcLightableShapeRunnable [friend] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 356 of file zone_lighter.h. +

+Referenced by lightShapes().

+

+ + + + +
+ + +
friend class NL3D::CLightRunnable [friend] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 66 of file zone_lighter.h.

+

+ + + + +
+ + +
friend class NL3D::CRenderZBuffer [friend] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 67 of file zone_lighter.h.

+


Field Documentation

+

+ + + + +
+ + +
std::vector<std::vector<CBezierPatch> > NL3D::CZoneLighter::_BezierPatch [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 508 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), and getNormal().

+

+ + + + +
+ + +
std::vector<std::vector<std::vector<bool> > > NL3D::CZoneLighter::_Binded [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 511 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), and getNormal().

+

+ + + + +
+ + +
std::vector<std::vector<std::vector<CPatch::CBindInfo> > > NL3D::CZoneLighter::_BindInfo [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 510 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), and getNormal().

+

+ + + + +
+ + +
std::map<std::string, NLMISC::CBitmap> NL3D::CZoneLighter::_Bitmaps [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 474 of file zone_lighter.h. +

+Referenced by getTexture(), and init().

+

+ + + + +
+ + +
std::vector<CBorderVertex> NL3D::CZoneLighter::_BorderVertices [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 505 of file zone_lighter.h. +

+Referenced by light().

+

+ + + + +
+ + +
uint64 NL3D::CZoneLighter::_CPUMask [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 470 of file zone_lighter.h. +

+Referenced by light().

+

+ + + + +
+ + +
sint16 CZoneLighter::_GetNormalDeltaS = { -1, 0, 1, 0 } [static, private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 1501 of file zone_lighter.cpp. +

+Referenced by getNormal(), and isLumelOnEdgeMustBeOversample().

+

+ + + + +
+ + +
sint16 CZoneLighter::_GetNormalDeltaT = { 0, 1, 0, -1 } [static, private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 1502 of file zone_lighter.cpp. +

+Referenced by getNormal(), and isLumelOnEdgeMustBeOversample().

+

+ + + + +
+ + +
NLMISC::CVector NL3D::CZoneLighter::_GetNormalNormal [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 517 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), and getNormal().

+

+ + + + +
+ + +
const NL3D::CPatch* NL3D::CZoneLighter::_GetNormalPatch [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 516 of file zone_lighter.h.

+

+ + + + +
+ + +
uint NL3D::CZoneLighter::_GetNormalRadius [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 518 of file zone_lighter.h.

+

+ + + + +
+ + +
uint NL3D::CZoneLighter::_GetNormalSqRadius [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 519 of file zone_lighter.h.

+

+ + + + +
+ + +
std::vector<float> NL3D::CZoneLighter::_HeightField [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 494 of file zone_lighter.h.

+

+ + + + +
+ + +
sint NL3D::CZoneLighter::_HeightFieldCellCount [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 495 of file zone_lighter.h. +

+Referenced by getMaxPhi(), and light().

+

+ + + + +
+ + +
float NL3D::CZoneLighter::_HeightfieldCellSize [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 497 of file zone_lighter.h. +

+Referenced by getMaxPhi(), getSkyContribution(), and light().

+

+ + + + +
+ + +
NLMISC::CVector NL3D::CZoneLighter::_K[256][8] [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 524 of file zone_lighter.h.

+

+ + + + +
+ + +
NL3D::CLandscape* NL3D::CZoneLighter::_Landscape [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 460 of file zone_lighter.h.

+

+ + + + +
+ + +
std::vector<uint> NL3D::CZoneLighter::_LastPatchComputed [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 467 of file zone_lighter.h. +

+Referenced by getAPatch(), and light().

+

+ + + + +
+ + +
TShapeVect NL3D::CZoneLighter::_LightableShapes [private] +
+
+ + + + + +
+   + + +

+lightable shapes +

+ +

+Definition at line 598 of file zone_lighter.h. +

+Referenced by addLightableShape(), lightShapes(), and lightSingleShape().

+

+ + + + +
+ + +
std::vector<std::vector<std::vector<CPatchUVLocator> > > NL3D::CZoneLighter::_Locator [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 509 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), and getNormal().

+

+ + + + +
+ + +
std::vector<std::vector<CLumelDescriptor> > NL3D::CZoneLighter::_Lumels [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 506 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), and processCalc().

+

+ + + + +
+ + +
NLMISC::CFastMutex NL3D::CZoneLighter::_Mutex [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 479 of file zone_lighter.h. +

+Referenced by NL3D::CRenderZBuffer::run().

+

+ + + + +
+ + +
uint NL3D::CZoneLighter::_NumberOfPatchComputed [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 468 of file zone_lighter.h. +

+Referenced by getAPatch(), light(), and NL3D::CRenderZBuffer::run().

+

+ + + + +
+ + +
uint NL3D::CZoneLighter::_NumLightableShapesProcessed [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 599 of file zone_lighter.h. +

+Referenced by lightShapes(), and lightSingleShape().

+

+ + + + +
+ + +
NLMISC::CVector NL3D::CZoneLighter::_OrigineHeightField [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 496 of file zone_lighter.h. +

+Referenced by getSkyContribution(), and light().

+

+ + + + +
+ + +
std::vector<std::vector<bool> > NL3D::CZoneLighter::_OversampleEdges [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 512 of file zone_lighter.h. +

+Referenced by buildZoneInformation().

+

+ + + + +
+ + +
NLMISC::CSynchronized<std::vector<bool> > NL3D::CZoneLighter::_PatchComputed [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 466 of file zone_lighter.h. +

+Referenced by getAPatch(), and light().

+

+ + + + +
+ + +
std::vector<CPatchInfo> NL3D::CZoneLighter::_PatchInfo [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 504 of file zone_lighter.h. +

+Referenced by getAPatch(), light(), processCalc(), and processZonePointLightRT().

+

+ + + + +
+ + +
uint NL3D::CZoneLighter::_ProcessCount [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 469 of file zone_lighter.h. +

+Referenced by light(), and lightShapes().

+

+ + + + +
+ + +
volatile uint NL3D::CZoneLighter::_ProcessExited [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 471 of file zone_lighter.h. +

+Referenced by light(), lightShapes(), and NL3D::CRenderZBuffer::run().

+

+ + + + +
+ + +
CQuadGrid<const CTriangle*> NL3D::CZoneLighter::_QuadGrid[ 10 ] [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 456 of file zone_lighter.h.

+

+ + + + +
+ + +
NLMISC::CRandom NL3D::CZoneLighter::_Random [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 491 of file zone_lighter.h. +

+Referenced by attenuation().

+

+ + + + +
+ + +
NLMISC::CMatrix NL3D::CZoneLighter::_RayBasis [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 457 of file zone_lighter.h. +

+Referenced by light().

+

+ + + + +
+ + +
std::vector<std::vector<uint8> > NL3D::CZoneLighter::_ShadowArray [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 463 of file zone_lighter.h. +

+Referenced by light(), and processCalc().

+

+ + + + +
+ + +
float NL3D::CZoneLighter::_ShadowBias [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 461 of file zone_lighter.h.

+

+ + + + +
+ + +
bool NL3D::CZoneLighter::_Softshadow [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 462 of file zone_lighter.h.

+

+ + + + +
+ + +
CQuadGrid<CPointLightRT*> NL3D::CZoneLighter::_StaticPointLightQuadGrid [private] +
+
+ + + + + +
+   + + +

+QuadGrid of PointLights. Builded from _StaticPointLights. +

+ +

+Definition at line 582 of file zone_lighter.h.

+

+ + + + +
+ + +
std::vector<CPointLightRT> NL3D::CZoneLighter::_StaticPointLights [private] +
+
+ + + + + +
+   + + +

+List of PointLights. +

+ +

+Definition at line 580 of file zone_lighter.h.

+

+ + + + +
+ + +
NLMISC::CVector NL3D::CZoneLighter::_SunDirection [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 458 of file zone_lighter.h. +

+Referenced by NL3D::CRenderZBuffer::run().

+

+ + + + +
+ + +
TWaterShapeQuadGrid NL3D::CZoneLighter::_WaterShapeQuadGrid [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 607 of file zone_lighter.h. +

+Referenced by computeTileFlagsForPositionTowardWater(), and makeQuadGridFromWaterShapes().

+

+ + + + +
+ + +
TShapeVect NL3D::CZoneLighter::_WaterShapes [private] +
+
+ + + + + +
+   + + +

+List of all the water shapes in the zone. We need them to check wether the tiles are above / below water, or if theyr intersect water +

+Definition at line 603 of file zone_lighter.h.

+

+ + + + +
+ + +
std::vector<CZBuffer> NL3D::CZoneLighter::_ZBufferLandscape +
+
+ + + + + +
+   + + +

+ +

+Definition at line 483 of file zone_lighter.h. +

+Referenced by attenuation(), light(), and NL3D::CRenderZBuffer::run().

+

+ + + + +
+ + +
CZBuffer NL3D::CZoneLighter::_ZBufferObject +
+
+ + + + + +
+   + + +

+ +

+Definition at line 484 of file zone_lighter.h. +

+Referenced by attenuation(), light(), and NL3D::CRenderZBuffer::run().

+

+ + + + +
+ + +
bool NL3D::CZoneLighter::_ZBufferOverflow [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 488 of file zone_lighter.h. +

+Referenced by attenuation(), init(), and light().

+

+ + + + +
+ + +
std::map<uint, uint> NL3D::CZoneLighter::_ZoneId [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 513 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), and getNormal().

+

+ + + + +
+ + +
uint NL3D::CZoneLighter::_ZoneToLight [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 459 of file zone_lighter.h. +

+Referenced by buildZoneInformation(), computeTileFlagsForPositionTowardWater(), light(), processCalc(), processZonePointLightRT(), and setTileFlagsToDefault().

+


The documentation for this class was generated from the following files: +
Generated on Tue Mar 16 08:35:04 2004 for NeL by + +doxygen +1.3.6
+ + -- cgit v1.2.1