Skip to main content

eulumdat_bevy/photometric/
light.rs

1//! PhotometricLight component and bundle for Bevy.
2//!
3//! This module provides the core components for spawning photometric lights
4//! in a Bevy application.
5
6use super::PhotometricData;
7use bevy::prelude::*;
8use std::marker::PhantomData;
9
10/// Component for photometric light data.
11///
12/// Attach this component to an entity to create a photometric light.
13/// The `PhotometricPlugin` will automatically spawn Bevy lights,
14/// luminaire models, and photometric solids based on the settings.
15///
16/// # Type Parameters
17/// * `T` - The photometric data type (must implement [`PhotometricData`])
18///
19/// # Example
20/// ```ignore
21/// commands.spawn((
22///     PhotometricLight::new(ldt_data),
23///     Transform::from_xyz(0.0, 3.0, 0.0),
24/// ));
25/// ```
26#[derive(Component, Clone, Debug)]
27pub struct PhotometricLight<T: PhotometricData> {
28    /// The photometric data
29    pub data: T,
30    /// Intensity scale factor (default: 1.0)
31    pub intensity_scale: f32,
32    /// Whether to render the photometric solid mesh
33    pub show_solid: bool,
34    /// Whether to render the luminaire geometry model
35    pub show_model: bool,
36    /// Whether to enable shadows
37    pub shadows_enabled: bool,
38}
39
40impl<T: PhotometricData> PhotometricLight<T> {
41    /// Create a new PhotometricLight with default settings.
42    pub fn new(data: T) -> Self {
43        Self {
44            data,
45            intensity_scale: 1.0,
46            show_solid: false,
47            show_model: true,
48            shadows_enabled: false,
49        }
50    }
51
52    /// Set the intensity scale factor.
53    pub fn with_intensity_scale(mut self, scale: f32) -> Self {
54        self.intensity_scale = scale;
55        self
56    }
57
58    /// Enable or disable the photometric solid visualization.
59    pub fn with_solid(mut self, show: bool) -> Self {
60        self.show_solid = show;
61        self
62    }
63
64    /// Enable or disable the luminaire model.
65    pub fn with_model(mut self, show: bool) -> Self {
66        self.show_model = show;
67        self
68    }
69
70    /// Enable or disable shadows.
71    pub fn with_shadows(mut self, enabled: bool) -> Self {
72        self.shadows_enabled = enabled;
73        self
74    }
75}
76
77/// Bundle for spawning a photometric light with transform.
78///
79/// This is the recommended way to spawn a photometric light.
80///
81/// # Example
82/// ```ignore
83/// commands.spawn(
84///     PhotometricLightBundle::new(ldt_data)
85///         .with_transform(Transform::from_xyz(0.0, 3.0, 0.0))
86/// );
87/// ```
88#[derive(Bundle, Clone)]
89pub struct PhotometricLightBundle<T: PhotometricData> {
90    /// The photometric light component
91    pub light: PhotometricLight<T>,
92    /// Transform for positioning
93    pub transform: Transform,
94    /// Global transform (computed automatically)
95    pub global_transform: GlobalTransform,
96}
97
98impl<T: PhotometricData> PhotometricLightBundle<T> {
99    /// Create a new bundle with default transform at origin.
100    pub fn new(data: T) -> Self {
101        Self {
102            light: PhotometricLight::new(data),
103            transform: Transform::default(),
104            global_transform: GlobalTransform::default(),
105        }
106    }
107
108    /// Set the transform.
109    pub fn with_transform(mut self, transform: Transform) -> Self {
110        self.transform = transform;
111        self
112    }
113
114    /// Set the intensity scale.
115    pub fn with_intensity_scale(mut self, scale: f32) -> Self {
116        self.light = self.light.with_intensity_scale(scale);
117        self
118    }
119
120    /// Enable or disable the photometric solid.
121    pub fn with_solid(mut self, show: bool) -> Self {
122        self.light = self.light.with_solid(show);
123        self
124    }
125
126    /// Enable or disable the luminaire model.
127    pub fn with_model(mut self, show: bool) -> Self {
128        self.light = self.light.with_model(show);
129        self
130    }
131
132    /// Enable or disable shadows.
133    pub fn with_shadows(mut self, enabled: bool) -> Self {
134        self.light = self.light.with_shadows(enabled);
135        self
136    }
137}
138
139/// Marker component for Bevy lights spawned by PhotometricPlugin.
140///
141/// Used to track and update lights when the PhotometricLight component changes.
142#[derive(Component)]
143pub struct BevyLightMarker<T: PhotometricData> {
144    /// The parent entity with PhotometricLight
145    pub parent: Entity,
146    _phantom: PhantomData<T>,
147}
148
149impl<T: PhotometricData> BevyLightMarker<T> {
150    /// Create a new marker pointing to the parent entity.
151    pub fn new(parent: Entity) -> Self {
152        Self {
153            parent,
154            _phantom: PhantomData,
155        }
156    }
157}
158
159/// Marker component for photometric solid mesh entities.
160#[derive(Component)]
161pub struct PhotometricSolid<T: PhotometricData> {
162    /// The parent entity with PhotometricLight
163    pub parent: Entity,
164    _phantom: PhantomData<T>,
165}
166
167impl<T: PhotometricData> PhotometricSolid<T> {
168    /// Create a new marker pointing to the parent entity.
169    pub fn new(parent: Entity) -> Self {
170        Self {
171            parent,
172            _phantom: PhantomData,
173        }
174    }
175}
176
177/// Marker component for luminaire model entities.
178#[derive(Component)]
179pub struct LuminaireModel<T: PhotometricData> {
180    /// The parent entity with PhotometricLight
181    pub parent: Entity,
182    _phantom: PhantomData<T>,
183}
184
185impl<T: PhotometricData> LuminaireModel<T> {
186    /// Create a new marker pointing to the parent entity.
187    pub fn new(parent: Entity) -> Self {
188        Self {
189            parent,
190            _phantom: PhantomData,
191        }
192    }
193}
194
195/// Resource to track whether the plugin has been initialized.
196#[derive(Resource)]
197pub struct PhotometricPluginState<T: PhotometricData> {
198    _phantom: PhantomData<T>,
199}
200
201impl<T: PhotometricData> Default for PhotometricPluginState<T> {
202    fn default() -> Self {
203        Self {
204            _phantom: PhantomData,
205        }
206    }
207}