source: OGRE/trunk/ogre_changes/Ogre1.2/PlugIns/OctreeSceneManager/include/OgreTerrainRenderable.h @ 1669

Revision 1669, 15.0 KB checked in by szirmay, 18 years ago (diff)
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#include <OgreMaterialManager.h>
46
47#include <vector>
48
49#define MORPH_CUSTOM_PARAM_ID 77
50
51#ifdef GTP_VISIBILITY_MODIFIED_OGRE
52#define MAX_RENDERLEVEL_INDEX 15 // maximal different number of render levels, e.g., used for chc
53#endif // GTP_VISIBILITY_MODIFIED_OGRE
54
55namespace Ogre
56{
57
58    typedef std::map <unsigned int, IndexData* > IndexMap;
59    typedef std::vector < IndexData* > IndexArray;
60    typedef std::vector < IndexMap* > LevelArray;
61
62    /**
63    * A cache of TerrainIndexBuffers.  Used to keep track of the buffers, and
64    * delete them when the program finishes.
65    */
66    class TerrainBufferCache
67    {
68    public:
69        void shutdown(void)
70        {
71            for( size_t i=0; i<mCache.size(); i++ )
72            {
73                delete mCache[i];
74            }
75            mCache.clear();
76        }
77        ~TerrainBufferCache()
78        {
79            shutdown();
80        }
81
82        IndexArray mCache;
83    };
84
85    inline Real _max( Real x, Real y )
86    {
87        return ( x > y ) ? x : y;
88    }
89
90    /** A simple class for encapsulating parameters which are commonly needed by
91    both TerrainSceneManager and TerrainRenderable.
92    */
93    class TerrainOptions
94    {
95    public:
96        TerrainOptions()
97        {
98            pageSize = 0;
99            tileSize = 0;
100            tilesPerPage = 0;
101            maxGeoMipMapLevel = 0;
102            scale = Vector3::UNIT_SCALE;
103            maxPixelError = 4;
104            detailTile = 1;
105            lit = false;
106            coloured = false;
107            lodMorph = false;
108            lodMorphStart = 0.5;
109            useTriStrips = false;
110            primaryCamera = 0;
111            terrainMaterial.setNull();
112        };
113        /// The size of one edge of a terrain page, in vertices
114        size_t pageSize;
115        /// The size of one edge of a terrain tile, in vertices
116        size_t tileSize;
117        /// Precalculated number of tiles per page
118        size_t tilesPerPage;
119        /// The primary camera, used for error metric calculation and page choice
120        const Camera* primaryCamera;
121        /// The maximum terrain geo-mipmap level
122        size_t maxGeoMipMapLevel;
123        /// The scale factor to apply to the terrain (each vertex is 1 unscaled unit
124        /// away from the next, and height is from 0 to 1)
125        Vector3 scale;
126        /// The maximum pixel error allowed
127        size_t maxPixelError;
128        /// Whether we should use triangle strips
129        bool useTriStrips;
130        /// The number of times to repeat a detail texture over a tile
131        size_t detailTile;
132        /// Whether LOD morphing is enabled
133        bool lodMorph;
134        /// At what point (parametric) should LOD morphing start
135        Real lodMorphStart;
136        /// Whether dynamic lighting is enabled
137        bool lit;
138        /// Whether vertex colours are enabled
139        bool coloured;
140        /// Pointer to the material to use to render the terrain
141        MaterialPtr terrainMaterial;
142
143    };
144
145#define STITCH_NORTH_SHIFT 0
146#define STITCH_SOUTH_SHIFT 8
147#define STITCH_WEST_SHIFT  16
148#define STITCH_EAST_SHIFT  24
149
150#define STITCH_NORTH  128 << STITCH_NORTH_SHIFT
151#define STITCH_SOUTH  128 << STITCH_SOUTH_SHIFT
152#define STITCH_WEST   128 << STITCH_WEST_SHIFT
153#define STITCH_EAST   128 << STITCH_EAST_SHIFT
154
155    /**
156    Represents a terrain tile.
157    @remarks
158    A TerrainRenderable represents a tile used to render a block of terrain using the geomipmap approach
159    for LOD.
160    *@author Jon Anderson
161    */
162
163    class _OgreTerrainExport TerrainRenderable : public Renderable, public MovableObject
164    {
165    public:
166
167        TerrainRenderable(const String& name, TerrainSceneManager* tsm);
168        ~TerrainRenderable();
169
170        void deleteGeometry();
171
172        enum Neighbor
173        {
174            NORTH = 0,
175            SOUTH = 1,
176            EAST = 2,
177            WEST = 3,
178            HERE = 4
179        };
180
181        /** Initializes the TerrainRenderable.
182        @param startx, startz
183        The starting points of the top-left of this tile, in terms of the
184        number of vertices.
185        @param pageHeightData The source height data for the entire parent page
186        */
187        void initialise(int startx, int startz, Real* pageHeightData);
188
189        //movable object methods
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#ifdef GTP_VISIBILITY_MODIFIED_OGRE
230            return mRenderLevel[msCurrentRenderLevelIndex];
231#else
232            return mRenderLevel;
233#endif // GTP_VISIBILITY_MODIFIED_OGRE
234        };
235
236        /** Forces the LOD to the given level from this point on. */
237        inline void setForcedRenderLevel( int i )
238        {
239            mForcedRenderLevel = i;
240        }
241
242        /** Calculates the normal at the given location */
243        void _getNormalAt( float x, float y, Vector3 * result );
244
245        /** Returns the terrain height at the given coordinates */
246        float getHeightAt( float x, float y );
247
248        /** Intersects the segment witht he terrain tile
249        */
250        bool intersectSegment( const Vector3 & start, const Vector3 & end, Vector3 * result );
251
252        /** Sets the appropriate neighbor for this TerrainRenderable.  Neighbors are necessary
253        to know when to bridge between LODs.
254        */
255        void _setNeighbor( Neighbor n, TerrainRenderable *t )
256        {
257            mNeighbors[ n ] = t;
258        };
259
260        /** Returns the neighbor TerrainRenderable.
261        */
262        TerrainRenderable * _getNeighbor( Neighbor n )
263        {
264            return mNeighbors[ n ];
265        }
266
267
268        void setMaterial(const MaterialPtr& m )
269        {
270            mMaterial = m;
271        };
272
273#ifdef GAMETOOLS_ILLUMINATION_MODULE
274                void setMaterialName(const String &name)
275                {
276                        setMaterial(MaterialManager::getSingleton().getByName(name));
277                }
278#endif
279
280        /** Calculates static normals for lighting the terrain. */
281        void _calculateNormals();
282
283
284
285
286        /** Generates terrain shadows and lighting using vertex colors
287        */
288        void _generateVertexLighting( const Vector3 &sun, ColourValue ambient );
289
290
291        /** Overridden, see Renderable */
292        Real getSquaredViewDepth(const Camera* cam) const;
293
294        /** Overridden from MovableObject */
295        Real getBoundingRadius(void) const { return mBoundingRadius; }
296
297        /** @copydoc Renderable::getLights */
298        const LightList& getLights(void) const;
299
300        /// Overridden from Renderable to allow the morph LOD entry to be set
301        void _updateCustomGpuParameter(
302            const GpuProgramParameters::AutoConstantEntry& constantEntry,
303            GpuProgramParameters* params) const;
304                /// @see MovableObject
305                uint32 getTypeFlags(void) const;
306
307#ifdef GTP_VISIBILITY_MODIFIED_OGRE
308                // resets index of renderlevel used for current pass
309                static void ResetRenderLevelIndex();
310                // next index of renderlevel
311                static void NextRenderLevelIndex();
312#endif // GTP_VISIBILITY_MODIFIED_OGRE
313
314    protected:
315                /// Parent SceneManager
316                TerrainSceneManager* mSceneManager;
317        /// Link to shared options
318        const TerrainOptions* mOptions;
319
320        /** Returns the index into the height array for the given coords. */
321        inline size_t _index( int x, int z ) const
322        {
323            return ( x + z * mOptions->tileSize );
324        };
325
326        /** Returns the  vertex coord for the given coordinates */
327        inline float _vertex( int x, int z, int n )
328        {
329            return mPositionBuffer[x * 3 + z * mOptions->tileSize * 3 + n];
330        };
331
332
333        inline int _numNeighbors() const
334        {
335            int n = 0;
336
337            for ( int i = 0; i < 4; i++ )
338            {
339                if ( mNeighbors[ i ] != 0 )
340                    n++;
341            }
342
343            return n;
344        }
345
346        inline bool _hasNeighborRenderLevel( int i ) const
347        {
348            for ( int j = 0; j < 4; j++ )
349            {
350/*** msz: added for v1-2-0 compatibility ***/
351#ifdef GTP_VISIBILITY_MODIFIED_OGRE
352                                if ( mNeighbors[ j ] != 0 && mNeighbors[ j ] ->getRenderLevel() == i )
353                    return true;
354#else
355                if ( mNeighbors[ j ] != 0 && mNeighbors[ j ] ->mRenderLevel == i )
356                    return true;
357#endif //GTP_VISIBILITY_MODIFIED_OGRE
358            }
359
360            return false;
361
362        }
363
364        void _adjustRenderLevel( int i );
365
366        bool _checkSize( int n );
367
368        void _calculateMinLevelDist2( Real C );
369
370        Real _calculateCFactor();
371
372        VertexData* mTerrain;
373
374        /// The current LOD level
375#ifdef GTP_VISIBILITY_MODIFIED_OGRE
376        int mRenderLevel[MAX_RENDERLEVEL_INDEX];
377
378                /*** msz: added for v1-2-0 compatibility ***/
379                // index of renderlevel of current pass
380                static int msCurrentRenderLevelIndex;
381#else
382                int mRenderLevel;
383#endif // GTP_VISIBILITY_MODIFIED_OGRE
384
385        /// The previous 'next' LOD level down, for frame coherency
386        int mLastNextLevel;
387        /// The morph factor between this and the next LOD level down
388        Real mLODMorphFactor;
389        /// List of squared distances at which LODs change
390        Real *mMinLevelDistSqr;
391        /// Connection to tiles four neighbours
392        TerrainRenderable *mNeighbors [ 4 ];
393        /// Whether light list need to re-calculate
394        mutable bool mLightListDirty;
395        /// Cached light list
396        mutable LightList mLightList;
397        /// The bounding radius of this tile
398        Real mBoundingRadius;
399        /// Bounding box of this tile
400        AxisAlignedBox mBounds;
401        /// The center point of this tile
402        Vector3 mCenter;
403        /// The MovableObject type
404        static String mType;
405        /// Current material used by this tile
406        MaterialPtr mMaterial;   
407        /// Whether this tile has been initialised   
408        bool mInit;
409        /// The buffer with all the renderable geometry in it
410        HardwareVertexBufferSharedPtr mMainBuffer;
411        /// Optional set of delta buffers, used to morph from one LOD to the next
412        HardwareVertexBufferSharedPtr* mDeltaBuffers;
413        /// System-memory buffer with just positions in it, for CPU operations
414        float* mPositionBuffer;
415        /// Forced rendering LOD level, optional
416        int mForcedRenderLevel;
417        /// Array of LOD indexes specifying which LOD is the next one down
418        /// (deals with clustered error metrics which cause LODs to be skipped)
419        int mNextLevelDown[10];
420        /// Gets the index data for this tile based on current settings
421        IndexData* getIndexData(void);
422        /// Internal method for generating stripified terrain indexes
423        IndexData* generateTriStripIndexes(unsigned int stitchFlags);
424        /// Internal method for generating triangle list terrain indexes
425        IndexData* generateTriListIndexes(unsigned int stitchFlags);
426        /** Utility method to generate stitching indexes on the edge of a tile
427        @param neighbor The neighbor direction to stitch
428        @param hiLOD The LOD of this tile
429        @param loLOD The LOD of the neighbor
430        @param omitFirstTri Whether the first tri of the stitch (always clockwise
431        relative to the centre of this tile) is to be omitted because an
432        adjoining edge is also being stitched
433        @param omitLastTri Whether the last tri of the stitch (always clockwise
434        relative to the centre of this tile) is to be omitted because an
435        adjoining edge is also being stitched
436        @param pIdx Pointer to a pointer to the index buffer to push the results
437        into (this pointer will be updated)
438        @returns The number of indexes added
439        */
440        int stitchEdge(Neighbor neighbor, int hiLOD, int loLOD,
441            bool omitFirstTri, bool omitLastTri, unsigned short** ppIdx);
442
443        /// Create a blank delta buffer for usein morphing
444        HardwareVertexBufferSharedPtr createDeltaBuffer(void);
445
446    };
447
448}
449
450#endif
Note: See TracBrowser for help on using the repository browser.