113 lines
2.8 KiB
Rust
113 lines
2.8 KiB
Rust
use super::DepthCalculation;
|
|
use bevy_math::Mat4;
|
|
use bevy_reflect::{Reflect, ReflectDeserialize};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
pub trait CameraProjection {
|
|
fn get_projection_matrix(&self) -> Mat4;
|
|
fn update(&mut self, width: usize, height: usize);
|
|
fn depth_calculation(&self) -> DepthCalculation;
|
|
}
|
|
|
|
#[derive(Debug, Clone, Reflect)]
|
|
pub struct PerspectiveProjection {
|
|
pub fov: f32,
|
|
pub aspect_ratio: f32,
|
|
pub near: f32,
|
|
pub far: f32,
|
|
}
|
|
|
|
impl CameraProjection for PerspectiveProjection {
|
|
fn get_projection_matrix(&self) -> Mat4 {
|
|
Mat4::perspective_rh(self.fov, self.aspect_ratio, self.near, self.far)
|
|
}
|
|
|
|
fn update(&mut self, width: usize, height: usize) {
|
|
self.aspect_ratio = width as f32 / height as f32;
|
|
}
|
|
|
|
fn depth_calculation(&self) -> DepthCalculation {
|
|
DepthCalculation::Distance
|
|
}
|
|
}
|
|
|
|
impl Default for PerspectiveProjection {
|
|
fn default() -> Self {
|
|
PerspectiveProjection {
|
|
fov: std::f32::consts::PI / 4.0,
|
|
near: 1.0,
|
|
far: 1000.0,
|
|
aspect_ratio: 1.0,
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: make this a component instead of a property
|
|
#[derive(Debug, Clone, Reflect, Serialize, Deserialize)]
|
|
#[reflect_value(Serialize, Deserialize)]
|
|
pub enum WindowOrigin {
|
|
Center,
|
|
BottomLeft,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Reflect)]
|
|
pub struct OrthographicProjection {
|
|
pub left: f32,
|
|
pub right: f32,
|
|
pub bottom: f32,
|
|
pub top: f32,
|
|
pub near: f32,
|
|
pub far: f32,
|
|
pub window_origin: WindowOrigin,
|
|
}
|
|
|
|
impl CameraProjection for OrthographicProjection {
|
|
fn get_projection_matrix(&self) -> Mat4 {
|
|
Mat4::orthographic_rh(
|
|
self.left,
|
|
self.right,
|
|
self.bottom,
|
|
self.top,
|
|
self.near,
|
|
self.far,
|
|
)
|
|
}
|
|
|
|
fn update(&mut self, width: usize, height: usize) {
|
|
match self.window_origin {
|
|
WindowOrigin::Center => {
|
|
let half_width = width as f32 / 2.0;
|
|
let half_height = height as f32 / 2.0;
|
|
self.left = -half_width;
|
|
self.right = half_width;
|
|
self.top = half_height;
|
|
self.bottom = -half_height;
|
|
}
|
|
WindowOrigin::BottomLeft => {
|
|
self.left = 0.0;
|
|
self.right = width as f32;
|
|
self.top = height as f32;
|
|
self.bottom = 0.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn depth_calculation(&self) -> DepthCalculation {
|
|
DepthCalculation::ZDifference
|
|
}
|
|
}
|
|
|
|
impl Default for OrthographicProjection {
|
|
fn default() -> Self {
|
|
OrthographicProjection {
|
|
left: 0.0,
|
|
right: 0.0,
|
|
bottom: 0.0,
|
|
top: 0.0,
|
|
near: 0.0,
|
|
far: 1000.0,
|
|
window_origin: WindowOrigin::Center,
|
|
}
|
|
}
|
|
}
|