Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file was 9428, checked in by bensch, 19 years ago

minor change

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