use crate::{
core::{
color::Color,
inspect::{Inspect, PropertyInfo},
math::aabb::AxisAlignedBoundingBox,
pool::Handle,
visitor::{Visit, VisitResult, Visitor},
},
resource::texture::Texture,
scene::{
base::{Base, BaseBuilder},
graph::Graph,
node::Node,
},
};
use std::ops::{Deref, DerefMut};
#[derive(Debug, Inspect)]
pub struct Sprite {
base: Base,
texture: Option<Texture>,
color: Color,
#[inspect(min_value = 0.0, step = 0.1)]
size: f32,
rotation: f32,
}
impl Deref for Sprite {
type Target = Base;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl DerefMut for Sprite {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl Default for Sprite {
fn default() -> Self {
SpriteBuilder::new(BaseBuilder::new()).build_sprite()
}
}
impl Sprite {
pub fn raw_copy(&self) -> Self {
Self {
base: self.base.raw_copy(),
texture: self.texture.clone(),
color: self.color,
size: self.size,
rotation: self.rotation,
}
}
pub fn set_size(&mut self, size: f32) {
self.size = size;
}
pub fn size(&self) -> f32 {
self.size
}
pub fn set_color(&mut self, color: Color) {
self.color = color;
}
pub fn color(&self) -> Color {
self.color
}
pub fn set_rotation(&mut self, rotation: f32) {
self.rotation = rotation;
}
pub fn rotation(&self) -> f32 {
self.rotation
}
pub fn set_texture(&mut self, texture: Option<Texture>) {
self.texture = texture;
}
pub fn texture(&self) -> Option<Texture> {
self.texture.clone()
}
pub fn texture_ref(&self) -> Option<&Texture> {
self.texture.as_ref()
}
#[inline]
pub fn local_bounding_box(&self) -> AxisAlignedBoundingBox {
AxisAlignedBoundingBox::from_radius(self.size)
}
pub fn world_bounding_box(&self) -> AxisAlignedBoundingBox {
self.base.world_bounding_box()
}
}
impl Visit for Sprite {
fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
visitor.enter_region(name)?;
self.texture.visit("Texture", visitor)?;
self.color.visit("Color", visitor)?;
self.size.visit("Size", visitor)?;
self.rotation.visit("Rotation", visitor)?;
self.base.visit("Base", visitor)?;
visitor.leave_region()
}
}
pub struct SpriteBuilder {
base_builder: BaseBuilder,
texture: Option<Texture>,
color: Color,
size: f32,
rotation: f32,
}
impl SpriteBuilder {
pub fn new(base_builder: BaseBuilder) -> Self {
Self {
base_builder,
texture: None,
color: Color::WHITE,
size: 0.2,
rotation: 0.0,
}
}
pub fn with_texture(mut self, texture: Texture) -> Self {
self.texture = Some(texture);
self
}
pub fn with_opt_texture(mut self, texture: Option<Texture>) -> Self {
self.texture = texture;
self
}
pub fn with_color(mut self, color: Color) -> Self {
self.color = color;
self
}
pub fn with_size(mut self, size: f32) -> Self {
self.size = size;
self
}
pub fn with_rotation(mut self, rotation: f32) -> Self {
self.rotation = rotation;
self
}
fn build_sprite(self) -> Sprite {
Sprite {
base: self.base_builder.build_base(),
texture: self.texture,
color: self.color,
size: self.size,
rotation: self.rotation,
}
}
pub fn build_node(self) -> Node {
Node::Sprite(self.build_sprite())
}
pub fn build(self, graph: &mut Graph) -> Handle<Node> {
graph.add_node(self.build_node())
}
}