From d2e160d44af1ba0a19fbfd8215a14f9a76b33f8f Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sat, 21 Mar 2020 21:55:33 -0700 Subject: [PATCH] refactor cameras. add defaults --- examples/custom_shader.rs | 8 +- examples/entity_builder_comparison.rs | 23 +-- examples/instancing.rs | 8 +- examples/instancing_old.rs | 7 +- examples/parenting.rs | 9 +- .../plugin_loading/example_plugin/src/lib.rs | 8 +- examples/simple.rs | 8 +- examples/spawner.rs | 8 +- examples/texture.rs | 10 +- examples/ui.rs | 18 +-- examples/ui_bench.rs | 11 +- src/ecs/default_archetypes.rs | 11 +- src/render/camera.rs | 148 +++++++++++------- src/render/light.rs | 18 ++- 14 files changed, 129 insertions(+), 166 deletions(-) diff --git a/examples/custom_shader.rs b/examples/custom_shader.rs index b301ea7f45..08c92a96a4 100644 --- a/examples/custom_shader.rs +++ b/examples/custom_shader.rs @@ -107,18 +107,12 @@ fn setup(world: &mut World, resources: &mut Resources) { }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }) .build(); } diff --git a/examples/entity_builder_comparison.rs b/examples/entity_builder_comparison.rs index 3f23b81bd0..a754053903 100644 --- a/examples/entity_builder_comparison.rs +++ b/examples/entity_builder_comparison.rs @@ -53,12 +53,7 @@ fn create_entities_insert_vec( world.insert( (), vec![( - Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), + Camera::default(), ActiveCamera, LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), @@ -103,12 +98,7 @@ fn create_entities_builder_add_component( .add(Rotation::from_euler_angles(0.0, 0.0, 0.0)) // camera .build_entity() - .add(Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - })) + .add(Camera::default()) .add(ActiveCamera) .add(LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), @@ -137,6 +127,7 @@ fn create_entities_builder_archetype( .add_entity(MeshEntity { mesh: cube_handle, material: cube_material_handle, + translation: Translation::new(0.0, 0.0, 1.0), ..Default::default() }) // light @@ -146,18 +137,12 @@ fn create_entities_builder_archetype( }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }) .build(); } diff --git a/examples/instancing.rs b/examples/instancing.rs index 3fec9e3cfc..c5472643f3 100644 --- a/examples/instancing.rs +++ b/examples/instancing.rs @@ -63,18 +63,12 @@ fn setup(world: &mut World, resources: &mut Resources) { }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }); let mut rng = StdRng::from_entropy(); diff --git a/examples/instancing_old.rs b/examples/instancing_old.rs index 8f2eabe960..1792cf9441 100644 --- a/examples/instancing_old.rs +++ b/examples/instancing_old.rs @@ -50,12 +50,7 @@ fn setup(world: &mut World, resources: &mut Resources) { vec![ // camera ( - Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), + Camera::default(), ActiveCamera, LocalToWorld(Mat4::look_at_rh( Vec3::new(6.0, -40.0, 20.0), diff --git a/examples/parenting.rs b/examples/parenting.rs index 742d0c7c6d..8d10965bbf 100644 --- a/examples/parenting.rs +++ b/examples/parenting.rs @@ -56,23 +56,16 @@ fn setup(world: &mut World, resources: &mut Resources) { // light .add_entity(LightEntity { translation: Translation::new(4.0, -4.0, 5.0), - rotation: Rotation::from_euler_angles(0.0, 0.0, 0.0), ..Default::default() }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(5.0, 10.0, 10.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }) .build(); } diff --git a/examples/plugin_loading/example_plugin/src/lib.rs b/examples/plugin_loading/example_plugin/src/lib.rs index b4773cb0db..873f397c26 100644 --- a/examples/plugin_loading/example_plugin/src/lib.rs +++ b/examples/plugin_loading/example_plugin/src/lib.rs @@ -49,18 +49,12 @@ pub fn setup(world: &mut World, resources: &mut Resources) { }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }) .build(); } \ No newline at end of file diff --git a/examples/simple.rs b/examples/simple.rs index 21a8cabcd8..408dde0be2 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -53,18 +53,12 @@ fn setup(world: &mut World, resources: &mut Resources) { }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }) .build(); } diff --git a/examples/spawner.rs b/examples/spawner.rs index 2310532973..f52e99a7da 100644 --- a/examples/spawner.rs +++ b/examples/spawner.rs @@ -63,18 +63,12 @@ fn setup(world: &mut World, resources: &mut Resources) { }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }); let mut rng = StdRng::from_entropy(); diff --git a/examples/texture.rs b/examples/texture.rs index a46127567b..3348c3a8fa 100644 --- a/examples/texture.rs +++ b/examples/texture.rs @@ -10,7 +10,7 @@ fn setup(world: &mut World, resources: &mut Resources) { let mut texture_storage = resources.get_mut::>().unwrap(); let texture = Texture::load(TextureType::Png( - concat!(env!("CARGO_MANIFEST_DIR"), "/assets/temp_bevy_logo.png").to_string(), + concat!(env!("CARGO_MANIFEST_DIR"), "/assets/bevy_logo_dark.png").to_string(), )); let texture_handle = texture_storage.add(texture); @@ -52,18 +52,12 @@ fn setup(world: &mut World, resources: &mut Resources) { }) // camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }) .build(); } diff --git a/examples/ui.rs b/examples/ui.rs index c724ce6bb8..a5e90938b6 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -31,30 +31,16 @@ fn setup(world: &mut World, resources: &mut Resources) { }) // 3d camera .add_entity(CameraEntity { - camera: Camera::new(CameraType::Projection { - fov: std::f32::consts::PI / 4.0, - near: 1.0, - far: 1000.0, - aspect_ratio: 1.0, - }), - active_camera: ActiveCamera, local_to_world: LocalToWorld(Mat4::look_at_rh( Vec3::new(3.0, 8.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 1.0), )), + ..Default::default() }) // 2d camera .add_entity(Camera2dEntity { - camera: Camera::new(CameraType::Orthographic { - left: 0.0, - right: 0.0, - bottom: 0.0, - top: 0.0, - near: 0.0, - far: 1.0, - }), - active_camera_2d: ActiveCamera2d, + ..Default::default() }) // bottom left anchor with vertical fill .add_entity(UiEntity { diff --git a/examples/ui_bench.rs b/examples/ui_bench.rs index 5b6aba3918..3e135620de 100644 --- a/examples/ui_bench.rs +++ b/examples/ui_bench.rs @@ -25,15 +25,8 @@ fn build_move_system() -> Box { fn setup(world: &mut World, _resources: &mut Resources) { let mut builder = world.build().add_entity(Camera2dEntity { - camera: Camera::new(CameraType::Orthographic { - left: 0.0, - right: 0.0, - bottom: 0.0, - top: 0.0, - near: 0.0, - far: 1.0, - }), - active_camera_2d: ActiveCamera2d, + camera: Camera::new(CameraType::default_orthographic()), + ..Default::default() }); let mut prev = Vec2::default(); diff --git a/src/ecs/default_archetypes.rs b/src/ecs/default_archetypes.rs index dc5504053d..7558c878af 100644 --- a/src/ecs/default_archetypes.rs +++ b/src/ecs/default_archetypes.rs @@ -35,7 +35,7 @@ pub struct LightEntity { pub rotation: Rotation, } -#[derive(EntityArchetype)] +#[derive(EntityArchetype, Default)] pub struct CameraEntity { pub camera: Camera, pub active_camera: ActiveCamera, @@ -48,6 +48,15 @@ pub struct Camera2dEntity { pub active_camera_2d: ActiveCamera2d, } +impl Default for Camera2dEntity { + fn default() -> Self { + Camera2dEntity { + camera: Camera::new(CameraType::default_orthographic()), + active_camera_2d: ActiveCamera2d, + } + } +} + #[derive(EntityArchetype)] pub struct UiEntity { pub node: Node, diff --git a/src/render/camera.rs b/src/render/camera.rs index dc096632a7..7c8c169a49 100644 --- a/src/render/camera.rs +++ b/src/render/camera.rs @@ -1,25 +1,94 @@ use crate::math::Mat4; +#[derive(Default)] pub struct ActiveCamera; + +#[derive(Default)] pub struct ActiveCamera2d; -pub enum CameraType { - Projection { - fov: f32, - aspect_ratio: f32, - near: f32, - far: f32, - }, - Orthographic { - left: f32, - right: f32, - bottom: f32, - top: f32, - near: f32, - far: f32, - }, +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, + ); + opengl_to_wgpu_matrix() * 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, + } + } +} + +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); + opengl_to_wgpu_matrix() * 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, + } + } +} + +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)] pub struct Camera { pub view_matrix: Mat4, pub camera_type: CameraType, @@ -34,53 +103,20 @@ impl Camera { } pub fn update(&mut self, width: u32, height: u32) { - match &mut self.camera_type { - CameraType::Projection { - aspect_ratio, - fov, - near, - far, - } => { - *aspect_ratio = width as f32 / height as f32; - self.view_matrix = - get_perspective_projection_matrix(*fov, *aspect_ratio, *near, *far) + 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 { - left, - right, - bottom, - top, - near, - far, - } => { - *right = width as f32; - *top = height as f32; - self.view_matrix = - get_orthographic_projection_matrix(*left, *right, *bottom, *top, *near, *far) + CameraType::Orthographic(orthographic) => { + orthographic.right = width as f32; + orthographic.top = height as f32; + orthographic.get_view_matrix() } } } } -pub fn get_perspective_projection_matrix(fov: f32, aspect_ratio: f32, near: f32, far: f32) -> Mat4 { - let projection = Mat4::perspective_rh_gl(fov, aspect_ratio, near, far); - - opengl_to_wgpu_matrix() * projection -} - -pub fn get_orthographic_projection_matrix( - left: f32, - right: f32, - bottom: f32, - top: f32, - near: f32, - far: f32, -) -> Mat4 { - let projection = Mat4::orthographic_rh_gl(left, right, bottom, top, near, far); - - opengl_to_wgpu_matrix() * projection -} - pub fn opengl_to_wgpu_matrix() -> Mat4 { Mat4::from_cols_array(&[ 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 1.0, diff --git a/src/render/light.rs b/src/render/light.rs index d5b467399c..3cc5249210 100644 --- a/src/render/light.rs +++ b/src/render/light.rs @@ -1,5 +1,5 @@ -use super::Color; -use crate::{math, prelude::Translation, render::camera}; +use super::{PerspectiveCamera, Color}; +use crate::{math, prelude::Translation}; use std::ops::Range; use zerocopy::{AsBytes, FromBytes}; @@ -29,12 +29,14 @@ pub struct LightRaw { impl LightRaw { pub fn from(light: &Light, transform: &math::Mat4, translation: &Translation) -> LightRaw { - let proj = camera::get_perspective_projection_matrix( - light.fov, - 1.0, - light.depth.start, - light.depth.end, - ) * *transform; + let perspective = PerspectiveCamera { + fov: light.fov, + aspect_ratio: 1.0, + near: light.depth.start, + far: light.depth.end, + }; + + let proj = perspective.get_view_matrix() * *transform; let (x, y, z) = translation.0.into(); LightRaw { proj: proj.to_cols_array_2d(),