From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_terrain_8cpp_source.html | 678 +++++++++++++++++++++++++++++ 1 file changed, 678 insertions(+) create mode 100644 Doc/doxygen/html/_terrain_8cpp_source.html (limited to 'Doc/doxygen/html/_terrain_8cpp_source.html') diff --git a/Doc/doxygen/html/_terrain_8cpp_source.html b/Doc/doxygen/html/_terrain_8cpp_source.html new file mode 100644 index 0000000..19a7e6e --- /dev/null +++ b/Doc/doxygen/html/_terrain_8cpp_source.html @@ -0,0 +1,678 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/Terrain.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Terrain.cpp
+
+
+Go to the documentation of this file.
1 /* Project Starshatter 4.5
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2005. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Stars.exe
+
6  FILE: Terrain.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12 */
+
13 
+
14 #include "MemDebug.h"
+
15 #include "Terrain.h"
+
16 #include "TerrainApron.h"
+
17 #include "TerrainClouds.h"
+
18 #include "TerrainLayer.h"
+
19 #include "TerrainPatch.h"
+
20 #include "TerrainRegion.h"
+
21 #include "Water.h"
+
22 
+
23 #include "CameraView.h"
+
24 #include "Projector.h"
+
25 #include "Scene.h"
+
26 #include "Bitmap.h"
+
27 #include "DataLoader.h"
+
28 #include "Game.h"
+
29 #include "MachineInfo.h"
+
30 
+
31 // +--------------------------------------------------------------------+
+
32 
+
33 int Terrain::detail_level = 3; // default = MEDIUM DETAIL
+
34 
+
35 const int PATCH_SIZE = 16;
+
36 
+
37 // +--------------------------------------------------------------------+
+
38 
+ +
40 : region(trgn), patches(0), water_patches(0), water(0),
+
41 aprons(0), clouds(0), terrain_normals(0)
+
42 {
+
43  detail_frame = 0;
+
44  datapath = "Galaxy/";
+
45  terrain_texture = 0;
+
46  apron_texture = 0;
+
47  water_texture = 0;
+
48 
+
49  for (int i = 0; i < 2; i++) {
+
50  cloud_texture[i] = 0;
+
51  shade_texture[i] = 0;
+
52  noise_texture[i] = 0;
+
53  }
+
54 
+
55  if (region) {
+ + +
58 
+ +
60  while (++iter) {
+
61  TerrainLayer* orig = iter.value();
+
62  TerrainLayer* copy = new(__FILE__,__LINE__) TerrainLayer;
+
63  *copy = *orig;
+
64  layers.append(copy);
+
65  }
+
66 
+
67  layers.sort();
+
68  }
+
69 
+
70  else {
+
71  scale = 1;
+
72  mtnscale = 1;
+
73  }
+
74 }
+
75 
+
76 // +--------------------------------------------------------------------+
+
77 
+ +
79 {
+
80  int i, j;
+
81 
+
82  if (patches)
+
83  for (i = 0; i < subdivisions; i++)
+
84  for (j = 0; j < subdivisions; j++)
+
85  GRAPHIC_DESTROY(patches[i*subdivisions+j]);
+
86 
+
87  if (water_patches)
+
88  for (i = 0; i < subdivisions; i++)
+
89  for (j = 0; j < subdivisions; j++)
+
90  GRAPHIC_DESTROY(water_patches[i*subdivisions+j]);
+
91 
+
92  if (aprons)
+
93  for (i = 0; i < 8; i++)
+ +
95 
+
96  if (clouds)
+
97  for (i = 0; i < nclouds; i++)
+ +
99 
+
100  if (water)
+
101  for (i = 0; i < 6; i++)
+
102  delete water[i];
+
103 
+
104  delete [] aprons;
+
105  delete [] clouds;
+
106  delete [] patches;
+
107  delete [] water;
+
108  delete [] terrain_normals;
+
109 
+ + +
112 
+
113  layers.destroy();
+
114 }
+
115 
+
116 // +--------------------------------------------------------------------+
+
117 
+
118 void
+ +
120 {
+
121  DataLoader* loader = DataLoader::GetLoader();
+
122  loader->SetDataPath(datapath);
+ + + + +
127  if (region->WaterTexture().length()) {
+ +
129 
+
130  if (region->EnvironmentTexture(0).length() > 0) {
+ + + + + + +
137  }
+
138  }
+
139 
+ + + +
143 
+
144  if (region->DetailTexture0().length())
+ +
146 
+
147  if (region->DetailTexture1().length())
+
148  loader->LoadTexture(region->DetailTexture1(),noise_texture[1], Bitmap::BMP_TRANSLUCENT, false, true);
+
149 
+ + +
152 
+
153  BuildNormals();
+
154 
+
155  int i, j;
+
156  int ntiles = terrain_patch.Width()/2 * terrain_patch.Height()/2;
+
157  double dx = scale * patch_size;
+
158  double dz = scale * patch_size;
+
159  double offset = -subdivisions/2;
+
160 
+
161  if (water_texture) {
+
162  water = new(__FILE__,__LINE__) Water*[6];
+
163  for (i = 0; i < 6; i++) {
+
164  water[i] = new(__FILE__,__LINE__) Water();
+
165  int n = (1<<i) + 1;
+
166  water[i]->Init(n, (float) (scale*patch_size), 90.0f);
+
167  }
+
168  }
+
169 
+
170  // load tile textures:
+
171  for (i = 0; i < layers.size(); i++) {
+
172  TerrainLayer* layer = layers.at(i);
+
173 
+
174  if (i < layers.size()-1)
+
175  layer->max_height = layers.at(i+1)->min_height;
+
176  else
+
177  layer->max_height = 1e6;
+
178 
+
179  if (layer->tile_name.length())
+
180  loader->LoadTexture(layer->tile_name, layer->tile_texture);
+
181 
+
182  if (layer->detail_name.length())
+
183  loader->LoadTexture(layer->detail_name, layer->detail_texture);
+
184  }
+
185 
+
186  patches = new(__FILE__,__LINE__) TerrainPatch*[subdivisions*subdivisions];
+
187 
+
188  if (water_texture)
+
189  water_patches = new(__FILE__,__LINE__) TerrainPatch*[subdivisions*subdivisions];
+
190 
+
191  for (i = 0; i < subdivisions; i++) {
+
192  for (j = 0; j < subdivisions; j++) {
+
193  int j1 = subdivisions - j;
+
194  Rect rect(j * patch_size, i * patch_size, patch_size, patch_size);
+
195  Point p1((j1 + offset )*dx, 0, (i + offset )*dz);
+
196  Point p2((j1 + offset+1)*dx, mtnscale, (i + offset+1)*dz);
+
197 
+
198  int index = i*subdivisions+j;
+
199  patches[index] = new(__FILE__,__LINE__) TerrainPatch(this, &terrain_patch, rect, p1, p2);
+
200 
+
201  if (water_texture && patches[index]->MinHeight() < 3)
+
202  water_patches[index] = new(__FILE__,__LINE__) TerrainPatch(this, rect, p1, p2, 30);
+
203 
+
204  else if (water_patches != 0)
+
205  water_patches[index] = 0;
+
206  }
+
207  }
+
208 
+
209  int a = 0;
+
210  dx = scale * terrain_patch.Width();
+
211  dz = scale * terrain_patch.Height();
+
212  offset = -3.0/2;
+
213  double xoffset = offset + 1.0/16.0;
+
214 
+
215  aprons = new(__FILE__,__LINE__) TerrainApron*[8];
+
216 
+
217  for (i = 0; i < 3; i++) {
+
218  for (j = 0; j < 3; j++) {
+
219  int j1 = 2 - j;
+
220  if (i != 1 || j1 != 1) {
+
221  Rect rect(j * subdivisions, i * subdivisions, subdivisions, subdivisions);
+
222  Point p1((j1 + xoffset )*dx, 0, (i + offset )*dz);
+
223  Point p2((j1 + xoffset+1)*dx, mtnscale, (i + offset+1)*dz);
+
224 
+
225  aprons[a++] = new(__FILE__,__LINE__) TerrainApron(this, &terrain_apron, rect, p1, p2);
+
226  }
+
227  }
+
228  }
+
229 
+
230  Weather::STATE state = region->GetWeather().State();
+
231 
+
232  if (state == Weather::HIGH_CLOUDS || state == Weather::MODERATE_CLOUDS) {
+
233  double altitude = region->CloudAltHigh();
+
234  nclouds = 9;
+
235 
+
236  if (state == Weather::MODERATE_CLOUDS)
+
237  nclouds *= 2;
+
238 
+
239  clouds = new(__FILE__,__LINE__) TerrainClouds*[nclouds];
+
240 
+
241  a = 0;
+
242  for (i = 0; i < 3; i++) {
+
243  for (j = 0; j < 3; j++) {
+
244  clouds[a] = new(__FILE__,__LINE__) TerrainClouds(this, 0);
+
245 
+
246  double xloc = (j-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
+
247  double yloc = (i-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
+
248 
+
249  clouds[a]->MoveTo(Point(xloc, altitude, yloc));
+
250  a++;
+
251  }
+
252  }
+
253 
+
254  if (state == Weather::MODERATE_CLOUDS) {
+
255  altitude = region->CloudAltLow();
+
256 
+
257  for (i = 0; i < 3; i++) {
+
258  for (j = 0; j < 3; j++) {
+
259  clouds[a] = new(__FILE__,__LINE__) TerrainClouds(this, 1);
+
260 
+
261  double xloc = (j-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
+
262  double yloc = (i-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
+
263 
+
264  clouds[a]->MoveTo(Point(xloc, altitude, yloc));
+
265  a++;
+
266  }
+
267  }
+
268  }
+
269  }
+
270 }
+
271 
+
272 // +--------------------------------------------------------------------+
+
273 
+
274 void
+ +
276 {
+
277  if (terrain_normals) {
+
278  delete [] terrain_normals;
+
279  terrain_normals = 0;
+
280  }
+
281 
+
282  int i, x, y;
+
283 
+
284  int w = terrain_patch.Width();
+
285  int h = terrain_patch.Height();
+
286  Color* pix = terrain_patch.HiPixels();
+
287  BYTE* alt = new(__FILE__,__LINE__) BYTE[h*w];
+
288  int nverts = w * h;
+
289  double scale = region->MountainScale() / (region->LateralScale() * 2.0);
+
290 
+
291  terrain_normals = new(__FILE__,__LINE__) Vec3B[nverts];
+
292 
+
293  ZeroMemory(terrain_normals, sizeof(Vec3B) * nverts);
+
294 
+
295  for (i = 0; i < w; i++) {
+
296  alt [ i] = 0;
+
297  alt [(h-1)*w + i] = 0;
+
298  terrain_normals[ i] = Vec3B(128,128,255);
+
299  terrain_normals[(h-1)*w + i] = Vec3B(128,128,255);
+
300  }
+
301 
+
302  for (i = 0; i < h; i++) {
+
303  alt [i*w ] = 0;
+
304  alt [i*w + (w-1)] = 0;
+
305  terrain_normals[i*w ] = Vec3B(128,128,255);
+
306  terrain_normals[i*w + (w-1)] = Vec3B(128,128,255);
+
307  }
+
308 
+
309  for (y = 1; y < h-1; y++) {
+
310  for (x = 1; x < w-1; x++) {
+
311  alt[y*w+x] = (BYTE) pix[y*w+x].Red();
+
312  }
+
313  }
+
314 
+
315  for (y = 1; y < h-1; y++) {
+
316  for (x = 1; x < w-1; x++) {
+
317  double dx = (alt[y*w + (x-1)] - alt[y*w + (x+1)]) * scale +
+
318  (alt[(y-1)*w + (x-1)] - alt[(y-1)*w + (x+1)]) * scale * 0.5 +
+
319  (alt[(y+1)*w + (x-1)] - alt[(y+1)*w + (x+1)]) * scale * 0.5;
+
320 
+
321  double dy = (alt[(y-1)*w + x ] - alt[(y+1)*w + x ]) * scale +
+
322  (alt[(y-1)*w + (x-1)] - alt[(y+1)*w + (x-1)]) * scale * 0.5 +
+
323  (alt[(y-1)*w + (x+1)] - alt[(y+1)*w + (x+1)]) * scale * 0.5;
+
324 
+
325  Point norm(dx,dy,1);
+
326  norm.Normalize();
+
327 
+
328  Vec3B* tnorm = &terrain_normals[y*w + x];
+
329 
+
330  tnorm->x = (BYTE) (norm.x * 127 + 128);
+
331  tnorm->y = (BYTE) (norm.y * 127 + 128);
+
332  tnorm->z = (BYTE) (norm.z * 127 + 128);
+
333 
+
334  double foo = dx/dy;
+
335  }
+
336  }
+
337 
+
338  delete [] alt;
+
339 }
+
340 
+
341 // +--------------------------------------------------------------------+
+
342 
+
343 void
+ +
345 {
+
346  int i, j;
+
347 
+
348  StarSystem* system = region->System();
+
349  if (system)
+
350  datapath = system->GetDataPath();
+
351 
+
352  region->GetWeather().Update();
+
353 
+
354  if (!patches)
+
355  BuildTerrain();
+
356 
+
357  if (patches) {
+
358  for (i = 0; i < subdivisions; i++)
+
359  for (j = 0; j < subdivisions; j++)
+
360  if (patches[i*subdivisions+j])
+
361  scene.AddGraphic(patches[i*subdivisions+j]);
+
362  }
+
363 
+
364  if (water_patches) {
+
365  for (i = 0; i < subdivisions; i++)
+
366  for (j = 0; j < subdivisions; j++)
+
367  if (water_patches[i*subdivisions+j])
+
368  scene.AddGraphic(water_patches[i*subdivisions+j]);
+
369  }
+
370 
+
371  if (aprons) {
+
372  for (i = 0; i < 8; i++)
+
373  if (aprons[i])
+
374  scene.AddGraphic(aprons[i]);
+
375  }
+
376 
+
377  if (clouds) {
+
378  for (i = 0; i < nclouds; i++)
+
379  if (clouds[i])
+
380  scene.AddGraphic(clouds[i]);
+
381  }
+
382 }
+
383 
+
384 void
+ +
386 {
+
387  int i, j;
+
388 
+
389  if (patches) {
+
390  for (i = 0; i < subdivisions; i++) {
+
391  for (j = 0; j < subdivisions; j++) {
+
392  TerrainPatch* p = patches[i*subdivisions+j];
+
393 
+
394  if (p) {
+
395  p->DeletePrivateData();
+
396  scene.DelGraphic(p);
+
397  }
+
398  }
+
399  }
+
400  }
+
401 
+
402  if (water_patches) {
+
403  for (i = 0; i < subdivisions; i++) {
+
404  for (j = 0; j < subdivisions; j++) {
+
405  TerrainPatch* p = water_patches[i*subdivisions+j];
+
406 
+
407  if (p) {
+
408  p->DeletePrivateData();
+
409  scene.DelGraphic(p);
+
410  }
+
411  }
+
412  }
+
413  }
+
414 
+
415  if (aprons) {
+
416  for (i = 0; i < 8; i++)
+
417  if (aprons[i])
+
418  scene.DelGraphic(aprons[i]);
+
419  }
+
420 
+
421  if (clouds) {
+
422  for (i = 0; i < nclouds; i++)
+
423  if (clouds[i])
+
424  scene.DelGraphic(clouds[i]);
+
425  }
+
426 
+
427  StarSystem* system = region->System();
+
428 
+
429  // restore sunlight color and brightness on exit:
+
430  if (system) {
+
431  system->RestoreTrueSunColor();
+
432  }
+
433 }
+
434 
+
435 // +--------------------------------------------------------------------+
+
436 
+
437 void
+
438 Terrain::ExecFrame(double seconds)
+
439 {
+
440  if (water) {
+
441  for (int i = 0; i < 6; i++) {
+
442  if (water[i])
+
443  water[i]->CalcWaves(seconds);
+
444  }
+
445  }
+
446 }
+
447 
+
448 // +--------------------------------------------------------------------+
+
449 
+
450 void
+ +
452 {
+
453  if (!patches)
+
454  return;
+
455 
+
456  if (detail_frame >= Game::Frame())
+
457  return;
+
458 
+
459  // compute detail map:
+
460  int x, z;
+
461 
+
462  for (z = 0; z < subdivisions; z++) {
+
463  for (x = 0; x < subdivisions; x++) {
+
464  TerrainPatch* patch = patches[z*subdivisions + x];
+
465  int ndetail = 0;
+
466  Point loc = patch->Location();
+
467  float radius = patch->Radius();
+
468 
+
469  if (loc.length() < 2*radius) {
+
470  ndetail = detail_level;
+
471  }
+
472 
+
473  else {
+
474  double threshold = 4; //16;
+
475 
+
476  for (int level = 1; level <= detail_level; level++) {
+
477  double feature_size = radius / (1 << level);
+
478 
+
479  if (projector->ApparentRadius(loc, (float) feature_size) > threshold)
+
480  ndetail = level;
+
481  }
+
482  }
+
483 
+
484  patch->SetDetailLevel(ndetail);
+
485 
+
486  if (water_patches) {
+
487  patch = water_patches[z*subdivisions + x];
+
488  if (patch)
+
489  patch->SetDetailLevel(ndetail);
+
490  }
+
491  }
+
492  }
+
493 
+
494  // compute fog fade level:
+
495  double hour = region->DayPhase();
+
496 
+
497  if (hour < 12)
+
498  fog_fade = (hour) / 12.0;
+
499  else
+
500  fog_fade = (24-hour) / 12.0;
+
501 
+ +
503 
+ +
505 }
+
506 
+
507 // +--------------------------------------------------------------------+
+
508 
+
509 double
+
510 Terrain::Height(double x, double y) const
+
511 {
+
512  double h = 0;
+
513 
+
514  if (patches) {
+
515  int ix = (int) floor(x / (patch_size * scale));
+
516  int iy = (int) floor(y / (patch_size * scale));
+
517 
+
518  double px = x - ix * patch_size * scale;
+
519  double py = y - iy * patch_size * scale;
+
520 
+
521  ix = subdivisions/2 - ix;
+
522  iy = subdivisions/2 + iy;
+
523 
+
524  TerrainPatch* patch = 0;
+
525 
+
526  if (ix >= 0 && ix < subdivisions &&
+
527  iy >= 0 && iy < subdivisions)
+
528  patch = patches[iy*subdivisions+ix];
+
529 
+
530  if (patch)
+
531  h = patch->Height(px, py);
+
532  }
+
533 
+
534  if (water_patches && h < 30)
+
535  h = 30;
+
536 
+
537  return h;
+
538 }
+
539 
+
540 // +--------------------------------------------------------------------+
+
541 
+
542 void
+ +
544 {
+
545  if (detail >= 1 && detail <= 4) {
+
546 
+
547  // limit detail on low memory machines:
+
548  if (detail > 3 && MachineInfo::GetTotalRam() < 64)
+
549  detail = 3;
+
550 
+
551  detail_level = detail;
+
552  }
+
553 }
+
554 
+
555 // +--------------------------------------------------------------------+
+
556 
+
557 bool
+ +
559 {
+
560  return (patches && *patches == p);
+
561 }
+
+
+ + + + -- cgit v1.1