00001 // 00002 // This code is a hacked up version of the Demeter Terrain 00003 // code from http://www.terrainengine.com 00004 // (hacked up because I removed the SDL and CommonC++ 00005 // dependencies, and helpded it compile with gcc3.x) 00006 // -David Jung. 00007 // 00008 00009 // Demeter Terrain Visualization Library by Clay Fowler 00010 // Copyright (C) 2001 Clay Fowler 00011 00012 /* 00013 This library is free software; you can redistribute it and/or 00014 modify it under the terms of the GNU Lesser General Public 00015 License as published by the Free Software Foundation; either 00016 version 2.1 of the License, or (at your option) any later version. 00017 00018 This library is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 Library General Public License for more details. 00022 00023 You should have received a copy of the GNU Library General Public 00024 License along with this library; if not, write to the 00025 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00026 Boston, MA 02111-1307, USA. 00027 */ 00028 00029 //#define _USE_RAYTRACING_SUPPORT_ 00030 //_USE_RAYTRACING_SUPPORT_ enables the ray tracing methods on the Terrain class, but increases 00031 //memory usage considerably. Demeter's ray tracing is very fast and can be used for mouse picking, 00032 //line-of-sight tests, etc. If you enable this option, then be aware that MUCH more memory will be needed, 00033 //particularly for terrains that are over 256x256 vertices. With this option turned off, larger 00034 //terrains are no problem. 00035 00036 //#define _USE_VERTEX_ARRAYS_ 00037 // _USE_VERTEX_ARRAYS_ turns on OpenGL vertex arrays for the terrain vertices. There are 00038 // still some unresolved problems with the use of vertex arrays, such as how to use 00039 // multi-texturing with vertex arrays, how to correctly assign texture coordinates, etc. so 00040 // you should only enable this option if you want to debug some of these problems for yourself. 00041 00042 //#define _PROTECT_ACCESS_ 00043 // _PROTECT_ACCESS_ turns on extra checks to validate parameters passed to various terrain methods to make sure 00044 // the parameters are within range. Turn this option on when you want the Terrain to clamp 00045 // all values to legal ranges for you - this will slow performance but lets external callers 00046 // not worry about clamping values. If external callers can be trusted to keep all parameters within 00047 // legal extents, then disable this option for performance gains. 00048 00049 #define _SUPPORT_OPENSCENEGRAPH_ 00050 // _SUPPORT_OPENSCENEGRAPH_ makes the Terrain class a "Drawable" for use in OpenSceneGraph. 00051 // If you enable this flag, you will need to have OpenSceneGraph installed on your system 00052 // in order to build Demeter. 00053 00054 #ifndef _GFX_CLODTERRAINRENDERER_ 00055 #define _GFX_CLODTERRAINRENDERER_ 00056 00057 #include <gfx/gfx> 00058 #include <base/BitArray> 00059 #include <string> 00060 00061 #include <GL/gl.h> 00062 #include <GL/glu.h> 00063 00064 // Get rid of these if possible 00065 #include <cstdlib> 00066 #include <cmath> 00067 #include <cstdio> 00068 00069 #include <vector> 00070 00071 #include <osg/Referenced> 00072 00073 #define MAX_VERTICES_PER_FAN 10 00074 #define EPSILON 0.00001f 00075 #ifdef INFINITY 00076 #undef INFINITY 00077 #endif 00078 #define INFINITY 999999999.0f 00079 00080 // Forgive the long comment lines. They are all single lines to accomodate doxygen. 00081 00082 namespace demeter 00083 { 00084 class TerrainBlock; 00085 class Terrain; 00086 class Manifest; 00087 class TriangleStrip; 00088 class TriangleFan; 00089 class Vector; 00090 00091 typedef base::Byte Uint8; 00092 typedef unsigned int Uint32; 00093 00094 /// An extremely basic 3D plane class. 00095 class Plane 00096 { 00097 public: 00098 Plane() {} 00099 Plane( Vector& p1,Vector& p2,Vector& p3 ); 00100 ~Plane() {} 00101 void defineFromPoints( Vector& p1,Vector& p2,Vector& p3 ); 00102 float a,b,c,d; 00103 }; 00104 00105 /// An extremely basic 3D vector class. Demeter does not rely on all of the bells and whistles of most public vector classes 00106 class Vector 00107 { 00108 public: 00109 Vector() {} 00110 ~Vector() {} 00111 float GetLength(); 00112 float Normalize( float tolerance = EPSILON ); 00113 Vector& operator = ( const Vector& vector ); 00114 float x,y,z; 00115 }; 00116 00117 class Ray 00118 { 00119 public: 00120 Ray() {} 00121 ~Ray() {} 00122 Vector m_Origin; 00123 Vector m_Direction; 00124 }; 00125 00126 class Box 00127 { 00128 public: 00129 Box() {} 00130 ~Box() {} 00131 Vector m_Max; 00132 Vector m_Min; 00133 }; 00134 00135 class Texture 00136 { 00137 public: 00138 Texture(Uint8* pBuffer,int width,int height,int stride,int borderSize,bool bClamp,bool useCompression); 00139 ~Texture(); 00140 GLuint UploadTexture(); 00141 void UnloadTexture(); 00142 private: 00143 Uint8* m_pBuffer; 00144 int m_Width; 00145 int m_Height; 00146 int m_RowLength; 00147 int m_BorderSize; 00148 bool m_UseCompression; 00149 bool m_bClamp; 00150 GLuint m_TextureID; 00151 }; 00152 00153 /// This class represents a single, contiguous chunk of terrain and is the primary public interface to Demeter. Most applications will create a single instance of this class to represent the terrain in the application, but multiple instances could be used to create separate islands or to stitch together a very large world comprised of multiple terrains. 00154 class Terrain : public osg::Referenced 00155 { 00156 public: 00157 /// Constructs a new terrain from raw grayscale data. This constructor is only used by the terrain compiler and should generally not be used by applications. Applications should use the constructor that takes map files (map files are generated by the terrain compiler.) 00158 Terrain(char* szElevationsFilename,char* szTextureFilename,char* szDetailTextureFilename,float vertexSpacing,float elevationScale,int maxNumTriangles,bool bUseBorders); 00159 /// Constructs a new terrain from a compiled map file. Map files are created by the terrain compiler and they can be distributed with your application. 00160 Terrain(char* szCompiledMapFilename,int maxNumTriangles,bool bUseBorders = false,float offsetX = 0.0f,float offsetY = 0.0f); 00161 /// Constructs a new terrain by downloading a compiled map file from a remote HTTP server. Map files are created by the terrain compiler. The URL should be a well formed address with the protocol explicitly listed (for example, "http://www.terrainengine.com") The compiled map file AND the texture and detail texture files that are referenced by the compiled map file should be available from the same URL. 00162 Terrain(char* szURL,char* szCompiledMapFilename,int maxNumTriangles,bool bUseBorders = false); 00163 /// Destructor. 00164 ~Terrain(); 00165 /// Based on the current viewing parameters, this method breaks the terrain down into a visually optimum set of triangles that can be rendered. Normally, an application will never call this method directly, but will instead call the method ModelViewMatrixChanged() to allow Demeter to take care of this automatically. 00166 int Tessellate(); 00167 /// Renders the terrain to the current OpenGL surface. \warning Applications should always call ModelViewMatrixChanged() at least once prior to calling Render(), so that Demeter will have a chance to tessellate the terrain. 00168 void Render(); 00169 /// Sets the "detail theshold", which controls how much Demeter simplifies the terrain. Higher thresholds will increase performance but make the terrain look worse, while lower thresholds will reduce performance and increase visual quality. Extremely high thresholds can cause significant visual artifacts and make the terrain look very strange. 00170 void SetDetailThreshold( float threshold ); 00171 /// Returns the "detail threshold", which controls how much Demeter simplifies the terrain. Higher thresholds will increase performance but make the terrain look worse, while lower thresholds will reduce performance and increase visual quality. Extremely high thresholds can cause significant visual artifacts and make the terrain look very strange. 00172 float GetDetailThreshold(); 00173 /// Sets the maximum size of blocks that can be simplified when the terrain is tessellated. The parameter stride specifies the number of vertices along one edge of the block (blocks are always square.) This parameter can be used by applications that allow much of the terrain to be visible from above, such as flight simulators, to prevent oversimplification of terrain in the distance. Setting this value too low will adversely affect performance. 00174 void SetMaximumVisibleBlockSize( int stride ); 00175 /// Returns the width of the terrain in vertices (this is the count of vertices along the world's x-axis.) 00176 int GetWidthVertices(); 00177 /// Returns the height of the terrain in vertices (this is the count of vertices along the world's y-axis.) 00178 int GetHeightVertices(); 00179 /// Returns the width of the terrain in real units (this is the length of the terrain along the world's x-axis.) 00180 float GetWidth() const; 00181 /// Returns the height of the terrain in real units (this is the length of the terrain along the world's y-axis.) 00182 float GetHeight() const; 00183 /// Returns the number of real units between vertices in the terrain's mesh. 00184 float GetVertexSpacing(); 00185 /// Returns the elevation (z-coordinate) in real units of the specified point on the terrain. 00186 float GetElevation( float x,float y ); 00187 /// Returns the elevation (z-coordinate) in real units of the specified terrain vertex. 00188 float GetElevation( int index ); 00189 /// Returns the surface normal of the terrain at the specified point. 00190 void GetNormal( float x,float y,float& normalX,float& normalY,float& normalZ ); 00191 /// Returns the elevation (z-coordinate) in real units of the highest point on the terrain. 00192 float GetMaxElevation() const; 00193 /// Returns the elevation (z-coordinate) in real units of the specified vertex on the terrain. 00194 float GetVertexElevation(int index) const; 00195 /// Sets the elevation (z-coordinate) in real units of the specified vertex on the terrain. 00196 void SetVertexElevation(int index,float newElevation); 00197 /// Writes the current terrain to disk as a compiled map file. This method is used by the terrain compiler, but could also be used by applications as a way to persist the terrain's current state. 00198 bool Write( char* szCompiledMapFilename ); 00199 /// Returns the total number of vertices in the terrain's mesh. 00200 int GetNumberOfVertices(); 00201 /// Returns the width (in vertices) of the terrain's texture tiles. 00202 int GetTextureTileWidth(); 00203 /// Returns the height (in vertices) of the terrain's texture tiles. 00204 int GetTextureTileHeight(); 00205 /// Returns the number of texture tiles along the terrain's x-axis. 00206 int GetNumberOfTextureTilesWidth(); 00207 /// Returns the number of texture tiles along the terrain's y-axis. 00208 int GetNumberOfTextureTilesHeight(); 00209 /// Returns the OpenGL texture number (which can be used in calls to glBindTexture()) of the specified tile. This method could be used by applications that allow some form of terrain "editing" by the user, etc. where it is necessary to show the user some or all of the tiles on the map. 00210 GLuint GetTerrainTile( int index ); 00211 /// Applies the specified graphics image as a texture to the terrain. This is done by breaking the specified image up into smaller textures of 256x256 called "tiles" and mapping these contiguously onto the terrain's surface. The parameter bUseBorders specified whether or not the texture border OpenGL extensions should be used when creating the tiles. Textures are automatically applied when loading compiled map files, so use of this method is strictly optional. 00212 bool SetTexture( char* szFilename,bool bUseBorders ); 00213 /// A simple convenience method that draws the terrain's texture to a SDL surface. This method is a cheap way to show the terrain from directly overhead, such as in a "map view", etc. It is a simple matter to scale the resultant SDL surface to the desired size, using normal SDL functionality. 00214 // void DrawTexture( SDL_Surface* pTargetSurface,int width,int height ); 00215 /// A simple convenience method that draws the specified terrain tile to a SDL surface. This method could be used by applications that allow some form of terrain "editing" by the user, etc. where it is necessary to show the user some or all of the tiles on the map. 00216 //void DrawTile( SDL_Surface* pSurface,int index,int width,int height ); 00217 /// Uses the specified graphics file to apply a "common" texture to the entire surface of the terrain. A common texture is repeated across the entire terrain and is blended with the terrain's normal texture (if blending is supported by the user's hardware - which covers almost all OpenGL cards.) This is used to provide a "detailed" texture to give the ground some definition when the camera is close to the ground. 00218 bool SetCommonTexture( char* szFilename ); 00219 /// Sets the number of times that the "common" texture (as set by a call to SetCommonTexture()) is to repeated within each texture tile. 00220 void SetCommonTextureRepeats( float commonTextureRepeats ); 00221 /// Returns the number of times that the "common" texture (as set by a call to SetCommonTexture()) is to repeated within each texture tile. 00222 float GetCommonTextureRepeats(); 00223 /// Not yet well implemented. Fluid support will be available soon. \todo Provide better support for fluids (bodies of water, etc.) 00224 void SetFluidElevation( float elevation ); 00225 /// Not yet well implemented. Fluid support will be available soon. \todo Provide better support for fluids (bodies of water, etc.) 00226 bool SetFluidTexture( char* szFilename ); 00227 /// Not yet well implemented. Animation support will be available soon. \todo Provide better support for animation of terrain features such as fluids, moving features, etc. 00228 void Animate(); 00229 /// Notifies Demeter that OpenGL's modelview matrix has been modified, allowing Demeter to tessellate the terrain based on the new modelview matrix. It is IMPERATIVE that his method be called every time the modelview matrix is changed, even if this is in every single rendering cycle of the application. 00230 int ModelViewMatrixChanged(); 00231 /// Returns whether or not the specified cube is inside of the viewing frustum (as defined at the previous call to ModelViewMatrixChanged()) 00232 bool CubeInFrustum( float x,float y,float z,float size ); 00233 #ifdef _USE_RAYTRACING_SUPPORT_ 00234 /// Casts a ray from the specified point, in the specified direction, and calculates the ray's point of intersection with the terrain. The return value is the distance from the starting point to the intersection. This method makes use of the terrain's quad tree to optimize the ray-tracing. 00235 float IntersectRay( float startX,float startY,float startZ,float dirX,float dirY,float dirZ,float& intersectX,float& intersectY,float& intersectZ ); 00236 #endif 00237 /// Indicates whether or not OpenGL multitexture extensions are available from the OpenGL driver that this terrain instance is currently rendering against (as determined at the time the terrain instance was first constructed.) 00238 bool IsMultiTextureSupported(); 00239 /// A convenience method that sets the current OpenGL state to untextured. \warning Calling this method disables texture state immediately; it has no effect on the terrain itself (which will reenable textures the next time it is rendered.) This is only a convenience method that allows external callers to have easy access to OpenGL multitexture extensions. There is rarely a good reason for applications to call this method. 00240 void DisableTextures(); 00241 /// A convenience method that sets the current OpenGL state to textured. \warning Calling this method enables texture state immediately; it has no effect on the terrain itself (which will reenable textures the next time it is rendered.) This is only a convenience method that allows external callers to have easy access to OpenGL multitexture extensions. There is rarely a good reason for applications to call this method. 00242 void EnableTextures(); 00243 void SetLatticePosition(int x,int y); 00244 void GetLatticePosition(int& x,int& y); 00245 00246 enum DIRECTION {DIR_NORTH = 0,DIR_NORTHEAST = 1,DIR_EAST = 2,DIR_SOUTHEAST = 3,DIR_SOUTH = 4,DIR_SOUTHWEST = 5,DIR_WEST = 6,DIR_NORTHWEST = 7,DIR_CENTER = 8,DIR_INVALID = 9}; 00247 private: 00248 void UnloadTerrainTile(int index); 00249 void UpdateNeighbor(Terrain* pTerrain,DIRECTION direction); 00250 void Init(char* szCompiledMapFilename,int maxNumTriangles,bool bUseBorders,float offsetX = 0.0f,float offsetY = 0.0f); 00251 bool DownloadFile(char* szFilename); 00252 void SetVertexStatus(int index,bool status); 00253 bool GetVertexStatus(int index); 00254 bool Read( char* szCompiledMapFilename,bool bUseBorders ); 00255 void BuildBlocks(); 00256 void ChopTexture(Uint8* pImage,int width,int height,int tileSize,bool bUseBorders); 00257 void ExtractFrustum(); 00258 char* m_szTextureFilename; 00259 char* m_szDetailTextureFilename; 00260 int m_WidthVertices; 00261 int m_HeightVertices; 00262 float m_DetailThreshold; 00263 float m_VertexSpacing; 00264 TerrainBlock* m_pRootBlock; 00265 base::BitArray* m_pVertexStatus; 00266 int m_NumberOfVertices; 00267 // GLuint* m_pTextureList; 00268 std::vector<Texture*> m_Textures; 00269 int m_TextureTileWidth,m_TextureTileHeight; 00270 int m_NumberOfTextureTilesWidth; 00271 int m_NumberOfTextureTilesHeight; 00272 int m_TileSize; 00273 Uint8** m_pTiles; 00274 int m_NumberOfTextureTiles; 00275 // GLuint m_CommonTextureId; 00276 Texture* m_pCommonTexture; 00277 float m_FogColorRed,m_FogColorGreen,m_FogColorBlue,m_FogColorAlpha; 00278 Vector* m_pVertices; 00279 int m_MaximumVisibleBlockSize; 00280 float m_CommonTextureRepeats; 00281 TriangleStrip* m_pTriangleStrips; 00282 TriangleFan* m_pTriangleFans; 00283 int m_CountStrips,m_CountFans; 00284 float m_Frustum[6][4]; 00285 bool m_bMultiTextureSupported; 00286 int m_MaxNumberOfPrimitives; 00287 char* m_szSourceURL; 00288 float m_MaxElevation; 00289 float m_OffsetX,m_OffsetY; 00290 int m_LatticePositionX,m_LatticePositionY; 00291 00292 friend class Triangle; 00293 friend class TriangleStrip; 00294 friend class TerrainBlock; 00295 friend class TriangleFan; 00296 friend class TerrainLattice; 00297 }; 00298 00299 /// The Settings class is simply a manager of global variables. It provides a single place to set and retrieve all of the global settings that affect Demeter as a whole. 00300 class Settings 00301 { 00302 public: 00303 /// Destructor. 00304 ~Settings(); 00305 /// Returns the global instance of this class. The Settings class acts a singleton, so there is only one instance of this class per application. 00306 static Settings* GetInstance(); 00307 /// Sets the filesystem path that Demeter will look in when reading textures, maps, etc. 00308 void SetMediaPath( char* szPath ); 00309 /// Gets the filesystem path that Demeter will look in when reading textures, maps, etc. 00310 void GetMediaPath( char** szPath ); 00311 /// Prepends the current media path to the specified filename. 00312 void PrependMediaPath( char* szFilename,char** pszFullFilename ); 00313 /// Specifies whether or not Demeter should output diagnostic information at runtime. 00314 void SetVerbose( bool bVerbose ); 00315 /// Indicates whether or not Demeter is outputting diagnostic information at runtime. 00316 bool IsVerbose(); 00317 /// Tells Demeter what the current width of the rendering surface is. 00318 void SetScreenWidth( int width ); 00319 /// Retrieves the current width of the rendering surface assumed by Demeter. 00320 int GetScreenWidth(); 00321 /// Tells Demeter what the current height of the rendering surface is. 00322 void SetScreenHeight( int height ); 00323 /// Retrieves the current height of the rendering surface assumed by Demeter. 00324 int GetScreenHeight(); 00325 /// Sets a named global property to the specified value. 00326 bool SetProperty( char* szProperty,char* szValue ); 00327 /// Retrieves a named global property. 00328 bool GetProperty( char* szProperty,char* szValue ); 00329 /// Indicates whether or not the application that is using Demeter is a terrain compiler-like tool or a real application 00330 bool IsCompilerOnly(); 00331 /// Determins whether or not the application that is using Demeter is a terrain compiler-like tool or a real application 00332 void SetCompilerOnly( bool bIsCompilerOnly ); 00333 void SetUseDynamicTextures(bool useDynamic); 00334 bool UseDynamicTextures(); 00335 bool IsTextureCompression(); 00336 void SetTextureCompression(bool bCompress); 00337 void SetHeadless(bool isHeadless); 00338 bool IsHeadless(); 00339 private: 00340 Settings(); 00341 static Settings* m_pInstance; 00342 char* m_szMediaPath; 00343 bool m_bVerbose; 00344 bool m_bIsCompilerOnly; 00345 bool m_bCompressTextures; 00346 int m_ScreenWidth,m_ScreenHeight; 00347 bool m_IsHeadless; 00348 bool m_UseDynamicTextures; 00349 }; 00350 00351 class TriangleFan 00352 { 00353 public: 00354 TriangleFan(); 00355 ~TriangleFan(); 00356 void Render( Terrain* pTerrain ); 00357 void Setup( Terrain* pTerrain ); 00358 private: 00359 int m_pVertices[MAX_VERTICES_PER_FAN]; // Indices into the terrain vertices 00360 // TBD: It is a pretty awful waste of memory to preallocate MAX_VERTICES_PER_FAN vertices for every triangle fan, 00361 // when in most cases only a few vertices are needed. However, dynamically allocating these vertices 00362 // during every tessellation is not an option either because it causes huge performance problems and 00363 // badly fragments memory. Any good ideas for this? 00364 unsigned char m_NumberOfVertices; 00365 float minX,minY; 00366 int textureId; 00367 00368 friend class TerrainBlock; 00369 friend class Terrain; 00370 }; 00371 00372 class TriangleStrip 00373 { 00374 public: 00375 TriangleStrip(); 00376 ~TriangleStrip(); 00377 void Render( Terrain* pTerrain ); 00378 void Setup( Terrain* pTerrain ); 00379 private: 00380 GLuint m_pVertices[6]; // Indices into the terrain vertices 00381 unsigned char m_NumberOfVertices; 00382 float minX,minY; 00383 int textureId; 00384 bool m_bEnabled; 00385 00386 friend class TerrainBlock; 00387 friend class Terrain; 00388 }; 00389 00390 class Triangle 00391 { 00392 public: 00393 Triangle(); 00394 ~Triangle(); 00395 void DefineFromPoints( Vector& p1,Vector& p2,Vector& p3 ); 00396 Vector* GetVertex( int index ); 00397 #ifdef _USE_RAYTRACING_SUPPORT_ 00398 Plane* GetPlane(); 00399 #endif 00400 private: 00401 Vector m_pVertices[3]; 00402 #ifdef _USE_RAYTRACING_SUPPORT_ 00403 Plane m_Plane; 00404 #endif 00405 }; 00406 00407 class TerrainBlock 00408 { 00409 public: 00410 TerrainBlock( TerrainBlock* pParent ); 00411 TerrainBlock( int homeVertex,int stride,Terrain* pTerrain,TerrainBlock* pParent ); 00412 ~TerrainBlock(); 00413 void Tessellate( double* pMatrixModelview,double* pMatrixProjection,int* pViewport,TriangleStrip* pTriangleStrips,TriangleFan* pTriangleFans,int* pCountStrips,int* pCountFans,Terrain* pTerrain ); 00414 void Write( FILE* file ); 00415 void Read( FILE* file,Terrain* pTerrain ); 00416 void DummyFunc( Terrain* pTerrain ); // Forces all exported methods to be referenced 00417 bool IsActive(); 00418 void RepairCracks( Terrain* pTerrain,TriangleStrip* pTriangleStrips,TriangleFan* pTriangleFans,int* pCountStrips,int* pCountFans ); 00419 TerrainBlock* GetParent(); 00420 int GetStride(); 00421 void EnableStrip( bool bEnabled ); 00422 int GetHomeIndex(); 00423 void CalculateGeometry( Terrain* pTerrain ); 00424 void IntersectRay( Ray& ray,Vector& intersectionPoint,float& lowestDistance,Terrain* pTerrain ); 00425 private: 00426 void CreateTriangleStrip( TriangleStrip* pTriangleStrips,int* pCount,Terrain* pTerrain ); 00427 TerrainBlock** m_pChildren; 00428 Vector m_BoundingBoxUpperCenter,m_BoundingBoxLowerCenter; // These members are redundant and have become stupid - m_BoundingBox should entirely replace them. 00429 int m_HomeIndex; 00430 int m_Stride; 00431 bool m_bIsActive; 00432 bool m_bChildrenActive; 00433 TerrainBlock* m_pParent; 00434 TriangleStrip* m_pTriangleStrip; 00435 float m_CubeSize; // These members are redundant and have become stupid - m_BoundingBox should entirely replace them. 00436 float m_CubeCenterZ; // These members are redundant and have become stupid - m_BoundingBox should entirely replace them. 00437 unsigned char m_DisabledCount; 00438 Box m_BoundingBox; 00439 #ifdef _USE_RAYTRACING_SUPPORT_ 00440 Triangle* m_pTriangles; 00441 #endif 00442 00443 friend class Terrain; 00444 }; 00445 00446 class TerrainLoadListener 00447 { 00448 public: 00449 virtual void TerrainLoaded(Terrain* pTerrain) = 0; 00450 virtual void TerrainUnloading(Terrain* pTerrain) = 0; 00451 }; 00452 00453 class TerrainLattice 00454 { 00455 public: 00456 TerrainLattice(int widthTerrains,int heightTerrains,float terrainWidth,float terrainHeight); 00457 ~TerrainLattice(); 00458 void Load(char* szBaseName,int maxNumTriangles,int maxBlockSize,float commonRepeats,bool bUseBorders = false); 00459 void AddTerrainLoadListener(TerrainLoadListener& listener); 00460 void RemoveTerrainLoadListener(TerrainLoadListener& listener); 00461 void AddTerrain(Terrain* pTerrain,int positionX,int positionY); 00462 Terrain* GetTerrain(int positionX,int positionY); 00463 Terrain* GetTerrainAtPoint(float x,float y); 00464 void SetCameraPosition(float x,float y,float z); 00465 void SetDetailThreshold(float threshold); 00466 void Tessellate(); 00467 void Render(); 00468 float GetElevation(float x,float y); 00469 float GetWidth(); 00470 float GetHeight(); 00471 private: 00472 std::vector<TerrainLoadListener*> m_TerrainLoadListeners; 00473 Terrain::DIRECTION GetOppositeDirection(Terrain::DIRECTION direction); 00474 Terrain* GetTerrainRelative(Terrain* pTerrain,int positionX,int positionY); 00475 Terrain* GetTerrainRelative(Terrain* pTerrain,Terrain::DIRECTION direction); 00476 void LoadTerrain(int index); 00477 int m_WidthTerrains,m_HeightTerrains; 00478 int m_WidthActiveTerrains,m_HeightActiveTerrains; 00479 float m_TerrainWidth,m_TerrainHeight; 00480 Terrain** m_pTerrains; 00481 int m_CurrentTerrainIndex[9]; 00482 std::string m_BaseName; 00483 int m_MaxNumTriangles; 00484 int m_MaxBlockSize; 00485 float m_CommonRepeats; 00486 bool m_bUseBorders; 00487 }; 00488 00489 } 00490 00491 00492 namespace gfx { 00493 00494 typedef demeter::Terrain CLODTerrainRenderer; 00495 typedef demeter::TerrainLattice CLODTerrainLattice; 00496 typedef demeter::Settings CLODTerrainSettings; 00497 } 00498 00499 #endif 00500 00501