@@ -109,6 +109,14 @@ enum AppSetting {
109109 SoftShadows ( bool ) ,
110110}
111111
112+ /// Stores the entities of each spawned light in the example.
113+ #[ derive( Resource ) ]
114+ struct DirectionalPointSpotLights {
115+ directional : Entity ,
116+ point : Entity ,
117+ spot : Entity ,
118+ }
119+
112120/// The example application entry point.
113121fn main ( ) {
114122 #[ cfg( not( feature = "free_camera" ) ) ]
@@ -149,7 +157,7 @@ fn main() {
149157/// Creates all the objects in the scene.
150158fn setup ( mut commands : Commands , asset_server : Res < AssetServer > , app_status : Res < AppStatus > ) {
151159 spawn_camera ( & mut commands, & asset_server) ;
152- spawn_light ( & mut commands, & app_status) ;
160+ spawn_lights ( & mut commands, & app_status) ;
153161 spawn_gltf_scene ( & mut commands, & asset_server) ;
154162 spawn_buttons ( & mut commands) ;
155163}
@@ -183,28 +191,49 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
183191 } ) ;
184192}
185193
186- /// Spawns the initial light.
187- fn spawn_light ( commands : & mut Commands , app_status : & AppStatus ) {
188- // Because this light can become a directional light, point light, or spot
189- // light depending on the settings, we add the union of the components
190- // necessary for this light to behave as all three of those.
191- commands
194+ /// Spawns the initial light and placeholder for other lights.
195+ fn spawn_lights ( commands : & mut Commands , app_status : & AppStatus ) {
196+ let transform = Transform :: from_rotation ( Quat :: from_array ( [
197+ 0.6539259 ,
198+ -0.34646285 ,
199+ 0.36505926 ,
200+ -0.5648683 ,
201+ ] ) )
202+ . with_translation ( vec3 ( 57.693 , 34.334 , -6.422 ) ) ;
203+ // Spawn an initial directional light
204+ let directional = commands
205+ . spawn ( (
206+ create_directional_light ( app_status, light_consts:: lux:: AMBIENT_DAYLIGHT ) ,
207+ transform. clone ( ) ,
208+ ) )
209+ . id ( ) ;
210+ // Spawn placeholder entities for point and spot lights.
211+ // They are located in the same place as the directional light.
212+ let point = commands
213+ . spawn ( (
214+ create_point_light ( app_status, 0. ) ,
215+ transform. clone ( ) ,
216+ // These two are needed for point lights.
217+ CubemapVisibleEntities :: default ( ) ,
218+ CubemapFrusta :: default ( ) ,
219+ ) )
220+ . id ( ) ;
221+
222+ let spot = commands
192223 . spawn ( (
193- create_directional_light ( app_status) ,
194- Transform :: from_rotation ( Quat :: from_array ( [
195- 0.6539259 ,
196- -0.34646285 ,
197- 0.36505926 ,
198- -0.5648683 ,
199- ] ) )
200- . with_translation ( vec3 ( 57.693 , 34.334 , -6.422 ) ) ,
224+ create_spot_light ( app_status, 0. ) ,
225+ transform,
226+ // These two are needed for spot lights.
227+ VisibleMeshEntities :: default ( ) ,
228+ Frustum :: default ( ) ,
201229 ) )
202- // These two are needed for point lights.
203- . insert ( CubemapVisibleEntities :: default ( ) )
204- . insert ( CubemapFrusta :: default ( ) )
205- // These two are needed for spot lights.
206- . insert ( VisibleMeshEntities :: default ( ) )
207- . insert ( Frustum :: default ( ) ) ;
230+ . id ( ) ;
231+
232+ commands. insert_resource ( DirectionalPointSpotLights {
233+ directional,
234+ point,
235+ spot,
236+ } ) ;
208237}
209238
210239/// Loads and spawns the glTF palm tree scene.
@@ -282,7 +311,7 @@ fn update_radio_buttons(
282311/// Handles requests from the user to change the type of light.
283312fn handle_light_type_change (
284313 mut commands : Commands ,
285- mut lights : Query < Entity , Or < ( With < DirectionalLight > , With < PointLight > , With < SpotLight > ) > > ,
314+ lights : Res < DirectionalPointSpotLights > ,
286315 mut events : MessageReader < WidgetClickEvent < AppSetting > > ,
287316 mut app_status : ResMut < AppStatus > ,
288317) {
@@ -291,23 +320,33 @@ fn handle_light_type_change(
291320 continue ;
292321 } ;
293322 app_status. light_type = light_type;
294-
295- for light in lights. iter_mut ( ) {
296- let mut light_commands = commands. entity ( light) ;
297- light_commands
298- . remove :: < DirectionalLight > ( )
299- . remove :: < PointLight > ( )
300- . remove :: < SpotLight > ( ) ;
301- match light_type {
302- LightType :: Point => {
303- light_commands. insert ( create_point_light ( & app_status) ) ;
304- }
305- LightType :: Spot => {
306- light_commands. insert ( create_spot_light ( & app_status) ) ;
307- }
308- LightType :: Directional => {
309- light_commands. insert ( create_directional_light ( & app_status) ) ;
310- }
323+ commands
324+ . entity ( lights. directional )
325+ . insert ( create_directional_light ( & app_status, 0. ) ) ;
326+ commands
327+ . entity ( lights. point )
328+ . insert ( create_point_light ( & app_status, 0. ) ) ;
329+ commands
330+ . entity ( lights. spot )
331+ . insert ( create_spot_light ( & app_status, 0. ) ) ;
332+ match light_type {
333+ LightType :: Directional => {
334+ commands
335+ . entity ( lights. directional )
336+ . insert ( create_directional_light (
337+ & app_status,
338+ light_consts:: lux:: AMBIENT_DAYLIGHT ,
339+ ) ) ;
340+ }
341+ LightType :: Point => {
342+ commands
343+ . entity ( lights. point )
344+ . insert ( create_point_light ( & app_status, POINT_LIGHT_INTENSITY ) ) ;
345+ }
346+ LightType :: Spot => {
347+ commands
348+ . entity ( lights. spot )
349+ . insert ( create_spot_light ( & app_status, POINT_LIGHT_INTENSITY ) ) ;
311350 }
312351 }
313352 }
@@ -348,7 +387,8 @@ fn handle_shadow_filter_change(
348387
349388/// Handles requests from the user to toggle soft shadows on and off.
350389fn handle_pcss_toggle (
351- mut lights : Query < AnyOf < ( & mut DirectionalLight , & mut PointLight , & mut SpotLight ) > > ,
390+ mut commands : Commands ,
391+ lights : Res < DirectionalPointSpotLights > ,
352392 mut events : MessageReader < WidgetClickEvent < AppSetting > > ,
353393 mut app_status : ResMut < AppStatus > ,
354394) {
@@ -359,23 +399,33 @@ fn handle_pcss_toggle(
359399 app_status. soft_shadows = value;
360400
361401 // Recreating the lights is the simplest way to toggle soft shadows.
362- for ( directional_light, point_light, spot_light) in lights. iter_mut ( ) {
363- if let Some ( mut directional_light) = directional_light {
364- * directional_light = create_directional_light ( & app_status) ;
402+ match app_status. light_type {
403+ LightType :: Directional => {
404+ commands
405+ . entity ( lights. directional )
406+ . insert ( create_directional_light (
407+ & app_status,
408+ light_consts:: lux:: AMBIENT_DAYLIGHT ,
409+ ) ) ;
365410 }
366- if let Some ( mut point_light) = point_light {
367- * point_light = create_point_light ( & app_status) ;
411+ LightType :: Point => {
412+ commands
413+ . entity ( lights. point )
414+ . insert ( create_point_light ( & app_status, POINT_LIGHT_INTENSITY ) ) ;
368415 }
369- if let Some ( mut spot_light) = spot_light {
370- * spot_light = create_spot_light ( & app_status) ;
416+ LightType :: Spot => {
417+ commands
418+ . entity ( lights. spot )
419+ . insert ( create_spot_light ( & app_status, POINT_LIGHT_INTENSITY ) ) ;
371420 }
372421 }
373422 }
374423}
375424
376425/// Creates the [`DirectionalLight`] component with the appropriate settings.
377- fn create_directional_light ( app_status : & AppStatus ) -> DirectionalLight {
426+ fn create_directional_light ( app_status : & AppStatus , illuminance : f32 ) -> DirectionalLight {
378427 DirectionalLight {
428+ illuminance,
379429 shadow_maps_enabled : true ,
380430 soft_shadow_size : if app_status. soft_shadows {
381431 Some ( LIGHT_RADIUS )
@@ -388,9 +438,9 @@ fn create_directional_light(app_status: &AppStatus) -> DirectionalLight {
388438}
389439
390440/// Creates the [`PointLight`] component with the appropriate settings.
391- fn create_point_light ( app_status : & AppStatus ) -> PointLight {
441+ fn create_point_light ( app_status : & AppStatus , intensity : f32 ) -> PointLight {
392442 PointLight {
393- intensity : POINT_LIGHT_INTENSITY ,
443+ intensity,
394444 range : POINT_LIGHT_RANGE ,
395445 shadow_maps_enabled : true ,
396446 radius : LIGHT_RADIUS ,
@@ -402,9 +452,9 @@ fn create_point_light(app_status: &AppStatus) -> PointLight {
402452}
403453
404454/// Creates the [`SpotLight`] component with the appropriate settings.
405- fn create_spot_light ( app_status : & AppStatus ) -> SpotLight {
455+ fn create_spot_light ( app_status : & AppStatus , intensity : f32 ) -> SpotLight {
406456 SpotLight {
407- intensity : POINT_LIGHT_INTENSITY ,
457+ intensity,
408458 range : POINT_LIGHT_RANGE ,
409459 radius : LIGHT_RADIUS ,
410460 shadow_maps_enabled : true ,
0 commit comments