#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ShadowCascadeViewConfig {
pub num_cascades: u32,
pub opacity: f32,
pub color_per_cascade: bool,
}
impl Default for ShadowCascadeViewConfig {
fn default() -> Self {
Self { num_cascades: 4, opacity: 0.5, color_per_cascade: true }
}
}
#[derive(Debug, Clone)]
pub struct ShadowCascadeView {
pub config: ShadowCascadeViewConfig,
pub enabled: bool,
pub active_cascade: Option<u32>,
}
impl Default for ShadowCascadeView {
fn default() -> Self {
Self { config: ShadowCascadeViewConfig::default(), enabled: false, active_cascade: None }
}
}
pub fn scv_enable(view: &mut ShadowCascadeView) {
view.enabled = true;
}
pub fn scv_disable(view: &mut ShadowCascadeView) {
view.enabled = false;
}
pub fn scv_set_active_cascade(view: &mut ShadowCascadeView, index: Option<u32>) {
view.active_cascade = index.map(|i| i.min(view.config.num_cascades.saturating_sub(1)));
}
pub fn scv_cascade_color(index: u32) -> [f32; 4] {
let colors = [
[1.0, 0.2, 0.2, 0.5],
[0.2, 1.0, 0.2, 0.5],
[0.2, 0.2, 1.0, 0.5],
[1.0, 1.0, 0.2, 0.5],
];
colors[(index as usize) % colors.len()]
}
pub fn scv_split_distance(cascade: u32, near: f32, far: f32) -> f32 {
let t = (cascade + 1) as f32 / 4.0;
near + (far - near) * t * t
}
pub fn scv_to_json(view: &ShadowCascadeView) -> String {
format!(
r#"{{"num_cascades":{},"opacity":{:.2},"enabled":{}}}"#,
view.config.num_cascades, view.config.opacity, view.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_disabled() {
let v = ShadowCascadeView::default();
assert!(!v.enabled);
}
#[test]
fn test_enable_disable() {
let mut v = ShadowCascadeView::default();
scv_enable(&mut v);
assert!(v.enabled);
scv_disable(&mut v);
assert!(!v.enabled);
}
#[test]
fn test_active_cascade_clamped() {
let mut v = ShadowCascadeView::default();
scv_set_active_cascade(&mut v, Some(9999));
assert!(v.active_cascade.expect("should succeed") < v.config.num_cascades);
}
#[test]
fn test_active_cascade_none() {
let mut v = ShadowCascadeView::default();
scv_set_active_cascade(&mut v, Some(1));
scv_set_active_cascade(&mut v, None);
assert!(v.active_cascade.is_none());
}
#[test]
fn test_cascade_color_valid() {
let c = scv_cascade_color(0);
assert_eq!(c.len(), 4);
}
#[test]
fn test_cascade_color_cycles() {
let c0 = scv_cascade_color(0);
let c4 = scv_cascade_color(4);
assert_eq!(c0, c4);
}
#[test]
fn test_split_distance_ordering() {
let d0 = scv_split_distance(0, 0.1, 1000.0);
let d1 = scv_split_distance(1, 0.1, 1000.0);
assert!(d1 > d0);
}
#[test]
fn test_to_json_enabled() {
let mut v = ShadowCascadeView::default();
scv_enable(&mut v);
let json = scv_to_json(&v);
assert!(json.contains("true"));
}
#[test]
fn test_default_num_cascades() {
let v = ShadowCascadeView::default();
assert_eq!(v.config.num_cascades, 4);
}
}