bevy/crates/bevy_render/src/camera.rs
Carter Anderson d50313c285 ui is back!
2020-05-03 19:30:31 -07:00

144 lines
3.6 KiB
Rust

use bevy_app::{Events, GetEventReader};
use bevy_window::WindowResized;
use glam::Mat4;
use legion::prelude::*;
#[derive(Default)]
pub struct ActiveCamera;
#[derive(Default)]
pub struct ActiveCamera2d;
#[derive(Debug)]
pub struct OrthographicCamera {
pub left: f32,
pub right: f32,
pub bottom: f32,
pub top: f32,
pub near: f32,
pub far: f32,
}
impl OrthographicCamera {
fn get_view_matrix(&self) -> Mat4 {
let projection = Mat4::orthographic_rh_gl(
self.left,
self.right,
self.bottom,
self.top,
self.near,
self.far,
);
projection
}
}
impl Default for OrthographicCamera {
fn default() -> Self {
OrthographicCamera {
left: 0.0,
right: 0.0,
bottom: 0.0,
top: 0.0,
near: 0.0,
far: 1.0,
}
}
}
#[derive(Debug)]
pub struct PerspectiveCamera {
pub fov: f32,
pub aspect_ratio: f32,
pub near: f32,
pub far: f32,
}
impl PerspectiveCamera {
pub fn get_view_matrix(&self) -> Mat4 {
let projection = Mat4::perspective_rh_gl(self.fov, self.aspect_ratio, self.near, self.far);
projection
}
}
impl Default for PerspectiveCamera {
fn default() -> Self {
PerspectiveCamera {
fov: std::f32::consts::PI / 4.0,
near: 1.0,
far: 1000.0,
aspect_ratio: 1.0,
}
}
}
#[derive(Debug)]
pub enum CameraType {
Perspective(PerspectiveCamera),
Orthographic(OrthographicCamera),
}
impl CameraType {
pub fn default_perspective() -> CameraType {
CameraType::Perspective(PerspectiveCamera::default())
}
pub fn default_orthographic() -> CameraType {
CameraType::Orthographic(OrthographicCamera::default())
}
}
impl Default for CameraType {
fn default() -> Self {
CameraType::default_perspective()
}
}
#[derive(Default, Debug)]
pub struct Camera {
pub view_matrix: Mat4,
pub camera_type: CameraType,
}
impl Camera {
pub fn new(camera_type: CameraType) -> Self {
Camera {
view_matrix: Mat4::identity(),
camera_type,
}
}
pub fn update(&mut self, width: u32, height: u32) {
self.view_matrix = match &mut self.camera_type {
CameraType::Perspective(projection) => {
projection.aspect_ratio = width as f32 / height as f32;
projection.get_view_matrix()
}
CameraType::Orthographic(orthographic) => {
orthographic.right = width as f32;
orthographic.top = height as f32;
orthographic.get_view_matrix()
}
}
}
}
pub fn camera_update_system(resources: &mut Resources) -> Box<dyn Schedulable> {
let mut window_resized_event_reader = resources.get_event_reader::<WindowResized>();
SystemBuilder::new("camera_update")
.read_resource::<Events<WindowResized>>()
.with_query(<Write<Camera>>::query())
.build(move |_, world, window_resized_events, query| {
let primary_window_resized_event = window_resized_event_reader
.find_latest(&window_resized_events, |event| event.is_primary);
if let Some(primary_window_resized_event) = primary_window_resized_event {
for mut camera in query.iter_mut(world) {
camera.update(
primary_window_resized_event.width,
primary_window_resized_event.height,
);
}
}
})
}