source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTerrainRenderable.h @ 1273

Revision 1273, 14.8 KB checked in by szydlowski, 18 years ago (diff)

Added the KdTerrainSceneManager?, a subclass of the KdTreeSceneManager? capable of rendering terrain like the TerrainSceneManager? from Ogre.
All the *Kd*Terrain* classes are identical to their octree counterparts, save prefixing all classes and structures with Kd to avoid namespace clashes.
This was necessary, since the TerrainSceneManager? was hard coded in these classes, and all references had to be replaced with the KdTerrainSceneManager?.
Also added a comprehensive README for the demo application.

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