use crate::{
core::{
algebra::Vector3,
color::Color,
reflect::prelude::*,
variable::InheritableVariable,
visitor::{Visit, VisitResult, Visitor},
},
scene::base::{Base, BaseBuilder},
};
use std::ops::{Deref, DerefMut};
pub mod directional;
pub mod point;
pub mod spot;
pub const DEFAULT_SCATTER_R: f32 = 0.03;
pub const DEFAULT_SCATTER_G: f32 = 0.03;
pub const DEFAULT_SCATTER_B: f32 = 0.03;
#[derive(Debug, Reflect, Clone, Visit)]
pub struct BaseLight {
base: Base,
#[reflect(setter = "set_color")]
color: InheritableVariable<Color>,
#[visit(rename = "ScatterFactor")]
#[reflect(setter = "set_scatter")]
scatter: InheritableVariable<Vector3<f32>>,
#[reflect(setter = "enable_scatter")]
scatter_enabled: InheritableVariable<bool>,
#[reflect(min_value = 0.0, step = 0.1)]
#[reflect(setter = "set_intensity")]
intensity: InheritableVariable<f32>,
}
impl Deref for BaseLight {
type Target = Base;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl DerefMut for BaseLight {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl Default for BaseLight {
fn default() -> Self {
Self {
base: Default::default(),
color: InheritableVariable::new_modified(Color::WHITE),
scatter: InheritableVariable::new_modified(Vector3::new(
DEFAULT_SCATTER_R,
DEFAULT_SCATTER_G,
DEFAULT_SCATTER_B,
)),
scatter_enabled: InheritableVariable::new_modified(true),
intensity: InheritableVariable::new_modified(1.0),
}
}
}
impl BaseLight {
#[inline]
pub fn set_color(&mut self, color: Color) -> Color {
self.color.set_value_and_mark_modified(color)
}
#[inline]
pub fn color(&self) -> Color {
*self.color
}
#[inline]
pub fn set_scatter(&mut self, f: Vector3<f32>) -> Vector3<f32> {
self.scatter.set_value_and_mark_modified(f)
}
#[inline]
pub fn scatter(&self) -> Vector3<f32> {
*self.scatter
}
pub fn set_intensity(&mut self, intensity: f32) -> f32 {
self.intensity.set_value_and_mark_modified(intensity)
}
pub fn intensity(&self) -> f32 {
*self.intensity
}
#[inline]
pub fn scatter_linear(&self) -> Vector3<f32> {
self.scatter.map(|v| v.powf(2.2))
}
#[inline]
pub fn enable_scatter(&mut self, state: bool) -> bool {
self.scatter_enabled.set_value_and_mark_modified(state)
}
#[inline]
pub fn is_scatter_enabled(&self) -> bool {
*self.scatter_enabled
}
}
pub struct BaseLightBuilder {
base_builder: BaseBuilder,
color: Color,
scatter_factor: Vector3<f32>,
scatter_enabled: bool,
intensity: f32,
}
impl BaseLightBuilder {
pub fn new(base_builder: BaseBuilder) -> Self {
Self {
base_builder,
color: Color::WHITE,
scatter_factor: Vector3::new(DEFAULT_SCATTER_R, DEFAULT_SCATTER_G, DEFAULT_SCATTER_B),
scatter_enabled: true,
intensity: 1.0,
}
}
pub fn with_color(mut self, color: Color) -> Self {
self.color = color;
self
}
pub fn with_scatter_factor(mut self, f: Vector3<f32>) -> Self {
self.scatter_factor = f;
self
}
pub fn with_scatter_enabled(mut self, state: bool) -> Self {
self.scatter_enabled = state;
self
}
pub fn with_intensity(mut self, intensity: f32) -> Self {
self.intensity = intensity;
self
}
pub fn build(self) -> BaseLight {
BaseLight {
base: self.base_builder.build_base(),
color: self.color.into(),
scatter: self.scatter_factor.into(),
scatter_enabled: self.scatter_enabled.into(),
intensity: self.intensity.into(),
}
}
}