Umasoft
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
SMTerrain.h
1 //
2 // SMTerrain class : Dynamically rendering terrain
3 //
4 // Copyright (c) 2001-2011 Virtual Terrain Project
5 // Free for all uses, see license.txt for details.
6 //
7 
8 #ifndef SMTERRAINH
9 #define SMTERRAINH
10 
11 #include <limits.h>
12 #include "DynTerrain.h"
13 
16 
17 // Configure the implementation with the following definitions:
18 
19 // Converts all elevation values to signed short integers, such that each
20 // unit = 0.25 meters. The range of a short (*/-32768) allows an elevation
21 // range of +/- 8000 meters, which is enough for all the topography on Earth.
22 #define INTEGER_HEIGHT 1
23 
24 // Store the frustum state (out, part in, all in) which each triangle so
25 // that they can be drawn with special colors to aid in debugging.
26 #define STORE_FRUSTUM 0
27 
28 // Use quick (macro, no assert) triangle stack, may give performance increase
29 // (not compatible with STORE_FRUSTUM)
30 #define FAST_ALLOC 0
31 
32 // Pack the variable values into a single byte, using the FP8 macros.
33 // This saves memory by 1 byte per heixel.
34 #define USE_FP8 1
35 
36 
37 /*
38 Seumas says:
39 
40  "I use bytes for my variance info, since my vertical height map
41  resolution is 25cm. Since the variance tree can get pretty big,
42  I'd suggest using bytes anyway, perhaps with a non-linear scaling
43  if you need larger dynamic range."
44 
45  "I believe my implicit variance tree is max-4 levels deep, so imagine
46  the finest tessellation possible, then step back 4 levels from there."
47 */
48 
49 #if INTEGER_HEIGHT
50  typedef short HeightType;
51  #if USE_FP8
52  typedef uchar VarianceType;
53  #else
54  typedef unsigned short VarianceType;
55  #endif
56  typedef int MathType; // use this type to perform arithmetic on
57  // the heights and variances
58 #else
59  typedef float HeightType;
60  typedef float VarianceType;
61  typedef float MathType;
62 #endif
63 
64 #if STORE_FRUSTUM
65  #define SetFrust(t, i) (t)->m_frust = i
66 #else
67  #define SetFrust(t, i)
68 #endif
69 
70 #define FRUST_OUT 0
71 #define FRUST_PARTIN 1
72 #define FRUST_ALLIN 2
73 
74 class BinTri
75 {
76 public:
77  BinTri *LeftChild;
78  BinTri *RightChild;
79  BinTri *LeftNeighbor;
80  BinTri *RightNeighbor;
81  BinTri *BottomNeighbor;
82  // to add: some goop for geomorphs
83 #if STORE_FRUSTUM
84  int m_frust;
85 #endif
86 };
87 
88 class Block
89 {
90 public:
91  // the two root triangles of the block
92  BinTri *root[2];
93  int num[2];
94  int v0[2];
95  int v1[2];
96  int va[2];
97 };
98 typedef Block *BlockPtr;
99 
100 
130 {
131 public:
132  SMTerrain();
133 
135  DTErr Init(const vtElevationGrid *pGrid, float fZScale);
136  static int MemoryRequired(int iDimension);
137 
138  // overrides
139  void DoRender();
140  void DoCulling(const vtCamera *pCam);
141  float GetElevation(int iX, int iZ, bool bTrue = false) const;
142  void GetWorldLocation(int iX, int iZ, FPoint3 &p, bool bTrue = false) const;
143  void SetVerticalExag(float fExag);
144  float GetVerticalExag() const;
145 
146  float GetQualityConstant() const { return m_fQualityConstant; }
147 
148 protected:
149  // initialization
150  void Init2();
151  void AllocatePool();
152  void ComputeVariances();
153  MathType ComputeTriangleVariance(int num, int v0, int v1, int va, int level);
154  void SetupBlocks();
155 
156  // per-frame
157  void AdjustQualityConstant();
158  void SplitToBlocks(int num, BinTri *tri, int v0, int v1, int va);
159  void SplitIfNeeded(int num, BinTri *tri, int v0, int v1, int va, bool bEntirelyInFrustum, int level);
160  void Split(BinTri *tri);
161  void Split2(BinTri *tri);
162 #if !FAST_ALLOC
163  inline BinTri *AllocateBinTri();
164 #endif
165 
166  // rendering
167  void RenderSurface();
168  void RenderBlock(BlockPtr block, bool bFans);
169  bool BlockIsVisible(BlockPtr block);
170  void LoadSingleMaterial();
171  void render_triangle_as_fan(BinTri *pTri, int v0, int v1, int va,
172  bool even, bool right);
173  void render_triangle_single(BinTri *pTri, int v0, int v1, int va);
174  void flush_buffer(int type);
175  inline float DistanceToTriangle(int num);
176 
177  // cleanup
178  virtual ~SMTerrain();
179 
180 private:
181  HeightType *m_pData; // the elevation height array
182  VarianceType *m_pVariance; // the variance implicit binary tree
183  float *m_HypoLength; // table of hypotenuse lengths
184 
185  // indices of the corners of the height array
186  int m_sw, m_nw, m_ne, m_se;
187 
188  int m_iDim; // dimension: same as width
189  int m_n; // the power-of-2 which defines the grid
190  int m_iLevels; // triangle tree's number of levels deep
191  int m_iNodes; // triangle tree's number of nodes
192  int m_iUsedNodes; // number of nodes needed for variance tree
193  int m_iSplitCutoff;
194  FPoint3 m_Eyepos; // world position of the viewpoint
195  float m_fZScale; // converts from values in height field to world scale
196 
197  float m_fQualityConstant;
198 
199  BlockPtr *m_pBlockArray;
200  int m_iBlockN;
201  int m_iBlockLevel;
202  int m_iBlockCutoff;
203  int m_iBlockPoolEnd;
204  int m_iBlockArrayDim;
205 
206  // The triangle pool use to hold rendered triangles
207  int m_iTriPoolSize;
208  BinTri *m_TriPool;
209  int m_NextBinTriPool;
210 
211  // the two root triangles of the binary triangle trees
212  BinTri *m_pNWTri;
213  BinTri *m_pSETri;
214 
215  bool hack_detail_pass;
216  bool m_bUseTriStrips;
217 };
218  // Group dynterr
220 
221 #endif