From 4af65ed961165156862d1e2bdd050df4ae36856a Mon Sep 17 00:00:00 2001 From: lisk77 Date: Sat, 8 Mar 2025 02:04:50 +0100 Subject: [PATCH] feat: implemented a priority camera system that searches for the `Entity` with the `Camera2D` component with the smallest priority --- crates/comet_ecs/src/component.rs | 23 +++++++++++++++++++++-- crates/comet_renderer/src/camera.rs | 11 +++++++---- crates/comet_renderer/src/renderer2d.rs | 25 +++++++++++++++++++++---- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/crates/comet_ecs/src/component.rs b/crates/comet_ecs/src/component.rs index f77b99b..bb47b1c 100644 --- a/crates/comet_ecs/src/component.rs +++ b/crates/comet_ecs/src/component.rs @@ -54,6 +54,7 @@ pub struct Render2D { pub struct Camera2D { zoom: f32, dimensions: Vec2, + priority: u8 } // ################################################## @@ -275,10 +276,20 @@ impl Transform3D { } impl Camera2D { - pub fn new(dimensions: Vec2, zoom: f32) -> Self { + /// Creates a Camera2D component. + /// + /// # Parameters + /// - `dimensions`: The dimensions of the camera as a `Vec2` (width, height). + /// - `zoom`: The zoom level of the camera. + /// - `priority`: The priority of the camera, with lower numbers indicating higher priority. + /// + /// # Returns + /// - Returns a `Camera2D` instance. + pub fn new(dimensions: Vec2, zoom: f32, priority: u8) -> Self { Self { dimensions, - zoom + zoom, + priority } } @@ -298,6 +309,14 @@ impl Camera2D { self.dimensions = dimensions; } + pub fn priority(&self) -> u8 { + self.priority + } + + pub fn set_priority(&mut self, priority: u8) { + self.priority = priority; + } + pub fn in_view_frustum(&self, camera_pos: Position2D, entity: Position2D) -> bool { let left = camera_pos.x() - self.zoom; let right = camera_pos.x() + self.zoom; diff --git a/crates/comet_renderer/src/camera.rs b/crates/comet_renderer/src/camera.rs index d3ad19c..86606eb 100644 --- a/crates/comet_renderer/src/camera.rs +++ b/crates/comet_renderer/src/camera.rs @@ -30,10 +30,13 @@ impl Camera { } pub fn build_view_projection_matrix(&self) -> cgmath::Matrix4 { - OPENGL_TO_WGPU_MATRIX * cgmath::ortho(self.position.x() - self.dimension.x() / 2.0, - self.position.x() + self.dimension.x() / 2.0, - self.position.y() - self.dimension.y() / 2.0, - self.position.y() + self.dimension.y() / 2.0, + let zoomed_width = self.dimension.x() / self.zoom; + let zoomed_height = self.dimension.y() / self.zoom; + + OPENGL_TO_WGPU_MATRIX * cgmath::ortho(self.position.x() - zoomed_width / 2.0, + self.position.x() + zoomed_width / 2.0, + self.position.y() - zoomed_height / 2.0, + self.position.y() + zoomed_height / 2.0, 1.0, 0.0) } diff --git a/crates/comet_renderer/src/renderer2d.rs b/crates/comet_renderer/src/renderer2d.rs index f232049..d04f476 100644 --- a/crates/comet_renderer/src/renderer2d.rs +++ b/crates/comet_renderer/src/renderer2d.rs @@ -730,6 +730,17 @@ impl<'a> Renderer2D<'a> { todo!() } + fn find_priority_camera(&self, cameras: Vec) -> usize { + let mut priority = 0; + let mut position = 0; + for (i, camera) in cameras.iter().enumerate() { + if camera.priority() < priority { + position = i; + } + } + + position + } /// A function to automatically render all the entities of the `World` struct. /// The entities must have the `Render2D` and `Transform2D` components to be rendered as well as set visible. pub fn render_scene_2d(&mut self, world: &World) { @@ -739,8 +750,14 @@ impl<'a> Renderer2D<'a> { return; } - let camera_component = world.get_component::(cameras[0]).unwrap(); - let camera_position = world.get_component::(cameras[0]).unwrap().position(); + let cam = cameras.get( + self.find_priority_camera( + cameras.iter().map(|e| *world.get_component::(*e).unwrap() + ).collect::>()) + ).unwrap(); + + let camera_component = world.get_component::(*cam).unwrap(); + let camera_position = world.get_component::(*cam).unwrap().position(); let camera = OldCam::new( camera_component.zoom(), @@ -791,11 +808,11 @@ impl<'a> Renderer2D<'a> { for entity in world.get_entities_with(ComponentSet::from_ids(vec![Transform2D::type_id(), Render2D::type_id()])) { let entity_id = entity as usize; - /*if !camera_component + if !camera_component .in_view_frustum(*camera_position, *world.get_component::(entity_id).unwrap().position()) { continue; - }*/ + } match world.get_component::(entity_id) { Some(render) => {