# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

patch.h

Go to the documentation of this file.
00001 
00011 /* Copyright, 2000 Nevrax Ltd.
00012  *
00013  * This file is part of NEVRAX NEL.
00014  * NEVRAX NEL is free software; you can redistribute it and/or modify
00015  * it under the terms of the GNU General Public License as published by
00016  * the Free Software Foundation; either version 2, or (at your option)
00017  * any later version.
00018 
00019  * NEVRAX NEL is distributed in the hope that it will be useful, but
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00022  * General Public License for more details.
00023 
00024  * You should have received a copy of the GNU General Public License
00025  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00027  * MA 02111-1307, USA.
00028  */
00029 
00030 #ifndef NL_PATCH_H
00031 #define NL_PATCH_H
00032 
00033 #include "nel/misc/types_nl.h"
00034 #include "nel/misc/vector.h"
00035 #include "nel/misc/vector_2f.h"
00036 #include "3d/tessellation.h"
00037 #include "nel/misc/aabbox.h"
00038 #include "nel/misc/bsphere.h"
00039 #include "nel/misc/triangle.h"
00040 #include "nel/misc/geom_ext.h"
00041 #include "3d/tile_element.h"
00042 #include "3d/tile_color.h"
00043 #include "3d/tess_block.h"
00044 #include "3d/tile_light_influence.h"
00045 #include "nel/3d/point_light_influence.h"
00046 
00047 
00048 namespace NL3D {
00049 
00050 #define NL_MAX_TILES_BY_PATCH_EDGE_SHIFT 4                                                                              // max 16x16 tiles by patch (shift version)
00051 #define NL_MAX_TILES_BY_PATCH_EDGE (1<<NL_MAX_TILES_BY_PATCH_EDGE_SHIFT)                // max 16x16 tiles by patch
00052 #define NL_PATCH_FAR0_ROTATED 0x1                                                                                               // Flags far0 rotated
00053 #define NL_PATCH_FAR1_ROTATED 0x2                                                                                               // Flags far1 rotated
00054 #define NL_PATCH_SMOOTH_FLAG_SHIFT 0x2                                                                                  // Smooth flags shift
00055 #define NL_PATCH_SMOOTH_FLAG_MASK 0x3c                                                                                  // Smooth flags mask
00056 
00057 #define NL_LUMEL_BY_TILE_SHIFT 2                                                                                                // 4 lumels by tile
00058 #define NL_LUMEL_BY_TILE (1<<NL_LUMEL_BY_TILE_SHIFT)                                                    // 4 lumels by tile
00059 #define NL_BLOCK_LUMEL_COMPRESSED_SIZE 8                                                                                // Compressed block size 8 bytes
00060 
00061 
00062 #define NL_PATCH_BLOCK_MAX_QUAD 4                                                                                               // Max quad per CPatchQuadBlock.
00063 #define NL_PATCH_BLOCK_MAX_VERTEX (NL_PATCH_BLOCK_MAX_QUAD+1)                                   // Max vertex per CPatchQuadBlock.
00064 
00065 
00066 using NLMISC::CVector;
00067 using NLMISC::CPlane;
00068 using NLMISC::CAABBox;
00069 using NLMISC::CBSphere;
00070 
00071 
00072 class   CLandscape;
00073 class   CZone;
00074 class   CBezierPatch;
00075 class   ITexture;
00076 class   CVegetableClipBlock;
00077 class   CVegetableManager;
00078 class   CVegetableInstanceGroup;
00079 class   CLandscapeVegetableBlock;
00080 class   CLandscapeVegetableBlockCreateContext;
00081 class   CPatchDLMContext;
00082 class   CPatchDLMPointLight;
00083 
00084 
00085 // ***************************************************************************
00086 #define NL3D_NOISE_MAX  1
00087 
00088 
00089 // ***************************************************************************
00090 /* 
00091         NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK == 2 means that 
00092         clipBlocks enclose 2*2 tessBlocks (hence 4*4 tiles).
00093 */
00094 #define NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK_SHIFT  1
00095 #define NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK                (1<<NL3D_PATCH_VEGETABLE_NUM_TESSBLOCK_PER_CLIPBLOCK_SHIFT)
00096 
00097 
00098 // ***************************************************************************
00099 class   CVector3s
00100 {
00101 public:
00102         sint16  x,y,z;
00103 
00104 public:
00105         void    pack(const CVector &v, const CVector &bias, float scale)
00106         {
00107                 float   xr,yr,zr;
00108                 xr= (v.x - bias.x)/scale;
00109                 yr= (v.y - bias.y)/scale;
00110                 zr= (v.z - bias.z)/scale;
00111                 NLMISC::clamp(xr, -32768, 32767);
00112                 NLMISC::clamp(yr, -32768, 32767);
00113                 NLMISC::clamp(zr, -32768, 32767);
00114                 x= (sint16)xr;
00115                 y= (sint16)yr;
00116                 z= (sint16)zr;
00117         }
00118         void    unpack(CVector &v, const CVector &bias, float scale) const
00119         {
00120                 v.x= x*scale + bias.x;
00121                 v.y= y*scale + bias.y;
00122                 v.z= z*scale + bias.z;
00123         }
00124         void    serial(NLMISC::IStream &f)
00125         {
00126                 f.serial(x,y,z);
00127         }
00128 };
00129 
00130 
00131 // ***************************************************************************
00139 struct  CPatchIdent
00140 {
00141         sint32          ZoneId;         // From which zone this patch come from...
00142         uint16          PatchId;        // Id of this patch.
00143 
00144         // default ctor
00145         CPatchIdent() {}
00146         //
00147         CPatchIdent(sint32 zoneId, uint16 patchId) : ZoneId(zoneId), PatchId(patchId) {}
00148 public:
00149         bool                    operator<(const CPatchIdent &p) const
00150         {
00151                 if(ZoneId!=p.ZoneId) return ZoneId<p.ZoneId;
00152                 return PatchId<p.PatchId;
00153         }
00154 
00155         bool                    operator==(const CPatchIdent &p) const
00156         {
00157                 return ZoneId==p.ZoneId && PatchId==p.PatchId;
00158         }
00159         bool                    operator!=(const CPatchIdent &p) const
00160         {
00161                 return !(*this==p);
00162         }
00163 
00164 };
00165 
00166 
00167 // ***************************************************************************
00175 struct  CTrianglePatch : public NLMISC::CTriangleUV
00176 {
00178         CPatchIdent             PatchId;
00179 };
00180 
00181 
00182 // ***************************************************************************
00190 class   CPatchBlockIdent
00191 {
00192 public:
00194         CPatchIdent             PatchId;
00196         uint8                   OrderS,OrderT;
00198         uint8                   S0,S1,T0,T1;
00199 
00200 public:
00202         // @{
00203         bool                    operator==(const CPatchBlockIdent &pb) const
00204         {
00205                 return PatchId==pb.PatchId &&
00206                         S0==pb.S0 && S1==pb.S1 &&
00207                         T0==pb.T0 && T1==pb.T1;
00208         }
00209         bool                    operator!=(const CPatchBlockIdent &pb) const
00210         {
00211                 return !(*this==pb);
00212         }
00213 
00214         bool                    operator<(const CPatchBlockIdent &pb) const
00215         {
00216                 if(PatchId!=pb.PatchId)
00217                         return PatchId<pb.PatchId;
00218                 if(S0!=pb.S0)   return S0<pb.S0;
00219                 if(S1!=pb.S1)   return S1<pb.S1;
00220                 if(T0!=pb.T0)   return T0<pb.T0;
00221                 return T1<pb.T1;
00222         }
00223         bool                    operator<=(const CPatchBlockIdent &pb) const
00224         {
00225                 return (*this<pb) || (*this==pb);
00226         }
00227         bool                    operator>(const CPatchBlockIdent &pb) const
00228         {
00229                 return !(*this<=pb);
00230         }
00231         bool                    operator>=(const CPatchBlockIdent &pb) const
00232         {
00233                 return !(*this<pb);
00234         }
00235 
00236         // @}
00237 };
00238 
00239 
00240 // ***************************************************************************
00248 class   CPatchQuadBlock
00249 {
00250 public:
00252         CPatchBlockIdent        PatchBlockId;
00253 
00255         CVector                         Vertices[NL_PATCH_BLOCK_MAX_VERTEX*NL_PATCH_BLOCK_MAX_VERTEX];
00256 
00257 public:
00258 
00262         void            buildTileTriangles(uint8 quadId, CTrianglePatch  triangles[2]) const;
00263 };
00264 
00265 
00266 
00267 // ***************************************************************************
00299 class CPatch
00300 {
00301 public:
00302 
00303         struct  CBindInfo
00304         {
00305                 // The zone on this edge. NULL if not loaded (or if none).
00306                 CZone                   *Zone;
00307 
00308                 // The number of patchs on this edge. 0,1, 2 or 4. if MultipleBindNum>1, NPatchs==1.
00309                 sint                    NPatchs;
00310 
00311                 // Special case: on this edge, we are a small patch connected to a bigger: this is the X of 1/X (1,2 or 4).
00312                 // 0 if this is not the case.
00313                 uint8                   MultipleBindNum;
00314                 // valid only if MultipleBindNum>1. this tells our place in this MultipleBind: 0<=MultipleBindId<MultipleBindNum.
00315                 uint8                   MultipleBindId;
00316 
00317 
00318                 CPatch                  *Next[4];       // The neighbor patch i.
00319                 sint                    Edge[4];        // On which edge of Nexti we are binded.
00320         };
00321 
00322 public:
00324         CVector3s               Vertices[4];
00325         CVector3s               Tangents[8];
00326         CVector3s               Interiors[4];
00327         /*
00328                 \todo yoyo: TODO_NOISE: - displacement map (ptr/index).
00329                 \todo yoyo: TODO_UVCORRECT: - "UV correction" infos.
00330                 
00331         */
00332 
00333         // Lumel array compressed.
00334         std::vector<uint8>                      CompressedLumels;
00335 
00336         // There is OrderS*OrderT tiles. CZone build it at build() time.
00337         std::vector<CTileElement>       Tiles;
00338 
00339         // There is OrderS*OrderT tiles color. CZone build it at build() time.
00340         std::vector<CTileColor>         TileColors;
00341 
00342         // There is OrderS/2+1 * OrderT/2+1 tiles light influence. CZone build it at build() time.
00343         std::vector<CTileLightInfluence>                TileLightInfluences;
00344 
00345 
00347         // @{
00349         uint8                   NoiseRotation;
00350 
00354         void                    setCornerSmoothFlag(uint corner, bool smooth);
00355         bool                    getCornerSmoothFlag(uint corner) const;
00356 
00357 private:
00359         uint8                   _CornerSmoothFlag;
00360 
00361 public:
00362         // @}
00363 
00364 
00365 public:
00366 
00368         CPatch();
00370         ~CPatch();
00371 
00381         void                    compile(CZone *z, uint patchId, uint8 orderS, uint8 orderT, CTessVertex *baseVertices[4], float errorSize=0);
00383         void                    release();
00384 
00385 
00387         CLandscape              *getLandscape () const;
00388         CZone                   *getZone() const {return Zone;}
00389         uint8                   getOrderS() const {return OrderS;}
00390         uint8                   getOrderT() const {return OrderT;}
00391         uint8                   getOrderForEdge(sint8 edge) const;
00392         float                   getErrorSize() const {return ErrorSize;}
00393         sint                    getFar0() const {return Far0;}
00394         sint                    getFar1() const {return Far1;}
00395         uint16                  getPatchId () const {return PatchId;}
00397         void                    getBindNeighbor(uint edge, CBindInfo &neighborEdge) const;
00398 
00400         CAABBox                 buildBBox() const;
00401 
00403         const CBSphere  &getBSphere() const {return BSphere;}
00404 
00412         CVector                 computeVertex(float s, float t) const;
00413 
00414 
00422         CVector                 computeContinousVertex(float s, float t) const;
00423 
00424 
00427         void                    unbind();
00428 
00433         void                    bind(CBindInfo  Edges[4], bool rebind);
00434 
00436         void                    forceMergeAtTileLevel();
00437 
00440         void                    averageTesselationVertices();
00441 
00443         void                    forceNoClip() {Clipped= false;}
00445         void                    forceClip() {Clipped= true;}
00447         void                    forceNoRenderClip() {RenderClipped= false;}
00449         void                    forceRenderClip() {RenderClipped= true;}
00451         void                    clip(const std::vector<CPlane>  &pyramid);
00453         void                    refineAll();
00454 
00455 
00457 
00458 
00460         void                    preRender();
00461         // like preRender(), but update TextureFar only. no-op if(!RenderClipped). (you should call preRender() in this case).
00462         void                    updateTextureFarOnly();
00464         // Global Setup setup it in CLandscape::render().
00465         void                    renderFar0();
00466         void                    renderFar1();
00467         // NB: renderTile() is now in CTileMaterial.
00468         // For All Far0/Far1/Tile etc..., compute Geomorph and Alpha in software (no VertexShader).
00469         void                    computeSoftwareGeomorphAndAlpha();
00471 
00472 
00473         // release Far render pass/reset Tile/Far render.
00474         void                    resetRenderFar();
00475 
00476 
00477 
00478         // For CZone changePatchTexture only.
00479         void                    deleteTileUvs();
00480         void                    recreateTileUvs();
00481         // For CZone::refreshTesselationGeometry() only.
00482         void                    refreshTesselationGeometry();
00483 
00484 
00485         // Serial just the un-compiled part.
00486         void                    serial(NLMISC::IStream &f);
00487 
00488         // unpack the patch into a floating point one.
00489         void                    unpack(CBezierPatch     &p) const;
00490 
00492 
00502         void                    unpackShadowMap (uint8 *pShadow);
00503 
00512         void                    packShadowMap (const uint8 *pLumel);
00513 
00519         void                    resetCompressedLumels ();
00520 
00529         void setupColorsFromTileFlags(const NLMISC::CRGBA colors[4]);
00530 
00534         void copyTileFlagsFromPatch(const CPatch *src);
00535         
00536 private:
00537 
00538         // Methods used internaly to compute shadowmaps
00539 
00545         void                    packLumelBlock (uint8 *dest, const uint8 *source, uint8 alpha0, uint8 alpha1);
00546 
00552         uint                    evalLumelBlock (const uint8 *original, const uint8 *unCompressed, uint width, uint height);
00553 
00559         void                    unpackLumelBlock (uint8 *dest, const uint8 *src);
00560 
00561 public:
00562 
00564 
00568         void setSmoothFlag (uint edge, bool flag)
00569         {
00570                 // Erase it
00571                 Flags&=~(1<<(edge+NL_PATCH_SMOOTH_FLAG_SHIFT));
00572                 
00573                 // Set it
00574                 Flags|=(((uint)flag)<<(edge+NL_PATCH_SMOOTH_FLAG_SHIFT));
00575         }
00576 
00580         bool getSmoothFlag (uint edge) const
00581         {
00582                 // Test it
00583                 return ((Flags&(1<<(edge+NL_PATCH_SMOOTH_FLAG_SHIFT)))!=0);
00584         }
00585 
00586 
00588         // @{
00596         void            addTrianglesInBBox(CPatchIdent paId, const CAABBox &bbox, std::vector<CTrianglePatch> &triangles, uint8 tileTessLevel) const;
00597 
00601         void            fillPatchQuadBlock(CPatchQuadBlock &quadBlock) const;
00602 
00609         void            addPatchBlocksInBBox(CPatchIdent paId, const CAABBox &bbox, std::vector<CPatchBlockIdent> &paBlockIds) const;
00610 
00611 
00614         CVector         getTesselatedPos(CUV uv) const;
00615 
00616 
00619         void            appendTessellationLeaves(std::vector<const CTessFace*>  &leaves) const;
00620 
00621 
00622         // @}
00623 
00624 
00626         // @{
00627 
00629         uint8           getLumel(const CUV &uv) const;
00630 
00632         void            appendTileLightInfluences(const CUV &uv, 
00633                 std::vector<CPointLightInfluence> &pointLightList) const;
00634 
00638         void            computeCurrentTLILightmap(NLMISC::CRGBA *array) const;
00639 
00640         // @}
00641 
00642 
00644         // @{
00645 
00647         CTileElement    *getTileElement(const CUV &uv);
00648 
00649         // @}
00650 
00651 public:
00652 
00653         // only usefull for CZone refine.
00654         bool                    isClipped() const {return Clipped;}
00655         // only usefull for CZone preRender.
00656         bool                    isRenderClipped() const {return RenderClipped;}
00657 
00658 
00659         // get the according vertex for a corner. use wisely
00660         const CTessVertex       *getCornerVertex(uint corner)
00661         {
00662                 return BaseVertices[corner];
00663         }
00664 
00665 
00666 public:
00667 
00669         // @{
00670 
00671         // delete all VB allocated in VertexBuffers, according to Far0 and Far1. Do not Test RenderClipped state.
00672         // With VB, allocate to he faces array.
00673         void            deleteVBAndFaceVector();
00674 
00675         // allocate all VB, according to Far0 and Far1. Do not Test RenderClipped state.
00676         // With VB, allocate to he faces array.
00677         void            allocateVBAndFaceVector();
00678 
00679         // fill all VB, according to Far0, Far1 and CTessFace VBInfos. Do not Test RenderClipped state.
00680         // Do not fill a VB if reallocationOccurs().
00681         void            fillVB();
00682 
00683         // if RenderClipped==false, fillVB().
00684         void            fillVBIfVisible();
00685 
00686         // delete Far1 VB allocated in VertexBuffers. do it only if Far1==true. Do not Test RenderClipped state.
00687         // With VB, allocate to he faces array.
00688         void            deleteVBAndFaceVectorFar1Only();
00689 
00690         // allocate Far1 VB, . do it only if Far1==true. Do not Test RenderClipped state.
00691         // With VB, allocate to he faces array.
00692         void            allocateVBAndFaceVectorFar1Only();
00693 
00694         // fill Far0 VB according CTessFace VBInfos and Far0 (do not fill if !Far0). Do not Test RenderClipped state.
00695         // Do not fill a VB if reallocationOccurs().
00696         void            fillVBFar0Only();
00697         // same for Far1
00698         void            fillVBFar1Only();
00699 
00700 
00701         // fill DLM Uv (ie UV1) for Far0 and Far1 VB only. NB: do not fill Far0 if !Far0 (idem fro Far1). 
00702         // Do not Test RenderClipped state. Do not fill a VB if reallocationOccurs().
00703         void            fillVBFarsDLMUvOnly();
00704         void            fillFar0DLMUvOnlyVertexListVB(CTessList<CTessFarVertex>  &vertList);
00705         void            fillFar1DLMUvOnlyVertexListVB(CTessList<CTessFarVertex>  &vertList);
00706 
00707 
00708         // Test Old anc Current RenderClipped test, and fill VBuffer/face/renderPass according to.
00709         void            updateClipPatchVB();
00710 
00711 
00712         // For Debug only.
00713         void            debugAllocationMarkIndices(uint marker);
00714 
00715 
00716         // Because of refine... tessBlock FaceVector may have been deleted, this method do nothing if RenderClipped.
00717         // If not, recreate FaceVector for this tessBlock only, according to Far0 and Far1.
00718         void            recreateTessBlockFaceVector(CTessBlock &block);
00719 
00720 
00721         // @}
00722 
00723 
00724 public:
00725 
00727         // @{
00728 
00730         void            deleteAllVegetableIgs();
00731 
00733         void            recreateAllVegetableIgs();
00734 
00735         // @}
00736 
00737 
00739         // @{
00743         void            resetTileLightInfluences();
00744         // @}
00745 
00746 
00748         // @{
00749 
00751         void            linkBeforeNearUL(CPatch *patchNext);
00753         void            unlinkNearUL();
00755         CPatch          *getNextNearUL() const {return _ULNearNext;}
00756 
00758         uint            getNumNearTessBlocks() const {return TessBlocks.size();}
00759 
00766         uint            updateTessBlockLighting(uint numTb);
00767 
00768         // @}
00769 
00770 
00772         // @{
00773 
00778         void            beginDLMLighting();
00782         void            processDLMLight(CPatchDLMPointLight &pl);
00787         void            endDLMLighting();
00788 
00789         // @}
00790 
00791 
00793         uint            getTileMaterialRefCount() const {return MasterBlock.TileMaterialRefCount;}
00794 
00795 // Private part.
00796 private:
00797 /*********************************/
00798 
00799         friend  class CTessFace;
00800         friend  class CZone;
00801         friend  class CLandscapeVegetableBlock;
00802 
00803         CZone                   *Zone;
00804 
00805         // Number of this patch in the zone. valid at compile Time.
00806         uint16                  PatchId;
00807         // Tile Order for the patch.
00808         uint8                   OrderS, OrderT;
00809 
00810         // This is especially for Pacs. false by default, and used by CZone::refineAll() and CZone::excludePatchFromRefineAll().
00811         bool                    ExcludeFromRefineAll;
00812 
00813         // For this patch, which level is required for a face to be inserted in the secondary TessBlocks (and not the masterblock)??
00814         sint                    TessBlockLimitLevel;
00815         // For this patch, which level is required for a face to be a valid Tile??
00816         sint                    TileLimitLevel;
00817         // For this patch, which level is required for a face to be a "square" face (not rectangular)??
00818         sint                    SquareLimitLevel;
00819         // The Base Size*bumpiness of the patch (/2 at each subdivide).
00820         float                   ErrorSize;
00821         // The root for tesselation.
00822         CTessFace               *Son0, *Son1;
00823         // The base vertices.
00824         CTessVertex             *BaseVertices[4];
00825         // The base Far vertices (always here!!).
00826         CTessFarVertex  BaseFarVertices[4];
00827         // BSphere.
00828         CBSphere                BSphere;
00829 
00830 
00831         // Local info for CTessFace tiles. CPatch must setup them at the begining at refine()/render().
00832         // For Far Texture coordinates.
00833         sint                    Far0;                   // The level of First Far: 0,1,2 or 3. 0 means Tile.
00834         sint                    Far1;                   // The level of second Far, for transition: 1,2 or 3. 0 means none.
00835         float                   Far0UScale, Far0VScale, Far0UBias, Far0VBias;
00836         float                   Far1UScale, Far1VScale, Far1UBias, Far1VBias;
00837 
00838         // Pack 4 bytes
00839         // {
00850         uint8                   Flags;
00851                                                                 
00852         // are we cliped?
00853         bool                    Clipped;
00854         // are we cliped in Render? Yes by default.
00855         bool                    RenderClipped;
00856         // are we cliped in prec Render? Yes by default. updated by updateClipPatchVB().
00857         bool                    OldRenderClipped;
00858 
00859         // }
00860         
00861         // The render Pass of Far0 and Far1.
00862         CRdrPatchId             Pass0, Pass1;
00863         // Info for alpha transition with Far1.
00864         float                   TransitionSqrMin;
00865         float                   OOTransitionSqrDelta;
00866 
00868         // @{
00869         // The block render of far only. Only Far faces bigger than a block are inserted here.
00870         CTessBlock                                      MasterBlock;
00871         // The 2*2 block render. For memory optimisation, none is allocated when no faces need it.
00872         // There is (OrderT/2)*(OrderS/2) TessBlocks.
00873         std::vector<CTessBlock>         TessBlocks;
00874         // The counter of faces which need TessBlocks (FarFaces, TileMaterial and FarVertices). When 0, the vector is contReset()-ed.
00875         sint                                            TessBlockRefCount;
00876         // Tells how many Renderable Face this Patch has. updated in append/remove/FaceToRenderList()
00877         sint                                            NumRenderableFaces;
00878         // @}
00879 
00880 
00882         // @{
00884         std::vector<CVegetableClipBlock*>       VegetableClipBlocks;
00885         // @}
00886 
00887 
00891         static uint32   _Version;
00892 
00893 private:
00894         // Guess.
00895         void                    computeDefaultErrorSize();
00896         // based on BaseVertices, recompute positions, and Make Face roots Son0 and Son1.
00897         void                    makeRoots();
00898         // Guess. For bind() reasons.
00899         CTessFace               *getRootFaceForEdge(sint edge) const;
00900         // Guess. For bind() reasons. return the vertex 0 of edge.
00901         CTessVertex             *getRootVertexForEdge(sint edge) const;
00902         void                    changeEdgeNeighbor(sint edge, CTessFace *to);
00903 
00904 
00906         // @{
00907 
00908         // reset all list of MasterBlock.
00909         void                    resetMasterBlock();
00910         // simply clear the tessnbloc array and reset cout to 0.
00911         void                    clearTessBlocks();
00912         // add a ref to tess blocks, allocate them if necessary.
00913         void                    addRefTessBlocks();
00914         // dec a ref to tess blocks, destroy them if necessary.
00915         void                    decRefTessBlocks();
00916         // UGLY SIDE EFFECT: when refcount TessBlocks RefCount reach 0, tessblockas are deleted. think of it in tesselation.cpp.
00917 
00918 
00919         // Retrieve the tessblockId, depending on face info.
00920         uint                    getNumTessBlock(CTessFace *face);
00921         // FarVertType.
00922         enum                    TFarVertType {FVMasterBlock=0, FVTessBlock, FVTessBlockEdge};
00923         // Retrieve the tessblockId, depending on a ParamCoord.
00924         void                    getNumTessBlock(CParamCoord pc, TFarVertType &type, uint &numtb);
00925 
00926 
00927         // If pathc is visible, force deletion of this TessBlock.
00928         void                    dirtTessBlockFaceVector(CTessBlock &block);
00929 
00930 
00931         // For rdr. Insert in the GOOD TessBlock the face (depending on level, patchcoordinates etc...)
00932         // call appendFaceToTileRenderList() to insert his TileFaces into the good renderList.
00933         void                    appendFaceToRenderList(CTessFace *face);
00934         // Remove a face and his tileface from the patch renderlist.
00935         // call removeFaceFromTileRenderList() to insert his TileFaces into the good renderList.
00936         void                    removeFaceFromRenderList(CTessFace *face);
00937         // for changePatchTexture, insert just the TileFace into the good render List.
00938         void                    appendFaceToTileRenderList(CTessFace *face);
00939         void                    removeFaceFromTileRenderList(CTessFace *face);
00940         // For refreshTesselationGeometry() only. enlarge the TessBlock (if any) with face->V*->EndPos.
00941         void                    extendTessBlockWithEndPos(CTessFace *face);
00942 
00943         // Set/Unset (to NULL) a TileMaterial from the TessBlocks. Material must exist for both functions.
00944         // And TileS/TileT must be OK.
00945         void                    appendTileMaterialToRenderList(CTileMaterial *tm);
00946         void                    removeTileMaterialFromRenderList(CTileMaterial *tm);
00947 
00948         // Add/Remove FarVertices. Use fv->PCoord to know where.
00949         void                    appendFarVertexToRenderList(CTessFarVertex *fv);
00950         void                    removeFarVertexFromRenderList(CTessFarVertex *fv);
00951         // Add/Remove NearVertices. Use tileMat to know where.
00952         void                    appendNearVertexToRenderList(CTileMaterial *tileMat, CTessNearVertex *nv);
00953         void                    removeNearVertexFromRenderList(CTileMaterial *tileMat, CTessNearVertex *nv);
00954 
00955         // @}
00956 
00957 
00958 
00960         // @{
00961         // For CTessFace::computeMaterial(). Return the render pass for this material, given the number of the tile, and the
00962         // desired pass. NULL may be returned if the pass is not present (eg: no additive for this tile...).
00963         CPatchRdrPass   *getTileRenderPass(sint tileId, sint pass);
00964         // For CTessFace::computeMaterial(). Return the orient/scalebias for the tile in the patchtexture, and the
00965         // desired pass (and the desired stage: RGB/Alpha).
00966         void                    getTileUvInfo(sint tileId, sint pass, bool alpha, uint8 &orient, CVector &uvScaleBias, bool &is256x256, uint8 &uvOff);
00967         // @}
00968 
00969         // Tile LightMap mgt.
00970         // @{
00971         // for a given tile (accessed from the (ts,tt) coordinates), compute a lightmap if necessary, and get a RenderPass.
00972         void            getTileLightMap(uint ts, uint tt, CPatchRdrPass *&rdrpass);
00973         // get uvInfo for tile. NB: ts,tt form because simpler.
00974         void            getTileLightMapUvInfo(uint ts, uint tt, CVector &uvScaleBias);
00975         // release the tile lightmap. NB: ts,tt form because simpler.
00976         void            releaseTileLightMap(uint ts, uint tt);
00977 
00978         // Compute the Lightmap for 2x2 tiles. => 10x10 pixels. ts, tt is in [0,OrderS], [0, OrderT].
00979         void            computeNearBlockLightmap(uint ts, uint tt, NLMISC::CRGBA        *lightText);
00980         void            computeTileLightmapPixelAroundCorner(const NLMISC::CVector2f &stIn, NLMISC::CRGBA *dest, bool lookAround);
00981 
00982         // Compute a lightmap for a tile (ts,tt). 4x4 lumels are processed. NB: result= lumel*userColor.
00983         void            computeTileLightmap(uint ts, uint tt, NLMISC::CRGBA *dest, uint stride);
00984         // Compute a lightmap for an edge of a tile. 1x4 lumels. "edge" say what edge of the tile to compute.
00985         // pixels will be written in (dest+i*stride), where i vary from 0 to 3 or 3 to 0 (according to "inverse").
00986         void            computeTileLightmapEdge(uint ts, uint tt, uint edge, NLMISC::CRGBA *dest, uint stride, bool inverse);
00987         // Compute a lightmap just for a pixel (s,t) of a tile (ts,tt). (s,t) E [0;3], [0;3].
00988         void            computeTileLightmapPixel(uint ts, uint tt, uint s, uint t, NLMISC::CRGBA *dest);
00989 
00990 
00991         // Methods for automatic Lighting. NB: result= lumel only (no TileColors).
00992         void            computeTileLightmapAutomatic(uint ts, uint tt, NLMISC::CRGBA *dest, uint stride);
00993         void            computeTileLightmapEdgeAutomatic(uint ts, uint tt, uint edge, NLMISC::CRGBA *dest, uint stride, bool inverse);
00994         void            computeTileLightmapPixelAutomatic(uint ts, uint tt, uint s, uint t, NLMISC::CRGBA *dest);
00995         // Methods for Precomputed Lighting. NB: result= lumel only (no TileColors).
00996         void            computeTileLightmapPrecomputed(uint ts, uint tt, NLMISC::CRGBA *dest, uint stride);
00997         void            computeTileLightmapEdgePrecomputed(uint ts, uint tt, uint edge, NLMISC::CRGBA *dest, uint stride, bool inverse);
00998         void            computeTileLightmapPixelPrecomputed(uint ts, uint tt, uint s, uint t, NLMISC::CRGBA *dest);
00999         // Methods to modulate dest with TileColors. NB: A unmodified.
01000         void            modulateTileLightmapWithTileColors(uint ts, uint tt, NLMISC::CRGBA *dest, uint stride);
01001         void            modulateTileLightmapEdgeWithTileColors(uint ts, uint tt, uint edge, NLMISC::CRGBA *dest, uint stride, bool inverse);
01002         void            modulateTileLightmapPixelWithTileColors(uint ts, uint tt, uint s, uint t, NLMISC::CRGBA *dest);
01003         // get the tileColors at the corners of the tile. corner order: 0,0; 1,0; 0,1; 1,1. NB: A undefined.
01004         void            getTileTileColors(uint ts, uint tt, NLMISC::CRGBA corners[4]);
01005 
01006 
01007         // get the current TLIColor given a TLI coordinate (in (0..OrderS/2+1, 0..OrderT/2+1) )
01008         // NB: returned color is modulated by landscape material and precomputed diffuse factor
01009         CRGBA           CPatch::getCurrentTLIColor(uint x, uint y) const;
01010         // get the current TLIColors at the corners of the tile (according to pointLights current colors)
01011         // corner order: 0,0; 1,0; 0,1; 1,1. NB: A undefined.
01012         void            getCurrentTileTLIColors(uint ts, uint tt, NLMISC::CRGBA corners[4]);
01013         // Methods to add dest with result of TLI lighting. NB: A unmodified.
01014         void            addTileLightmapWithTLI(uint ts, uint tt, NLMISC::CRGBA *dest, uint stride);
01015         void            addTileLightmapEdgeWithTLI(uint ts, uint tt, uint edge, NLMISC::CRGBA *dest, uint stride, bool inverse);
01016         void            addTileLightmapPixelWithTLI(uint ts, uint tt, uint s, uint t, NLMISC::CRGBA *dest);
01017 
01018         // @}
01019 
01020 
01021         // Recompute of new Far Values, according to globals. Don't erase Far0 and Far1.
01022         void            computeNewFar(sint &newFar0, sint &newFar1);
01023 
01024 
01025         // For Render. Those methods compute the vertices for Driver (in CTessFace::Current*VB).
01026         void            fillFar0VertexVB(CTessFarVertex *pVert);
01027         void            fillFar1VertexVB(CTessFarVertex *pVert);
01028         void            fillTileVertexVB(CTessNearVertex *pVert);
01029         void            fillFar0VertexListVB(CTessList<CTessFarVertex>  &vertList);
01030         void            fillFar1VertexListVB(CTessList<CTessFarVertex>  &vertList);
01031         void            fillTileVertexListVB(CTessList<CTessNearVertex> &vertList);
01032         // For Render. Those methods allocate/delete vertices in VB.
01033         void            updateFar0VBAlloc(CTessList<CTessFarVertex>  &vertList, bool alloc);
01034         void            updateFar1VBAlloc(CTessList<CTessFarVertex>  &vertList, bool alloc);
01035         void            updateTileVBAlloc(CTessList<CTessNearVertex>  &vertList, bool alloc);
01036         void            updateVBAlloc(bool alloc);
01037         // For Debug Allcoation only.
01038         void            debugAllocationMarkIndicesFarList(CTessList<CTessFarVertex>  &vertList, uint marker);
01039         void            debugAllocationMarkIndicesNearList(CTessList<CTessNearVertex>  &vertList, uint marker);
01040         // For Render. Allocate / Fill FaceVector, according to Far0/Far1.
01041         void            createFaceVectorFar1();
01042         void            deleteFaceVectorFar1();
01043         void            createFaceVectorFar0OrTile();
01044         void            deleteFaceVectorFar0OrTile();
01045 
01046 
01047 
01048         // For Refine. Those methods do all the good job, and test if they can allocate the VB.
01049         void            checkCreateVertexVBFar(CTessFarVertex *pVert);
01050         void            checkCreateVertexVBNear(CTessNearVertex *pVert);
01051         // For Refine. Those methods do all the good job, and test if they can fill the VB.
01052         void            checkFillVertexVBFar(CTessFarVertex *pVert);
01053         void            checkFillVertexVBNear(CTessNearVertex   *pVert);
01054         // For Refine. Those methods do all the good job, and test if they have to delete the VB.
01055         void            checkDeleteVertexVBFar(CTessFarVertex *pVert);
01056         void            checkDeleteVertexVBNear(CTessNearVertex *pVert);
01057 
01058         // For Render, geomorph / Alpha in software.
01059         void            computeGeomorphVertexList(CTessList<CTessFarVertex>  &vertList);
01060         void            computeGeomorphFar0VertexListVB(CTessList<CTessFarVertex>  &vertList);
01061         void            computeGeomorphAlphaFar1VertexListVB(CTessList<CTessFarVertex>  &vertList);
01062         void            computeGeomorphTileVertexListVB(CTessList<CTessNearVertex>  &vertList);
01063 
01065         // @{
01067         void            buildBBoxFromBezierPatch(const CBezierPatch &p, CAABBox &ret) const;
01073         void            addTrianglesInBBoxRecurs(CPatchIdent paId, const CAABBox &bbox, std::vector<CTrianglePatch> &triangles, uint8 tessLevel, 
01074                 const CBezierPatch &pa, uint8 s0, uint8 s1, uint8 t0, uint8 t1) const;
01079         void            addTileTrianglesInBBox(CPatchIdent paId, const CAABBox &bbox, std::vector<CTrianglePatch> &triangles, uint8 tessLevel, 
01080                 uint8 s0, uint8 t0) const;
01081 
01084         void            addPatchBlocksInBBoxRecurs(CPatchIdent paId, const CAABBox &bbox, std::vector<CPatchBlockIdent> &paBlockIds, 
01085                 const CBezierPatch &pa, uint8 s0, uint8 s1, uint8 t0, uint8 t1) const;
01086 
01088         CVector         computeVertexButCorner(float s, float t, bool &onCorner) const;
01089 
01090         // @}
01091 
01092 
01093 private:
01094 
01095 
01096 
01098         // @{
01099 
01101         CZone           *_BindZoneNeighbor[4];
01102 
01106         CTessFace       *linkTessFaceWithEdge(const NLMISC::CVector2f &uv0, const NLMISC::CVector2f &uv1, CTessFace *linkTo);
01107 
01108         // @}
01109 
01110 
01111 
01113         // @{
01114 
01115 
01116         float           computeDisplaceRawInteger(sint ts, sint tt, sint ms, sint mt) const;
01117         void            computeDisplaceRawCoordinates(float sTile, float tTile, float s, float t,
01118         sint &ts, sint &tt, sint &ms, sint &mt) const;
01124         float           computeDisplaceRaw(float sTile, float tTile, float s, float t) const;
01128         float           computeDisplaceRawOnNeighbor(float sTile, float tTile, float s, float t) const;
01129 
01130 
01133         float           computeDisplaceInteriorSmooth(float s, float t) const;
01136         float           computeDisplaceEdgeSmooth(float s, float t, sint8 smoothBorderX, sint8 smoothBorderY) const;
01139         float           computeDisplaceCornerSmooth(float s, float t, sint8 smoothBorderX, sint8 smoothBorderY) const;
01140 
01141 
01144         CVector         computeNormalEdgeSmooth(float s, float t, sint8 smoothBorderX, sint8 smoothBorderY) const;
01147         CVector         computeNormalCornerSmooth(float s, float t, sint8 smoothBorderX, sint8 smoothBorderY) const;
01150         CVector         computeNormalOnNeighbor(float s, float t, uint edgeExclude) const;
01151 
01152 
01156         void            computeNoise(float s, float t, CVector &displace) const;
01157 
01158         // @}
01159 
01160 
01161         // From tile coordinates, return the tessBlockId, and the id of the material in this tessBlock.
01162         void            computeTbTm(uint &numtb, uint &numtm, uint ts, uint tt);
01163 
01164 
01166         // @{
01167 
01169         void            createVegetableBlock(uint numTb, uint ts, uint tt);
01171         void            releaseVegetableBlock(uint numTb);
01172 
01173         /*
01174                 generate the vegetables for a given tile in the vegetable manager.
01175                 instances are added to vegetIg.
01176                 Warning! Use OptFastFloor()! So call must be enclosed with a OptFastFloorBegin()/OptFastFloorEnd().
01177         */
01178         void            generateTileVegetable(CVegetableInstanceGroup *vegetIg, uint distType, uint ts, uint tt,
01179                 CLandscapeVegetableBlockCreateContext &vbCreateCtx);
01180 
01181         // same as computeTileLightmapPrecomputed(), but brut result, not modified by colorTable.
01182         void            getTileLumelmapPrecomputed(uint ts, uint tt, uint8 *dest, uint stride);
01186         void            getTileLumelmapPixelPrecomputed(uint ts, uint tt, uint s, uint t, uint8 &dest) const;
01187 
01188         // @}
01189 
01190 
01192         // @{
01193         CPatch          *_ULNearPrec;
01194         CPatch          *_ULNearNext;
01195         // @}
01196 
01197 
01199         // @{
01200 
01205         CPatchDLMContext        *_DLMContext;
01206 
01210         sint                            _DLMContextRefCount;
01211 
01213         void                            addRefDLMContext();
01215         void                            decRefDLMContext(uint count= 1);
01216 
01217         // @}
01218 
01219 
01220 private:
01221         // NB: All global render info are stored in CTessFace class static members....
01222 
01223         // The Patch cache (may be a short list/vector later...).
01224         static  CBezierPatch    CachePatch;
01225         // For cahcing.
01226         static  const CPatch    *LastPatch;
01227 
01228 public:
01229         // unpack the patch into the cache.
01230         CBezierPatch    *unpackIntoCache() const;
01231 
01232 };
01233 
01234 
01235 } // NL3D
01236 
01237 
01238 #endif // NL_PATCH_H
01239 
01240 /* End of patch.h */