# 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  

nel_patch_mesh.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef __RYKOL_PATCH_MESH_H
00027 #define __RYKOL_PATCH_MESH_H
00028 
00029 #pragma warning (disable : 4786)
00030 #include <vector>
00031 #include <set>
00032 #include <string>
00033 #include <nel/misc/debug.h>
00034 #include <nel/3d/tile_bank.h>
00035 #include <nel/misc/file.h>
00036 #include <nel/misc/rgba.h>
00037 #include "path_mesh_alloc.h"
00038 
00039 //#define USE_CACHE
00040 
00041 namespace NL3D
00042 {
00043 class CZone;
00044 };
00045 
00046 typedef unsigned int uint;
00047 
00048 #define RYKOLPATCHOBJ_CLASS_ID  Class_ID(0x368c679f, 0x711c22ee)
00049 
00050 extern TCHAR *GetString(int id);
00051 
00052 extern HINSTANCE hInstance;
00053 
00054 extern ClassDesc* GetRPODesc();
00055 
00056 #define RPATCHMESH_SERIALIZE_VERSION_7 7
00057 #define RPATCHMESH_SERIALIZE_VERSION_6 6
00058 #define RPATCHMESH_SERIALIZE_VERSION_5 5
00059 #define RPATCHMESH_SERIALIZE_VERSION_4 4
00060 #define RPATCHMESH_SERIALIZE_VERSION_3 3
00061 #define RPATCHMESH_SERIALIZE_VERSION_2 2
00062 #define RPATCHMESH_SERIALIZE_VERSION_1 1
00063 #define RPATCHMESH_SERIALIZE_VERSION RPATCHMESH_SERIALIZE_VERSION_7
00064 
00065 #define EP_OBJECT       0
00066 #define EP_VERTEX       1
00067 #define EP_EDGE         2
00068 #define EP_PATCH        3
00069 #define EP_TILE         4
00070 
00071 #define PO_TILE         4
00072 
00073 #define PATCH_HIT_TILE (PATCH_HIT_INTERIOR+1)
00074 
00075 #define MAX_TILE_IN_PATCH 16
00076 #define NUM_TILE_SEL (MAX_TILE_IN_PATCH*MAX_TILE_IN_PATCH)
00077 
00078 #pragma warning (disable : 4786)
00079 
00080 // ------------------------------------------------------------------------------------------------------------------------------------------------
00081 
00082 /*
00083 
00084   Here the user infos (UI) for face, edge, vertex, vertex-face.
00085   All these infos are stored in one class (RPO_UI) through vectors 
00086 
00087 
00088 */
00089 
00090 class CVertexNeighborhood;
00091 
00092 int CheckBind (int nVert, int nSeg, int& v0, int& v1, int& v2, int& v3, const CVertexNeighborhood& tab, const PatchMesh& patch, bool bAssert, bool bCreate);
00093 std::string GetBankPathName ();
00094 int GetBankTileSetSet ();
00095 void SetBankPathName (const std::string& path);
00096 void SetBankTileSetSet (int);
00097 int WhereIsTheEdge (int nPatch, int nEdge, const PatchMesh& patch);
00098 
00099 extern NL3D::CTileBank bank;
00100 
00101 #define RPO_DEFAULT_TESSEL 4
00102 
00103 enum typeBind { BIND_25=0, BIND_75, BIND_50, BIND_SINGLE, BIND_COUNT, BIND_ALIGN=0xffffffff };
00104 
00105 extern float bindWhere[BIND_COUNT];
00106 
00107 class bindingDesc
00108 {
00109 public:
00110         uint8                   bBinded;                        // true, this vertex is binded, false, is not. default 0
00111         uint8                   nType;                          // Type of the vertex
00112         uint16                  nPatch;                         // # of the patch on which the vertex is binded. Valid only if bBinded==true.
00113         uint16                  nEdge;                          // # of the edge in the patch on which the vertex is binded. Valid only if bBinded==true.
00114         uint16                  nPrimVert;                      // # of the primary vertex in this bind
00115         uint16                  nBefore;                        // # of the before tangant
00116         uint16                  nBefore2;                       // # of the before tangant
00117         uint16                  nAfter;                         // # of the after tangant
00118         uint16                  nAfter2;                        // # of the after tangant
00119         uint16                  nT;                                     // # of the tangant of the binded edge
00120         uint16                  fnslmq;
00121         //float                 fWhere;                         // Where on the edge the vertex is binded. Value must be 0.25f, 0.5f or 0.75f.
00122                                                                                 // Valid only if bBinded==true.
00123 };
00124 
00125 class tileIndex
00126 {
00127 public:
00128         tileIndex ()
00129         {}
00130         tileIndex ( bool invert, int tile, int rotate)
00131         {
00132                 Invert=invert;
00133                 Tile=tile;
00134                 Rotate=rotate;
00135         }
00136         uint Tile:16;
00137         int Rotate:8;
00138         int Invert:1;
00139 };
00140 
00141 class tileDesc
00142 {
00143 #define CASE_MASK 0x7
00144         friend class RPatchMesh;
00145 public:
00146         void setTile (int num, int ncase, tileIndex tile0, tileIndex tile1, tileIndex tile2)
00147         {
00148                 _Num=num;
00149                 _MatIDTab[0]=tile0;
00150                 _MatIDTab[1]=tile1;
00151                 _MatIDTab[2]=tile2;
00152                 setCase (ncase);
00153         }
00154         tileIndex& getLayer (int num)
00155         {
00156                 return _MatIDTab[num];
00157         }
00158         const tileIndex& getLayer (int num) const
00159         {
00160                 return _MatIDTab[num];
00161         }
00162         int getNumLayer ()
00163         {
00164                 return _Num;
00165         }
00166         void setEmpty ()
00167         {
00168                 _Num=0;
00169                 _Flags=0;
00170         }
00171         bool isEmpty ()
00172         {
00173                 return _Num==0;
00174         }
00175         void rotate (int nRotate)
00176         {
00177                 for (int i=0; i<3; i++)
00178                 {
00179                         _MatIDTab[i].Rotate+=nRotate;
00180                         _MatIDTab[i].Rotate&=3;
00181                 }
00182         }
00183         int getCase() const
00184         {
00185                 return _Flags&CASE_MASK;
00186         }
00187         void setCase(int nCase)
00188         {
00189                 nlassert ((nCase>=0)&&(nCase<5));
00190                 _Flags&=~CASE_MASK;
00191                 _Flags|=nCase;
00192         }
00193 private:
00194         tileIndex _MatIDTab[3];
00195         USHORT  _Num;
00196         USHORT  _Flags;
00197 };
00198 
00199 class UI_VERTEX
00200 {
00201 public:
00202         bindingDesc             Binding;                        // Binding struct for the vertex
00203         void Init ()
00204         {
00205                 Binding.bBinded=false;
00206         }
00207 };
00208 
00209 // Edge flags for no smoothing
00210 #define UI_EDGE_FLAGS_NO_SMOOTH_MASK    0x1
00211 
00212 // User info for edge
00213 class CEdgeInfo
00214 {
00215 public:
00216         // Default Ctor
00217         CEdgeInfo ()
00218         {
00219                 // No flags 
00220                 Flags=0;
00221         }
00222 
00223         // Flags for a edge
00224         uint32  Flags;
00225 };
00226 
00227 class UI_PATCH
00228 {
00229 public:
00230         int                                     NbTilesU;               // Default = 3 (2^3 = 8)
00231         int                                     NbTilesV;               // Default = 3 (2^3 = 8)
00232 
00233 private:
00234         // Tabl for tile number ( size: (2^NbTilesU) * (2^NbTilesV) ) default, all 0
00235         tileDesc                        Tile[16*16];
00236 
00237         // Tabl for color on tile ( size: ((2^NbTilesU)+1) * ((2^NbTilesV)+1) ) default, all 0xffffffff. Color in 32 bits ARGB.
00238         uint                            Colors[17*17];
00239 
00240         // Info by edges
00241         CEdgeInfo                       _Edges[4];
00242 public:
00243         // Return  a tileDesc ref
00244         tileDesc& getTileDesc (uint iD)
00245         {
00246                 // Debug
00247                 nlassert (iD<getTileSize ());
00248 
00249                 // Return the ref
00250                 return Tile[iD];
00251         }
00252 
00253         // Return a const tileDesc ref
00254         const tileDesc& getTileDesc (uint iD) const
00255         {
00256                 // Debug
00257                 nlassert (iD<getTileSize ());
00258 
00259                 // Return the ref
00260                 return Tile[iD];
00261         }
00262 
00263         // Return  a color ref
00264         uint getColor (uint iD) const
00265         {
00266                 // Debug
00267                 nlassert (iD<getColorSize ());
00268 
00269                 // Return the ref
00270                 return Colors[iD];
00271         }
00272 
00273         // Return a const tileDesc ref
00274         void setColor (uint iD, uint newColor)
00275         {
00276                 // Debug
00277                 nlassert (iD<getColorSize ());
00278 
00279                 // Return the ref
00280                 Colors[iD]=newColor;
00281         }
00282 
00283         // Return the size of the Tile array
00284         uint getTileSize () const
00285         {
00286                 return (1<<NbTilesU)*(1<<NbTilesV);
00287         }
00288 
00289         // Return the size of the Color array
00290         uint getColorSize () const
00291         {
00292                 return ((1<<NbTilesU)+1)*((1<<NbTilesV)+1);
00293         }
00294 
00295         // Return edge flags
00296         bool getEdgeFlag (uint edge)
00297         {
00298                 nlassert ((edge>=0)&&(edge<4));
00299                 return (_Edges[edge].Flags&UI_EDGE_FLAGS_NO_SMOOTH_MASK)!=0;
00300         }
00301 
00302         // Set edge flags
00303         void setEdgeFlag (uint edge, bool flags)
00304         {
00305                 nlassert ((edge>=0)&&(edge<4));
00306                 // Erase and set the flag
00307                 _Edges[edge].Flags&=~UI_EDGE_FLAGS_NO_SMOOTH_MASK;
00308                 _Edges[edge].Flags|=(uint32)flags;
00309         }
00310 
00311         // Get edge
00312         CEdgeInfo& getEdge (uint edge)
00313         {
00314                 return _Edges[edge];
00315         }
00316 
00317         // Get edge
00318         const CEdgeInfo& getEdge (uint edge) const
00319         {
00320                 return _Edges[edge];
00321         }
00322 public:
00323         void Init (int nU=RPO_DEFAULT_TESSEL, int nV=RPO_DEFAULT_TESSEL, bool bKeep=false)
00324         {
00325                 // Copy old patch infos
00326                 UI_PATCH old=*this;
00327 
00328                 // New size
00329                 int nOldU=old.NbTilesU;
00330                 int nOldV=old.NbTilesV;
00331                 int nNewU=1<<nU;
00332                 int nNewV=1<<nV;
00333                 NbTilesU=nU;
00334                 NbTilesV=nV;
00335                 int nTileCount=(1<<NbTilesU)*(1<<NbTilesV);
00336                 int nVertexCount=((1<<NbTilesU)+1)*((1<<NbTilesV)+1);
00337 
00338                 // Keep old infos
00339                 if (bKeep)
00340                 {
00341                         // Copy old coord...
00342                         int i,j;
00343                         int nMinU=std::min (nOldU, nNewU);
00344                         int nMinV=std::min (nOldV, nNewV);
00345                         for (j=0; j<nMinV; j++)
00346                         {
00347                                 for (i=0; i<nMinU; i++)
00348                                 {
00349                                         Tile[i+j*nNewU]=old.getTileDesc (i+j*nOldU);
00350                                 }
00351                                 for (; i<nNewU; i++)
00352                                 {
00353                                         Tile[i+j*nNewU].setEmpty ();
00354                                 }
00355                         }
00356                         for (; j<nNewV; j++)
00357                         {
00358                                 for (i=0; i<nNewU; i++)
00359                                 {
00360                                         Tile[i+j*nNewU].setEmpty ();
00361                                 }
00362                         }
00363                         for (j=0; j<nMinV+1; j++)
00364                         {
00365                                 for (i=0; i<nMinU+1; i++)
00366                                 {
00367                                         Colors[i+j*(nNewU+1)]=old.getColor (i+j*(nOldU+1));
00368                                 }
00369                                 for (; i<nNewU+1; i++)
00370                                 {
00371                                         Colors[i+j*nNewU]=0xffffff;
00372                                 }
00373                         }
00374                         for (; j<nNewV+1; j++)
00375                         {
00376                                 for (i=0; i<nMinU+1; i++)
00377                                 {
00378                                         Colors[i+j*nNewU]=0xffffff;
00379                                 }
00380                         }
00381                 }
00382                 else
00383                 {
00384                         // Init new coord
00385                         int j;
00386                         for(j=0; j<nTileCount; j++)
00387                         {
00388                                 Tile[j].setEmpty ();
00389                         }
00390                         for(j=0; j<nVertexCount; j++)
00391                         {
00392                                 Colors[j]=0xffffff;
00393                         }
00394                 }
00395         }
00396 };
00397 
00398 class CPatchAllocator
00399 {
00400 public:
00401         CPatchAllocator ();
00402         CPathMeshAlloc<UI_PATCH>        AllocPatch;             // 100 patch by mesh
00403         CPathMeshAlloc<UI_VERTEX>       AllocVertex;            // 100 vertices by mesh
00404         CPathMeshAlloc<int>                     AllocInt;
00405 };
00406 
00407 struct RPOTess
00408 {
00409         int                             TileTesselLevel;
00410         bool                    ModeTile;
00411         bool                    KeepMapping;
00412         int                             TransitionType;
00413 };
00414 
00415 class CBankManager
00416 {
00417 public:
00418         CBankManager ()
00419         {
00420                 _lastPath="";
00421         }
00422         const NL3D::CTileBank& getBank (std::string& path=GetBankPathName ())
00423         {
00424                 if (path!=_lastPath)
00425                 {
00426                         try
00427                         {
00428                                 NLMISC::CIFile file;
00429                                 if (file.open (path))
00430                                 {
00431                                         _bank.clear();
00432                                         _bank.serial (file);
00433                                 }
00434                         }
00435                         catch (NLMISC::EStream& excp)
00436                         {
00437                                 MessageBox (NULL, excp.what(), "Load error", MB_OK|MB_ICONEXCLAMATION);
00438                         }
00439                 }
00440                 return _bank;
00441         }
00442 private:
00443         NL3D::CTileBank _bank;
00444         std::string _lastPath;
00445 };
00446 
00447 // Class container of data with copy operator
00448 class CPatchMeshData
00449 {
00450 public:
00451         // Default constructor, allocate the array
00452         CPatchMeshData ();
00453 
00454         // Copy constructor, allocate the array
00455         CPatchMeshData (const CPatchMeshData& src);
00456         // Destructor
00457         ~CPatchMeshData ();
00458 
00459         // Copy
00460         CPatchMeshData& operator= (const CPatchMeshData& src);
00461 
00462         // The pointers
00463         std::vector<UI_PATCH>   *_UIPatch;
00464         std::vector<UI_VERTEX>  *_UIVertex;
00465         std::vector<int>                *_MapHitToTileIndex;
00466 };
00467 
00468 class RPatchMesh
00469 {
00470         friend class RPO;
00471 public:
00472         RPatchMesh ();
00473         ~RPatchMesh ();
00474 
00475         // Info per patch
00476         
00477 private:
00478         CPatchMeshData          _Data;
00479 private:
00480         // Remap the map hit size
00481         void resizeMapHit (uint size)
00482         {
00483                 _Data._MapHitToTileIndex->resize (size);
00484         }
00485 
00486         // Remap the map hit size
00487         void setRemapEntry (uint iD, uint remap)
00488         {
00489                 (*_Data._MapHitToTileIndex)[iD]=remap;
00490         }
00491 
00492         // Resize the user info size
00493         void resizeUIPatch (uint size)
00494         {
00495                 _Data._UIPatch->resize (size);
00496         }
00497 
00498         // Resize the user info size
00499         void resizeUIVertex (uint size)
00500         {
00501                 _Data._UIVertex->resize (size);
00502         }
00503 public:
00504         // Get map hit size
00505         uint getMapHitSize () const
00506         {
00507                 return _Data._MapHitToTileIndex->size ();
00508         }
00509 
00510         // Remap a triangle
00511         uint remapTriangle (uint iD) const
00512         {
00513                 nlassert (iD<getMapHitSize ());
00514                 return (*_Data._MapHitToTileIndex)[iD];
00515         }
00516 
00517         // Get the patch user info size
00518         uint getUIPatchSize () const
00519         {
00520                 return _Data._UIPatch->size();
00521         }
00522 
00523         // Get a patch user info
00524         UI_PATCH& getUIPatch (uint iD)
00525         {
00526                 // Check
00527                 nlassert (iD<getUIPatchSize ());
00528 
00529                 return (*_Data._UIPatch)[iD];
00530         }
00531 
00532         // Get a const patch user info
00533         const UI_PATCH& getUIPatch (uint iD) const
00534         {
00535                 // Check
00536                 nlassert (iD<getUIPatchSize ());
00537 
00538                 return (*_Data._UIPatch)[iD];
00539         }
00540 
00541         // Get vertex user info size
00542         uint getUIVertexSize () const
00543         {
00544                 return _Data._UIVertex->size();
00545         }
00546 
00547         // Get a vertex user info
00548         UI_VERTEX& getUIVertex (uint iD)
00549         {
00550                 // Check
00551                 nlassert (iD<getUIVertexSize ());
00552 
00553                 return (*_Data._UIVertex)[iD];
00554         }
00555 
00556         // Get a const vertex user info
00557         const UI_VERTEX& getUIVertex (uint iD) const
00558         {
00559                 // Check
00560                 nlassert (iD<getUIVertexSize ());
00561 
00562                 return (*_Data._UIVertex)[iD];
00563         }
00564 
00565 public:
00566         // Validity of the mesh
00567         Interval                        ValidGeom;
00568         Interval                        ValidTopo;
00569         Interval                        ValidTexmap;
00570         Interval                        ValidSelect;
00571         Interval                        ValidDisplay;
00572         Interval                        ValidBindingPos;
00573         Interval                        ValidBindingInfo;
00574         BitArray                        tileSel;
00575 #pragma warning (disable : 4786)
00576 
00577         // Tessel mode
00578         RPOTess                         rTess;
00579 private:
00580         // cached Mesh for the ModeRykolPatchMesh mode
00581         Mesh                            mesh;
00582 
00583         int                                     selLevel;
00584         int                                     tileSet;
00585         int                                     build;
00586 public:
00587         bool                            paint;
00588         bool                            paintHack;
00589 private:
00590         static CBankManager     manager;
00591 
00592         // Fill the binding info for a vertex. Don't forget to call UpdateBindingInfo after
00593         void BindingVertex (int nVertex, int nPatch, int nEdge, int nPrimary, typeBind nType);
00594 
00595         // Unbind a vertex
00596         void UnBindingVertex (int nVertex);
00597 
00598         // Unbind vertex associed to the patch
00599         void UnbindRelatedPatch (int nPatch, PatchMesh& patch);
00600 
00601         // Unbind vertex associed to the vertex
00602         void UnbindRelatedVertex (int nPatch, PatchMesh& patch);
00603 
00604         // Update binded vertices's position BIND SAFE
00605         void UpdateBindingPos (PatchMesh& patch);
00606 
00607         // Build internal binding info
00608         void UpdateBindingInfo (PatchMesh& patch);
00609 
00610         // Look for a patch with this edge
00611         void FindPatch (PatchMesh *patch, int nEdge, int &WhichEdge, int &nPatch, int nFirstPatch);
00612 public:
00613         // Constructor
00614         RPatchMesh (PatchMesh *pmesh);          // Patch mesh
00615 
00616         // Invalidate binding infos
00617         void InvalidateBindingPos () { ValidBindingPos=NEVER; };
00618         void InvalidateBindingInfo () { ValidBindingInfo=NEVER; InvalidateBindingPos (); };
00619 
00620         // Update binding
00621         void UpdateBinding (PatchMesh& patch, TimeValue t);
00622 
00623         // Check the validity of the RPatchMesh's data with the RPO's data (debug stuff) BIND SAFE
00624         bool Validity (const PatchMesh& patch, bool bAssert);
00625 
00626         // Resize vertex buffer BIND SAFE
00627         void SetNumVerts (int nVert);
00628 
00629         // Resize patches buffer BIND SAFE
00630         void SetNumPatches (int nPatch);
00631 
00632         // Subdivide both way BIND SAFE
00633         void Subdivide (int nPatch, int nV0, int nV1, int nV2, int nV3, int nCenter, int nFirstPatch, PatchMesh& patch);
00634 
00635         // Subdivide edge 1 and 3 BIND SAFE
00636         void SubdivideU (int nPatch, int nV0, int nV1, int nFirstPatch, PatchMesh& patch);
00637 
00638         // Subdivide edge 0 and 2 BIND SAFE
00639         void SubdivideV (int nPatch, int nV0, int nV1, int nFirstPatch, PatchMesh& patch);
00640 
00641         // AddHook BIND SAFE
00642         void AddHook (int nVert, int nSeg, PatchMesh& patch);
00643 
00644         // AddHook BIND SAFE
00645         void AddHook (int nVert0, int nVert1, int nVert2, int nSeg, PatchMesh& patch);
00646 
00647         // RemoveHook BIND SAFE
00648         void RemoveHook (PatchMesh& patch);
00649 
00650         // Attach BIND SAFE
00651         void Attach(RPatchMesh *rattPatch, PatchMesh& patch);
00652 
00653         // Extrude BIND SAFE
00654         void CreateExtrusion (PatchMesh *rpatch);
00655 
00656         // Weld BIND SAFE
00657         void Weld (PatchMesh *patch);
00658 
00659         // Add a patch BIND SAFE
00660         void AddPatch (int nEdge, int nFirstPatch, PatchMesh *patch);
00661 
00662         // Delete patches and vertices BIND SAFE
00663         void DeleteAndSweep (const BitArray &remapVerts, const BitArray &remapPatches, PatchMesh& patch);
00664 
00665         // Invalidate channels BIND SAFE
00666         void InvalidateChannels(ChannelMask channels);
00667 
00668         // Update topo change BIND SAFE
00669         void ResolveTopoChanges(PatchMesh *patch);
00670 
00671         // Change sel level BIND SAFE
00672         void SetSelLevel (int sellevel)
00673         {
00674                 selLevel=sellevel;
00675                 InvalidateChannels(PART_SELECT);
00676         }
00677 
00678         // Get sel level BIND SAFE
00679         int GetSelLevel ()
00680         {
00681                 return selLevel;
00682         }
00683 
00684         // Load
00685         IOResult Load(ILoad *iload);
00686 
00687         // Save
00688         IOResult Save(ISave *isave);
00689 
00690         // *** Tile Methods
00691 
00692         // Get the matrix of the selected tiles
00693         Matrix3 GetSelTileTm(PatchMesh& patch, TimeValue t, INode *node, bool& bHasSel) const;
00694 
00695         // Get the center of the selected tiles
00696         Point3 GetSelTileCenter(PatchMesh& patch, TimeValue t, INode *node, bool& bHasSel) const;
00697 
00698         // Hittest method
00699         BOOL SubObjectHitTest(GraphicsWindow *gw, Material *ma, HitRegion *hr, DWORD flags, SubPatchHitList& hitList, TimeValue t, 
00700                 PatchMesh& patch);
00701 
00702         // Return the tile number
00703         int GetTileNumber(int nPatch, int nU, int nV) const
00704         {
00705                 nlassert (nU>=0);
00706                 nlassert (nU<MAX_TILE_IN_PATCH);
00707                 nlassert (nV>=0);
00708                 nlassert (nV<MAX_TILE_IN_PATCH);
00709                 return nV*MAX_TILE_IN_PATCH+nU+nPatch*NUM_TILE_SEL;
00710         }
00711 
00712         // Build the mesh
00713         void BuildMesh(TimeValue t, PatchMesh& patch, Mesh *pMesh=NULL);
00714 
00715         // Get tessel level of a patch
00716         void GetPatchTess (int nPatch, int& nUTess, int& nVTess);
00717 
00718         // Display
00719         int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, PatchMesh& patch);
00720 
00721         // Tile access
00722         tileDesc& getTileDesc (int nTile);
00723 
00724         // Tile access
00725         void setTileDesc (int nTile, const tileDesc& desc);
00726 
00727         // Turn selected patch
00728         void TurnPatch(PatchMesh *patch);
00729 
00730         // Export a zone to NeL format
00731         void exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, int zoneId);
00732 
00733         // *** Vertex color Methods
00734 
00735         // Get the vertex color of a patch
00736         void getVertexColor (int patch, int s, int t, NLMISC::CRGBA& dest)
00737         {
00738                 // Get the color
00739                 uint encodedColor=getUIPatch (patch).getColor (t*((1<<getUIPatch (patch).NbTilesU)+1)+s);
00740 
00741                 // Store the color
00742                 dest.A=encodedColor>>24;
00743                 dest.R=(encodedColor>>16)&0xff;
00744                 dest.G=(encodedColor>>8)&0xff;
00745                 dest.B=encodedColor&0xff;
00746         }
00747 
00748         // Set the vertex color of a patch
00749         void setVertexColor (int patch, int s, int t, const NLMISC::CRGBA& newColor)
00750         {
00751                 // Get the color
00752                 uint encodedColor=(newColor.A<<24)|(newColor.R<<16)|(newColor.G<<8)|newColor.B;
00753                 
00754                 // Store the color
00755                 getUIPatch (patch).setColor (t*((1<<getUIPatch (patch).NbTilesU)+1)+s, encodedColor);
00756         }
00757 };
00758 
00759 // ------------------------------------------------------------------------------------------------------------------------------------------------
00760 
00761 #endif // __RYKOL_PATCH_MESH_H