nightshade 0.13.0

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

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[repr(u32)]
pub enum VolumeShape {
    #[default]
    Box = 0,
    Cylinder = 1,
    Sphere = 2,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[repr(u32)]
pub enum VolumeFlowType {
    #[default]
    Waterfall = 0,
    Mist = 1,
    Cascade = 2,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Water {
    pub base_color: [f32; 4],
    pub water_color: [f32; 4],
    pub base_height: f32,
    pub wave_height: f32,
    pub choppy: f32,
    pub speed: f32,
    pub frequency: f32,
    pub specular_strength: f32,
    pub fresnel_power: f32,
    pub edge_feather_distance: f32,
    pub enabled: bool,
    pub bounds: Option<Vec<[f32; 2]>>,
    pub is_vertical: bool,
    pub is_volumetric: bool,
    pub volume_shape: VolumeShape,
    pub volume_flow_type: VolumeFlowType,
    pub volume_size: [f32; 3],
    pub flow_direction: [f32; 2],
    pub flow_strength: f32,
}

impl Default for Water {
    fn default() -> Self {
        Self {
            base_color: [0.0, 0.09, 0.18, 1.0],
            water_color: [0.48, 0.54, 0.36, 1.0],
            base_height: 0.0,
            wave_height: 0.6,
            choppy: 4.0,
            speed: 0.8,
            frequency: 0.16,
            specular_strength: 1.0,
            fresnel_power: 3.0,
            edge_feather_distance: 2.0,
            enabled: true,
            bounds: None,
            is_vertical: false,
            is_volumetric: false,
            volume_shape: VolumeShape::Box,
            volume_flow_type: VolumeFlowType::Waterfall,
            volume_size: [1.0, 1.0, 1.0],
            flow_direction: [0.0, 0.0],
            flow_strength: 0.0,
        }
    }
}

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

    pub fn with_height(mut self, height: f32) -> Self {
        self.wave_height = height;
        self
    }

    pub fn with_choppy(mut self, choppy: f32) -> Self {
        self.choppy = choppy;
        self
    }

    pub fn with_speed(mut self, speed: f32) -> Self {
        self.speed = speed;
        self
    }

    pub fn with_frequency(mut self, frequency: f32) -> Self {
        self.frequency = frequency;
        self
    }

    pub fn with_base_color(mut self, r: f32, g: f32, b: f32) -> Self {
        self.base_color = [r, g, b, 1.0];
        self
    }

    pub fn with_water_color(mut self, r: f32, g: f32, b: f32) -> Self {
        self.water_color = [r, g, b, 1.0];
        self
    }

    pub fn with_vertical(mut self, is_vertical: bool) -> Self {
        self.is_vertical = is_vertical;
        self
    }

    pub fn with_volumetric(mut self, is_volumetric: bool) -> Self {
        self.is_volumetric = is_volumetric;
        self
    }

    pub fn with_volume_shape(mut self, shape: VolumeShape) -> Self {
        self.volume_shape = shape;
        self
    }

    pub fn with_volume_flow_type(mut self, flow_type: VolumeFlowType) -> Self {
        self.volume_flow_type = flow_type;
        self
    }

    pub fn with_volume_size(mut self, width: f32, height: f32, depth: f32) -> Self {
        self.volume_size = [width, height, depth];
        self
    }

    pub fn with_flow(mut self, direction_x: f32, direction_z: f32, strength: f32) -> Self {
        let len = (direction_x * direction_x + direction_z * direction_z).sqrt();
        if len > 0.0001 {
            self.flow_direction = [direction_x / len, direction_z / len];
        } else {
            self.flow_direction = [0.0, 0.0];
        }
        self.flow_strength = strength;
        self
    }
}