earth/rendering/
ocean_rendering.rs1pub struct OceanParams {
2 pub wind_speed_ms: f64,
3 pub wind_direction: [f64; 2],
4 pub fetch_km: f64,
5 pub depth_m: f64,
6 pub grid_size: u32,
7 pub patch_size_m: f64,
8 pub gravity: f64,
9}
10impl Default for OceanParams {
11 fn default() -> Self {
12 Self {
13 wind_speed_ms: 10.0,
14 wind_direction: [1.0, 0.0],
15 fetch_km: 500.0,
16 depth_m: 4000.0,
17 grid_size: 256,
18 patch_size_m: 1000.0,
19 gravity: *crate::SURFACE_GRAVITY,
20 }
21 }
22}
23pub struct OceanSpectrum {
24 pub heights: Vec<f64>,
25 pub normals: Vec<[f64; 3]>,
26 pub grid_size: u32,
27}
28impl OceanParams {
29 pub fn phillips_spectrum(&self, kx: f64, ky: f64) -> f64 {
30 let k_sq = kx * kx + ky * ky;
31 if k_sq < 1e-12 {
32 return 0.0;
33 }
34 let k = k_sq.sqrt();
35 let l = self.wind_speed_ms * self.wind_speed_ms / self.gravity;
36 let k_dot_w = (kx * self.wind_direction[0] + ky * self.wind_direction[1]) / k;
37 let damping = 0.001;
38 let phillips = ((-1.0 / (k * l).powi(2)).exp() / k_sq.powi(2))
39 * k_dot_w.powi(2)
40 * (-k_sq * damping * damping).exp();
41 phillips.max(0.0)
42 }
43 pub fn generate_spectrum(&self) -> OceanSpectrum {
44 let n = self.grid_size as usize;
45 let mut heights = vec![0.0; n * n];
46 let normals = vec![[0.0, 1.0, 0.0]; n * n];
47 for j in 0..n {
48 for i in 0..n {
49 let kx =
50 (2.0 * std::f64::consts::PI * (i as f64 - n as f64 / 2.0)) / self.patch_size_m;
51 let ky =
52 (2.0 * std::f64::consts::PI * (j as f64 - n as f64 / 2.0)) / self.patch_size_m;
53 heights[j * n + i] = self.phillips_spectrum(kx, ky).sqrt();
54 }
55 }
56 OceanSpectrum {
57 heights,
58 normals,
59 grid_size: self.grid_size,
60 }
61 }
62 pub fn dispersion(&self, k: f64) -> f64 {
63 (self.gravity * k * (k * self.depth_m).tanh()).sqrt()
64 }
65}