Rise
The Vieneo Province
weather.cpp
Go to the documentation of this file.
1 #include "weather.h"
2 #include "Viewscreen.h"
3 #include "../MathUtilities.h"
4 
6 {
7  viewscreen = ptr;
8  logger = ptr->logger;
9 }
10 
11 void weather::FrameMove(float fElapsedTime)
12 {
13  logger->AddToCallStack("weather::FrameMove");
14 
15  D3DXVECTOR3 result;
16  D3DXCOLOR colorzenith;
17  const D3DXVECTOR3 Xsunlight = viewscreen->sunlight.Direction; // Start of the ray
18  // ReSharper disable once CppJoinDeclarationAndAssignment
19  HRESULT hr;
20 
21  // LIGHTNING FROM LEGACY CLIENT-----------------------------------------------------------------------------
22  const float scaledTurbidity = GetTurbidity() - 2.0f; // now 0-14
23  const float scaledTurbulence = scaledTurbidity * GetTurbulence() * 18.214f; // 0-255;
24 
25  if (!g_bAboveClouds && rand() < static_cast<short>(scaledTurbulence * 2.0f)) // made 2.0f*as likely now
26  {
27  // so no storm is 2 so 14+0 is 14 minus 0-14 randomly is 0-14
28  // bad storm is 16 so 14+14 is 28 minus 0-14 randomly is 14-28
29  float distance = 14.0f + scaledTurbidity - RandomFloat() * 14.0f;
30  // no storm is 2 so distance would now be 0-0.5 ...
31  // bad storm is 16 so distance would now be 0.5 to 1 ...
32  distance /= 28.0f; // based on a 10 this would give values from .41 to 1.0
33  if (distance > 0.0f) // 1 is very close, 0 is far away
34  {
35  const float intensity = RandomFloat(); // 1.0f is violent
36  const float seconds = (1.0f - distance) * 15.0f; // seconds
37  const float volume = sqrtf(distance * intensity) * viewscreen->ptrPropulsion->staticDensity; // volume
38 
39  if (volume > 0.5f && rand() % 2 && intensity > 0.5f && viewscreen->gameclass->GUI->player[viewscreen->gameclass->GUI->ourplayerC].frame == 0)
40  {
42  if (distance > 0.98f) // 2%
44  }
45 
46  viewscreen->gameclass->sound->AddDelayedSound(SOUND_THUNDER1 + rand() % 15, seconds, volume * viewscreen->gameclass->sound->GetAttenuation(false));
47  viewscreen->TriggerBCLLightning(distance, intensity);
48 
49  char msg[99];
50  sprintf_s(msg, sizeof(msg), "Lightning! Distance: %.3f Intensity: %.3f", seconds, volume * viewscreen->gameclass->sound->GetAttenuation(false));
51  logger->Log(msg);
52  }
53  }
54 
55  // this datapacket.f_z is from the client to the sound module and appears to have been calculated
56  if (!hullionization && GetTurbidity() > 12.5f)
57  {
58  hullionization = true;
59  if (playerships[0].reference != REF_ONGROUND)
60  {
61  Command command;
62  command.name = "AuralHullIonization";
63  viewscreen->gameclass->bus->commandStream.emplace_back(command);
64  logger->Log("Hull ionization detected!");
65  }
66  }
67  if (hullionization && GetTurbidity() < 12.5f)
68  hullionization = false;
69 
70 
71  // Fog calculation routines --------------------------------------------------------------
72 
73 
74  // Above or below clouds and sunlight on or off and set g_bAboveClouds
75  if (f_MSL > cloudTopsMslC)
76  {
77  if (!g_bAboveClouds)
78  {
79  g_bAboveClouds = true;
80  if (playerships[0].reference == REF_APNMODE)
81  playerships[0].reference = REF_ACLMODE;
82 
83  logger->Log("----------------------------------- ACMPL");
84 
85  // Not sure why but this caused the program to crash
86  /* for (t=0; t<citytextureC; t++)
87  {
88  m_pddsCityTexture[t]->SetPriority(0); // default priority
89  m_pddsCityLights[t]->SetPriority(0);
90  }
91  // fireworks, lightning below clouds, cloud bases, terrain
92  for (t=0; t<docktextureC; t++)
93  {
94  m_pddsDockTexture[t]->SetPriority(1); // higher priority
95  m_pddsDockLights[t]->SetPriority(1);
96  }
97  */ // also should do cloud upper layer, lightning above clouds
98  // flare, cockpit should be on 3
99  }
100  }
101  else if (f_MSL < cloudBufferMslC)
102  {
103  if (g_bAboveClouds)
104  {
105  g_bAboveClouds = false;
106  if (playerships[0].reference == REF_ACLMODE)
107  playerships[0].reference = REF_APNMODE;
108 
111 
112  logger->Log("----------------------------------- BCMPL");
113 
114  // Not sure why but this caused the program to crash
115  /* for (t=0; t<citytextureC; t++)
116  {
117  m_pddsCityTexture[t]->SetPriority(1); // higher priority
118  m_pddsCityLights[t]->SetPriority(1);
119  }
120  for (t=0; t<docktextureC; t++)
121  {
122  m_pddsDockTexture[t]->SetPriority(0); // default priority
123  m_pddsDockLights[t]->SetPriority(0);
124  }
125  */
126  // Request new grid, happens here, 000COMMANDC0, cubeface, and on VP load if on the ground
127  // cube=oldcube=game->CalculateCube( playerships[0].position );
128  // if (cube==-1)
129  // {
130  // char msg[99];
131  // sprintf_s(msg, sizeof(msg), "HG2 trapped a violation cube -1 for position x:%f y:%f z:%f", playerships[0].position.x, playerships[0].position.y, playerships[0].position.z);
132  // logger->Log(msg);
133  // MessageBox(DXUTGetHWND(), L"Encountered a telemetry error!\n\nPlease send the \"trace.log\" to \"support@risetvp.com\" before reloading.\n\nSorry for the inconvenience and thanks for helping us track down a bug!", L"Program fault!", MB_OK | MB_ICONERROR );
134  // }
135  // tcp=oldtcp=game->CalculateCGC( playerships[0].position, cube );
136  //
137  // SClientPacket outpacket;
138  // outpacket.type=16; // Terrain request
139  // outpacket.f_x=tcp.u;
140  // outpacket.f_y=tcp.v;
141  // outpacket.f_z=cube;
142  // ground.gridready=false; // VB not set
143  // ground.initialized=false; // Wait on stuff until main grid is received, reset if above clouds
144  // ground.waiting=99;
145  // outpacket.f_w=0.0f; // Whole grid
146  // game->gameclass->networking->SendToServer( &outpacket, sizeof(SClientPacket), true, 0 );
147  // // Ambient light level is always calculated (dynamically) therefore not in this condition
148  }
149  }
150 
151  float f_temp;
152  // Distance from CG
153  if (f_MSL > 0.0f)
154  f_temp = f_MSL + radiusC;
155  else
156  f_temp = radiusC;
157 
158  // Sun elevation (light level hitting flat plane)
159  if (!playerships[0].simulator)
160  {
161  const float angle = D3DX_HALFPI - acosf(radiusC / f_temp); // one half view width on surface (1A)
162  D3DXVECTOR3 result1 = -viewscreen->posnorml;
163  elevation = D3DXVec3Dot(&result1, &Xsunlight); // Elevation needs adjustment after cloud illum.
164  elevation += cosf(angle); // passed in, accounts for the planet obstructing our view
165  if (elevation > 1.0f)
166  elevation = 1.0f;
167  }
168  else
169  {
170  elevation = 1.0f; // needs to be adjustable by slider
171  }
172 
173 
174 
175  float inview;
177  {
178  inview = static_cast<float>(m_dwSunViz) / powf(viewscreen->gameclass->displayWidth / 1024.0f * 10.25f, 2.0f);
179  // f_temp=sqrtf(f_temp);
180  // inview=f_temp*0.1f*inview-0.9f;
181  if (inview < 0.0f)
182  inview = 0.0f;
183  else if (inview > 0.9f)
184  inview = 0.9f;
185  }
186  else
187  {
188  inview = -D3DXVec3Dot(&viewscreen->headlightvec, &Xsunlight); // 1 means it is in view
189  if (inview < 0.0f)
190  inview = 0.0f;
191  }
192 
193 
194  // Shear rate calculations ----------------------------------------------------------------------
195  D3DXVec3Subtract(&result, &playerships[0].velocity, &playerships[0].barycentric);
196  shearRate = D3DXVec3Length(&result) + 0.0353f * cosf(viewscreen->gameclass->bus->LatitudeRad);
197  shearRate *= 0.6f * fElapsedTime; // /1.5km to be safe in which it can change over
198  if (shearRate > 100.0f || shearRate < -100.0f || _isnan(shearRate) || isinf(shearRate))
199  {
200  sprintf_s(msg, sizeof(msg), " velocity %.3f %.3f %.3f", playerships[0].velocity.x, playerships[0].velocity.y, playerships[0].velocity.z);
201  logger->Log(msg, Logger::Level::Warn);
202  sprintf_s(msg, sizeof(msg), " barycentric %.3f %.3f %.3f", playerships[0].barycentric.x, playerships[0].barycentric.y, playerships[0].barycentric.z);
203  logger->Log(msg, Logger::Level::Warn);
204  sprintf_s(msg, sizeof(msg), " LatitudeRad %.3f", viewscreen->gameclass->bus->LatitudeRad);
205  logger->Log(msg, Logger::Level::Warn);
206  sprintf_s(msg, sizeof(msg), "Trapped a violation with shearRate...");
207  logger->Log(msg, Logger::Level::Error);
208  }
209 
210 
211  // Turbidity smoothing -----------------------------------------------------------------------
212  if (g_bAboveClouds)
213  {
214  SetTurbidity(1.0f); // theoretical limit of pure clean air
215  smoothTurbidity = 1.0f;
216  }
217  if (smoothTurbidity != -1.0f)
218  {
220  {
224  }
225  else if (smoothTurbidity > turbidity)
226  {
230  }
231  }
233 
234 
235 
236  if (cloudCeilingSmoothAglKm != -1.0f) // got a target value
237  {
239  cloudCeilingSmoothAglKm += f_temp * fElapsedTime * 0.01f; // 50 meters in 100 seconds
240  }
242 
243 
244  if (cloudSurfaceSmoothKm != -1.0f) // got a target value
245  {
247  cloudSurfaceSmoothKm += f_temp * fElapsedTime * 0.01f;
248  }
249 
250  if (cloudSurfaceSmoothKm != -1.0f && cloudCeilingSmoothAglKm != -1.0f && !g_bAboveClouds && f_MSL != -1.0f)
252  else
253  f_BCL = -20.0f;
254 
256 
257 
258  // Inside cloud adjustment of turbidity
259  if (g_bAboveClouds)
260  f_temp = f_ACL;
261  else
262  f_temp = f_BCL;
263 
264 
265  if (f_temp <= 0.0f && f_temp > -20.0f) // in cloud
266  {
267  viewscreen->alphascreen.a = cloudVisTarget = cloudVisSmooth = 0.0f; // no visibility
268  }
269  else if (f_temp > 0.0f && f_temp <= 0.05f) // Failsafe transition zone 50m
270  {
271  // take existing smooth value and modulate it (and the target) forceable to 0
272  viewscreen->alphascreen.a = cloudVisTarget = cloudVisSmooth * f_temp / 0.05f;
273  }
274  else // above or below the transition area
275  {
276  if (f_temp > 0.15f || f_temp == -20.0f) // in the clear 150 meters above or below the cloud layer
278  else if (cloudVisSmooth == cloudVisTarget) // Between 0.05 and 0.15 pick a new target based on +/- f_temp/0.15f
279  cloudVisTarget = (f_temp - 0.05f) / 0.1f - (RandomFloat() * (f_temp - 0.05f) / 0.1f * 0.25f);
280 
281  // Speed at which we arrive at new target is based on our tangent
283  {
284  cloudVisSmooth += D3DXVec3Length(&locvelcomp) * fElapsedTime * 5.0f;
287  }
288  else if (cloudVisSmooth > cloudVisTarget)
289  {
290  cloudVisSmooth -= D3DXVec3Length(&locvelcomp) * fElapsedTime * 5.0f;
293  }
294 
296  }
297  // this gets inversed down below
298 
299 
300 
301 
302  // wind direction smoothing =========================
303  // 350 - 010 = 340 ... if > D3DX_PI then we go DOWN
304  // 010 - 350 = -340 ... if < -D3DX_PI then we go UP
305  // 240 - 220 = 20 // we go up
306  // 220 - 240 = -20
307  const float winddiff = winddir - smoothwinddir; // radians
308  if (winddiff > D3DX_PI)
309  {
311  if (smoothwinddir < 0)
312  smoothwinddir += D3DX_TAU;
313  }
314  else if (winddiff < -D3DX_PI)
315  {
317  if (smoothwinddir > D3DX_TAU)
318  smoothwinddir -= D3DX_TAU;
319  }
320  else if (fabsf(winddiff) > shearRate)
321  smoothwinddir += shearRate * copysignf(1.0f, winddiff);
322  else
324 
325 
326 
327  logger->AddToCallStack("TemperatureSmoothingDiff");
328 
329  // temperature and winds above 63km
330  const float whereWeThinkWeLeaveOffAt63 = -27.89f;
331  if (f_MSL >= 63.0f && f_MSL < 80.0f) // server stops sending updates at 63km ... added this filler 5/23/2018
332  {
333  //63km to 80km we are losing 4.12 per km
334  temperature = whereWeThinkWeLeaveOffAt63 - (f_MSL - 63.0f) * 4.12f;
335  SetWindspeedKms(0.0f);
336  SetTurbulenceScalar(0.0f);
337  }
338  else if (f_MSL >= 80.0f && f_MSL < 90.0f)
339  {
340  //80km to 90km constant
341  temperature = whereWeThinkWeLeaveOffAt63 - 70.0f;
342  SetWindspeedKms(0.0f);
343  SetTurbulenceScalar(0.0f);
344  }
345  else if (f_MSL >= 90.0f) // thermosphere
346  {
348  temperature = 1006.115f - 1097.39779f / (1.0f + powf(f_MSL / 179.8561f, 9.161937f));
349  SetWindspeedKms(0.0f);
350  SetTurbulenceScalar(0.0f);
351  }
352 
353  // == Temperature Smoothing ==
354  const float tempdiff = temperature - smoothTemperature;
355  smoothTemperature += tempdiff * fElapsedTime * 0.1f;
356 
357 
358 
359 
360  // Illumination under clouds --------------------------------------------------------------------
361  if (daylightOverride != -1.0f)
362  f_temp = daylightOverride;
363  else
364  f_temp = elevation;
365 
366  if (f_temp < 0.05f) // Don't want them to get turned off because they can't see ANYTHING
367  f_temp = 0.05f;
368  else if (f_temp > 1.0f)
369  f_temp = 1.0f;
370 
371  // Rain not only reduces visibility but should lower light level
372  // https://jira.risetvp.com/view.php?id=422
373  // turbidity is 2-16 BCL at 16 (heaviest rain) I would imagine half the light level, 2 is 100%
374  f_temp *= sqrtf(1.0f - (GetTurbidity() - 2.0f) / 14.0f) * 0.5f + 0.5f; // modulated with turbidity 1-0.5 logrithmically
375  // so at turbidity 2 we get sqrt(1)=1 * .5 is .5 + .5 is 1, perfecto
376  // so at turbidity 16 we get sqrt(0)=0 * .5 is 0 + .5 is .5, perfecto
377  // so at turbidity 9 we get sqrtf(.5)=.707 * .5 is .353 is .8535, perfecto
378  // so at turbidity 3 we get sqrt(0.9286)=0.96363893653172815327029561361547*.5=0.48181946826586407663514780680774+.5=.982, perfecto
379 
380  // Brightest it can get // it is intensified a bit to match map brightness of sun
381  D3DXCOLOR bcllight;
382  bcllight.r = sunrC * f_temp;// 0.9618320611f*f_temp;
383  //if (g_bNightVision)
384  // bcllight.g=max(f_temp, 0.5f);
385  //else
386  bcllight.g = sungC * f_temp;
387  bcllight.b = sunbC * f_temp; // 0.9847328244f*f_temp;
388  bcllight.a = f_temp;
389 
390  if (g_bAboveClouds)
391  {
392  if (f_ACL <= 0.0f) // In clouds
393  {
394  f_temp = 0.8875f + (f_MSL - cloudTopsMslC) / ((f_MSL - f_ACL) - cloudTopsMslC) * 0.1125f; // Percent of height
395  }
396  else // Above the upper
397  {
398  f_temp = 1.0f;
399  }
400  }
401  else
402  {
403  // what fraction of light is visible?
404  if (f_BCL <= 0.0f) // In clouds
405  f_temp = 0.6375f - f_BCL / (cloudTopsMslC - (f_MSL + f_BCL)) * 0.25f; // 0.85 at f_BCL=0 to 0.90 at midcloudlevelC
406  else // Below the lower layer
407  f_temp = 1.0f - cloudThickness * 0.05f;// 0.6375f;//1.0f+(f_ACL+f_BCL)*0.05f; // 5% per kilometer
408  }
409 
410  bcllight *= f_temp;
411  // Illumination under clouds --------------------------------------------------------------------
412 
413 
414  if (lightningbelow.inuse && !playerships[0].simulator && playerships[0].reference != REF_SIMBAY)
415  {
416  if (f_ACL < 0.150f)
417  {
418  f_temp = lightningbelow.intensity * sqrtf(1.0f - lightningbelow.distance);
419  bcllight.r += 0.7f * f_temp; // 1.0f is closest/brightest/loudest
420  if (bcllight.r > 1.0f)
421  bcllight.r = 1.0f;
422  bcllight.g += 0.7f * f_temp;
423  if (bcllight.g > 1.0f)
424  bcllight.g = 1.0f;
425  bcllight.b += f_temp;
426  if (bcllight.b > 1.0f)
427  bcllight.b = 1.0f;
428  }
429 
430  lightningbelow.timeleft -= fElapsedTime;
431  if (lightningbelow.trend)
432  {
433  lightningbelow.intensity += RandomFloat() * fElapsedTime * 50.0f;
434  if (lightningbelow.intensity > 1.0f)
435  {
436  lightningbelow.intensity = 1.0f;
437  if (rand() > 16384)
438  lightningbelow.trend = false;
439  }
440  }
441  else
442  {
443  lightningbelow.intensity -= RandomFloat() * fElapsedTime * 50.0f;
444  if (lightningbelow.intensity < 0.0f)
445  {
446  lightningbelow.intensity = 0.0f;
447  if (rand() > 16384)
448  lightningbelow.trend = true;
450  lightningbelow.inuse = false;
451  }
452  }
453  }
454 
455 
456  for (s = 0; s < ACLlightningC; s++)
457  {
458  if (lightningabove[s].inuse && !playerships[0].simulator)
459  {
460  lightningabove[s].timeleft -= fElapsedTime;
461  if (lightningabove[s].trend)
462  {
463  lightningabove[s].intensity += RandomFloat() * fElapsedTime * 50.0f;
464  if (lightningabove[s].intensity > 1.0f)
465  {
466  lightningabove[s].intensity = 1.0f;
467  if (rand() > 16384)
468  lightningabove[s].trend = false;
469  }
470  }
471  else
472  {
473  lightningabove[s].intensity -= RandomFloat() * fElapsedTime * 50.0f;
474  if (lightningabove[s].intensity < 0.0f)
475  {
476  lightningabove[s].intensity = 0.0f;
477  if (rand() > 16384)
478  lightningabove[s].trend = true;
479  if (lightningabove[s].timeleft < 0.0f && lightningabove[s].trend)
480  lightningabove[s].inuse = false;
481  }
482  }
483  }
484  else if (f_ACL > 0.300f) // !lightningabove[s].inuse
485  {
486  lightningabove[s].timeleft = RandomFloat() * 2.0f;
487  lightningabove[s].trend = true;
488 
489  lightningabove[s].panel = static_cast<short>(RandomFloat() * 90.0f) * 25; // Totals 2250
490  lightningabove[s].texture = static_cast<short>(rand()) % 3;
491 
492  lightningabove[s].inuse = true;
493  lightningabove[s].intensity = RandomFloat(); // 1.0f is violent
494  }
495  }
496 
497 
498  // Fireworks
499  if (f_ACL < 0.150f)
500  {
501  float r = 0.0f, g = 0.0f, b = 0.0f, avg = 0.0f;
502  for (t = 0; t < fireworksC; t++)
503  {
504  if (fireworks[t].inuse)
505  {
506  result = -viewscreen->position - fireworks[t].position;
507  f_temp = D3DXVec3Length(&result) / 20.0f;
508  if (f_temp <= 1.0f)
509  {
510  f_temp = sqrtf(1.0f - f_temp) * 0.15f;
511  // in addition it depends on where it is in the sequence
512  // like dark light dark
513  if (fireworks[t].type == 0)
514  f_temp *= sinf(D3DX_PI * static_cast<float>(fireworks[t].texture) / (firework1C - 1));
515  else if (fireworks[t].type == 1)
516  f_temp *= sinf(D3DX_PI * static_cast<float>(fireworks[t].texture) / (firework2C - 1));
517  else
518  f_temp *= sinf(D3DX_PI * static_cast<float>(fireworks[t].texture) / (firework3C - 1));
519  r += fireworks[t].color.r * f_temp;
520  g += fireworks[t].color.g * f_temp;
521  b += fireworks[t].color.b * f_temp;
522  avg++;
523  }
524  }
525  }
526  if (avg > 0.0f)
527  {
528  bcllight.r += r / avg;
529  if (bcllight.r > 1.0f)
530  bcllight.r = 1.0f;
531  bcllight.g += g / avg;
532  if (bcllight.g > 1.0f)
533  bcllight.g = 1.0f;
534  bcllight.b += b / avg;
535  if (bcllight.b > 1.0f)
536  bcllight.b = 1.0f;
537  }
538  }
539 
540 
541 
542 
543 
544 
545 
546 
547  // Horizon color calculation --------------------------------------------------------------------
548  if (g_bAboveClouds)
549  {
550  if (elevation < -0.2f) // below -12° just red
551  {
552  colorhorizon.r = 255.0f;
553  colorhorizon.g = colorhorizon.b = 0.0f;
554  }
555  else if (elevation >= -0.2f && elevation < 0.09f) // -12° to 5° fade to orange
556  {
557  colorhorizon.r = 255.0f;
558  colorhorizon.g = (elevation + 0.2f) / 0.29f * 127.5f;
559  colorhorizon.b = 0.0f;
560  }
561  else if (elevation >= 0.09f && elevation < 0.25f) // 5° to 15° fade to yellow
562  {
563  colorhorizon.r = 255.0f - 63.5f * (elevation - 0.09f) / 0.16f; // fade from 255 to 191.5
564  colorhorizon.g = 127.5f + 64.0f * (elevation - 0.09f) / 0.16f; // fade from 128 to 191.5
565  colorhorizon.b = 0.0f;
566  }
567  else if (elevation >= 0.25f) // above 15° fade to white
568  {
569  colorhorizon.r = 191.5f;//255.0f-(elevation-0.25f)/0.75f*63.75f; // runs it to 192
570  colorhorizon.g = 191.5f;//255.0f-(elevation-0.25f)/0.75f*63.75f; // runs it to 192
571  colorhorizon.b = (elevation - 0.25f) / 0.75f * 255.0f; // runs it to 255
572  }
573  colorhorizon /= 255.0f;
574  }
575  // Horizon color calculation --------------------------------------------------------------------
576 
577 
578  // Zenith color calculations --------------------------------------------------------------------
579  if (g_bAboveClouds)
580  {
581  if (elevation < -0.09f) // Purple
582  {
583  colorzenith.r = 100.0f / 255.0f; colorzenith.g = 50.0f / 255.0f; colorzenith.b = 100.0f / 255.0f;
584  }
585  if (elevation >= -0.09f && elevation < -0.06f) // -5° to -3° turns more red
586  {
587  colorzenith.r = 100.0f / 255.0f;
588  colorzenith.g = 50.0f / 255.0f;
589  colorzenith.b = (100.0f - 50.0f * (elevation + 0.09f) / 0.03f) / 255.0f;
590  }
591  if (elevation >= -0.06f && elevation < -0.02f) // -3° to -1° turns to blue
592  {
593  colorzenith.r = (100.0f - 50.0f * (elevation + 0.06f) / 0.04f) / 255.0f;
594  colorzenith.g = 50.0f / 255.0f;
595  colorzenith.b = (50.0f + 50.0f * (elevation + 0.06f) / 0.04f) / 255.0f;
596  }
597  if (elevation >= -0.02f) // Increasing brightness of blue throughout the day
598  {
599  colorzenith.r = colorzenith.g = (50.0f + 50.0f * (elevation + 0.02f) / 1.02f) / 255.0f;
600  colorzenith.b = (100.0f + 100.0f * (elevation + 0.02f) / 1.02f) / 255.0f;
601  }
602  }
603  // Zenith color calculations --------------------------------------------------------------------
604 
605 
606  // Interpolate color as we climb up to top of clouds
607 
608  //D3DXCOLOR tempcolor;
609 
610 
611  //f_temp=elevation;
612  //if (f_temp<0.0f)
613  // f_temp=0.0f; // clamped
614  //tempcolor = colorhorizon * f_temp;
615  //lerp between bcllight and tempcolor?
616 
617  // The diffuse light through clouds on city and ground (if normals were available)
618  if (daylightOverride == -1.0f)
619  viewscreen->sunlight.Diffuse = bcllight;
620  else
621  viewscreen->sunlight.Diffuse = bcllight * daylightOverride;
622 
623 
624  // Inverse
626 
627 
628  // Vessel illumination --------------------------------------------------------------------------
629  D3DXCOLOR shiplight;
630 
631  // Start with exterior hull illumination
632  shiplight.r = 0; shiplight.g = 0; shiplight.b = 0; // zeroed out 5/27/2018 looks like Ian is adding hull lights to models now
633 
634  int index = 0;
635  if (playerships[0].reference == REF_INANOTHER)
636  index = playerships[0].inarray;
637  if (playerships[index].logolight)
638  {
639  // so this has revealed that it isn't a simple "max" between two lights...
640  // it is additive, 2 flashlights shining on the same spot doubles the brightness
641  // problem is we have a finite limit to the brightness unless we go to HDR
642  const short temptype = playerships[index].VB;
643  for (s = 0; s < static_cast<short>(polyobjects[temptype].effects.size()); s++)
644  {
645  const s_light_effect effect = polyobjects[temptype].effects.at(s);
646  if (effect.sequencing & playerships[index].compare)
647  {
648  if (effect.power == 2.0f)
649  {
650  if (!playerships[index].headlight)
651  continue;
652  f_temp = 0.025f;
653  }
654  else if (effect.power == 1.5f) // rotating lights
655  {
656  continue;
657  //if (playerships[index].type == VehicleType::P13)
658  //{
659  // if (!playerships[index].police || !playerships[index].specialight)
660  // continue;
661  //}
662  }
663  else if (effect.power == 0.5f) // strobe
664  f_temp = 0.075f;
665  else
666  f_temp = 0.05f; // needs to be set or continue!!
667 
668  shiplight.r += effect.diffuse.r * f_temp;
669  shiplight.g += effect.diffuse.g * f_temp;
670  shiplight.b += effect.diffuse.b * f_temp;
671  }
672  }
673  if (index == 0)
674  shiplight *= ourcockpit.power;
675  }
676 
677  D3DXVECTOR4 shipdiff;
678  shipdiff.x = shiplight.r; shipdiff.y = shiplight.g; shipdiff.z = shiplight.b; shipdiff.w = 0; // unused but could be viewscreen->alphascreen.a;
679  // ReSharper disable once CppJoinDeclarationAndAssignment
680  V(viewscreen->gameclass->graphics->g_pEffect->SetVector("shiplight", &shipdiff));
681 
682  // Reflection of our light based on turbidity
683  f_temp = sqrtf(bcllight.r * bcllight.r + bcllight.g * bcllight.g + bcllight.b * bcllight.b);
684  if (f_temp > 1.0f)
685  f_temp = 1.0f;
686  f_temp = (1.0f - f_temp) * 0.5f;
687 
688  // Vessel illumination --------------------------------------------------------------------------
689 
690 
691 
692  // Find our alphascreen color
693  if (f_ACL <= 0.150f)
694  {
695  f_temp *= 1.0f - Clamp(sqrtf(fFogEndHorizon / 0.4f), 0, 1);
696  viewscreen->alphascreen.r = Clamp(bcllight.r + f_temp * shiplight.r, 0, 1);
697  viewscreen->alphascreen.g = Clamp(bcllight.g + f_temp * shiplight.g, 0, 1);
698  viewscreen->alphascreen.b = Clamp(bcllight.b + f_temp * shiplight.b, 0, 1);
699  }
700 
701  // Reduce visibility by 1/2 when sun in view (flare)
702  if (f_ACL > 0.0f)
703  {
704  shadow = viewscreen->ProbeBoundSphere(&playerships[0].position, &Xsunlight);
705  if (inview > 0.0f)
706  {
707  f_temp = inview * shadow;
708  betascreen.r = sunrC * f_temp;
709  betascreen.g = sungC * f_temp;
710  betascreen.b = sunbC * f_temp;
711  betascreen.a = f_temp;
712  }
713  else
714  {
715  betascreen.a = betascreen.r = betascreen.g = betascreen.b = 0.0f;
716  }
717  }
718  else
719  {
720  betascreen.a = betascreen.r = betascreen.g = betascreen.b = shadow = 0.0f;
721  }
722 
723 
724 
725  // Horizon and Zenith -------------------------------------------------------------------------
726  dwFogColorHorizon = bcllight;
727 
728 
729 
730 
731  // Ambient light scattered by the atmosphere
732 // scatter.r=r/714.0f; scatter.g=g/714.0f; scatter.b=b/714.0f; // Based on middle radius sunmap.bmp
733 
734 
735  cloudHorizonAngle = D3DX_HALFPI - acosf(cloudTopsRadiusC / (f_MSL + radiusC));
736  cloudHorizonDistance = cloudTopsRadiusC / tanf(cloudHorizonAngle); // distance to horizon 1b or 2c
737  if (cloudHorizonDistance < 256.0f)
738  cloudHorizonDistance = 256.0f;
739 
740 
741  // here is where we will play with the visibility 10m to 400m in the clouds
742  if (f_ACL < 0.150f && f_BCL < 0.150f) // ACL is above upper cloud level, BCL is below cloud bases)
743  {
744  static float cloudVisTarget1 = RandomFloat();
745  static float cloudVisSmooth1 = RandomFloat();
746 
747  // Speed at which we arrive at new target is based on our tangent
748  if (cloudVisSmooth1 < cloudVisTarget1)
749  {
750  cloudVisSmooth1 += D3DXVec3Length(&locvelcomp) * fElapsedTime * 10.0f;
751  if (cloudVisSmooth1 > cloudVisTarget1)
752  cloudVisSmooth1 = cloudVisTarget1;
753  }
754  else if (cloudVisSmooth1 > cloudVisTarget1)
755  {
756  cloudVisSmooth1 -= D3DXVec3Length(&locvelcomp) * fElapsedTime * 10.0f;
757  if (cloudVisSmooth1 < cloudVisTarget1)
758  cloudVisSmooth1 = cloudVisTarget1;
759  }
760  if (cloudVisTarget1 == cloudVisSmooth1)
761  {
762  // should side on 400 at turbidity 2 ... 14 is on the 10 meter side ... maybe to 20 meters?
763  const float targetSpectrum = (GetTurbidity() - 2.0f) / 12.0f;
764  const float fluctuate = 1.0f - GetTurbidity() / 20.0f; // 0.1 to 0.7
765  if (rand() % 2)
766  cloudVisTarget1 = Clamp(targetSpectrum + RandomFloat() * fluctuate, 0, 1);
767  else
768  cloudVisTarget1 = Clamp(targetSpectrum - RandomFloat() * fluctuate, 0, 1);
769  }
770 
771  if (playerships[0].reference != REF_INANOTHER || playerships[playerships[0].inarray].baydoor)
772  fFogEndHorizon = Lerp(168.64f / powf(GetTurbidity(), 2.0f), 0.400f - 0.390f * cloudVisSmooth1, viewscreen->alphascreen.a);
773  else
774  fFogEndHorizon = 168.64f / powf(GetTurbidity(), 2.0f);
775  }
776  else
777  {
778  fFogEndHorizon = 168.64f / powf(GetTurbidity(), 2.0f);
779  }
780 
781 
782  if (alphascreenOverride == 1.0f)
783  {
784  if (playerships[0].reference != REF_INANOTHER || playerships[playerships[0].inarray].baydoor)
785  fFogEndHorizon = 0.400f;
786  else
787  fFogEndHorizon = 42.16f;
789  }
790  else if (alphascreenOverride == 0.0f)
791  {
792  fFogEndHorizon = 42.16f;
794  }
795 
796 
797  if (g_bAboveClouds)
798  {
799  f_temp = f_MSL / (ScaleHeightC * 6.0f); // was 9 until 8/10/2019 so we get blackness sooner
800  if (f_temp > 1.0f)
801  f_temp = 1.0f;
802  else if (f_temp < 0.0f)
803  f_temp = 0.0f;
804  f_temp = sqrtf(1.0f - f_temp);
805  if (elevation<0.0f && elevation>-0.09f)
806  f_temp *= (elevation + 0.09f) / 0.09f; // Time of day adjustment
807  if (elevation <= -0.09f)
808  f_temp = 0.01f;
809 
810  colorzenith.a = f_temp;
811  // for static stars, Iomere, sun blend
812  D3DXColorLerp(&colorzenith, &colorzenith, &viewscreen->alphascreen, viewscreen->alphascreen.a);
813  dwFogFactorZenith = colorzenith;
814 
815  colorzenith.a = 1.0f;
816  colorzenith.r *= dwFogFactorZenith.a;
817  // if (g_bNightVision)
818  // colorzenith.g*=max(f_temp,0.5f);
819  // else
820  colorzenith.g *= dwFogFactorZenith.a;
821  colorzenith.b *= dwFogFactorZenith.a;
822  // for skyring and Iomere and ambient darkness
823  dwFogColorZenith = colorzenith;
824  }
825  else
826  {
828  }
829 
830  // End of fog calculations ----------------------------------------------------------------------
831 
832  logger->AddToCallStack("weather::FrameMove END");
833 }
834 
835 void weather::SetWindDirectionRadians(float prmWinddir)
836 {
837  winddir = prmWinddir;
838  if (smoothwinddir == -1.0f)
839  {
841  logger->Log("Weather1 initialized smoothwinddir!");
842  }
843 }
844 
845 void weather::SetTurbulenceScalar(float prmTurbulence)
846 {
848  turbulence = prmTurbulence;
849 }
850 
851 void weather::SetTemperatureCelsius(float prmTemperature)
852 {
853  temperature = prmTemperature;
854  if (smoothTemperature == -1.0f)
855  {
857  logger->Log("Weather1 initialized smoothTemperature!");
858  }
859 }
860 
861 void weather::SetWindspeedKms(float prmWindspeed)
862 {
864  windspeed = prmWindspeed;
865 }
866 
867 void weather::SetTurbidity(float prmTurbidity)
868 {
869  turbidity = prmTurbidity;
870  if (smoothTurbidity == -1.0f)
871  {
873  logger->Log("Weather1 initialized smoothVisibility!");
874  }
875 }
876 
877 void weather::SetCloudSurfaceTargetKm(float prmCloudSurfaceTargetKm)
878 {
879  cloudSurfaceTargetKm = prmCloudSurfaceTargetKm;
880  if (cloudSurfaceSmoothKm == -1.0f)
881  {
883  logger->Log("Weather2 initialized cloudSurfaceSmoothKm!");
884  }
885 }
886 
887 void weather::SetCloudCeilingTargetKm(float prmCloudCeilingTargetKm)
888 {
889  cloudCeilingTargetKm = prmCloudCeilingTargetKm;
890  if (cloudCeilingSmoothAglKm == -1.0f)
891  {
893  logger->Log("Weather2 initialized cloudCeilingSmoothKm!");
894  }
895 }
896 
898 {
899  smoothwinddir = -1.0f;
900  smoothTemperature = -1.0f;
901  cloudSurfaceSmoothKm = -1.0f;
902  cloudCeilingSmoothAglKm = -1.0f;
903 }
904 
906 {
907  if (!playerships[0].simulator)
908  return windspeed;
910  return 0.0f;
911 }
912 
914 {
915  if (!playerships[0].simulator)
916  return smoothTurbidity;
918  return 2.0f;
919 }
920 
922 {
923  if (!playerships[0].simulator)
924  return winddir;
926  return 0.0f;
927 }
928 
930 {
931  if (!playerships[0].simulator)
932  return turbulence;
934  return 0.0f;
935 }
936 
938 {
939  if (!playerships[0].simulator)
940  return smoothTemperature;
942  return 20.0f;
943 }
944 
946 {
947  if (!playerships[0].simulator)
950  return f_MSL - f_AGL + 1.8f;
951 }
void SetCloudCeilingTargetKm(float prmCloudCeilingTargetKm)
Definition: weather.cpp:887
#define radiusC
Definition: globals.h:88
float cloudVisTarget
Definition: weather.h:70
float GetCloudCeilingMslKm() const
Definition: weather.cpp:945
float cloudSurfaceSmoothKm
Definition: weather.h:41
#define firework3C
Definition: globals.h:51
#define firework1C
Definition: globals.h:49
D3DXCOLOR color
Definition: globals.h:752
float cloudVisSmooth
Definition: weather.h:70
Scockpit ourcockpit
Definition: globals.cpp:176
D3DXVECTOR3 position
Definition: globals.h:753
D3DLIGHT9 sunlight
Definition: Viewscreen.h:217
#define sunbC
Definition: globals.h:99
weather(Viewscreen *ptr)
Definition: weather.cpp:5
float staticDensity
Definition: propulsion.h:84
void EnergyWeaponImpact()
Definition: weapon.cpp:21
ID3DXEffect * g_pEffect
Definition: Graphics.h:30
float LatitudeRad
Definition: Bus.h:235
float power
Definition: globals.h:608
D3DXVECTOR3 posnorml
Definition: Viewscreen.h:248
bool g_bAboveClouds
Definition: globals.cpp:22
D3DXVECTOR3 position
Definition: Viewscreen.h:247
std::vector< Command > commandStream
Definition: Bus.h:342
float daylightOverride
Definition: weather.h:83
float GetWindDirectionRadians() const
Definition: weather.cpp:921
D3DXCOLOR colorhorizon
Definition: weather.h:68
#define cloudTopsMslC
Definition: globals.h:92
GameClass * gameclass
Definition: Viewscreen.h:292
short t
Definition: weather.h:24
bool hullionization
Definition: weather.h:26
FIREWORKS fireworks[fireworksC]
Definition: globals.cpp:181
s_network_objects playerships[MAX_SCAN]
Definition: globals.cpp:174
float cloudThickness
Definition: weather.h:81
float alphascreenOverride
Definition: weather.h:84
float ProbeBoundSphere(D3DXVECTOR3 *position, const D3DXVECTOR3 *Xsunlight) const
void SetTurbidity(float prmTurbidity)
Definition: weather.cpp:867
weapon * ptrWeapon
Definition: Viewscreen.h:280
D3DXCOLOR alphascreen
Definition: Viewscreen.h:231
#define ScaleHeightC
Definition: globals.h:84
float distance
Definition: globals.h:738
float cloudCeilingTargetKm
Definition: weather.h:38
bool m_bDeviceSupportsVizQuery
Definition: Viewscreen.h:224
float cloudHorizonDistance
Definition: weather.h:66
float timeleft
Definition: globals.h:723
void SetTurbulenceScalar(float prmTurbulence)
Definition: weather.cpp:845
float f_ACL
Definition: globals.cpp:16
float displayWidth
Definition: GameClass.h:129
#define sungC
Definition: globals.h:98
std::vector< s_light_effect > effects
Definition: globals.h:367
D3DXVECTOR3 locvelcomp
Definition: globals.cpp:99
unsigned long sequencing
Definition: globals.h:356
float DebugCeiling
Definition: Bus.h:421
std::string name
Definition: Command.h:11
float fFogEndHorizon
Definition: weather.h:74
short panel
Definition: globals.h:726
#define fireworksC
Definition: globals.h:746
propulsion * ptrPropulsion
Definition: Viewscreen.h:285
float GetWindspeedKms() const
Definition: weather.cpp:905
float GetTemperatureCelsius() const
Definition: weather.cpp:937
D3DXCOLOR diffuse
Definition: globals.h:355
float smoothwinddir
Definition: weather.h:34
void FrameMove(float fElapsedTime)
Definition: weather.cpp:11
void TriggerBCLLightning(float distanceScalar, float intensityScalar) const
unsigned char ourplayerC
Definition: gui.h:766
void InitializeSmoothValues()
Definition: weather.cpp:897
LIGHTNINGBELOW lightningbelow
Definition: globals.cpp:179
float f_MSL
Definition: globals.cpp:36
SPlayerData player[MAX_ONLINEPLAYERS]
Definition: gui.h:765
void SetWindDirectionRadians(float prmWinddir)
Definition: weather.cpp:835
float Clamp(float val, float min, float max)
Definition: MathUtilities.h:3
float cloudSurfaceTargetKm
Definition: weather.h:39
DWORD m_dwSunViz
Definition: globals.cpp:68
LIGHTNINGABOVE lightningabove[ACLlightningC]
Definition: globals.cpp:178
short s
Definition: weather.h:24
Logger * logger
Definition: weather.h:21
float DebugTurbidity
Definition: Bus.h:421
void AddDelayedSound(int soundEnum, float delay, float volume=1.0f)
Definition: Sound.cpp:1927
Definition: Command.h:5
Graphics * graphics
Definition: GameClass.h:109
D3DXVECTOR3 velocity
Definition: globals.cpp:9
D3DXVECTOR3 velocity
Definition: globals.h:540
Sound * sound
Definition: GameClass.h:108
float GetAttenuation(bool applyDensity) const
Definition: Sound.cpp:1062
D3DXVECTOR3 headlightvec
Definition: Viewscreen.h:230
float timeleft
Definition: globals.h:737
void Log(const char *msg, Level level=Info, int errorCode=0)
Definition: Logger.cpp:11
unsigned long compare
Definition: globals.h:552
s_polygon_object polyobjects[maxpolyC]
Definition: globals.cpp:160
float cloudHorizonAngle
Definition: weather.h:66
D3DXCOLOR betascreen
Definition: weather.h:69
Viewscreen * viewscreen
Definition: weather.h:20
#define firework2C
Definition: globals.h:50
short texture
Definition: globals.h:727
D3DXCOLOR dwFogColorHorizon
Definition: weather.h:65
float Play(int soundEnum)
Definition: Sound.cpp:577
D3DXCOLOR dwFogColorZenith
Definition: weather.h:63
float intensity
Definition: globals.h:724
float f_BCL
Definition: globals.cpp:17
void SetTemperatureCelsius(float prmTemperature)
Definition: weather.cpp:851
float turbulence
Definition: weather.h:28
float turbidity
Definition: weather.h:31
float Lerp(float val1, float val2, float lerp)
Definition: MathUtilities.h:12
HMI * GUI
Definition: GameClass.h:110
float shearRate
Definition: weather.h:71
float power
Definition: globals.h:357
float intensity
Definition: globals.h:738
#define ACLlightningC
Definition: globals.h:71
float GetTurbulence() const
Definition: weather.cpp:929
float smoothTemperature
Definition: weather.h:36
float shadow
Definition: weather.h:80
D3DXVECTOR3 barycentric
Definition: globals.h:540
#define cloudTopsRadiusC
Definition: globals.h:94
void SetWindspeedKms(float prmWindspeed)
Definition: weather.cpp:861
float GetTurbidity() const
Definition: weather.cpp:913
float temperature
Definition: weather.h:35
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
void SetCloudSurfaceTargetKm(float prmCloudSurfaceTargetKm)
Definition: weather.cpp:877
Bus * bus
Definition: GameClass.h:112
float smoothTurbidity
Definition: weather.h:32
float winddir
Definition: weather.h:33
#define sunrC
Definition: globals.h:97
char msg[199]
Definition: weather.h:23
#define cloudBufferMslC
Definition: globals.h:93
float RandomFloat()
Definition: MathUtilities.h:98
float windspeed
Definition: weather.h:29
Logger * logger
Definition: Viewscreen.h:293
D3DXCOLOR dwFogFactorZenith
Definition: weather.h:64
float elevation
Definition: weather.h:67
float f_AGL
Definition: globals.cpp:14
float cloudCeilingSmoothAglKm
Definition: weather.h:40
short r
Definition: weather.h:24