#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(). |
1.3.6