Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
quadtree.cpp
Go to the documentation of this file.
1 #include "quadtree.h"
2 #include "matrix.h"
3 #include "aux_texture.h"
4 #include "universe.h"
5 #include "vegastrike.h"
6 #include "vs_globals.h"
7 
9  GFXVertex( Vector( 0, 0, 0 ), Vector( 0, 1, 0 ), 0, 0 ),
10  GFXVertex( Vector( 0, 0, 0 ), Vector( 0, 1, 0 ), 0, 0 ),
11  GFXVertex( Vector( 0, 0, 0 ), Vector( 0, 1, 0 ), 0, 0 ),
12  GFXVertex( Vector( 0, 0, 0 ), Vector( 0, 1, 0 ), 0, 0 )
13 };
14 
15 QuadTree::QuadTree( const char *filename, const Vector &Scales, const float radius ) : minX( 0 )
16  , minZ( 0 )
17  , maxX( 0 )
18  , maxZ( 0 )
19  , Scales( Scales )
20  , vertices( GFXTRI, 4, InitialVertices, 4, true )
21 {
22  neighbors[0] = NULL;
23  neighbors[1] = NULL;
24  neighbors[2] = NULL;
25  neighbors[3] = NULL;
26  detail = 128;
28  transformation.r[0] = Scales.i;
29  transformation.r[4] = Scales.j;
30  transformation.r[8] = Scales.k;
31  //nonlinear_transform = new IdentityTransform;
32  RootCornerData.Parent = NULL;
33  RootCornerData.Square = NULL;
34  RootCornerData.ChildIndex = 0;
35  RootCornerData.Level = 15;
36  RootCornerData.xorg = 0;
37  RootCornerData.zorg = 0;
38  RootCornerData.Verts[0].Y = 0;
39  RootCornerData.Verts[0].vertindex = 0;
40  RootCornerData.Verts[1].Y = 0;
41  RootCornerData.Verts[1].vertindex = 1;
42  RootCornerData.Verts[2].Y = 0;
43  RootCornerData.Verts[2].vertindex = 2;
44  RootCornerData.Verts[3].Y = 0;
45  RootCornerData.Verts[3].vertindex = 3;
46  RootCornerData.Verts[0].SetTex( 0 );
47  RootCornerData.Verts[1].SetTex( 0 );
48  RootCornerData.Verts[2].SetTex( 0 );
49  RootCornerData.Verts[3].SetTex( 0 );
50  VertexAllocated = VertexCount = 4;
51  /*
52  * textures.push_back (TerrainTexture());
53  * for (int i=1;i<10;i++) {
54  * char name[]="terrainX.bmp";
55  * name[7] = '0'+i;
56  * TerrainTexture tmp;
57  * tmp.tex.t = new Texture (name);
58  * textures.push_back (tmp);
59  * }
60  */
61  if (filename) {
62  LoadXML( filename, Scales, radius );
63  //adData();
64  } else {
65  quadsquare::SetCurrentTerrain( &VertexAllocated,
66  &VertexCount,
67  &vertices,
68  &unusedvertices,
69  nonlinear_transform,
70  &textures,
71  Vector( 1.0F/Scales.i, 1.0F/Scales.j, 1.0F/Scales.k ),
72  neighbors );
73  root = new quadsquare( &RootCornerData );
74  }
75  //root->StaticCullData (RootCornerData,25);
76  /*
77  * for (i = 0; i < 10; i++) {
78  * root->Update(RootCornerData, (const float*) ViewerLoc, Detail);
79  * }
80  */
81 }
82 
83 void QuadTree::StaticCullData( const float detail )
84 {
85  root->StaticCullData( RootCornerData, detail );
86 }
87 
88 void QuadTree::SetNeighbors( quadsquare *east, quadsquare *north, quadsquare *west, quadsquare *south )
89 {
90  neighbors[0] = east;
91  neighbors[1] = north;
92  neighbors[2] = west;
93  neighbors[3] = south;
94 }
95 
96 void QuadTree::SetNeighbors( QuadTree *east, QuadTree *north, QuadTree *west, QuadTree *south )
97 {
98  SetNeighbors( east->root, north->root, west->root, south->root );
99 }
100 
102 {
103  delete root;
104  delete nonlinear_transform;
105 }
106 
108  Vector &norm,
109  const Matrix &transf,
110  float TotalTerrainSizeX,
111  float TotalTerrainSizeZ ) const
112 {
113  QVector Loc = nonlinear_transform->InvTransform( InvScaleTransform( transf, Location ) );
114  if (TotalTerrainSizeX) {
115  float tmpx = Loc.i;
116  Loc.i = fmod( (double) Loc.i, (double) TotalTerrainSizeX );
117  if (Loc.i < 0)
118  Loc.i += TotalTerrainSizeX;
119  TotalTerrainSizeX = tmpx;
120  tmpx = Loc.k;
121  Loc.k = fmod( (double) Loc.k, (double) TotalTerrainSizeZ );
122  if (Loc.k < 0)
123  Loc.k += TotalTerrainSizeZ;
124  TotalTerrainSizeZ = tmpx;
125  } else {
126  TotalTerrainSizeX = Loc.i;
127  TotalTerrainSizeZ = Loc.k;
128  }
129  float tmp = root->GetHeight( RootCornerData, Loc.i, Loc.k, norm );
130  if (tmp > -FLT_MAX) {
131  //VSFileSystem::Fprintf (stderr,"Orig<%f,%f,%f> Now <%f,%f,%f>",Loc.i,Loc.j,Loc.k,Loc.i,tmp,Loc.k);
132  Location =
133  Transform( transf, nonlinear_transform->Transform( QVector( TotalTerrainSizeX, tmp, TotalTerrainSizeZ ) ) ).Cast();
134  norm = TransformNormal( transf, nonlinear_transform->TransformNormal( Location, norm ) );
135  norm.Normalize();
136 
137  return true;
138  }
139  return false;
140 }
141 
142 float QuadTree::GetHeight( Vector Location,
143  Vector &normal,
144  const Matrix &transf,
145  float TotalTerrainSizeX,
146  float TotalTerrainSizeZ ) const
147 {
148  Location = nonlinear_transform->InvTransform( InvScaleTransform( transf, Location ) );
149  if (TotalTerrainSizeX) {
150  //float t1=Location.i;
151  //float t2=Location.k;
152  Location.i = fmod( Location.i, TotalTerrainSizeX );
153  Location.k = fmod( Location.k, TotalTerrainSizeZ );
154  //if (t1!=Location.i|| t2!=Location.k) {
155  //VSFileSystem::Fprintf (stderr,"wired");
157  if (Location.i < 0)
158  Location.i += TotalTerrainSizeX;
159  if (Location.k < 0)
160  Location.k += TotalTerrainSizeZ;
161  }
162  float tmp = Location.j-root->GetHeight( RootCornerData, Location.i, Location.k, normal );
163  normal = TransformNormal( transf, nonlinear_transform->TransformNormal( Location, normal ) );
164  normal.Normalize();
165  //VSFileSystem::Fprintf (stderr,"<%f>",tmp);
166  return tmp;
167 }
168 
169 void QuadTree::Update( unsigned short numstages, unsigned short whichstage, updateparity *uo )
170 {
171  //GetViewerPosition
172  quadsquare::SetCurrentTerrain( &VertexAllocated,
173  &VertexCount,
174  &vertices,
175  &unusedvertices,
176  nonlinear_transform,
177  &textures,
178  Vector( 1.0F/Scales.i, 1.0F/Scales.j, 1.0F/Scales.k ),
179  neighbors );
180  root->Update( RootCornerData,
181  nonlinear_transform->InvTransform( InvScaleTransform( transformation,
182  _Universe->AccessCamera()->GetPosition() ) ), detail,
183  numstages, whichstage, uo );
184 }
185 
186 inline Vector calculatenormscale( const Matrix &trans )
187 {
188  return Vector( 1.0F/( Vector( trans.getP() ).Magnitude() ), 1.0F/( Vector( trans.getQ() ).Magnitude() ), 1.0F
189  /( Vector( trans.getR() ).Magnitude() ) );
190 }
191 
193 {
194  transformation = mat;
195  Scales = ( calculatenormscale( mat ) );
196 }
197 
199 {
202  GFXEnable( TEXTURE0 );
203  GFXDisable( TEXTURE1 );
204  GFXEnable( LIGHTING );
205  GFXBlendMode( ONE, ZERO );
206  quadsquare::SetCurrentTerrain( &VertexAllocated,
207  &VertexCount,
208  &vertices,
209  &unusedvertices,
210  nonlinear_transform,
211  &textures,
212  Scales,
213  neighbors );
214  root->Render( RootCornerData,
216 }
217 
218 void QuadTree::LoadData()
219 {
220 //Load some data and put it into the quadtree.
221  nonlinear_transform = new IdentityTransform();
222  HeightMapInfo hm;
223  hm.XOrigin = 0;
224  hm.ZOrigin = 0;
225  hm.XSize = 512;
226  hm.ZSize = 512;
227  hm.RowWidth = hm.XSize;
228  hm.Scale = 7;
229  hm.Data = new short[hm.XSize*hm.ZSize];
230  hm.terrainmap = new unsigned char[hm.XSize*hm.ZSize];
231  memset( hm.terrainmap, 0, sizeof (unsigned char)*hm.ZSize*hm.XSize );
232  printf( "Loading height grids...\n" );
233 
234  //Big coarse data, at 128 meter sample spacing.
235  FILE *fp = VSFileSystem::vs_open( "demdata/gc16at128.raw", "rb" );
236  VSFileSystem::vs_read( hm.Data, sizeof (unsigned short), hm.XSize*hm.ZSize, fp );
238  printf( "Building quadtree data...\n" );
239  root->AddHeightMap( RootCornerData, hm );
240 
241  //More detailed data at 64 meter spacing, covering the middle of the terrain.
242  hm.XOrigin = 16384;
243  hm.ZOrigin = 16384;
244  hm.Scale = 6;
245  fp = VSFileSystem::vs_open( "demdata/gc16at64.raw", "rb" );
246  VSFileSystem::vs_read( hm.Data, sizeof (unsigned short), hm.XSize*hm.ZSize, fp );
248  printf( "Adding quadtree data...\n" );
249  root->AddHeightMap( RootCornerData, hm );
250 
251  //Even more detailed data, at 32 meter spacing, covering a smaller area near the middle.
252  hm.XOrigin = 24576;
253  hm.ZOrigin = 24576;
254  hm.Scale = 5;
255  fp = VSFileSystem::vs_open( "demdata/gc16at32.raw", "rb" );
256  VSFileSystem::vs_read( hm.Data, sizeof (unsigned short), hm.XSize*hm.ZSize, fp );
258  printf( "Adding quadtree data...\n" );
259  root->AddHeightMap( RootCornerData, hm );
260 
261  delete[] hm.Data;
262 }
263 
264 Vector QuadTree::GetNormal( const Vector &position, const Vector &norm ) const
265 {
266  return TransformNormal( transformation, nonlinear_transform->TransformNormal( position, norm ) );
267 }
268