Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TerrainRegion.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: TerrainRegion.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Various Heavenly Bodies
13 */
14 
15 #include "MemDebug.h"
16 #include "TerrainRegion.h"
17 #include "Sky.h"
18 #include "TerrainHaze.h"
19 #include "TerrainLayer.h"
20 #include "Sim.h"
21 #include "Grid.h"
22 #include "CameraDirector.h"
23 #include "HUDView.h"
24 
25 #include "Game.h"
26 #include "Sound.h"
27 #include "Solid.h"
28 #include "Sprite.h"
29 #include "Light.h"
30 #include "Bitmap.h"
31 #include "DataLoader.h"
32 #include "Scene.h"
33 #include "ParseUtil.h"
34 
35 // +====================================================================+
36 
37 TerrainRegion::TerrainRegion(StarSystem* s, const char* n, double r, Orbital* p)
38 : OrbitalRegion(s, n, 0.0, r, 0.0, p),
39 scale(10e3),
40 mtnscale(1e3),
41 fog_density(0),
42 fog_scale(0),
43 day_phase(0),
44 eclipsed(false)
45 {
46  type = TERRAIN;
47 
48  if (primary) {
49  orbit = primary->Radius();
50  period = primary->Rotation();
51  }
52 
53  clouds_alt_high = 12.0e3;
54  clouds_alt_low = 8.0e3;
55 
56  Update();
57 }
58 
59 // +--------------------------------------------------------------------+
60 
62 {
63  layers.destroy();
64 }
65 
66 // +--------------------------------------------------------------------+
67 
68 void
70 {
71  if (system && primary) {
73  loc = primary->Location() + Point((double) (orbit * cos(phase)),
74  (double) (orbit * sin(phase)),
75  0);
76  }
77 
78  if (rep)
79  rep->MoveTo(loc.OtherHand());
80 
81  // calc day phase:
82  OrbitalBody* star = system->Bodies()[0];
83 
84  Point tvpn = Location() - primary->Location();
85  Point tvst = star->Location() - primary->Location();
86 
87  tvpn.Normalize();
88  tvst.Normalize();
89 
90  day_phase = acos(tvpn * tvst) + PI;
91 
92  Point meridian = tvpn.cross(tvst);
93 
94  if (meridian.z < 0) {
95  day_phase = 2*PI - day_phase;
96  }
97 
98  day_phase *= 24 / (2*PI);
99 
100  if (!system || system->ActiveRegion() != this)
101  return;
102 
103  // set sky color:
104  int base_hour = (int) day_phase;
105  double fraction = day_phase - base_hour;
106 
107  sky_color[24] = Color::Scale(sky_color[base_hour], sky_color[base_hour+1], fraction);
108  sun_color[24] = Color::Scale(sun_color[base_hour], sun_color[base_hour+1], fraction);
109  fog_color[24] = Color::Scale(fog_color[base_hour], fog_color[base_hour+1], fraction);
110  ambient[24] = Color::Scale(ambient[base_hour], ambient[base_hour+1], fraction);
111  overcast[24] = Color::Scale(overcast[base_hour], overcast[base_hour+1], fraction);
112  cloud_color[24] = Color::Scale(cloud_color[base_hour], cloud_color[base_hour+1], fraction);
113  shade_color[24] = Color::Scale(shade_color[base_hour], shade_color[base_hour+1], fraction);
114 
116  Sim* sim = Sim::GetSim();
117  double alt = 0;
118  double dim = 1;
119 
120  if (cam_dir && cam_dir->GetCamera())
121  alt = cam_dir->GetCamera()->Pos().y;
122 
123  if (alt > 0) {
124  if (alt < TERRAIN_ALTITUDE_LIMIT) {
125  if (weather.Ceiling() > 0) {
126  fog_color[24] = overcast[24];
127  sky_color[24] = overcast[24];
128  dim = 0.125;
129 
130  /***
131  if (alt < weather.Ceiling()) {
132  sky_color[24] = overcast[24];
133  dim = 0.125;
134  }
135  else if (alt < weather.Ceiling() + 500) {
136  double thick = (weather.Ceiling() + 500.0 - alt) / 500.0;
137  sky_color[24] = sky_color[24] * (1.0 - thick);
138  sky_color[24] += overcast[24] * thick;
139 
140  dim = 1 - thick * 0.875;
141  }
142  else {
143  sky_color[24] = sky_color[24] * (1 - alt/TERRAIN_ALTITUDE_LIMIT);
144  }
145  ***/
146  }
147 
148  else {
149  sky_color[24] = sky_color[24] * (1 - alt/TERRAIN_ALTITUDE_LIMIT);
150  }
151  }
152  else {
153  sky_color[24] = Color::Black;
154  }
155  }
156 
157  if (system) {
158  system->SetSunlight(sun_color[24], dim);
159  system->SetBacklight(sky_color[24], dim);
160 
161  HUDView* hud = HUDView::GetInstance();
162  if (hud) {
163  Color night_vision = hud->Ambient();
164  sky_color[24] += night_vision * 0.15;
165  }
166  }
167 }
168 
169 // +--------------------------------------------------------------------+
170 
171 void
172 TerrainRegion::LoadSkyColors(const char* bmp_name)
173 {
174  Bitmap sky_colors_bmp;
175 
176  DataLoader* loader = DataLoader::GetLoader();
177  loader->LoadBitmap(bmp_name, sky_colors_bmp);
178 
179  int max_color = sky_colors_bmp.Width();
180 
181  if (max_color > 24)
182  max_color = 24;
183 
184  for (int i = 0; i < 25; i++) {
185  sun_color[i] = Color::White;
186  sky_color[i] = Color::Black;
187  fog_color[i] = Color::White;
191  }
192 
193  for (int i = 0; i < max_color; i++)
194  sky_color[i] = sky_colors_bmp.GetColor(i, 0);
195 
196  if (sky_colors_bmp.Height() > 1)
197  for (int i = 0; i < max_color; i++)
198  fog_color[i].Set(sky_colors_bmp.GetColor(i, 1).Value() | Color(0,0,0,255).Value());
199 
200  if (sky_colors_bmp.Height() > 2)
201  for (int i = 0; i < max_color; i++)
202  ambient[i] = sky_colors_bmp.GetColor(i, 2);
203 
204  if (sky_colors_bmp.Height() > 3)
205  for (int i = 0; i < max_color; i++)
206  sun_color[i] = sky_colors_bmp.GetColor(i, 3);
207 
208  if (sky_colors_bmp.Height() > 4)
209  for (int i = 0; i < max_color; i++)
210  overcast[i] = sky_colors_bmp.GetColor(i, 4);
211 
212  if (sky_colors_bmp.Height() > 5)
213  for (int i = 0; i < max_color; i++)
214  cloud_color[i] = sky_colors_bmp.GetColor(i, 5);
215 
216  if (sky_colors_bmp.Height() > 6)
217  for (int i = 0; i < max_color; i++)
218  shade_color[i] = sky_colors_bmp.GetColor(i, 6);
219 }
220 
221 // +--------------------------------------------------------------------+
222 
223 void
224 TerrainRegion::AddLayer(double h, const char* tile, const char* detail)
225 {
226  TerrainLayer* layer = new(__FILE__,__LINE__) TerrainLayer;
227 
228  layer->min_height = h;
229  layer->tile_name = tile;
230 
231  if (detail && *detail)
232  layer->detail_name = detail;
233 
234  layers.append(layer);
235 }
236 
237 const Text&
239 {
240  switch (face) {
241  case 0: return env_texture_positive_x;
242 
243  case 1: if (env_texture_negative_x.length() > 0)
244  return env_texture_negative_x;
245  return env_texture_positive_x;
246 
247  case 2: return env_texture_positive_y;
248 
249  case 3: if (env_texture_negative_y.length() > 0)
250  return env_texture_negative_y;
251  return env_texture_positive_y;
252 
253  case 4: if (env_texture_positive_z.length() > 0)
254  return env_texture_positive_z;
255  return env_texture_positive_x;
256 
257  case 5: if (env_texture_negative_z.length() > 0)
258  return env_texture_negative_z;
259  if (env_texture_positive_z.length() > 0)
260  return env_texture_positive_z;
261  return env_texture_positive_x;
262  }
263 
264  return env_texture_positive_x;
265 }
266