use crate::{
core::{algebra::Matrix4, algebra::Vector2, math::Rect, pool::Handle, visitor::prelude::*},
scene2d::{
base::{Base, BaseBuilder},
graph::Graph,
node::Node,
},
};
use std::ops::{Deref, DerefMut};
#[derive(Visit)]
pub struct Camera {
base: Base,
viewport: Rect<f32>,
view_matrix: Matrix4<f32>,
projection_matrix: Matrix4<f32>,
enabled: bool,
}
impl Default for Camera {
fn default() -> Self {
Self {
base: Default::default(),
viewport: Rect::new(0.0, 0.0, 1.0, 1.0),
view_matrix: Matrix4::identity(),
projection_matrix: Matrix4::identity(),
enabled: true,
}
}
}
impl Deref for Camera {
type Target = Base;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl DerefMut for Camera {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl Camera {
#[inline]
pub fn viewport_pixels(&self, frame_size: Vector2<f32>) -> Rect<i32> {
Rect::new(
(self.viewport.x() * frame_size.x) as i32,
(self.viewport.y() * frame_size.y) as i32,
(self.viewport.w() * frame_size.x) as i32,
(self.viewport.h() * frame_size.y) as i32,
)
}
pub fn set_viewport(&mut self, viewport: Rect<f32>) {
self.viewport = viewport;
}
pub fn view_projection_matrix(&self) -> Matrix4<f32> {
self.projection_matrix * self.view_matrix
}
pub fn update(&mut self, render_target_size: Vector2<f32>) {
self.projection_matrix = Matrix4::new_orthographic(
0.0,
render_target_size.x,
render_target_size.y,
0.0,
0.0,
1.0,
);
self.view_matrix = self
.global_transform()
.try_inverse()
.unwrap_or_else(Matrix4::identity);
}
pub fn enabled(&self) -> bool {
self.enabled
}
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
pub fn raw_copy(&self) -> Self {
Self {
base: self.base.raw_copy(),
viewport: self.viewport,
view_matrix: self.view_matrix,
projection_matrix: self.projection_matrix,
enabled: self.enabled,
}
}
}
pub struct CameraBuilder {
base_builder: BaseBuilder,
viewport: Rect<f32>,
enabled: bool,
}
impl CameraBuilder {
pub fn new(base_builder: BaseBuilder) -> Self {
Self {
base_builder,
viewport: Rect::new(0.0, 0.0, 1.0, 1.0),
enabled: true,
}
}
pub fn with_viewport(mut self, viewport: Rect<f32>) -> Self {
self.viewport = viewport;
self
}
pub fn with_enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}
pub fn build(self, graph: &mut Graph) -> Handle<Node> {
graph.add_node(Node::Camera(Camera {
base: self.base_builder.build_base(),
viewport: self.viewport,
view_matrix: Matrix4::identity(),
projection_matrix: Default::default(),
enabled: self.enabled,
}))
}
}