mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
feat: added the beginnings of a ecs based camera system. render_scene_2d
crashes miserably right now but theoretically everything *should* be in place for a full adoption
This commit is contained in:
parent
a9a8d076ca
commit
4ce24b58dd
5 changed files with 128 additions and 33 deletions
|
@ -4,7 +4,7 @@ use std::sync::atomic::AtomicBool;
|
|||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
use crossbeam_channel::bounded;
|
||||
use comet_ecs::{Component, ComponentSet, Entity, Render, Transform2D, Transform3D, World};
|
||||
use comet_ecs::{Camera2D, Component, ComponentSet, Entity, Render, Render2D, Transform2D, Transform3D, World};
|
||||
use comet_resources::{ResourceManager, Vertex};
|
||||
use comet_renderer::renderer2d::Renderer2D;
|
||||
|
||||
|
@ -98,7 +98,9 @@ impl App {
|
|||
match preset {
|
||||
ApplicationType::App2D => {
|
||||
info!("Creating 2D app!");
|
||||
self.world.register_component::<Transform2D>()
|
||||
self.world.register_component::<Transform2D>();
|
||||
self.world.register_component::<Render2D>();
|
||||
self.world.register_component::<Camera2D>()
|
||||
},
|
||||
ApplicationType::App3D => {
|
||||
info!("Creating 3D app!");
|
||||
|
@ -129,8 +131,8 @@ impl App {
|
|||
self.game_state.as_mut()?.downcast_mut::<T>()
|
||||
}
|
||||
|
||||
pub fn input_manager(&self) -> &WinitInputHelper {
|
||||
&self.input_manager
|
||||
pub fn world(&self) -> &World {
|
||||
&self.world
|
||||
}
|
||||
|
||||
pub fn key_pressed(&self, key: Key) -> bool {
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
// Also just as a nomenclature: bundles are a component made up of multiple components,
|
||||
// so it's a collection of components bundled together (like Transform2D)
|
||||
|
||||
use comet_math::Mat4;
|
||||
use crate::math::{
|
||||
Vec2,
|
||||
Vec3
|
||||
};
|
||||
use component_derive::Component;
|
||||
use crate::Entity;
|
||||
use crate::{Entity, World};
|
||||
|
||||
// ##################################################
|
||||
// # BASIC #
|
||||
|
@ -51,13 +52,8 @@ pub struct Render2D {
|
|||
|
||||
#[derive(Component)]
|
||||
pub struct Camera2D {
|
||||
left: f32,
|
||||
right: f32,
|
||||
bottom: f32,
|
||||
top: f32,
|
||||
near: f32,
|
||||
far: f32,
|
||||
zoom: f32
|
||||
zoom: f32,
|
||||
dimensions: Vec2,
|
||||
}
|
||||
|
||||
// ##################################################
|
||||
|
@ -104,7 +100,8 @@ pub trait Render {
|
|||
}
|
||||
|
||||
pub trait Camera {
|
||||
fn get_visible_entities(&self) -> Vec<Entity>;
|
||||
fn get_visible_entities(&self, camera_position: Position2D, world: World) -> Vec<Entity>;
|
||||
fn get_projection_matrix(&self) -> Mat4;
|
||||
}
|
||||
|
||||
// ##################################################
|
||||
|
@ -278,18 +275,29 @@ impl Transform3D {
|
|||
}
|
||||
|
||||
impl Camera2D {
|
||||
pub fn new(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32, zoom: f32) -> Self {
|
||||
pub fn new(dimensions: Vec2, zoom: f32) -> Self {
|
||||
Self {
|
||||
left,
|
||||
right,
|
||||
bottom,
|
||||
top,
|
||||
near,
|
||||
far,
|
||||
dimensions,
|
||||
zoom
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zoom(&self) -> f32 {
|
||||
self.zoom
|
||||
}
|
||||
|
||||
pub fn set_zoom(&mut self, zoom: f32) {
|
||||
self.zoom = zoom;
|
||||
}
|
||||
|
||||
pub fn dimensions(&self) -> Vec2 {
|
||||
self.dimensions
|
||||
}
|
||||
|
||||
pub fn set_dimensions(&mut self, dimensions: Vec2) {
|
||||
self.dimensions = dimensions;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -301,7 +309,23 @@ impl Camera2D {
|
|||
}
|
||||
|
||||
impl Camera for Camera2D {
|
||||
fn get_visible_entities(&self) -> Vec<Entity> {
|
||||
unimplemented!()
|
||||
fn get_visible_entities(&self, camera_position: Position2D, world: World) -> Vec<Entity> {
|
||||
let entities = world.entities();
|
||||
let mut visible_entities = Vec::new();
|
||||
for entity in entities {
|
||||
if self.in_view_frustum(camera_position, *world.get_component::<Transform2D>(*entity.clone().unwrap().id() as usize).unwrap().position()) {
|
||||
visible_entities.push(entity.clone().unwrap());
|
||||
}
|
||||
}
|
||||
visible_entities
|
||||
}
|
||||
|
||||
fn get_projection_matrix(&self) -> Mat4 {
|
||||
let left = -self.dimensions.x() / 2.0;
|
||||
let right = self.dimensions.x() / 2.0;
|
||||
let bottom = -self.dimensions.y() / 2.0;
|
||||
let top = self.dimensions.y() / 2.0;
|
||||
|
||||
Mat4::OPENGL * Mat4::orthographic_matrix(left, right, bottom, top, 1.0, 0.0)
|
||||
}
|
||||
}
|
|
@ -200,7 +200,10 @@ impl World {
|
|||
|
||||
/// Returns a list of entities that have the given components.
|
||||
pub fn get_entities_with(&self, components: ComponentSet) -> Vec<u32> {
|
||||
assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components);
|
||||
self.archetypes.get_archetype(&components).unwrap().clone()
|
||||
//assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components);
|
||||
if self.archetypes.contains_archetype(&components) {
|
||||
return self.archetypes.get_archetype(&components).unwrap().clone();
|
||||
}
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -528,6 +528,13 @@ impl Mat4 {
|
|||
x30: 0.0, x31: 0.0, x32: 0.0, x33: 1.0
|
||||
};
|
||||
|
||||
pub const OPENGL: Mat4 = Mat4 {
|
||||
x00: 1.0, x01: 0.0, x02: 0.0, x03: 0.0,
|
||||
x10: 0.0, x11: 1.0, x12: 0.0, x13: 0.0,
|
||||
x20: 0.0, x21: 0.0, x22: 0.5, x23: 0.0,
|
||||
x30: 0.0, x31: 0.0, x32: 0.5, x33: 1.0
|
||||
};
|
||||
|
||||
pub const fn new(x00: f32, x01: f32,x02: f32,x03: f32,x10: f32,x11: f32,x12: f32,x13: f32,x20: f32,x21: f32,x22: f32,x23: f32,x30: f32, x31: f32, x32: f32,x33: f32) -> Self {
|
||||
Self {
|
||||
x00, x01, x02, x03,
|
||||
|
|
|
@ -8,12 +8,12 @@ use wgpu::util::DeviceExt;
|
|||
use winit::dpi::PhysicalSize;
|
||||
use winit::window::Window;
|
||||
use comet_colors::LinearRgba;
|
||||
use comet_ecs::{Component, ComponentSet, Render, Render2D, Transform2D, World};
|
||||
use comet_ecs::{Camera, Camera2D, Component, ComponentSet, Render, Render2D, Transform2D, World};
|
||||
use comet_log::{debug, info};
|
||||
use comet_math::{Point3, Vec2, Vec3};
|
||||
use comet_resources::{texture, graphic_resource_manager::GraphicResorceManager, Texture, Vertex};
|
||||
use comet_resources::texture_atlas::TextureRegion;
|
||||
use crate::camera::{Camera, CameraUniform};
|
||||
use crate::camera::{Camera as OldCam, CameraUniform};
|
||||
use crate::render_pass::RenderPassInfo;
|
||||
use crate::renderer::Renderer;
|
||||
|
||||
|
@ -37,7 +37,7 @@ pub struct Renderer2D<'a> {
|
|||
diffuse_texture: texture::Texture,
|
||||
diffuse_bind_group: wgpu::BindGroup,
|
||||
graphic_resource_manager: GraphicResorceManager,
|
||||
camera: Camera,
|
||||
camera: OldCam,
|
||||
camera_uniform: CameraUniform,
|
||||
camera_buffer: wgpu::Buffer,
|
||||
camera_bind_group: wgpu::BindGroup,
|
||||
|
@ -120,7 +120,7 @@ impl<'a> Renderer2D<'a> {
|
|||
|
||||
let diffuse_bytes = include_bytes!(r"../../../resources/textures/comet_icon.png");
|
||||
let diffuse_texture =
|
||||
texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "comet_icon.png", false).unwrap();
|
||||
Texture::from_bytes(&device, &queue, diffuse_bytes, "comet_icon.png", false).unwrap();
|
||||
|
||||
let texture_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
@ -160,7 +160,7 @@ impl<'a> Renderer2D<'a> {
|
|||
label: Some("diffuse_bind_group"),
|
||||
});
|
||||
|
||||
let camera = Camera::new(1.0, Vec2::new(2.0, 2.0), Vec3::new(0.0, 0.0, 0.0));
|
||||
let camera = OldCam::new(1.0, Vec2::new(2.0, 2.0), Vec3::new(0.0, 0.0, 0.0));
|
||||
|
||||
let mut camera_uniform = CameraUniform::new();
|
||||
camera_uniform.update_view_proj(&camera);
|
||||
|
@ -288,9 +288,9 @@ impl<'a> Renderer2D<'a> {
|
|||
diffuse_bind_group,
|
||||
graphic_resource_manager,
|
||||
camera,
|
||||
camera_uniform,
|
||||
camera_buffer,
|
||||
camera_bind_group,
|
||||
camera_uniform,
|
||||
camera_bind_group
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -732,7 +732,66 @@ impl<'a> Renderer2D<'a> {
|
|||
/// 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) {
|
||||
let entities = world.get_entities_with(ComponentSet::from_ids(vec![Render2D::type_id()]));
|
||||
let cameras = world.get_entities_with(ComponentSet::from_ids(vec![Camera2D::type_id()]));
|
||||
|
||||
if cameras == vec![] {
|
||||
info!("No camera found in the scene");
|
||||
return;
|
||||
}
|
||||
|
||||
info!("Camera found in the scene");
|
||||
|
||||
let entities = world.get_entities_with(ComponentSet::from_ids(vec![Transform2D::type_id(), Render2D::type_id()]));
|
||||
|
||||
for camera in cameras {
|
||||
let camera_position = world.get_component::<Transform2D>(camera as usize).unwrap().position();
|
||||
let camera_component = world.get_component::<Camera2D>(camera as usize);
|
||||
let camera = OldCam::new(camera_component.unwrap().zoom(), camera_component.unwrap().dimensions(), Vec3::new(camera_position.as_vec().x(), camera_position.as_vec().y(), 0.0));
|
||||
let mut camera_uniform = CameraUniform::new();
|
||||
camera_uniform.update_view_proj(&camera);
|
||||
|
||||
let camera_buffer = self.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Camera Buffer"),
|
||||
contents: bytemuck::cast_slice(&[camera_uniform]),
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
|
||||
let camera_bind_group_layout =
|
||||
self.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::VERTEX,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
label: Some("camera_bind_group_layout"),
|
||||
});
|
||||
|
||||
let camera_bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &camera_bind_group_layout,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: camera_buffer.as_entire_binding(),
|
||||
}],
|
||||
label: Some("camera_bind_group"),
|
||||
});
|
||||
|
||||
self.camera = camera;
|
||||
self.camera_buffer = camera_buffer;
|
||||
self.camera_uniform = camera_uniform;
|
||||
self.camera_bind_group = camera_bind_group;
|
||||
|
||||
let visible_entities = camera_component.unwrap().get_visible_entities(*camera_position, world.clone());
|
||||
println!("{:?}", visible_entities);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*let entities = world.get_entities_with(ComponentSet::from_ids(vec![Transform2D::type_id(), Render2D::type_id()]));
|
||||
let mut vertex_buffer: Vec<Vertex> = Vec::new();
|
||||
let mut index_buffer: Vec<u16> = Vec::new();
|
||||
|
||||
|
@ -767,7 +826,7 @@ impl<'a> Renderer2D<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
self.set_buffers(vertex_buffer, index_buffer);
|
||||
self.set_buffers(vertex_buffer, index_buffer);*/
|
||||
}
|
||||
|
||||
pub fn update(&mut self) -> f32 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue