#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< CShapeInfo > | TShapeVect |
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 |
|
A vector of lightable shapes.
Definition at line 403 of file zone_lighter.h. Referenced by NL3D::CCalcLightableShapeRunnable::CCalcLightableShapeRunnable(), and processLightableShapeCalc(). |
|
Definition at line 605 of file zone_lighter.h. |
|
Definition at line 245 of file zone_lighter.cpp.
00245 : _PatchComputed ("PatchComputed") 00246 { 00247 } |
|
Definition at line 70 of file zone_lighter.h.
00070 {} |
|
Some shape (water shapes for now) can be lit. This add such a shape to the process of lighting.
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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().
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Make a quad grid of all the water shapes that where registered by calling addWaterShape() The vector of water shapes is released then
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Definition at line 342 of file zone_lighter.h. Referenced by buildZoneInformation(), compilePointLightRT(), computeTileFlagsForPositionTowardWater(), light(), lightShapes(), lightSingleShape(), makeQuadGridFromWaterShapes(), and processZonePointLightRT().
00342 {}; |
|
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 } |
|
Definition at line 356 of file zone_lighter.h. Referenced by lightShapes(). |
|
Definition at line 66 of file zone_lighter.h. |
|
Definition at line 67 of file zone_lighter.h. |
|
Definition at line 508 of file zone_lighter.h. Referenced by buildZoneInformation(), and getNormal(). |
|
Definition at line 511 of file zone_lighter.h. Referenced by buildZoneInformation(), and getNormal(). |
|
Definition at line 510 of file zone_lighter.h. Referenced by buildZoneInformation(), and getNormal(). |
|
Definition at line 474 of file zone_lighter.h. Referenced by getTexture(), and init(). |
|
Definition at line 505 of file zone_lighter.h. Referenced by light(). |
|
Definition at line 470 of file zone_lighter.h. Referenced by light(). |
|
Definition at line 1501 of file zone_lighter.cpp. Referenced by getNormal(), and isLumelOnEdgeMustBeOversample(). |
|
Definition at line 1502 of file zone_lighter.cpp. Referenced by getNormal(), and isLumelOnEdgeMustBeOversample(). |
|
Definition at line 517 of file zone_lighter.h. Referenced by buildZoneInformation(), and getNormal(). |
|
Definition at line 516 of file zone_lighter.h. |
|
Definition at line 518 of file zone_lighter.h. |
|
Definition at line 519 of file zone_lighter.h. |
|
Definition at line 494 of file zone_lighter.h. |
|
Definition at line 495 of file zone_lighter.h. Referenced by getMaxPhi(), and light(). |
|
Definition at line 497 of file zone_lighter.h. Referenced by getMaxPhi(), getSkyContribution(), and light(). |
|
Definition at line 524 of file zone_lighter.h. |
|
Definition at line 460 of file zone_lighter.h. |
|
Definition at line 467 of file zone_lighter.h. Referenced by getAPatch(), and light(). |
|
lightable shapes
Definition at line 598 of file zone_lighter.h. Referenced by addLightableShape(), lightShapes(), and lightSingleShape(). |
|
Definition at line 509 of file zone_lighter.h. Referenced by buildZoneInformation(), and getNormal(). |
|
Definition at line 506 of file zone_lighter.h. Referenced by buildZoneInformation(), and processCalc(). |
|
Definition at line 479 of file zone_lighter.h. Referenced by NL3D::CRenderZBuffer::run(). |
|
Definition at line 468 of file zone_lighter.h. Referenced by getAPatch(), light(), and NL3D::CRenderZBuffer::run(). |
|
Definition at line 599 of file zone_lighter.h. Referenced by lightShapes(), and lightSingleShape(). |
|
Definition at line 496 of file zone_lighter.h. Referenced by getSkyContribution(), and light(). |
|
Definition at line 512 of file zone_lighter.h. Referenced by buildZoneInformation(). |
|
Definition at line 466 of file zone_lighter.h. Referenced by getAPatch(), and light(). |
|
Definition at line 504 of file zone_lighter.h. Referenced by getAPatch(), light(), processCalc(), and processZonePointLightRT(). |
|
Definition at line 469 of file zone_lighter.h. Referenced by light(), and lightShapes(). |
|
Definition at line 471 of file zone_lighter.h. Referenced by light(), lightShapes(), and NL3D::CRenderZBuffer::run(). |
|
Definition at line 456 of file zone_lighter.h. |
|
Definition at line 491 of file zone_lighter.h. Referenced by attenuation(). |
|
Definition at line 457 of file zone_lighter.h. Referenced by light(). |
|
Definition at line 463 of file zone_lighter.h. Referenced by light(), and processCalc(). |
|
Definition at line 461 of file zone_lighter.h. |
|
Definition at line 462 of file zone_lighter.h. |
|
QuadGrid of PointLights. Builded from _StaticPointLights.
Definition at line 582 of file zone_lighter.h. |
|
List of PointLights.
Definition at line 580 of file zone_lighter.h. |
|
Definition at line 458 of file zone_lighter.h. Referenced by NL3D::CRenderZBuffer::run(). |
|
Definition at line 607 of file zone_lighter.h. Referenced by computeTileFlagsForPositionTowardWater(), and makeQuadGridFromWaterShapes(). |
|
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. |
|
Definition at line 483 of file zone_lighter.h. Referenced by attenuation(), light(), and NL3D::CRenderZBuffer::run(). |
|
Definition at line 484 of file zone_lighter.h. Referenced by attenuation(), light(), and NL3D::CRenderZBuffer::run(). |
|
Definition at line 488 of file zone_lighter.h. Referenced by attenuation(), init(), and light(). |
|
Definition at line 513 of file zone_lighter.h. Referenced by buildZoneInformation(), and getNormal(). |
|
Definition at line 459 of file zone_lighter.h. Referenced by buildZoneInformation(), computeTileFlagsForPositionTowardWater(), light(), processCalc(), processZonePointLightRT(), and setTileFlagsToDefault(). |