oxihuman_export/
light_export.rs1#![allow(dead_code)]
4
5pub const LIGHT_POINT: u8 = 0;
8pub const LIGHT_DIRECTIONAL: u8 = 1;
9pub const LIGHT_SPOT: u8 = 2;
10
11#[derive(Debug, Clone)]
14pub struct LightExport {
15 pub name: String,
16 pub light_type: u8,
17 pub position: [f32; 3],
18 pub direction: [f32; 3],
19 pub color: [f32; 3],
20 pub intensity: f32,
21 pub radius: f32,
22 pub cast_shadow: bool,
23}
24
25pub fn default_point_light_export(name: &str) -> LightExport {
26 LightExport {
27 name: name.to_string(),
28 light_type: LIGHT_POINT,
29 position: [0.0; 3],
30 direction: [0.0, -1.0, 0.0],
31 color: [1.0; 3],
32 intensity: 1.0,
33 radius: 0.0,
34 cast_shadow: true,
35 }
36}
37
38#[derive(Debug, Clone)]
42pub struct LightData {
43 pub name: String,
44 pub light_type: String,
45 pub color: [f32; 3],
46 pub energy: f32,
47 pub shadow: bool,
48}
49
50pub fn new_light_data(name: &str, light_type: &str, energy: f32) -> LightData {
52 LightData {
53 name: name.to_string(),
54 light_type: light_type.to_string(),
55 color: [1.0, 1.0, 1.0],
56 energy,
57 shadow: true,
58 }
59}
60
61pub fn light_to_json(l: &LightData) -> String {
63 format!(
64 "{{\"name\":\"{}\",\"type\":\"{}\",\"energy\":{},\"shadow\":{}}}",
65 l.name, l.light_type, l.energy, l.shadow
66 )
67}
68
69pub fn lights_to_json(lights: &[LightData]) -> String {
71 let inner: Vec<String> = lights.iter().map(light_to_json).collect();
72 format!("[{}]", inner.join(","))
73}
74
75pub fn light_lux_at_distance(l: &LightData, distance: f32) -> f32 {
77 use std::f32::consts::PI;
78 if distance < f32::EPSILON {
79 return f32::MAX;
80 }
81 l.energy / (4.0 * PI * distance * distance)
82}
83
84pub fn light_is_directional(l: &LightData) -> bool {
86 l.light_type.eq_ignore_ascii_case("SUN") || l.light_type.eq_ignore_ascii_case("DIRECTIONAL")
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_new_light_data() {
95 let l = new_light_data("sun", "SUN", 5.0);
96 assert_eq!(l.name, "sun");
97 }
98
99 #[test]
100 fn test_light_to_json() {
101 let l = new_light_data("pt", "POINT", 1.0);
102 let j = light_to_json(&l);
103 assert!(j.contains("POINT"));
104 }
105
106 #[test]
107 fn test_light_lux_at_distance() {
108 let l = new_light_data("l", "POINT", 4.0);
109 let lux = light_lux_at_distance(&l, 1.0);
110 assert!(lux > 0.0);
111 }
112
113 #[test]
114 fn test_light_is_directional_true() {
115 let l = new_light_data("sun", "SUN", 1.0);
116 assert!(light_is_directional(&l));
117 }
118
119 #[test]
120 fn test_light_is_directional_false() {
121 let l = new_light_data("pt", "POINT", 1.0);
122 assert!(!light_is_directional(&l));
123 }
124}