fyrox_impl/scene/light/
point.rs1use crate::scene::base::BaseBuilder;
41use crate::scene::node::constructor::NodeConstructor;
42use crate::{
43 core::{
44 color::Color,
45 math::aabb::AxisAlignedBoundingBox,
46 pool::Handle,
47 reflect::prelude::*,
48 type_traits::prelude::*,
49 uuid::{uuid, Uuid},
50 variable::InheritableVariable,
51 visitor::{Visit, VisitResult, Visitor},
52 },
53 scene::{
54 base::Base,
55 debug::SceneDrawingContext,
56 graph::Graph,
57 light::{BaseLight, BaseLightBuilder},
58 node::{Node, NodeTrait},
59 },
60};
61use fyrox_graph::constructor::ConstructorProvider;
62use fyrox_graph::SceneGraph;
63use std::ops::{Deref, DerefMut};
64
65#[derive(Debug, Reflect, Clone, Visit, ComponentProvider)]
67#[reflect(derived_type = "Node")]
68pub struct PointLight {
69 #[component(include)]
70 base_light: BaseLight,
71
72 #[reflect(min_value = 0.0, step = 0.001)]
73 #[reflect(setter = "set_shadow_bias")]
74 shadow_bias: InheritableVariable<f32>,
75
76 #[reflect(min_value = 0.0, step = 0.1)]
77 #[reflect(setter = "set_radius")]
78 radius: InheritableVariable<f32>,
79}
80
81impl Deref for PointLight {
82 type Target = Base;
83
84 fn deref(&self) -> &Self::Target {
85 &self.base_light.base
86 }
87}
88
89impl DerefMut for PointLight {
90 fn deref_mut(&mut self) -> &mut Self::Target {
91 &mut self.base_light.base
92 }
93}
94
95impl TypeUuidProvider for PointLight {
96 fn type_uuid() -> Uuid {
97 uuid!("c81dcc31-7cb9-465f-abd9-b385ac6f4d37")
98 }
99}
100
101impl PointLight {
102 pub fn base_light_ref(&self) -> &BaseLight {
104 &self.base_light
105 }
106
107 pub fn base_light_mut(&mut self) -> &mut BaseLight {
109 &mut self.base_light
110 }
111
112 #[inline]
115 pub fn set_radius(&mut self, radius: f32) -> f32 {
116 self.radius.set_value_and_mark_modified(radius.abs())
117 }
118
119 #[inline]
121 pub fn radius(&self) -> f32 {
122 *self.radius
123 }
124
125 pub fn set_shadow_bias(&mut self, bias: f32) -> f32 {
128 self.shadow_bias.set_value_and_mark_modified(bias)
129 }
130
131 pub fn shadow_bias(&self) -> f32 {
133 *self.shadow_bias
134 }
135}
136
137impl ConstructorProvider<Node, Graph> for PointLight {
138 fn constructor() -> NodeConstructor {
139 NodeConstructor::new::<Self>()
140 .with_variant("Point Light", |_| {
141 PointLightBuilder::new(BaseLightBuilder::new(
142 BaseBuilder::new().with_name("PointLight"),
143 ))
144 .with_radius(10.0)
145 .build_node()
146 .into()
147 })
148 .with_group("Light")
149 }
150}
151
152impl NodeTrait for PointLight {
153 fn local_bounding_box(&self) -> AxisAlignedBoundingBox {
154 AxisAlignedBoundingBox::from_radius(*self.radius)
155 }
156
157 fn world_bounding_box(&self) -> AxisAlignedBoundingBox {
158 self.local_bounding_box()
160 .transform(&self.global_transform_without_scaling())
161 }
162
163 fn id(&self) -> Uuid {
164 Self::type_uuid()
165 }
166
167 fn debug_draw(&self, ctx: &mut SceneDrawingContext) {
168 ctx.draw_wire_sphere(self.global_position(), self.radius(), 30, Color::GREEN);
169 }
170}
171
172impl Default for PointLight {
173 fn default() -> Self {
174 Self {
175 base_light: Default::default(),
176 shadow_bias: InheritableVariable::new_modified(0.025),
177 radius: InheritableVariable::new_modified(10.0),
178 }
179 }
180}
181
182pub struct PointLightBuilder {
184 base_light_builder: BaseLightBuilder,
185 shadow_bias: f32,
186 radius: f32,
187}
188
189impl PointLightBuilder {
190 pub fn new(base_light_builder: BaseLightBuilder) -> Self {
192 Self {
193 base_light_builder,
194 shadow_bias: 0.025,
195 radius: 10.0,
196 }
197 }
198
199 pub fn with_radius(mut self, radius: f32) -> Self {
201 self.radius = radius;
202 self
203 }
204
205 pub fn with_shadow_bias(mut self, bias: f32) -> Self {
207 self.shadow_bias = bias;
208 self
209 }
210
211 pub fn build_point_light(self) -> PointLight {
213 PointLight {
214 base_light: self.base_light_builder.build(),
215 radius: self.radius.into(),
216 shadow_bias: self.shadow_bias.into(),
217 }
218 }
219
220 pub fn build_node(self) -> Node {
222 Node::new(self.build_point_light())
223 }
224
225 pub fn build(self, graph: &mut Graph) -> Handle<PointLight> {
227 graph.add_node(self.build_node()).to_variant()
228 }
229}