source: GTP/trunk/App/Demos/Geom/OgreStuff/include/opt/OgreTerrainRenderable.h @ 1092

Revision 1092, 14.1 KB checked in by gumbau, 18 years ago (diff)

LodStrips? and LODTrees demos

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25/***************************************************************************
26terrainrenderable.h  -  description
27-------------------
28begin                : Sat Oct 5 2002
29copyright            : (C) 2002 by Jon Anderson
30email                : janders@users.sf.net
31
32Enhancements 2003 - 2004 (C) The OGRE Team
33
34***************************************************************************/
35
36#ifndef TERRAINRENDERABLE_H
37#define TERRAINRENDERABLE_H
38
39#include "OgreTerrainPrerequisites.h"
40#include <OgreRenderable.h>
41#include <OgreMovableObject.h>
42#include <OgreAxisAlignedBox.h>
43#include <OgreString.h>
44#include <OgreHardwareBufferManager.h>
45
46#include <vector>
47
48#define MORPH_CUSTOM_PARAM_ID 77
49
50namespace Ogre
51{
52
53    typedef std::map <unsigned int, IndexData* > IndexMap;
54    typedef std::vector < IndexData* > IndexArray;
55    typedef std::vector < IndexMap* > LevelArray;
56
57    /**
58    * A cache of TerrainIndexBuffers.  Used to keep track of the buffers, and
59    * delete them when the program finishes.
60    */
61    class TerrainBufferCache
62    {
63    public:
64        void shutdown(void)
65        {
66            for( size_t i=0; i<mCache.size(); i++ )
67            {
68                delete mCache[i];
69            }
70            mCache.clear();
71        }
72        ~TerrainBufferCache()
73        {
74            shutdown();
75        }
76
77        IndexArray mCache;
78    };
79
80    inline Real _max( Real x, Real y )
81    {
82        return ( x > y ) ? x : y;
83    }
84
85    /** A simple class for encapsulating parameters which are commonly needed by
86    both TerrainSceneManager and TerrainRenderable.
87    */
88    class TerrainOptions
89    {
90    public:
91        TerrainOptions()
92        {
93            pageSize = 0;
94            tileSize = 0;
95            tilesPerPage = 0;
96            maxGeoMipMapLevel = 0;
97            scale = Vector3::UNIT_SCALE;
98            maxPixelError = 4;
99            detailTile = 1;
100            lit = false;
101            coloured = false;
102            lodMorph = false;
103            lodMorphStart = 0.5;
104            useTriStrips = false;
105            primaryCamera = 0;
106            terrainMaterial.setNull();
107        };
108        /// The size of one edge of a terrain page, in vertices
109        size_t pageSize;
110        /// The size of one edge of a terrain tile, in vertices
111        size_t tileSize;
112        /// Precalculated number of tiles per page
113        size_t tilesPerPage;
114        /// The primary camera, used for error metric calculation and page choice
115        const Camera* primaryCamera;
116        /// The maximum terrain geo-mipmap level
117        size_t maxGeoMipMapLevel;
118        /// The scale factor to apply to the terrain (each vertex is 1 unscaled unit
119        /// away from the next, and height is from 0 to 1)
120        Vector3 scale;
121        /// The maximum pixel error allowed
122        size_t maxPixelError;
123        /// Whether we should use triangle strips
124        bool useTriStrips;
125        /// The number of times to repeat a detail texture over a tile
126        size_t detailTile;
127        /// Whether LOD morphing is enabled
128        bool lodMorph;
129        /// At what point (parametric) should LOD morphing start
130        Real lodMorphStart;
131        /// Whether dynamic lighting is enabled
132        bool lit;
133        /// Whether vertex colours are enabled
134        bool coloured;
135        /// Pointer to the material to use to render the terrain
136        MaterialPtr terrainMaterial;
137
138    };
139
140#define STITCH_NORTH_SHIFT 0
141#define STITCH_SOUTH_SHIFT 8
142#define STITCH_WEST_SHIFT  16
143#define STITCH_EAST_SHIFT  24
144
145#define STITCH_NORTH  128 << STITCH_NORTH_SHIFT
146#define STITCH_SOUTH  128 << STITCH_SOUTH_SHIFT
147#define STITCH_WEST   128 << STITCH_WEST_SHIFT
148#define STITCH_EAST   128 << STITCH_EAST_SHIFT
149
150    /**
151    Represents a terrain tile.
152    @remarks
153    A TerrainRenderable represents a tile used to render a block of terrain using the geomipmap approach
154    for LOD.
155    *@author Jon Anderson
156    */
157
158    class _OgreTerrainExport TerrainRenderable : public Renderable, public MovableObject
159    {
160    public:
161
162        TerrainRenderable(const String& name);
163        ~TerrainRenderable();
164
165        void deleteGeometry();
166
167        enum Neighbor
168        {
169            NORTH = 0,
170            SOUTH = 1,
171            EAST = 2,
172            WEST = 3,
173            HERE = 4
174        };
175
176        /** Initializes the TerrainRenderable.
177        @param startx, startz
178        The starting points of the top-left of this tile, in terms of the
179        number of vertices.
180        @param pageHeightData The source height data for the entire parent page
181        */
182        void initialise(int startx, int startz, Real* pageHeightData);
183
184        //movable object methods
185        /** Returns the name of the TerrainRenderable */
186        virtual const String& getName( void ) const
187        {
188            return mName;
189        };
190
191        /** Returns the type of the movable. */
192        virtual const String& getMovableType( void ) const
193        {
194            return mType;
195        };
196
197        /** Returns the bounding box of this TerrainRenderable */
198        const AxisAlignedBox& getBoundingBox( void ) const
199        {
200            return mBounds;
201        };
202
203        /** Updates the level of detail to be used for rendering this TerrainRenderable based on the passed in Camera */
204        virtual void _notifyCurrentCamera( Camera* cam );
205
206        virtual void _updateRenderQueue( RenderQueue* queue );
207
208        /**
209        Constructs a RenderOperation to render the TerrainRenderable.
210        @remarks
211        Each TerrainRenderable has a block of vertices that represent the terrain.  Index arrays are dynamically
212        created for mipmap level, and then cached.
213        */
214        virtual void getRenderOperation( RenderOperation& rend );
215
216        virtual const MaterialPtr& getMaterial( void ) const
217        {
218            return mMaterial;
219        };
220
221        virtual void getWorldTransforms( Matrix4* xform ) const;
222
223        virtual const Quaternion& getWorldOrientation(void) const;
224        virtual const Vector3& getWorldPosition(void) const;
225
226        /** Returns the mipmap level that will be rendered for this frame. */
227        inline int getRenderLevel() const
228        {
229            return mRenderLevel;
230        };
231
232        /** Forces the LOD to the given level from this point on. */
233        inline void setForcedRenderLevel( int i )
234        {
235            mForcedRenderLevel = i;
236        }
237
238        /** Calculates the normal at the given location */
239        void _getNormalAt( float x, float y, Vector3 * result );
240
241        /** Returns the terrain height at the given coordinates */
242        float getHeightAt( float x, float y );
243
244        /** Intersects the segment witht he terrain tile
245        */
246        bool intersectSegment( const Vector3 & start, const Vector3 & end, Vector3 * result );
247
248        /** Sets the appropriate neighbor for this TerrainRenderable.  Neighbors are necessary
249        to know when to bridge between LODs.
250        */
251        void _setNeighbor( Neighbor n, TerrainRenderable *t )
252        {
253            mNeighbors[ n ] = t;
254        };
255
256        /** Returns the neighbor TerrainRenderable.
257        */
258        TerrainRenderable * _getNeighbor( Neighbor n )
259        {
260            return mNeighbors[ n ];
261        }
262
263
264        void setMaterial(const MaterialPtr& m )
265        {
266            mMaterial = m;
267        };
268
269        /** Calculates static normals for lighting the terrain. */
270        void _calculateNormals();
271
272
273
274
275        /** Generates terrain shadows and lighting using vertex colors
276        */
277        void _generateVertexLighting( const Vector3 &sun, ColourValue ambient );
278
279
280        /** Overridden, see Renderable */
281        Real getSquaredViewDepth(const Camera* cam) const;
282
283        /** Overridden from MovableObject */
284        Real getBoundingRadius(void) const { return 0; /* not needed */ }
285
286        /** @copydoc Renderable::getLights */
287        const LightList& getLights(void) const;
288
289        /// Overridden from Renderable to allow the morph LOD entry to be set
290        void _updateCustomGpuParameter(
291            const GpuProgramParameters::AutoConstantEntry& constantEntry,
292            GpuProgramParameters* params) const;
293        /// Get the static list of indexes cached (internal use only)
294        static TerrainBufferCache& _getIndexCache(void) {return msIndexCache;}
295    protected:
296        /// Static list of index buffers
297        static TerrainBufferCache msIndexCache;
298        /// Static link to static shared options
299        static const TerrainOptions* msOptions;
300
301        /** Returns the index into the height array for the given coords. */
302        inline size_t _index( int x, int z ) const
303        {
304            return ( x + z * msOptions->tileSize );
305        };
306
307        /** Returns the  vertex coord for the given coordinates */
308        inline float _vertex( int x, int z, int n )
309        {
310            return mPositionBuffer[x * 3 + z * msOptions->tileSize * 3 + n];
311        };
312
313
314        inline int _numNeighbors() const
315        {
316            int n = 0;
317
318            for ( int i = 0; i < 4; i++ )
319            {
320                if ( mNeighbors[ i ] != 0 )
321                    n++;
322            }
323
324            return n;
325        }
326
327        inline bool _hasNeighborRenderLevel( int i ) const
328        {
329            for ( int j = 0; j < 4; j++ )
330            {
331                if ( mNeighbors[ j ] != 0 && mNeighbors[ j ] ->mRenderLevel == i )
332                    return true;
333            }
334
335            return false;
336
337        }
338
339        void _adjustRenderLevel( int i );
340
341        void _initLevelIndexes();
342        void _destroyLevelIndexes();
343
344        bool _checkSize( int n );
345
346        void _calculateMinLevelDist2( Real C );
347
348        Real _calculateCFactor();
349
350        VertexData* mTerrain;
351
352        /// The current LOD level
353        int mRenderLevel;
354        /// The previous 'next' LOD level down, for frame coherency
355        int mLastNextLevel;
356        /// The morph factor between this and the next LOD level down
357        Real mLODMorphFactor;
358        /// List of squared distances at which LODs change
359        Real *mMinLevelDistSqr;
360        /// Connection to tiles four neighbours
361        TerrainRenderable *mNeighbors [ 4 ];
362        /// Bounding box of this tile
363        AxisAlignedBox mBounds;
364        /// The center point of this tile
365        Vector3 mCenter;
366        /// Name of this renderable
367        String mName;
368        /// The MovableObject type
369        static String mType;
370        /// Current material used by this tile
371        MaterialPtr mMaterial;   
372        /// Whether this tile has been initialised   
373        bool mInit;
374        /// Shared array of IndexData (reuse indexes across tiles)
375        static LevelArray mLevelIndex;
376        /// Whether the level array as been initialised yet
377        static bool mLevelInit;
378        /// The buffer with all the renderable geometry in it
379        HardwareVertexBufferSharedPtr mMainBuffer;
380        /// Optional set of delta buffers, used to morph from one LOD to the next
381        HardwareVertexBufferSharedPtr* mDeltaBuffers;
382        /// System-memory buffer with just positions in it, for CPU operations
383        float* mPositionBuffer;
384        /// Forced rendering LOD level, optional
385        int mForcedRenderLevel;
386        /// Array of LOD indexes specifying which LOD is the next one down
387        /// (deals with clustered error metrics which cause LODs to be skipped)
388        int mNextLevelDown[10];
389        /// Gets the index data for this tile based on current settings
390        IndexData* getIndexData(void);
391        /// Internal method for generating stripified terrain indexes
392        IndexData* generateTriStripIndexes(unsigned int stitchFlags);
393        /// Internal method for generating triangle list terrain indexes
394        IndexData* generateTriListIndexes(unsigned int stitchFlags);
395        /** Utility method to generate stitching indexes on the edge of a tile
396        @param neighbor The neighbor direction to stitch
397        @param hiLOD The LOD of this tile
398        @param loLOD The LOD of the neighbor
399        @param omitFirstTri Whether the first tri of the stitch (always clockwise
400        relative to the centre of this tile) is to be omitted because an
401        adjoining edge is also being stitched
402        @param omitLastTri Whether the last tri of the stitch (always clockwise
403        relative to the centre of this tile) is to be omitted because an
404        adjoining edge is also being stitched
405        @param pIdx Pointer to a pointer to the index buffer to push the results
406        into (this pointer will be updated)
407        @returns The number of indexes added
408        */
409        int stitchEdge(Neighbor neighbor, int hiLOD, int loLOD,
410            bool omitFirstTri, bool omitLastTri, unsigned short** ppIdx);
411
412        /// Create a blank delta buffer for usein morphing
413        HardwareVertexBufferSharedPtr createDeltaBuffer(void);
414
415    };
416
417}
418
419#endif
Note: See TracBrowser for help on using the repository browser.