Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/PlugIns/OctreeSceneManager/include/OgreTerrainRenderable.h @ 1

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