nightshade 0.47.0

A cross-platform data-oriented game engine.
Documentation
use nalgebra_glm::Vec2;
use serde::{Deserialize, Serialize};

/// A finite animated water surface anchored at the entity's global transform.
///
/// The surface spans `half_extents` along local X and Z, centered on the
/// entity origin, and follows the entity's full transform including rotation
/// and scale. Height comes from an iterated sum of wave octaves sampled in the
/// body's local space. Appearance is fully data driven so a single body can
/// range from a calm pool to a choppy sea.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, enum2schema::Schema)]
#[serde(default)]
pub struct Water {
    pub enabled: bool,
    pub half_extents: Vec2,
    pub tessellation: u32,
    pub wave_amplitude: f32,
    pub wave_steepness: f32,
    pub wave_length: f32,
    pub wave_speed: f32,
    pub wave_direction_radians: f32,
    pub shallow_color: [f32; 3],
    pub deep_color: [f32; 3],
    pub depth_fade_distance: f32,
    pub edge_foam_distance: f32,
    pub foam_amount: f32,
    pub foam_color: [f32; 3],
    pub roughness: f32,
    pub fresnel_power: f32,
    pub reflection_strength: f32,
    pub refraction_strength: f32,
    pub specular_strength: f32,
}

impl Default for Water {
    fn default() -> Self {
        Self {
            enabled: true,
            half_extents: Vec2::new(40.0, 40.0),
            tessellation: 192,
            wave_amplitude: 0.5,
            wave_steepness: 0.6,
            wave_length: 7.0,
            wave_speed: 1.1,
            wave_direction_radians: 0.6,
            shallow_color: [0.16, 0.46, 0.52],
            deep_color: [0.02, 0.11, 0.18],
            depth_fade_distance: 2.5,
            edge_foam_distance: 1.0,
            foam_amount: 0.0,
            foam_color: [0.92, 0.97, 1.0],
            roughness: 0.06,
            fresnel_power: 5.0,
            reflection_strength: 1.0,
            refraction_strength: 0.04,
            specular_strength: 0.6,
        }
    }
}

impl Water {
    pub fn ocean() -> Self {
        Self::default()
    }

    pub fn calm_pool() -> Self {
        Self {
            half_extents: Vec2::new(8.0, 8.0),
            tessellation: 96,
            wave_amplitude: 0.04,
            wave_steepness: 0.2,
            wave_length: 2.2,
            wave_speed: 0.5,
            shallow_color: [0.1, 0.5, 0.55],
            deep_color: [0.02, 0.16, 0.22],
            depth_fade_distance: 1.2,
            edge_foam_distance: 0.6,
            foam_amount: 0.1,
            roughness: 0.03,
            refraction_strength: 0.03,
            ..Self::default()
        }
    }

    pub fn with_half_extents(mut self, half_extents: Vec2) -> Self {
        self.half_extents = half_extents;
        self
    }
}