Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h @ 8593

Last change on this file since 8593 was 8593, checked in by ponder, 18 years ago
File size: 7.6 KB
Line 
1/*
2        orxonox - the future of 3D-vertical-scrollers
3 
4        Copyright (C) 2006 orx
5 
6        This program is free software; you can redistribute it and/or modify
7        it under the terms of the GNU General Public License as published by
8        the Free Software Foundation; either version 2, or (at your option)
9        any later version.
10 
11        ### File Specific:
12        main programmer: Marco Biasini
13 
14 */
15
16
17#ifndef TERRAIN_PAGE_H
18#define TERRAIN_PAGE_H
19#define USE_VBO
20#include "terrain_quad.h"
21#include <stdio.h>
22
23
24class TerrainPage;
25class Terrain;
26
27typedef TerrainPage *pTerrainPage;
28
29struct Vertex {
30        TexCoord        t;     
31        Triple          p;
32};
33
34typedef Vertex *pVertex;
35
36typedef struct {
37        Triple  correct;
38        Triple  real;
39        float   diff;
40} LODError, *pLODError;
41
42class TerrainPage : public TerrainQuad {
43        public:
44                enum { TP_LEFT = 0, TP_RIGHT = 1, TP_BOTTOM = 2, TP_TOP = 3 };
45                const static int MAX_LODS = 5;
46                /**
47                 * Creates a new terrain page with its lower left corner set
48                 * to C = ( _xOffset, _zOffset ), where the two values specify
49                 * the offset in the height-map.
50                 * The size of the page, as well as the scaling factors are read
51                 * from the _owner terrain page.
52                 */
53                TerrainPage( Terrain *_owner, int _xOffset, int _zOffset );
54               
55                /**
56                 * This is used only internally for communication between the TerrainPage and
57                 * the Terrain class itself.
58                 */
59                inline bool isActive() { return active; }
60               
61               
62                ~TerrainPage( )
63                { 
64                        if ( isVisible )
65                                hide(); 
66                }
67               
68                /**
69                 * @brief Makes the terrain look as if it were created with the given level of
70                 * detail.
71                 */
72                void mimick( int _level ) {}
73               
74                /**
75                 * @brief Draws a box around the TerrainPage. For debugging purposes.
76                 */
77                void drawBox();
78               
79                /**
80                 * @brief Calculates the smallest fitting axis aligned bounding box for this TerrainPage.
81                 */
82                virtual void calculateBounds();         
83               
84               
85                /**
86                 * @brief Sets the visibility to _flag. If the visibility changed, the vertex and index
87                 * arrays are allocated or freed, respectively.
88                 */
89                inline void setVisibility( bool _flag );
90
91                /**
92                 * @brief Prepares the page for rendering.
93                 */
94                void show( );
95               
96                /**
97                 * @brief Frees most of the memory for economomical reasons.
98                 */
99                void hide( ); 
100               
101                /**
102                 * @brief Updates the tesselation if necessary.
103                 */
104                void updateTesselation( );
105               
106                /**
107                 * @return The current tesselation level.
108                 */
109                int getLOD() { return currentLOD; }
110               
111                /**
112                 * @return The curren tween factor. This is a floating point value  between 0.0f and 1.0f
113                 */
114                float getTween() { return 0.0f; }
115               
116                /**
117                 * @brief Determines the new LOD which should be used by this terrain page based on
118                 * the distance from the camera.
119                 *
120                 * No geometry is updated in this method. You need to call
121                 * updateTesselation() in order to see a change in geometry. This method is
122                 * just a recommondation for the LOD. It might be invalid due to outer
123                 * constraints.
124                 */
125                int chooseLOD();
126               
127                /**
128                 * If the terrain pages tesselation level changed between the last and the
129                 * current frame, this function returns true, else you'll get false as the
130                 * return value.
131                 * @return True if the page needs an update and false if not.
132                 */
133                bool isDirty() { return forceTesselation; }
134               
135                /**
136                 * @brief Calculates the maximal errors for every LOD.
137                 */
138                void calculateErrors();
139               
140                /**
141                 * @brief Calculates the error for the given LOD. We just need to know the "worst"
142                 * vertex for choosing an appropriate LOD.
143                 */
144                void calculateError( int _lod );
145               
146               
147                /**
148                 * Tests if the terrain page would cull against the viewing frustum.
149                 */
150                bool cull( );
151
152                bool needsRetesselation();
153                /**
154                 * Sets the neighbors of this terrain page. pass null if a neighbor if this
155                 * pages is at the border.
156                 */
157                inline void setNeighbors( pTerrainPage _left, pTerrainPage _right, 
158                        pTerrainPage _top, pTerrainPage _bottom )
159                {
160                        left = _left; right = _right; top = _top; bottom = _bottom;
161                }
162               
163                /**
164                 * Sets the position of the TerrainPage. Is this needed?
165                 */
166                inline void setPosition( const Triple& _pos )
167                {
168                        position.x = _pos.x;
169                        position.y = _pos.y;
170                        position.z = _pos.z;
171                }
172
173                pTerrainPage getLeft() { return left; }
174                pTerrainPage getRight() { return right; }
175                pTerrainPage getBottom() { return bottom; }
176                pTerrainPage getTop() { return top; }                                           
177               
178                /**
179                 *  Does what exactly what the name says and nothing more.
180                 */
181                void draw( );
182               
183                /**
184                 * @return the next active page
185                 */
186                inline pTerrainPage getNext() { return next; }
187               
188                /**
189                 * Returns the previous active page
190                 */
191                inline pTerrainPage getPrevious() { return previous; }                 
192                inline int getCurrentLOD() { return currentLOD; }
193                /**
194                 * @return Returns the wanted LOD. Make sure you call this method after a call to
195                 * chooseLOD() or you will get screwed values.
196                 */
197                inline int getWantedLOD() { return wantedLOD; }
198               
199                /**
200                 * @brief Removes the page from the active page list.
201                 */
202                void deactivate();
203               
204                /**
205                 * @brief Inserts the page into the active page list.
206                 */
207                void activate();               
208                inline bool hasMaterial( int _i )
209                {
210                        return true;
211                }
212               
213                inline void setWantedLOD( int _lod )
214                {
215                        if ( _lod >= TerrainPage::MAX_LODS )
216                                wantedLOD = TerrainPage::MAX_LODS-1;
217                        else if ( _lod < 0 )
218                                wantedLOD = 0;
219                        else
220                                wantedLOD = _lod;
221                }
222                               
223        protected:
224               
225                /**
226                 * @brief Tesselates one row of the terrain page.
227                 * @param _z                    The z-offset of the row
228                 * @param _xStride              Determines the step-size horizontally
229                 * @param _zStride              Determines the step-size vertically.
230                 * @param _adaptRight   True if the right neighbor has a coarser
231                 *                                              tesselation level.
232                 * @param _adaptLeft    True if the left neighbor has a coarser
233                 *                                              tesselation level.                     
234                 */
235                void tesselateRow( int _z, int _xStride, int _zStride, bool _adaptLeft, bool _adaptRight );
236
237                /**
238                 * @brief Returns four boolean values in the oder
239                 */
240                void determineBorderAdaption( bool _adapt[] );
241               
242                /**
243                 * @brief Adds the given index to the index-array
244                 */
245                inline void addIndex( unsigned short _index );
246               
247                /**
248                 * @brief We programmers are very lazy :) This method just adds the last added index
249                 * again.
250                 */
251                inline void addAgain();
252               
253               
254                void getCoord( int _x, int _z, TexCoord& _coord) const;
255               
256                /**
257                 * Fills _vertex with the vertex information at index.
258                 */
259                void getVertex( int _x, int _z, Triple& _vertex ) const;
260               
261                /**
262                 * Use this method to safely get a vertex at location ( _x, _z ). If it wasn't
263                 * created before, this method does that for you.
264                 */                     
265                short getIndex( int _x, int _z );
266                void tesselateLevelFourPatch( bool _adapt[] );
267           /**
268                * Generates the tesselation for the given level of detail.
269                */
270                void tesselate( int _lod );                     
271
272                float getAltitude( int _x, int _z ) const;
273               
274                int                                                     currentLOD,
275                                                                        wantedLOD;
276                float                                           tween;
277                pTerrainPage                            left, 
278                                                                        right,
279                                                                        top,
280                                                                        bottom;
281                bool                                            forceTesselation;
282                bool                                            active;
283                pVertex                                         vertices;
284                unsigned short                          *indices;
285                unsigned short                          *indexHash;
286                int                                                     numIndices;
287                int                                                     numVertices;
288               
289#ifdef  USE_VBO
290                GLuint                                          ibIdentifier,
291                                                                        vbIdentifier;
292#endif         
293                bool                                            isVisible;
294                pTerrainPage                            next;
295                pTerrainPage                            previous;
296                LODError                                        *errors;
297                Triple                                          position;
298};
299
300inline void TerrainPage::setVisibility( bool _flag )
301{
302        if ( _flag ) {
303                if ( !isVisible ) {
304                        isVisible = true;
305                        show( );
306                }
307                active = true;
308        }
309        else {
310                if ( isVisible ) {
311                        isVisible = false;
312                        hide( );
313                }
314        }
315}
316
317inline void TerrainPage::addIndex( unsigned short _index )
318{
319        indices[numIndices] = _index; numIndices++;
320}
321
322inline void TerrainPage::addAgain() 
323{ 
324        indices[numIndices] = indices[numIndices-1]; numIndices++;                             
325}
326
327#endif
Note: See TracBrowser for help on using the repository browser.