mirror of
https://github.com/lisk77/comet.git
synced 2025-10-24 05:48:50 +00:00
feat: added a camera with orthographic projection and did some work restructuring the comet_app to make the setup system optional. Input handling is moved to the app
This commit is contained in:
parent
780365aeb8
commit
5a9f632e3a
22 changed files with 1173 additions and 349 deletions
|
|
@ -26,7 +26,8 @@ instant = "0.1"
|
||||||
image = { version = "0.24", default_features = false, features = ["png", "jpeg", "hdr"] }
|
image = { version = "0.24", default_features = false, features = ["png", "jpeg", "hdr"] }
|
||||||
chrono = "0.4.38"
|
chrono = "0.4.38"
|
||||||
colored = "2.1.0"
|
colored = "2.1.0"
|
||||||
|
winit_input_helper = "0.16.0"
|
||||||
|
spin_sleep = "1.2.1"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
|
@ -43,7 +44,7 @@ members = [
|
||||||
"./crates/comet_ecs",
|
"./crates/comet_ecs",
|
||||||
"./crates/comet_input",
|
"./crates/comet_input",
|
||||||
"./crates/comet_log"
|
"./crates/comet_log"
|
||||||
]
|
, "crates/comet_ui"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
comet_app = { path = "./crates/comet_app", workspace = true }
|
comet_app = { path = "./crates/comet_app", workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "comet_app"
|
name = "comet_app"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
@ -9,6 +9,7 @@ comet_renderer = { path = "../comet_renderer" }
|
||||||
comet_resources = { path = "../comet_resources" }
|
comet_resources = { path = "../comet_resources" }
|
||||||
comet_colors = { path = "../comet_colors" }
|
comet_colors = { path = "../comet_colors" }
|
||||||
comet_log = { path = "../comet_log" }
|
comet_log = { path = "../comet_log" }
|
||||||
|
comet_input = { path = "../comet_input" }
|
||||||
|
|
||||||
winit = { version = "0.29", features = ["rwh_05"] }
|
winit = { version = "0.29", features = ["rwh_05"] }
|
||||||
env_logger = "0.10"
|
env_logger = "0.10"
|
||||||
|
|
@ -18,6 +19,8 @@ log = "0.4.22"
|
||||||
anyhow = "1.0.89"
|
anyhow = "1.0.89"
|
||||||
bytemuck = "1.18.0"
|
bytemuck = "1.18.0"
|
||||||
chrono = "0.4.0"
|
chrono = "0.4.0"
|
||||||
|
winit_input_helper = "0.16.0"
|
||||||
|
spin_sleep = "1.2.1"
|
||||||
|
|
||||||
[dependencies.image]
|
[dependencies.image]
|
||||||
version = "0.24"
|
version = "0.24"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
||||||
use comet_resources::{ResourceManager, Vertex};
|
use comet_resources::{ResourceManager, Vertex};
|
||||||
use comet_renderer::{Renderer};
|
use comet_renderer::{Renderer};
|
||||||
|
|
@ -13,6 +14,11 @@ use comet_colors::LinearRgba;
|
||||||
use comet_ecs::math::Point3;
|
use comet_ecs::math::Point3;
|
||||||
use comet_log::*;
|
use comet_log::*;
|
||||||
use winit::dpi::{LogicalSize, PhysicalSize};
|
use winit::dpi::{LogicalSize, PhysicalSize};
|
||||||
|
use winit::event_loop::ControlFlow;
|
||||||
|
use winit::platform::windows::WindowBuilderExtWindows;
|
||||||
|
use winit_input_helper::WinitInputHelper;
|
||||||
|
use comet_input::input_handler::InputHandler;
|
||||||
|
use comet_input::keyboard::Key;
|
||||||
|
|
||||||
pub enum ApplicationType {
|
pub enum ApplicationType {
|
||||||
App2D,
|
App2D,
|
||||||
|
|
@ -24,6 +30,10 @@ pub struct App<'a> {
|
||||||
icon: Option<Icon>,
|
icon: Option<Icon>,
|
||||||
size: Option<LogicalSize<u32>>,
|
size: Option<LogicalSize<u32>>,
|
||||||
clear_color: Option<LinearRgba>,
|
clear_color: Option<LinearRgba>,
|
||||||
|
setup: Option<fn(&mut World)>,
|
||||||
|
input_manager: WinitInputHelper,
|
||||||
|
delta_time: f32,
|
||||||
|
update_timer: f32,
|
||||||
world: World,
|
world: World,
|
||||||
fullscreen: bool,
|
fullscreen: bool,
|
||||||
should_quit: bool
|
should_quit: bool
|
||||||
|
|
@ -41,6 +51,10 @@ impl<'a> App<'a> {
|
||||||
icon: None,
|
icon: None,
|
||||||
size: None,
|
size: None,
|
||||||
clear_color: None,
|
clear_color: None,
|
||||||
|
setup: None,
|
||||||
|
input_manager: WinitInputHelper::new(),
|
||||||
|
delta_time: 0.0,
|
||||||
|
update_timer: 0.0166667,
|
||||||
world,
|
world,
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
should_quit: false
|
should_quit: false
|
||||||
|
|
@ -67,6 +81,11 @@ impl<'a> App<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_setup(mut self, setup: fn(&mut World)) -> Self {
|
||||||
|
self.setup = Some(setup);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn load_icon(path: &std::path::Path) -> Option<Icon> {
|
fn load_icon(path: &std::path::Path) -> Option<Icon> {
|
||||||
let image = image::open(path).expect("Failed to open icon image");
|
let image = image::open(path).expect("Failed to open icon image");
|
||||||
let rgba_image = image.to_rgba8();
|
let rgba_image = image.to_rgba8();
|
||||||
|
|
@ -74,51 +93,6 @@ impl<'a> App<'a> {
|
||||||
Some(Icon::from_rgba(rgba_image.into_raw(), width, height).unwrap())
|
Some(Icon::from_rgba(rgba_image.into_raw(), width, height).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_scene_2d(&self, renderer: &mut Renderer) {
|
|
||||||
let entities = self.world.get_entities_with(ComponentSet::from_ids(vec![Renderer2D::type_id()]));
|
|
||||||
let mut vertex_buffer: Vec<Vertex> = Vec::new();
|
|
||||||
let mut index_buffer: Vec<u16> = Vec::new();
|
|
||||||
|
|
||||||
for entity in entities {
|
|
||||||
let renderer_component = self.world().get_component::<Renderer2D>(entity as usize);
|
|
||||||
let transform_component = self.world().get_component::<Transform2D>(entity as usize);
|
|
||||||
|
|
||||||
if renderer_component.is_visible() {
|
|
||||||
//renderer.draw_texture_at(renderer_component.get_texture(), Point3::new(transform_component.position().x(), transform_component.position().y(), 0.0));
|
|
||||||
let position = transform_component.position();
|
|
||||||
let region = renderer.get_texture(renderer_component.get_texture().to_string());
|
|
||||||
let (dim_x, dim_y) = region.dimensions();
|
|
||||||
|
|
||||||
let (bound_x, bound_y) =
|
|
||||||
((dim_x as f32/ renderer.config().width as f32) * 0.5, (dim_y as f32/ renderer.config().height as f32) * 0.5);
|
|
||||||
|
|
||||||
let buffer_size = vertex_buffer.len() as u16;
|
|
||||||
|
|
||||||
vertex_buffer.append(&mut vec![
|
|
||||||
Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0], [region.x0(), region.y0()] ),
|
|
||||||
Vertex :: new ( [-bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x0(), region.y1()] ),
|
|
||||||
Vertex :: new ( [ bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x1(), region.y1()] ) ,
|
|
||||||
Vertex :: new ( [ bound_x + position.x(), bound_y + position.y(), 0.0], [region.x1(), region.y0()] )
|
|
||||||
]);
|
|
||||||
|
|
||||||
index_buffer.append(&mut vec![
|
|
||||||
0 + buffer_size, 1 + buffer_size, 3 + buffer_size,
|
|
||||||
1 + buffer_size, 2 + buffer_size, 3 + buffer_size
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.set_buffers(vertex_buffer, index_buffer);
|
|
||||||
|
|
||||||
/*for entity in entities {
|
|
||||||
let renderer_component = self.world.get_component::<Renderer2D>(entity as usize);
|
|
||||||
let position_component = self.world.get_component::<Transform2D>(entity as usize);
|
|
||||||
if renderer_component.is_visible() {
|
|
||||||
renderer.draw_texture_at(renderer_component.get_texture(), Point3::new(position_component.position().x(), position_component.position().y(), 0.0));
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn world(&self) -> &World {
|
pub fn world(&self) -> &World {
|
||||||
&self.world
|
&self.world
|
||||||
}
|
}
|
||||||
|
|
@ -127,10 +101,37 @@ impl<'a> App<'a> {
|
||||||
&mut self.world
|
&mut self.world
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn input_manager(&self) -> &WinitInputHelper {
|
||||||
|
&self.input_manager
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_pressed(&self, key: Key) -> bool {
|
||||||
|
self.input_manager.key_pressed(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_held(&self, key: Key) -> bool {
|
||||||
|
self.input_manager.key_held(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_released(&self, key: Key) -> bool {
|
||||||
|
self.input_manager.key_released(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dt(&self) -> f32 {
|
||||||
|
self.delta_time
|
||||||
|
}
|
||||||
|
|
||||||
pub fn quit(&mut self) {
|
pub fn quit(&mut self) {
|
||||||
self.should_quit = true;
|
self.should_quit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_time_step(&self) -> f32 {
|
||||||
|
self.update_timer
|
||||||
|
}
|
||||||
|
pub fn set_time_step(&mut self, time_step: f32) {
|
||||||
|
self.update_timer = time_step;
|
||||||
|
}
|
||||||
|
|
||||||
fn create_window(app_title: &str, app_icon: &Option<Icon>, window_size: &Option<LogicalSize<u32>>, event_loop: &EventLoop<()>) -> winit::window::Window {
|
fn create_window(app_title: &str, app_icon: &Option<Icon>, window_size: &Option<LogicalSize<u32>>, event_loop: &EventLoop<()>) -> winit::window::Window {
|
||||||
let winit_window = winit::window::WindowBuilder::new()
|
let winit_window = winit::window::WindowBuilder::new()
|
||||||
.with_title(app_title);
|
.with_title(app_title);
|
||||||
|
|
@ -141,6 +142,13 @@ impl<'a> App<'a> {
|
||||||
else {
|
else {
|
||||||
winit_window
|
winit_window
|
||||||
};
|
};
|
||||||
|
let winit_window = if let Some(icon) = app_icon.clone() {
|
||||||
|
winit_window.with_taskbar_icon(Some(icon))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
winit_window
|
||||||
|
};
|
||||||
|
|
||||||
let winit_window = if let Some(size) = window_size.clone() {
|
let winit_window = if let Some(size) = window_size.clone() {
|
||||||
winit_window.with_inner_size(size)
|
winit_window.with_inner_size(size)
|
||||||
}
|
}
|
||||||
|
|
@ -151,66 +159,64 @@ impl<'a> App<'a> {
|
||||||
winit_window.build(event_loop).unwrap()
|
winit_window.build(event_loop).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_app<F: Fn(&WindowEvent, &mut App, &mut Renderer), G: Fn(&mut World, &mut Renderer)>(mut self, input_manager: F, game_manager: G) {
|
async fn run_app<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
||||||
env_logger::init();
|
|
||||||
let event_loop = EventLoop::new().unwrap();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let window = Self::create_window(self.title, &self.icon, &self.size ,&event_loop);
|
let window = Self::create_window(self.title, &self.icon, &self.size ,&event_loop);
|
||||||
|
|
||||||
let mut renderer = Renderer::new(&window, self.clear_color.clone()).await.unwrap();
|
let mut renderer = Renderer::new(&window, self.clear_color.clone()).await.unwrap();
|
||||||
let mut surface_configured = false;
|
|
||||||
|
|
||||||
window.set_maximized(true);
|
window.set_maximized(true);
|
||||||
|
|
||||||
|
if let Some(setup) = self.setup {
|
||||||
|
setup(&mut self.world);
|
||||||
|
}
|
||||||
|
|
||||||
renderer.initialize_atlas();
|
renderer.initialize_atlas();
|
||||||
|
|
||||||
event_loop.run(|event, control_flow| {
|
let mut time_stack = 0.0;
|
||||||
|
|
||||||
|
event_loop.run(|event, elwt| {
|
||||||
|
self.delta_time = renderer.update();
|
||||||
|
|
||||||
if self.should_quit {
|
if self.should_quit {
|
||||||
control_flow.exit()
|
elwt.exit()
|
||||||
}
|
}
|
||||||
game_manager(&mut self.world, &mut renderer);
|
|
||||||
self.render_scene_2d(&mut renderer);
|
self.input_manager.update(&event);
|
||||||
|
|
||||||
|
time_stack += self.delta_time;
|
||||||
|
while time_stack > self.update_timer {
|
||||||
|
let time = self.get_time_step();
|
||||||
|
update(&mut self, &mut renderer, time);
|
||||||
|
time_stack -= self.update_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.render_scene_2d(self.world());
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent {
|
Event::WindowEvent { ref event, window_id, }
|
||||||
ref event,
|
if window_id == renderer.window().id() => {
|
||||||
window_id,
|
|
||||||
} if window_id == renderer.window().id() => {
|
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::CloseRequested {} => control_flow.exit(),
|
WindowEvent::CloseRequested {} => elwt.exit(),
|
||||||
WindowEvent::Resized(physical_size) => {
|
WindowEvent::Resized(physical_size) => {
|
||||||
surface_configured = true;
|
|
||||||
renderer.resize(*physical_size);
|
renderer.resize(*physical_size);
|
||||||
}
|
}
|
||||||
WindowEvent::RedrawRequested => {
|
WindowEvent::RedrawRequested => {
|
||||||
renderer.window().request_redraw();
|
renderer.window().request_redraw();
|
||||||
|
|
||||||
if !surface_configured {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if self.fullscreen && !renderer.window().fullscreen().is_some() {
|
|
||||||
renderer.resize(renderer.window().inner_size().into());
|
|
||||||
}*/
|
|
||||||
|
|
||||||
renderer.update();
|
|
||||||
//println!("{}", 1.0/dt);
|
|
||||||
match renderer.render() {
|
match renderer.render() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(
|
Err(
|
||||||
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
|
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
|
||||||
) => renderer.resize(renderer.size()),
|
) => renderer.resize(renderer.size()),
|
||||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||||
log::error!("OutOfMemory");
|
error!("OutOfMemory");
|
||||||
control_flow.exit();
|
elwt.exit();
|
||||||
}
|
}
|
||||||
Err(wgpu::SurfaceError::Timeout) => {
|
Err(wgpu::SurfaceError::Timeout) => {
|
||||||
warn!("Surface timeout")
|
warn!("Surface timeout")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
input_manager(event, &mut self, &mut renderer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -218,7 +224,7 @@ impl<'a> App<'a> {
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F: Fn(&WindowEvent, &mut App, &mut Renderer), G: Fn(&mut World, &mut Renderer)>(mut self, input_manager: F, game_manager: G) {
|
pub fn run<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
||||||
pollster::block_on(self.run_app(input_manager, game_manager));
|
pollster::block_on(self.run_app(update));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,9 +4,10 @@ version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bit-set = "0.8.0"
|
|
||||||
component_derive = { path = "./component_derive" }
|
component_derive = { path = "./component_derive" }
|
||||||
comet_math = { path = "../comet_math" }
|
comet_math = { path = "../comet_math" }
|
||||||
comet_resources = { path = "../comet_resources" }
|
comet_resources = { path = "../comet_resources" }
|
||||||
comet_log = { path = "../comet_log" }
|
comet_log = { path = "../comet_log" }
|
||||||
|
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
bit-set = "0.8.0"
|
||||||
|
|
@ -1,22 +1,11 @@
|
||||||
//use comet_resources::Vertex;
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
use crate::math::{
|
use crate::math::{
|
||||||
Vec2,
|
Vec2,
|
||||||
Vec3
|
Vec3
|
||||||
};
|
};
|
||||||
use component_derive::Component;
|
use component_derive::Component;
|
||||||
|
|
||||||
pub trait Component: Send + Sync + PartialEq + Default + 'static {
|
|
||||||
fn new() -> Self where Self: Sized;
|
|
||||||
|
|
||||||
fn type_id() -> std::any::TypeId {
|
|
||||||
std::any::TypeId::of::<Self>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn type_name() -> String {
|
|
||||||
std::any::type_name::<Self>().to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ##################################################
|
// ##################################################
|
||||||
// # BASIC #
|
// # BASIC #
|
||||||
// ##################################################
|
// ##################################################
|
||||||
|
|
@ -43,6 +32,12 @@ pub struct Rotation3D {
|
||||||
theta_z: f32
|
theta_z: f32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Rectangle2D{
|
||||||
|
position: Position2D,
|
||||||
|
size: Vec2
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Renderer2D {
|
pub struct Renderer2D {
|
||||||
is_visible: bool,
|
is_visible: bool,
|
||||||
|
|
@ -50,6 +45,53 @@ pub struct Renderer2D {
|
||||||
scale: Vec2
|
scale: Vec2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ##################################################
|
||||||
|
// # BUNDLES #
|
||||||
|
// ##################################################
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Transform2D {
|
||||||
|
position: Position2D,
|
||||||
|
rotation: Rotation2D
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Transform3D {
|
||||||
|
position: Position3D,
|
||||||
|
rotation: Rotation3D
|
||||||
|
}
|
||||||
|
|
||||||
|
// ##################################################
|
||||||
|
// # TRAITS #
|
||||||
|
// ##################################################
|
||||||
|
|
||||||
|
pub trait Component: Send + Sync + PartialEq + Default + 'static {
|
||||||
|
fn new() -> Self where Self: Sized;
|
||||||
|
|
||||||
|
fn type_id() -> std::any::TypeId {
|
||||||
|
std::any::TypeId::of::<Self>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name() -> String {
|
||||||
|
std::any::type_name::<Self>().to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Collider {
|
||||||
|
fn is_colliding(&self, other: &Self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Render {
|
||||||
|
fn is_visible(&self) -> bool;
|
||||||
|
fn set_visibility(&mut self, is_visible: bool);
|
||||||
|
fn get_texture(&self) -> String;
|
||||||
|
fn set_texture(&mut self, texture: &'static str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ##################################################
|
||||||
|
// # IMPLS #
|
||||||
|
// ##################################################
|
||||||
|
|
||||||
impl Position2D {
|
impl Position2D {
|
||||||
pub fn from_vec(vec: Vec2) -> Self {
|
pub fn from_vec(vec: Vec2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -114,12 +156,44 @@ impl Position3D {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Render {
|
impl Rectangle2D {
|
||||||
fn is_visible(&self) -> bool;
|
pub fn new(position: Position2D, size: Vec2) -> Self {
|
||||||
fn set_visibility(&mut self, is_visible: bool);
|
Self {
|
||||||
fn get_texture(&self) -> String;
|
position,
|
||||||
fn set_texture(&mut self, texture: &'static str);
|
size
|
||||||
//fn get_vertex_data(&self) -> Vec<Vertex>;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn position(&self) -> Position2D {
|
||||||
|
self.position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_position(&mut self, position: Position2D) {
|
||||||
|
self.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> Vec2 {
|
||||||
|
self.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Collider for Rectangle2D {
|
||||||
|
fn is_colliding(&self, other: &Self) -> bool {
|
||||||
|
let x1 = self.position().x();
|
||||||
|
let y1 = self.position().y();
|
||||||
|
let w1 = self.size().x();
|
||||||
|
let h1 = self.size().y();
|
||||||
|
|
||||||
|
let x2 = other.position().x();
|
||||||
|
let y2 = other.position().y();
|
||||||
|
let w2 = other.size().x();
|
||||||
|
let h2 = other.size().y();
|
||||||
|
|
||||||
|
x1 < x2 + w2 &&
|
||||||
|
x1 + w1 > x2 &&
|
||||||
|
y1 < y2 + h2 &&
|
||||||
|
y1 + h1 > y2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for Renderer2D {
|
impl Render for Renderer2D {
|
||||||
|
|
@ -141,31 +215,6 @@ impl Render for Renderer2D {
|
||||||
fn set_texture(&mut self, texture: &'static str) {
|
fn set_texture(&mut self, texture: &'static str) {
|
||||||
self.texture = texture;
|
self.texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fn get_vertex_data(&self) -> Vec<Vertex> {
|
|
||||||
vec![
|
|
||||||
Vertex::new([0.0, 0.0, 0.0], [0.0, 0.0]),
|
|
||||||
Vertex::new([1.0, 0.0, 0.0], [1.0, 0.0]),
|
|
||||||
Vertex::new([1.0, 1.0, 0.0], [1.0, 1.0]),
|
|
||||||
Vertex::new([0.0, 1.0, 0.0], [0.0, 1.0])
|
|
||||||
]
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// ##################################################
|
|
||||||
// # BUNDLES #
|
|
||||||
// ##################################################
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct Transform2D {
|
|
||||||
position: Position2D,
|
|
||||||
rotation: Rotation2D
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct Transform3D {
|
|
||||||
position: Position3D,
|
|
||||||
rotation: Rotation3D
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transform2D {
|
impl Transform2D {
|
||||||
|
|
@ -184,6 +233,13 @@ impl Transform2D {
|
||||||
pub fn rotation_mut(&mut self) -> &mut Rotation2D {
|
pub fn rotation_mut(&mut self) -> &mut Rotation2D {
|
||||||
&mut self.rotation
|
&mut self.rotation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn translate(&mut self, displacement: Vec2) {
|
||||||
|
let x = self.position().x() + displacement.x();
|
||||||
|
let y = self.position().y() + displacement.y();
|
||||||
|
self.position_mut().set_x(x);
|
||||||
|
self.position_mut().set_y(y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transform3D {
|
impl Transform3D {
|
||||||
|
|
@ -203,5 +259,3 @@ impl Transform3D {
|
||||||
&mut self.rotation
|
&mut self.rotation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,16 +23,16 @@ pub struct World {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
pub fn new(dimension: &str) -> Self {
|
pub fn new(application: &str) -> Self {
|
||||||
let mut component_storage = ComponentStorage::new();
|
let mut component_storage = ComponentStorage::new();
|
||||||
match dimension {
|
match application {
|
||||||
"2D" => component_storage.register_component::<Transform2D>(0),
|
"2D" => component_storage.register_component::<Transform2D>(0),
|
||||||
"3D" => component_storage.register_component::<Transform3D>(0),
|
"3D" => component_storage.register_component::<Transform3D>(0),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
dimension: dimension.to_string(),
|
dimension: application.to_string(),
|
||||||
id_queue: IdQueue::new(),
|
id_queue: IdQueue::new(),
|
||||||
next_id: 0,
|
next_id: 0,
|
||||||
entities: Vec::new(),
|
entities: Vec::new(),
|
||||||
|
|
@ -118,7 +118,7 @@ impl World {
|
||||||
self.id_queue.sorted_enqueue(entity_id as u32);
|
self.id_queue.sorted_enqueue(entity_id as u32);
|
||||||
self.get_next_id();
|
self.get_next_id();
|
||||||
self.remove_entity_from_archetype_subsets(entity_id as u32, self.get_component_set(entity_id));
|
self.remove_entity_from_archetype_subsets(entity_id as u32, self.get_component_set(entity_id));
|
||||||
info!(format!("Deleted entity! ID: {}", entity_id));
|
info!("Deleted entity! ID: {}", entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_archetype(&mut self, components: ComponentSet) {
|
fn create_archetype(&mut self, components: ComponentSet) {
|
||||||
|
|
@ -179,12 +179,12 @@ impl World {
|
||||||
pub fn register_component<T: Component + 'static>(&mut self) {
|
pub fn register_component<T: Component + 'static>(&mut self) {
|
||||||
self.components.register_component::<T>(self.entities.len());
|
self.components.register_component::<T>(self.entities.len());
|
||||||
self.create_archetype(ComponentSet::from_ids(vec![T::type_id()]));
|
self.create_archetype(ComponentSet::from_ids(vec![T::type_id()]));
|
||||||
info!(format!("Registered component: {}", T::type_name()));
|
info!("Registered component: {}", T::type_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deregister_component<T: Component + 'static>(&mut self) {
|
pub fn deregister_component<T: Component + 'static>(&mut self) {
|
||||||
self.components.deregister_component::<T>();
|
self.components.deregister_component::<T>();
|
||||||
info!(format!("Deregistered component: {}", T::type_name()));
|
info!("Deregistered component: {}", T::type_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_component<T: Component + 'static>(&mut self, entity_id: usize, component: T) {
|
pub fn add_component<T: Component + 'static>(&mut self, entity_id: usize, component: T) {
|
||||||
|
|
@ -201,14 +201,13 @@ impl World {
|
||||||
if self.get_component_set(entity_id) != ComponentSet::from_ids(vec![T::type_id()]) {
|
if self.get_component_set(entity_id) != ComponentSet::from_ids(vec![T::type_id()]) {
|
||||||
self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id));
|
self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id));
|
||||||
}
|
}
|
||||||
info!(format!("Added component {} to entity {}", T::type_name(), entity_id));
|
info!("Added component {} to entity {}", T::type_name(), entity_id);
|
||||||
debug!(format!("{:?}", self.archetypes));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_component<T: Component + 'static>(&mut self, entity_id: usize) {
|
pub fn remove_component<T: Component + 'static>(&mut self, entity_id: usize) {
|
||||||
self.components.remove_component::<T>(entity_id);
|
self.components.remove_component::<T>(entity_id);
|
||||||
self.remove_entity_from_archetype_subsets(entity_id as u32, self.get_component_set(entity_id));
|
self.remove_entity_from_archetype_subsets(entity_id as u32, self.get_component_set(entity_id));
|
||||||
info!(format!("Removed component {} from entity {}", T::type_name(), entity_id));
|
info!("Removed component {} from entity {}", T::type_name(), entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_component<T: Component + 'static>(&self, entity_id: usize) -> &T {
|
pub fn get_component<T: Component + 'static>(&self, entity_id: usize) -> &T {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
[package]
|
[package]
|
||||||
name = "comet_input"
|
name = "comet_input"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
winit = { version = "0.29", features = ["rwh_05"] }
|
winit = { version = "0.29", features = ["rwh_05"] }
|
||||||
|
winit_input_helper = "0.16.0"
|
||||||
|
|
|
||||||
73
crates/comet_input/src/input_handler.rs
Normal file
73
crates/comet_input/src/input_handler.rs
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
use winit::event::{ElementState, WindowEvent, KeyEvent, Event};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use winit::event::WindowEvent::KeyboardInput;
|
||||||
|
use winit::keyboard::PhysicalKey;
|
||||||
|
use crate::keyboard::Key;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InputHandler {
|
||||||
|
keys_pressed: Vec<PhysicalKey>,
|
||||||
|
keys_held: Vec<PhysicalKey>,
|
||||||
|
keys_released: Vec<PhysicalKey>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputHandler {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
keys_pressed: Vec::new(),
|
||||||
|
keys_held: Vec::new(),
|
||||||
|
keys_released: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update<T>(&mut self, event: &Event<T>) {
|
||||||
|
match event {
|
||||||
|
Event::WindowEvent {
|
||||||
|
event: WindowEvent::KeyboardInput {
|
||||||
|
event: KeyEvent {
|
||||||
|
state,
|
||||||
|
physical_key: PhysicalKey::Code(keycode),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} =>
|
||||||
|
{
|
||||||
|
match state {
|
||||||
|
ElementState::Pressed => {
|
||||||
|
if self.keys_pressed.contains(&PhysicalKey::Code(keycode.clone())) {
|
||||||
|
self.keys_held.push(PhysicalKey::Code(keycode.clone()));
|
||||||
|
} else {
|
||||||
|
self.keys_pressed.push(PhysicalKey::Code(keycode.clone()));
|
||||||
|
}
|
||||||
|
self.keys_pressed.push(PhysicalKey::Code(keycode.clone()));
|
||||||
|
}
|
||||||
|
ElementState::Released => {
|
||||||
|
self.keys_released = vec![];
|
||||||
|
if let Some(index) = self.keys_pressed.iter().position(|&x| x == PhysicalKey::Code(keycode.clone())) {
|
||||||
|
self.keys_pressed.remove(index);
|
||||||
|
}
|
||||||
|
if let Some(index) = self.keys_held.iter().position(|&x| x == PhysicalKey::Code(keycode.clone())) {
|
||||||
|
self.keys_held.remove(index);
|
||||||
|
}
|
||||||
|
self.keys_released.push(PhysicalKey::Code(keycode.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_pressed(&self, key: Key) -> bool {
|
||||||
|
self.keys_pressed.contains(&PhysicalKey::Code(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_held(&self, key: Key) -> bool {
|
||||||
|
self.keys_held.contains(&PhysicalKey::Code(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_released(&self, key: Key) -> bool {
|
||||||
|
self.keys_released.contains(&PhysicalKey::Code(key))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -30,3 +30,17 @@ pub fn key_released(event: &WindowEvent, key_code: Key) -> bool {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn key_press(event: &WindowEvent, key_code: Key) -> bool {
|
||||||
|
match event {
|
||||||
|
WindowEvent::KeyboardInput {
|
||||||
|
event: KeyEvent {
|
||||||
|
state: ElementState::Pressed,
|
||||||
|
physical_key: PhysicalKey::Code(code),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => *code == key_code,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
pub mod mouse;
|
pub mod mouse;
|
||||||
|
pub mod input_handler;
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,83 @@
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! info {
|
macro_rules! info {
|
||||||
($msg:expr) => {
|
($fmt:expr $(, $args:expr)*) => {
|
||||||
println!(
|
eprintln!(
|
||||||
"{} {} : {}",
|
"{} [{}::{}] [{}] : {}",
|
||||||
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
std::env::var("CARGO_PKG_NAME").unwrap(),
|
||||||
|
module_path!(),
|
||||||
"\x1b[32m\x1b[1mINFO\x1b[0m",
|
"\x1b[32m\x1b[1mINFO\x1b[0m",
|
||||||
$msg
|
format!($fmt $(, $args)*)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! debug {
|
macro_rules! debug {
|
||||||
($msg:expr) => {
|
($fmt:expr $(, $args:expr)*) => {
|
||||||
println!(
|
eprintln!(
|
||||||
"{} {} : {}",
|
"{} [{}::{}] [{}] : {}",
|
||||||
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
std::env::var("CARGO_PKG_NAME").unwrap(),
|
||||||
|
module_path!(),
|
||||||
"\x1b[34m\x1b[1mDEBUG\x1b[0m",
|
"\x1b[34m\x1b[1mDEBUG\x1b[0m",
|
||||||
$msg
|
format!($fmt $(, $args)*)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! warn {
|
macro_rules! warn {
|
||||||
($msg:expr) => {
|
($fmt:expr $(, $args:expr)*) => {
|
||||||
println!(
|
eprintln!(
|
||||||
"{} {} : {}",
|
"{} [{}::{}] [{}] : {}",
|
||||||
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
std::env::var("CARGO_PKG_NAME").unwrap(),
|
||||||
|
module_path!(),
|
||||||
"\x1b[33m\x1b[1mWARNING\x1b[0m",
|
"\x1b[33m\x1b[1mWARNING\x1b[0m",
|
||||||
$msg
|
format!($fmt $(, $args)*)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! error {
|
macro_rules! error {
|
||||||
($msg:expr) => {
|
($fmt:expr $(, $args:expr)*) => {
|
||||||
println!(
|
eprintln!(
|
||||||
"{} {} : {}",
|
"{} [{}::{}] [{}] : {}",
|
||||||
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
std::env::var("CARGO_PKG_NAME").unwrap(),
|
||||||
|
module_path!(),
|
||||||
"\x1b[31m\x1b[1mERROR\x1b[0m",
|
"\x1b[31m\x1b[1mERROR\x1b[0m",
|
||||||
$msg
|
format!($fmt $(, $args)*)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! fatal {
|
||||||
|
($fmt:expr $(, $args:expr)*) => {
|
||||||
|
eprintln!(
|
||||||
|
"{} [{}::{}] [{}] : {}",
|
||||||
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
std::env::var("CARGO_PKG_NAME").unwrap(),
|
||||||
|
module_path!(),
|
||||||
|
"\x1b[41mFATAL\x1b[0m",
|
||||||
|
format!($fmt $(, $args)*)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! trace {
|
||||||
|
($fmt:expr $(, $args:expr)*) => {
|
||||||
|
eprintln!(
|
||||||
|
"{} [{}::{}] [{}] : {}",
|
||||||
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
std::env::var("CARGO_PKG_NAME").unwrap(),
|
||||||
|
module_path!(),
|
||||||
|
"\x1b[35m\x1b[1mTRACE\x1b[0m",
|
||||||
|
format!($fmt $(, $args)*)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
[package]
|
[package]
|
||||||
name = "comet_math"
|
name = "comet_math"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
comet_log = { path = "../comet_log" }
|
||||||
num-traits = "0.2.19"
|
num-traits = "0.2.19"
|
||||||
|
chrono = "0.4.0"
|
||||||
|
|
@ -11,7 +11,7 @@ trait LinearTransformation {
|
||||||
// ##################################################
|
// ##################################################
|
||||||
|
|
||||||
|
|
||||||
/// Representation of a 2x2 Matrix in row major
|
/// Representation of a 2x2 Matrix
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
|
@ -39,13 +39,20 @@ impl Mat2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_vec(row1: Vec2, row2: Vec2) -> Self {
|
pub fn from_rows(row1: Vec2, row2: Vec2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x00: row1.x(), x01: row1.y(),
|
x00: row1.x(), x01: row1.y(),
|
||||||
x10: row2.x(), x11: row2.y()
|
x10: row2.x(), x11: row2.y()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_cols(col1: Vec2, col2: Vec2) -> Self {
|
||||||
|
Self {
|
||||||
|
x00: col1.x(), x01: col2.x(),
|
||||||
|
x10: col1.y(), x11: col2.y()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, row: usize, col: usize) -> Option<f32> {
|
pub fn get(&self, row: usize, col: usize) -> Option<f32> {
|
||||||
assert!(row <= 1, "This row ({}) is out of bounds! Bounds: 0..1", row);
|
assert!(row <= 1, "This row ({}) is out of bounds! Bounds: 0..1", row);
|
||||||
assert!(col <= 1, "This row ({}) is out of bounds! Bounds: 0..1", col);
|
assert!(col <= 1, "This row ({}) is out of bounds! Bounds: 0..1", col);
|
||||||
|
|
@ -68,6 +75,15 @@ impl Mat2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_col(&self, col: usize) -> Option<Vec2> {
|
||||||
|
assert!(col <= 1, "This row ({}) is out of bounds! Bounds: 0..1", col);
|
||||||
|
match col {
|
||||||
|
0 => Some(Vec2::new(self.x00, self.x10)),
|
||||||
|
1 => Some(Vec2::new(self.x01, self.x11)),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, row: usize, col: usize, element: f32) {
|
pub fn set(&mut self, row: usize, col: usize, element: f32) {
|
||||||
assert!(row <= 1, "This row ({}) is out of bounds! Bounds: 0..1", row);
|
assert!(row <= 1, "This row ({}) is out of bounds! Bounds: 0..1", row);
|
||||||
assert!(col <= 1, "This row ({}) is out of bounds! Bounds: 0..1", col);
|
assert!(col <= 1, "This row ({}) is out of bounds! Bounds: 0..1", col);
|
||||||
|
|
@ -91,6 +107,16 @@ impl Mat2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_col(&mut self, col: usize, col_content: Vec2) {
|
||||||
|
assert!(col <= 1, "This row ({}) is out of bounds! Bounds: 0..1", col);
|
||||||
|
|
||||||
|
match col {
|
||||||
|
0 => { self.x00 = col_content.x(); self.x10 = col_content.y(); },
|
||||||
|
1 => { self.x01 = col_content.x(); self.x11 = col_content.y(); },
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn det(&self) -> f32 {
|
pub fn det(&self) -> f32 {
|
||||||
self.x00 * self.x11
|
self.x00 * self.x11
|
||||||
- self.x01 * self.x10
|
- self.x01 * self.x10
|
||||||
|
|
@ -108,6 +134,12 @@ impl Mat2 {
|
||||||
self.set_row(row1, self.get_row(row2).expect(format!("This row ({}) is out of bounds! Bounds: 0..1", row2).as_str()));
|
self.set_row(row1, self.get_row(row2).expect(format!("This row ({}) is out of bounds! Bounds: 0..1", row2).as_str()));
|
||||||
self.set_row(row2, tmp);
|
self.set_row(row2, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn swap_cols(&mut self, col1: usize, col2: usize) {
|
||||||
|
let tmp = self.get_col(col1).expect(format!("This row ({}) is out of bounds! Bounds: 0..1", col1).as_str());
|
||||||
|
self.set_col(col1, self.get_col(col2).expect(format!("This row ({}) is out of bounds! Bounds: 0..1", col2).as_str()));
|
||||||
|
self.set_col(col2, tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<Mat2> for Mat2 {
|
impl Add<Mat2> for Mat2 {
|
||||||
|
|
@ -187,11 +219,12 @@ impl Div<f32> for Mat2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [WARN]: This will return a column-major array for wgpu use!
|
||||||
impl Into<[[f32; 2]; 2]> for Mat2 {
|
impl Into<[[f32; 2]; 2]> for Mat2 {
|
||||||
fn into(self) -> [[f32; 2]; 2] {
|
fn into(self) -> [[f32; 2]; 2] {
|
||||||
[
|
[
|
||||||
[self.x00, self.x01],
|
[self.x00, self.x10],
|
||||||
[self.x10, self.x11],
|
[self.x01, self.x11],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +268,7 @@ impl Mat3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_vec(row1: Vec3, row2: Vec3, row3: Vec3) -> Self {
|
pub fn from_rows(row1: Vec3, row2: Vec3, row3: Vec3) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x00: row1.x(), x01: row1.y(), x02: row1.z(),
|
x00: row1.x(), x01: row1.y(), x02: row1.z(),
|
||||||
x10: row2.x(), x11: row2.y(), x12: row2.z(),
|
x10: row2.x(), x11: row2.y(), x12: row2.z(),
|
||||||
|
|
@ -243,6 +276,14 @@ impl Mat3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_cols(col1: Vec3, col2: Vec3, col3: Vec3) -> Self {
|
||||||
|
Self {
|
||||||
|
x00: col1.x(), x01: col2.x(), x02: col3.x(),
|
||||||
|
x10: col1.y(), x11: col2.y(), x12: col3.y(),
|
||||||
|
x20: col1.z(), x21: col2.z(), x22: col3.z()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, row: usize, col: usize) -> Option<f32> {
|
pub fn get(&self, row: usize, col: usize) -> Option<f32> {
|
||||||
assert!(row <= 2, "This row ({}) is out of bounds! Bounds: 0..2", row);
|
assert!(row <= 2, "This row ({}) is out of bounds! Bounds: 0..2", row);
|
||||||
assert!(col <= 2, "This row ({}) is out of bounds! Bounds: 0..2", col);
|
assert!(col <= 2, "This row ({}) is out of bounds! Bounds: 0..2", col);
|
||||||
|
|
@ -270,6 +311,16 @@ impl Mat3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_col(&self, col: usize) -> Option<Vec3> {
|
||||||
|
assert!(col <= 2, "This row ({}) is out of bounds! Bounds: 0..2", col);
|
||||||
|
match col {
|
||||||
|
0 => Some(Vec3::new(self.x00, self.x10, self.x20)),
|
||||||
|
1 => Some(Vec3::new(self.x01, self.x11, self.x21)),
|
||||||
|
2 => Some(Vec3::new(self.x02, self.x12, self.x22)),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, row: usize, col: usize, element: f32) {
|
pub fn set(&mut self, row: usize, col: usize, element: f32) {
|
||||||
assert!(row <= 2, "This row ({}) is out of bounds! Bounds: 0..2", row);
|
assert!(row <= 2, "This row ({}) is out of bounds! Bounds: 0..2", row);
|
||||||
assert!(col <= 2, "This row ({}) is out of bounds! Bounds: 0..2", col);
|
assert!(col <= 2, "This row ({}) is out of bounds! Bounds: 0..2", col);
|
||||||
|
|
@ -298,6 +349,16 @@ impl Mat3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_col(&mut self, col: usize, col_content: Vec3) {
|
||||||
|
assert!(col <= 2, "This row ({}) is out of bounds! Bounds: 0..2", col);
|
||||||
|
match col {
|
||||||
|
0 => { self.x00 = col_content.x; self.x10 = col_content.y; self.x20 = col_content.z; },
|
||||||
|
1 => { self.x01 = col_content.x; self.x11 = col_content.y; self.x21 = col_content.z; },
|
||||||
|
2 => { self.x02 = col_content.x; self.x12 = col_content.y; self.x22 = col_content.z; }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn det(&self) -> f32 {
|
pub fn det(&self) -> f32 {
|
||||||
self.x00 * self.x11 * self.x22
|
self.x00 * self.x11 * self.x22
|
||||||
+ self.x01 * self.x12 * self.x20
|
+ self.x01 * self.x12 * self.x20
|
||||||
|
|
@ -320,6 +381,12 @@ impl Mat3 {
|
||||||
self.set_row(row1, self.get_row(row2).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", row2).as_str()));
|
self.set_row(row1, self.get_row(row2).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", row2).as_str()));
|
||||||
self.set_row(row2, tmp);
|
self.set_row(row2, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn swap_cols(&mut self, col1: usize, col2: usize) {
|
||||||
|
let tmp = self.get_col(col1).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", col1).as_str());
|
||||||
|
self.set_col(col1, self.get_col(col2).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", col2).as_str()));
|
||||||
|
self.set_col(col2, tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<Mat3> for Mat3 {
|
impl Add<Mat3> for Mat3 {
|
||||||
|
|
@ -412,9 +479,9 @@ impl Div<f32> for Mat3 {
|
||||||
impl Into<[[f32; 3]; 3]> for Mat3 {
|
impl Into<[[f32; 3]; 3]> for Mat3 {
|
||||||
fn into(self) -> [[f32; 3]; 3] {
|
fn into(self) -> [[f32; 3]; 3] {
|
||||||
[
|
[
|
||||||
[self.x00, self.x01, self.x02],
|
[self.x00, self.x10, self.x20],
|
||||||
[self.x10, self.x11, self.x12],
|
[self.x01, self.x11, self.x21],
|
||||||
[self.x20, self.x21, self.x22],
|
[self.x02, self.x12, self.x22],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -470,7 +537,7 @@ impl Mat4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_vec(row1: Vec4, row2: Vec4, row3: Vec4, row4: Vec4) -> Self {
|
pub fn from_rows(row1: Vec4, row2: Vec4, row3: Vec4, row4: Vec4) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x00: row1.x(), x01: row1.y(), x02: row1.z(), x03: row1.w(),
|
x00: row1.x(), x01: row1.y(), x02: row1.z(), x03: row1.w(),
|
||||||
x10: row2.x(), x11: row2.y(), x12: row2.z(), x13: row2.w(),
|
x10: row2.x(), x11: row2.y(), x12: row2.z(), x13: row2.w(),
|
||||||
|
|
@ -479,6 +546,15 @@ impl Mat4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_cols(col1: Vec4, col2: Vec4, col3: Vec4, col4: Vec4) -> Self {
|
||||||
|
Self {
|
||||||
|
x00: col1.x(), x01: col2.x(), x02: col3.x(), x03: col4.x(),
|
||||||
|
x10: col1.y(), x11: col2.y(), x12: col3.y(), x13: col4.y(),
|
||||||
|
x20: col1.z(), x21: col2.z(), x22: col3.z(), x23: col4.z(),
|
||||||
|
x30: col1.w(), x31: col2.w(), x32: col3.w(), x33: col4.w()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rh_look_to(camera: Point3, dir: Vec3, up: Vec3) -> Self {
|
pub fn rh_look_to(camera: Point3, dir: Vec3, up: Vec3) -> Self {
|
||||||
let f = dir.normalize();
|
let f = dir.normalize();
|
||||||
let s = cross(f, up).normalize();
|
let s = cross(f, up).normalize();
|
||||||
|
|
@ -486,19 +562,19 @@ impl Mat4 {
|
||||||
let cam = camera.to_vec();
|
let cam = camera.to_vec();
|
||||||
|
|
||||||
|
|
||||||
/*Mat4::new(
|
Mat4::new(
|
||||||
s.x().clone(), u.x().clone(), -f.x().clone(), 0.0,
|
s.x().clone(), u.x().clone(), -f.x().clone(), 0.0,
|
||||||
s.y().clone(), u.y().clone(), -f.y().clone(), 0.0,
|
s.y().clone(), u.y().clone(), -f.y().clone(), 0.0,
|
||||||
s.z().clone(), u.z().clone(), -f.z().clone(), 0.0,
|
s.z().clone(), u.z().clone(), -f.z().clone(), 0.0,
|
||||||
-dot(&cam, &s), -dot(&cam, &u), dot(&cam, &f),1.0
|
-dot(&cam, &s), -dot(&cam, &u), dot(&cam, &f),1.0
|
||||||
)*/
|
)
|
||||||
|
|
||||||
Mat4::new(
|
/*Mat4::new(
|
||||||
s.x().clone(), s.y().clone(), s.z().clone(), 0.0,
|
s.x().clone(), s.y().clone(), s.z().clone(), 0.0,
|
||||||
u.x().clone(), u.y().clone(), u.z().clone(), 0.0,
|
u.x().clone(), u.y().clone(), u.z().clone(), 0.0,
|
||||||
-f.x().clone(), -f.y().clone(), -f.z().clone(), 0.0,
|
-f.x().clone(), -f.y().clone(), -f.z().clone(), 0.0,
|
||||||
-dot(&cam, &s), -dot(&cam, &u), dot(&cam, &f), 1.0
|
-dot(&cam, &s), -dot(&cam, &u), dot(&cam, &f), 1.0
|
||||||
)
|
)*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -524,22 +600,31 @@ impl Mat4 {
|
||||||
let bottom = -ymax;
|
let bottom = -ymax;
|
||||||
let top = ymax;
|
let top = ymax;
|
||||||
|
|
||||||
/*Mat4::new(
|
Mat4::new(
|
||||||
(2.0 * near) / (right - left), 0.0, (right + left) / (right - left), 0.0,
|
(2.0 * near) / (right - left), 0.0, (right + left) / (right - left), 0.0,
|
||||||
0.0, (2.0 * near) / (top - bottom), (top + bottom) / (top - bottom), 0.0,
|
0.0, (2.0 * near) / (top - bottom), (top + bottom) / (top - bottom), 0.0,
|
||||||
0.0, 0.0, -(far + near) / (far - near), -(2.0 * far * near) / (far - near),
|
0.0, 0.0, -(far + near) / (far - near), -(2.0 * far * near) / (far - near),
|
||||||
0.0, 0.0, -1.0, 0.0
|
0.0, 0.0, -1.0, 0.0
|
||||||
)*/
|
)
|
||||||
|
|
||||||
Mat4::new(
|
/*Mat4::new(
|
||||||
(2.0 * near) / (right - left), 0.0, 0.0, 0.0,
|
(2.0 * near) / (right - left), 0.0, 0.0, 0.0,
|
||||||
0.0, (2.0 * near) / (top - bottom), 0.0, 0.0,
|
0.0, (2.0 * near) / (top - bottom), 0.0, 0.0,
|
||||||
(right + left) / (right - left), (top + bottom) / (top - bottom), -(far + near) / (far - near), -1.0,
|
(right + left) / (right - left), (top + bottom) / (top - bottom), -(far + near) / (far - near), -1.0,
|
||||||
0.0, 0.0, -(2.0 * far * near) / (far - near), 0.0
|
0.0, 0.0, -(2.0 * far * near) / (far - near), 0.0
|
||||||
)
|
)*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn orthographic_matrix(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> Self {
|
||||||
|
Mat4::new(
|
||||||
|
2.0 / (right - left), 0.0, 0.0, 0.0,
|
||||||
|
0.0, 2.0 / (top - bottom), 0.0, 0.0,
|
||||||
|
0.0, 0.0, -2.0 / (far - near), 0.0,
|
||||||
|
-(right + left) / (right - left), -(top + bottom) / (top - bottom), -(far + near) / (far - near), 1.0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, row: usize, col: usize) -> Option<f32> {
|
pub fn get(&self, row: usize, col: usize) -> Option<f32> {
|
||||||
assert!(row <= 3, "This row ({}) is out of bounds! Bounds: 0..3", row);
|
assert!(row <= 3, "This row ({}) is out of bounds! Bounds: 0..3", row);
|
||||||
assert!(col <= 3, "This row ({}) is out of bounds! Bounds: 0..3", col);
|
assert!(col <= 3, "This row ({}) is out of bounds! Bounds: 0..3", col);
|
||||||
|
|
@ -575,6 +660,17 @@ impl Mat4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_col(&self, col: usize) -> Option<Vec4> {
|
||||||
|
assert!(col <= 3, "This row ({}) is out of bounds! Bounds: 0..3", col);
|
||||||
|
match col {
|
||||||
|
0 => Some(Vec4::new(self.x00, self.x10, self.x20, self.x30)),
|
||||||
|
1 => Some(Vec4::new(self.x01, self.x11, self.x21, self.x31)),
|
||||||
|
2 => Some(Vec4::new(self.x02, self.x12, self.x22, self.x32)),
|
||||||
|
3 => Some(Vec4::new(self.x03, self.x13, self.x23, self.x33)),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, row: usize, col: usize, element: f32) {
|
pub fn set(&mut self, row: usize, col: usize, element: f32) {
|
||||||
assert!(row <= 3, "The given row ({}) is out of bounds! Bounds: 0..3", row);
|
assert!(row <= 3, "The given row ({}) is out of bounds! Bounds: 0..3", row);
|
||||||
assert!(col <= 3, "The given column ({}) is out of bounds! Bounds: 0..3", col);
|
assert!(col <= 3, "The given column ({}) is out of bounds! Bounds: 0..3", col);
|
||||||
|
|
@ -610,6 +706,17 @@ impl Mat4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_col(&mut self, col: usize, col_content: Vec4) {
|
||||||
|
assert!(col <= 3, "This column ({}) is out of bounds! Bounds: 0..3", col);
|
||||||
|
match col {
|
||||||
|
0 => { self.x00 = col_content.x(); self.x10 = col_content.y(); self.x20 = col_content.z(); self.x30 = col_content.w(); },
|
||||||
|
1 => { self.x01 = col_content.x(); self.x11 = col_content.y(); self.x21 = col_content.z(); self.x31 = col_content.w(); },
|
||||||
|
2 => { self.x02 = col_content.x(); self.x12 = col_content.y(); self.x22 = col_content.z(); self.x32 = col_content.w(); },
|
||||||
|
3 => { self.x03 = col_content.x(); self.x13 = col_content.y(); self.x23 = col_content.z(); self.x33 = col_content.w(); }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn det(&self) -> f32 {
|
pub fn det(&self) -> f32 {
|
||||||
self.x00 * (self.x11 * (self.x22* self.x33 - self.x23 * self.x32)
|
self.x00 * (self.x11 * (self.x22* self.x33 - self.x23 * self.x32)
|
||||||
- self.x21 * (self.x12 * self.x33 - self.x13 * self.x32)
|
- self.x21 * (self.x12 * self.x33 - self.x13 * self.x32)
|
||||||
|
|
@ -633,6 +740,18 @@ impl Mat4 {
|
||||||
x30: self.x03, x31: self.x13, x32: self.x23, x33: self.x33
|
x30: self.x03, x31: self.x13, x32: self.x23, x33: self.x33
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn swap_rows(&mut self, row1: usize, row2: usize) {
|
||||||
|
let tmp = self.get_row(row1).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", row1).as_str());
|
||||||
|
self.set_row(row1, self.get_row(row2).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", row2).as_str()));
|
||||||
|
self.set_row(row2, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn swap_cols(&mut self, col1: usize, col2: usize) {
|
||||||
|
let tmp = self.get_col(col1).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", col1).as_str());
|
||||||
|
self.set_col(col1, self.get_col(col2).expect(format!("This row ({}) is out of bounds! Bounds: 0..2", col2).as_str()));
|
||||||
|
self.set_col(col2, tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<Mat4> for Mat4 {
|
impl Add<Mat4> for Mat4 {
|
||||||
|
|
@ -715,10 +834,10 @@ impl Mul<Mat4> for Mat4 {
|
||||||
impl Into<[[f32; 4]; 4]> for Mat4 {
|
impl Into<[[f32; 4]; 4]> for Mat4 {
|
||||||
fn into(self) -> [[f32; 4]; 4] {
|
fn into(self) -> [[f32; 4]; 4] {
|
||||||
[
|
[
|
||||||
[self.x00, self.x01, self.x02, self.x03],
|
[self.x00, self.x10, self.x20, self.x30],
|
||||||
[self.x10, self.x11, self.x12, self.x13],
|
[self.x01, self.x11, self.x21, self.x31],
|
||||||
[self.x20, self.x21, self.x22, self.x23],
|
[self.x02, self.x12, self.x22, self.x32],
|
||||||
[self.x30, self.x31, self.x32, self.x33],
|
[self.x03, self.x13, self.x23, self.x33],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
use crate::point::{Point2, Point3};
|
use crate::point::{Point2, Point3};
|
||||||
use crate::quaternion::Quat;
|
use crate::quaternion::Quat;
|
||||||
use crate::utilities::acos;
|
use crate::utilities::acos;
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
|
||||||
|
use comet_log::*;
|
||||||
|
|
||||||
pub trait InnerSpace {
|
pub trait InnerSpace {
|
||||||
fn dot(&self, other: &Self) -> f32;
|
fn dot(&self, other: &Self) -> f32;
|
||||||
fn dist(&self, other: &Self) -> f32;
|
fn dist(&self, other: &Self) -> f32;
|
||||||
fn vAngle(&self, other: &Self) -> f32;
|
fn v_angle(&self, other: &Self) -> f32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ##################################################
|
// ##################################################
|
||||||
|
|
@ -103,6 +104,13 @@ impl Add<Vec2> for Vec2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AddAssign for Vec2 {
|
||||||
|
fn add_assign(&mut self, other: Vec2) {
|
||||||
|
self.x += other.x;
|
||||||
|
self.y += other.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Sub<Vec2> for Vec2 {
|
impl Sub<Vec2> for Vec2 {
|
||||||
type Output = Vec2;
|
type Output = Vec2;
|
||||||
|
|
||||||
|
|
@ -114,6 +122,13 @@ impl Sub<Vec2> for Vec2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SubAssign for Vec2 {
|
||||||
|
fn sub_assign(&mut self, other: Vec2) {
|
||||||
|
self.x -= other.x;
|
||||||
|
self.y -= other.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Mul<f32> for Vec2 {
|
impl Mul<f32> for Vec2 {
|
||||||
type Output = Vec2;
|
type Output = Vec2;
|
||||||
|
|
||||||
|
|
@ -125,6 +140,228 @@ impl Mul<f32> for Vec2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<[f32;2]> for Vec2 {
|
||||||
|
fn into(self) -> [f32;2] {
|
||||||
|
[self.x, self.y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Vec2> for [f32;2] {
|
||||||
|
fn into(self) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self[0],
|
||||||
|
y: self[1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Representation of a 2D integer Vector
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct IVec2 {
|
||||||
|
x: i64,
|
||||||
|
y: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IVec2 {
|
||||||
|
pub const X: IVec2 = IVec2 { x: 1, y: 0 };
|
||||||
|
pub const Y: IVec2 = IVec2 { x: 0, y: 1 };
|
||||||
|
pub const ZERO: IVec2 = IVec2 { x: 0, y: 0 };
|
||||||
|
|
||||||
|
pub const fn new(x: i64, y: i64) -> Self {
|
||||||
|
IVec2 { x, y }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_point(p: Point2) -> Self {
|
||||||
|
Self { x: p.x() as i64, y: p.y() as i64 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_vec2(&self) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self.x as f32,
|
||||||
|
y: self.y as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn x(&self) -> i64 {
|
||||||
|
self.x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn y(&self) -> i64 {
|
||||||
|
self.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_x(&mut self, new_x: i64) {
|
||||||
|
self.x = new_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_y(&mut self, new_y: i64) {
|
||||||
|
self.y = new_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn length(&self) -> i64 {
|
||||||
|
((self.x * self.x + self.y * self.y) as f32).sqrt() as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize(&self) -> Self {
|
||||||
|
let factor = 1.0 / self.length() as f32;
|
||||||
|
IVec2 {
|
||||||
|
x: (factor * self.x as f32) as i64,
|
||||||
|
y: (factor * self.y as f32) as i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xx(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
x: self.x,
|
||||||
|
y: self.x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xy(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
x: self.x,
|
||||||
|
y: self.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn yx(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
x: self.y,
|
||||||
|
y: self.x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn yy(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
x: self.y,
|
||||||
|
y: self.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<IVec2> for IVec2 {
|
||||||
|
type Output = IVec2;
|
||||||
|
|
||||||
|
fn add(self, other: IVec2) -> IVec2 {
|
||||||
|
IVec2 {
|
||||||
|
x: self.x + other.x,
|
||||||
|
y: self.y + other.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<IVec2> for Vec2 {
|
||||||
|
type Output = Vec2;
|
||||||
|
|
||||||
|
fn add(self, other: IVec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self.x + other.x as f32,
|
||||||
|
y: self.y + other.y as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Vec2> for IVec2 {
|
||||||
|
type Output = Vec2;
|
||||||
|
|
||||||
|
fn add(self, other: Vec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self.x as f32 + other.x,
|
||||||
|
y: self.y as f32 + other.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddAssign for IVec2 {
|
||||||
|
fn add_assign(&mut self, other: IVec2) {
|
||||||
|
self.x += other.x;
|
||||||
|
self.y += other.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<IVec2> for IVec2 {
|
||||||
|
type Output = IVec2;
|
||||||
|
|
||||||
|
fn sub(self, other: IVec2) -> IVec2 {
|
||||||
|
IVec2 {
|
||||||
|
x: self.x - other.x,
|
||||||
|
y: self.y - other.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<IVec2> for Vec2 {
|
||||||
|
type Output = Vec2;
|
||||||
|
|
||||||
|
fn sub(self, other: IVec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self.x - other.x as f32,
|
||||||
|
y: self.y - other.y as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<Vec2> for IVec2 {
|
||||||
|
type Output = Vec2;
|
||||||
|
|
||||||
|
fn sub(self, other: Vec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self.x as f32 - other.x,
|
||||||
|
y: self.y as f32 - other.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SubAssign for IVec2 {
|
||||||
|
fn sub_assign(&mut self, other: IVec2) {
|
||||||
|
self.x -= other.x;
|
||||||
|
self.y -= other.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<f32> for IVec2 {
|
||||||
|
type Output = IVec2;
|
||||||
|
|
||||||
|
fn mul(self, other: f32) -> IVec2 {
|
||||||
|
IVec2 {
|
||||||
|
x: self.x * other as i64,
|
||||||
|
y: self.y * other as i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IVec2> for Vec2 {
|
||||||
|
fn from(v: IVec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: v.x as f32,
|
||||||
|
y: v.y as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec2> for IVec2 {
|
||||||
|
fn from(v: Vec2) -> IVec2 {
|
||||||
|
IVec2 {
|
||||||
|
x: v.x as i64,
|
||||||
|
y: v.y as i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<[i64;2]> for IVec2 {
|
||||||
|
fn into(self) -> [i64;2] {
|
||||||
|
[self.x, self.y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<[f32;2]> for IVec2 {
|
||||||
|
fn into(self) -> [f32;2] {
|
||||||
|
[self.x as f32, self.y as f32]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ##################################################
|
// ##################################################
|
||||||
// # VECTOR 3D #
|
// # VECTOR 3D #
|
||||||
// ##################################################
|
// ##################################################
|
||||||
|
|
@ -181,17 +418,6 @@ impl Vec3 {
|
||||||
self.z = new_z;
|
self.z = new_z;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_quaternion(&self) -> Quat {
|
|
||||||
Quat {
|
|
||||||
s: 0.0,
|
|
||||||
v: Vec3 {
|
|
||||||
x: self.x,
|
|
||||||
y: self.y,
|
|
||||||
z: self.z,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn length(&self) -> f32 {
|
pub fn length(&self) -> f32 {
|
||||||
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
|
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
|
||||||
}
|
}
|
||||||
|
|
@ -408,6 +634,14 @@ impl Add<Vec3> for Vec3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AddAssign for Vec3 {
|
||||||
|
fn add_assign(&mut self, other: Vec3) {
|
||||||
|
self.x += other.x;
|
||||||
|
self.y += other.y;
|
||||||
|
self.z += other.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Sub<Vec3> for Vec3 {
|
impl Sub<Vec3> for Vec3 {
|
||||||
type Output = Vec3;
|
type Output = Vec3;
|
||||||
|
|
||||||
|
|
@ -420,6 +654,14 @@ impl Sub<Vec3> for Vec3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SubAssign for Vec3 {
|
||||||
|
fn sub_assign(&mut self, other: Vec3) {
|
||||||
|
self.x -= other.x;
|
||||||
|
self.y -= other.y;
|
||||||
|
self.z -= other.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Mul<f32> for Vec3 {
|
impl Mul<f32> for Vec3 {
|
||||||
type Output = Vec3;
|
type Output = Vec3;
|
||||||
|
|
||||||
|
|
@ -432,6 +674,202 @@ impl Mul<f32> for Vec3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<Quat> for Vec3 {
|
||||||
|
fn into(self) -> Quat {
|
||||||
|
Quat::new(0.0, self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<[f32;3]> for Vec3 {
|
||||||
|
fn into(self) -> [f32;3] {
|
||||||
|
[self.x, self.y, self.z]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct IVec3 {
|
||||||
|
pub x: i64,
|
||||||
|
pub y: i64,
|
||||||
|
pub z: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IVec3 {
|
||||||
|
pub const X: IVec3 = IVec3 { x: 1, y: 0, z: 0 };
|
||||||
|
pub const Y: IVec3 = IVec3 { x: 0, y: 1, z: 0 };
|
||||||
|
pub const Z: IVec3 = IVec3 { x: 0, y: 0, z: 1 };
|
||||||
|
pub const ZERO: IVec3 = IVec3 { x: 0, y: 0, z: 0 };
|
||||||
|
|
||||||
|
pub const fn new(x: i64, y: i64, z: i64) -> Self {
|
||||||
|
IVec3 { x, y, z }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_point(p: Point3) -> Self {
|
||||||
|
Self {
|
||||||
|
x: p.x() as i64,
|
||||||
|
y: p.y() as i64,
|
||||||
|
z: p.z() as i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn x(&self) -> i64 {
|
||||||
|
self.x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn y(&self) -> i64 {
|
||||||
|
self.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn z(&self) -> i64 {
|
||||||
|
self.z
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_x(&mut self, new_x: i64) {
|
||||||
|
self.x = new_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_y(&mut self, new_y: i64) {
|
||||||
|
self.y = new_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_z(&mut self, new_z: i64) {
|
||||||
|
self.z = new_z;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn length(&self) -> i64 {
|
||||||
|
((self.x * self.x + self.y * self.y + self.z * self.z) as f32).sqrt() as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize(&self) -> Self {
|
||||||
|
let factor = 1 / self.length();
|
||||||
|
IVec3 {
|
||||||
|
x: factor * self.x,
|
||||||
|
y: factor * self.y,
|
||||||
|
z: factor * self.z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<IVec3> for IVec3 {
|
||||||
|
type Output = IVec3;
|
||||||
|
|
||||||
|
fn add(self, other: IVec3) -> IVec3 {
|
||||||
|
IVec3 {
|
||||||
|
x: self.x + other.x,
|
||||||
|
y: self.y + other.y,
|
||||||
|
z: self.z + other.z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<IVec3> for Vec3 {
|
||||||
|
type Output = Vec3;
|
||||||
|
|
||||||
|
fn add(self, other: IVec3) -> Vec3 {
|
||||||
|
Vec3 {
|
||||||
|
x: self.x + other.x as f32,
|
||||||
|
y: self.y + other.y as f32,
|
||||||
|
z: self.z + other.z as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Vec3> for IVec3 {
|
||||||
|
type Output = Vec3;
|
||||||
|
|
||||||
|
fn add(self, other: Vec3) -> Vec3 {
|
||||||
|
Vec3 {
|
||||||
|
x: self.x as f32 + other.x,
|
||||||
|
y: self.y as f32 + other.y,
|
||||||
|
z: self.z as f32 + other.z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddAssign for IVec3 {
|
||||||
|
fn add_assign(&mut self, other: IVec3) {
|
||||||
|
self.x += other.x;
|
||||||
|
self.y += other.y;
|
||||||
|
self.z += other.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<IVec3> for IVec3 {
|
||||||
|
type Output = IVec3;
|
||||||
|
|
||||||
|
fn sub(self, other: IVec3) -> IVec3 {
|
||||||
|
IVec3 {
|
||||||
|
x: self.x - other.x,
|
||||||
|
y: self.y - other.y,
|
||||||
|
z: self.z - other.z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<IVec3> for Vec3 {
|
||||||
|
type Output = Vec3;
|
||||||
|
|
||||||
|
fn sub(self, other: IVec3) -> Vec3 {
|
||||||
|
Vec3 {
|
||||||
|
x: self.x - other.x as f32,
|
||||||
|
y: self.y - other.y as f32,
|
||||||
|
z: self.z - other.z as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<Vec3> for IVec3 {
|
||||||
|
type Output = Vec3;
|
||||||
|
|
||||||
|
fn sub(self, other: Vec3) -> Vec3 {
|
||||||
|
Vec3 {
|
||||||
|
x: self.x as f32 - other.x,
|
||||||
|
y: self.y as f32 - other.y,
|
||||||
|
z: self.z as f32 - other.z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SubAssign for IVec3 {
|
||||||
|
fn sub_assign(&mut self, other: IVec3) {
|
||||||
|
self.x -= other.x;
|
||||||
|
self.y -= other.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<f32> for IVec3 {
|
||||||
|
type Output = IVec3;
|
||||||
|
|
||||||
|
fn mul(self, other: f32) -> IVec3 {
|
||||||
|
IVec3 {
|
||||||
|
x: self.x * other as i64,
|
||||||
|
y: self.y * other as i64,
|
||||||
|
z: self.z * other as i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IVec3> for Vec3 {
|
||||||
|
fn from(v: IVec3) -> Vec3 {
|
||||||
|
Vec3 {
|
||||||
|
x: v.x as f32,
|
||||||
|
y: v.y as f32,
|
||||||
|
z: v.z as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec3> for IVec3 {
|
||||||
|
fn from(v: Vec3) -> IVec3 {
|
||||||
|
IVec3 {
|
||||||
|
x: v.x as i64,
|
||||||
|
y: v.y as i64,
|
||||||
|
z: v.z as i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ##################################################
|
// ##################################################
|
||||||
// # VECTOR 4D #
|
// # VECTOR 4D #
|
||||||
// ##################################################
|
// ##################################################
|
||||||
|
|
@ -2568,6 +3006,15 @@ impl Add<Vec4> for Vec4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AddAssign for Vec4 {
|
||||||
|
fn add_assign(&mut self, other: Vec4) {
|
||||||
|
self.x += other.x;
|
||||||
|
self.y += other.y;
|
||||||
|
self.z += other.z;
|
||||||
|
self.w += other.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Sub<Vec4> for Vec4 {
|
impl Sub<Vec4> for Vec4 {
|
||||||
type Output = Vec4;
|
type Output = Vec4;
|
||||||
|
|
||||||
|
|
@ -2581,6 +3028,15 @@ impl Sub<Vec4> for Vec4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SubAssign for Vec4 {
|
||||||
|
fn sub_assign(&mut self, other: Vec4) {
|
||||||
|
self.x -= other.x;
|
||||||
|
self.y -= other.y;
|
||||||
|
self.z -= other.z;
|
||||||
|
self.w -= other.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Mul<f32> for Vec4 {
|
impl Mul<f32> for Vec4 {
|
||||||
type Output = Vec4;
|
type Output = Vec4;
|
||||||
|
|
||||||
|
|
@ -2594,6 +3050,12 @@ impl Mul<f32> for Vec4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<[f32;4]> for Vec4 {
|
||||||
|
fn into(self) -> [f32;4] {
|
||||||
|
[self.x, self.y, self.z, self.w]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl InnerSpace for Vec2 {
|
impl InnerSpace for Vec2 {
|
||||||
fn dot(&self, other: &Self) -> f32 {
|
fn dot(&self, other: &Self) -> f32 {
|
||||||
self.x * other.x + self.y * other.y
|
self.x * other.x + self.y * other.y
|
||||||
|
|
@ -2607,7 +3069,8 @@ impl InnerSpace for Vec2 {
|
||||||
.length()
|
.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vAngle(&self, other: &Self) -> f32 {
|
fn v_angle(&self, other: &Self) -> f32 {
|
||||||
|
//debug!("{:?}", dot(self,other)/(self.length()*other.length()));
|
||||||
acos(dot(self, other) / (self.length() * other.length()))
|
acos(dot(self, other) / (self.length() * other.length()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2626,7 +3089,7 @@ impl InnerSpace for Vec3 {
|
||||||
.length()
|
.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vAngle(&self, other: &Self) -> f32 {
|
fn v_angle(&self, other: &Self) -> f32 {
|
||||||
acos(dot(self, other) / (self.length() * other.length()))
|
acos(dot(self, other) / (self.length() * other.length()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2646,7 +3109,7 @@ impl InnerSpace for Vec4 {
|
||||||
.length()
|
.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vAngle(&self, other: &Self) -> f32 {
|
fn v_angle(&self, other: &Self) -> f32 {
|
||||||
acos(dot(self, other) / (self.length() * other.length()))
|
acos(dot(self, other) / (self.length() * other.length()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2672,5 +3135,5 @@ pub fn v_dist<T: InnerSpace>(v1: &T, v2: &T) -> f32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn v_angle<T: InnerSpace>(v1: &T, v2: &T) -> f32 {
|
pub fn v_angle<T: InnerSpace>(v1: &T, v2: &T) -> f32 {
|
||||||
v1.vAngle(v2)
|
v1.v_angle(v2)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
[package]
|
[package]
|
||||||
name = "comet_renderer"
|
name = "comet_renderer"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
comet_ecs = { path = "../comet_ecs" }
|
||||||
comet_math = { path = "../comet_math" }
|
comet_math = { path = "../comet_math" }
|
||||||
comet_resources = { path = "../comet_resources" }
|
comet_resources = { path = "../comet_resources" }
|
||||||
comet_colors = { path = "../comet_colors" }
|
comet_colors = { path = "../comet_colors" }
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use comet_math::Point3;
|
use comet_math::{Point3, Vec2, Vec3};
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
||||||
|
|
@ -11,44 +11,30 @@ pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
||||||
const SAFE_FRAC_PI_2: f32 = std::f32::consts::FRAC_PI_2 - 0.0001;
|
const SAFE_FRAC_PI_2: f32 = std::f32::consts::FRAC_PI_2 - 0.0001;
|
||||||
|
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
eye: cgmath::Point3<f32>,
|
zoom: f32,
|
||||||
target: cgmath::Point3<f32>,
|
dimension: Vec2,
|
||||||
up: cgmath::Vector3<f32>,
|
position: Vec3
|
||||||
aspect: f32,
|
|
||||||
fovy: f32,
|
|
||||||
znear: f32,
|
|
||||||
zfar: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
eye: cgmath::Point3<f32>,
|
zoom: f32,
|
||||||
target: cgmath::Point3<f32>,
|
dimension: Vec2,
|
||||||
up: cgmath::Vector3<f32>,
|
position: Vec3
|
||||||
aspect: f32,
|
|
||||||
fovy: f32,
|
|
||||||
znear: f32,
|
|
||||||
zfar: f32,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
eye,
|
zoom,
|
||||||
target,
|
dimension,
|
||||||
up,
|
position
|
||||||
aspect,
|
|
||||||
fovy,
|
|
||||||
znear,
|
|
||||||
zfar,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_view_projection_matrix(&self) -> cgmath::Matrix4<f32> {
|
pub fn build_view_projection_matrix(&self) -> cgmath::Matrix4<f32> {
|
||||||
// 1.
|
// 1.
|
||||||
let view = cgmath::Matrix4::look_at_rh(self.eye, self.target, self.up);
|
|
||||||
// 2.
|
|
||||||
let proj = cgmath::perspective(cgmath::Deg(self.fovy), self.aspect, self.znear, self.zfar);
|
|
||||||
|
|
||||||
|
let proj = 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, 1.0, 0.0);
|
||||||
// 3.
|
// 3.
|
||||||
return OPENGL_TO_WGPU_MATRIX * proj * view;
|
return OPENGL_TO_WGPU_MATRIX * proj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use std::sync::Arc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use cgmath::num_traits::FloatConst;
|
use cgmath::num_traits::FloatConst;
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use log::info;
|
|
||||||
use wgpu::Color;
|
use wgpu::Color;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
use winit::{
|
use winit::{
|
||||||
|
|
@ -16,9 +15,10 @@ use winit::{
|
||||||
};
|
};
|
||||||
use winit::dpi::Position;
|
use winit::dpi::Position;
|
||||||
use comet_colors::LinearRgba;
|
use comet_colors::LinearRgba;
|
||||||
use comet_log::error;
|
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
||||||
|
use comet_log::*;
|
||||||
use comet_math;
|
use comet_math;
|
||||||
use comet_math::{Mat4, Point3, Vec3};
|
use comet_math::{Mat4, Point3, Vec2, Vec3};
|
||||||
use comet_resources::{ResourceManager, texture, Vertex, Texture};
|
use comet_resources::{ResourceManager, texture, Vertex, Texture};
|
||||||
use comet_resources::texture_atlas::TextureRegion;
|
use comet_resources::texture_atlas::TextureRegion;
|
||||||
use crate::camera::{Camera, CameraUniform};
|
use crate::camera::{Camera, CameraUniform};
|
||||||
|
|
@ -67,10 +67,10 @@ pub struct Renderer<'a> {
|
||||||
diffuse_texture: texture::Texture,
|
diffuse_texture: texture::Texture,
|
||||||
diffuse_bind_group: wgpu::BindGroup,
|
diffuse_bind_group: wgpu::BindGroup,
|
||||||
resource_manager: ResourceManager,
|
resource_manager: ResourceManager,
|
||||||
/*camera: Camera,
|
camera: Camera,
|
||||||
camera_uniform: CameraUniform,
|
camera_uniform: CameraUniform,
|
||||||
camera_buffer: wgpu::Buffer,
|
camera_buffer: wgpu::Buffer,
|
||||||
camera_bind_group: wgpu::BindGroup,*/
|
camera_bind_group: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl<'a> Renderer<'a> {
|
||||||
|
|
@ -199,34 +199,20 @@ impl<'a> Renderer<'a> {
|
||||||
label: Some("diffuse_bind_group"),
|
label: Some("diffuse_bind_group"),
|
||||||
});
|
});
|
||||||
|
|
||||||
/*let camera = Camera::new(
|
let camera = Camera::new(1.0, Vec2::new(2.0, 2.0), Vec3::new(0.0, 0.0, 0.0));
|
||||||
// position the camera 1 unit up and 2 units back
|
|
||||||
// +z is out of the screen
|
|
||||||
(0.0, 1.0, 2.0).into(),
|
|
||||||
// have it look at the origin
|
|
||||||
(0.0, 0.0, 0.0).into(),
|
|
||||||
// which way is "up"
|
|
||||||
cgmath::Vector3::unit_y(),
|
|
||||||
config.width as f32 / config.height as f32,
|
|
||||||
45.0,
|
|
||||||
0.1,
|
|
||||||
100.0,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut camera_uniform = CameraUniform::new();
|
let mut camera_uniform = CameraUniform::new();
|
||||||
camera_uniform.update_view_proj(&camera);
|
camera_uniform.update_view_proj(&camera);
|
||||||
|
|
||||||
let camera_buffer = device.create_buffer_init(
|
let camera_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: Some("Camera Buffer"),
|
label: Some("Camera Buffer"),
|
||||||
contents: bytemuck::cast_slice(&[camera_uniform]),
|
contents: bytemuck::cast_slice(&[camera_uniform]),
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
let camera_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
let camera_bind_group_layout =
|
||||||
entries: &[
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
wgpu::BindGroupLayoutEntry {
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: wgpu::ShaderStages::VERTEX,
|
visibility: wgpu::ShaderStages::VERTEX,
|
||||||
ty: wgpu::BindingType::Buffer {
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
|
@ -235,28 +221,25 @@ impl<'a> Renderer<'a> {
|
||||||
min_binding_size: None,
|
min_binding_size: None,
|
||||||
},
|
},
|
||||||
count: None,
|
count: None,
|
||||||
}
|
}],
|
||||||
],
|
|
||||||
label: Some("camera_bind_group_layout"),
|
label: Some("camera_bind_group_layout"),
|
||||||
});
|
});
|
||||||
|
|
||||||
let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
layout: &camera_bind_group_layout,
|
layout: &camera_bind_group_layout,
|
||||||
entries: &[
|
entries: &[wgpu::BindGroupEntry {
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: camera_buffer.as_entire_binding(),
|
resource: camera_buffer.as_entire_binding(),
|
||||||
}
|
}],
|
||||||
],
|
|
||||||
label: Some("camera_bind_group"),
|
label: Some("camera_bind_group"),
|
||||||
});*/
|
});
|
||||||
|
|
||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("Render Pipeline Layout"),
|
label: Some("Render Pipeline Layout"),
|
||||||
bind_group_layouts: &[
|
bind_group_layouts: &[
|
||||||
&texture_bind_group_layout,
|
&texture_bind_group_layout,
|
||||||
//&camera_bind_group_layout,
|
&camera_bind_group_layout,
|
||||||
],
|
],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
@ -347,10 +330,10 @@ impl<'a> Renderer<'a> {
|
||||||
diffuse_texture,
|
diffuse_texture,
|
||||||
diffuse_bind_group,
|
diffuse_bind_group,
|
||||||
resource_manager,
|
resource_manager,
|
||||||
/*camera,
|
camera,
|
||||||
camera_uniform,
|
camera_uniform,
|
||||||
camera_buffer,
|
camera_buffer,
|
||||||
camera_bind_group,*/
|
camera_bind_group,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,10 +363,10 @@ impl<'a> Renderer<'a> {
|
||||||
((width/ self.config.width as f32) * 0.5, (height/ self.config.height as f32) * 0.5);
|
((width/ self.config.width as f32) * 0.5, (height/ self.config.height as f32) * 0.5);
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
Vertex :: new ( [-bound_x, bound_y, 0.0], [0.0, 0.0] ),
|
Vertex :: new ( [-bound_x, bound_y, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [-bound_x, -bound_y, 0.0], [0.0, 1.0] ),
|
Vertex :: new ( [-bound_x, -bound_y, 0.0], [0.0, 1.0], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [ bound_x, -bound_y, 0.0], [1.0, 1.0]) ,
|
Vertex :: new ( [ bound_x, -bound_y, 0.0], [1.0, 1.0], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [ bound_x, bound_y, 0.0], [1.0, 0.0] )
|
Vertex :: new ( [ bound_x, bound_y, 0.0], [1.0, 0.0], [0.0, 0.0, 0.0, 0.0] )
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -401,10 +384,10 @@ impl<'a> Renderer<'a> {
|
||||||
((self.diffuse_texture.size.width as f32/ self.config.width as f32) * 0.5, (self.diffuse_texture.size.height as f32/ self.config.height as f32) * 0.5);
|
((self.diffuse_texture.size.width as f32/ self.config.width as f32) * 0.5, (self.diffuse_texture.size.height as f32/ self.config.height as f32) * 0.5);
|
||||||
|
|
||||||
let vertices: Vec<Vertex> = vec![
|
let vertices: Vec<Vertex> = vec![
|
||||||
Vertex :: new ( [-bound_x, bound_y, 0.0], [0.0, 0.0] ),
|
Vertex :: new ( [-bound_x, bound_y, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [-bound_x, -bound_y, 0.0], [0.0, 1.0] ),
|
Vertex :: new ( [-bound_x, -bound_y, 0.0], [0.0, 1.0], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [ bound_x, -bound_y, 0.0], [1.0, 1.0]) ,
|
Vertex :: new ( [ bound_x, -bound_y, 0.0], [1.0, 1.0], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [ bound_x, bound_y, 0.0], [1.0, 0.0] )
|
Vertex :: new ( [ bound_x, bound_y, 0.0], [1.0, 0.0], [0.0, 0.0, 0.0, 0.0] )
|
||||||
];
|
];
|
||||||
|
|
||||||
/*let vertices: Vec<Vertex> = vec![
|
/*let vertices: Vec<Vertex> = vec![
|
||||||
|
|
@ -494,8 +477,6 @@ impl<'a> Renderer<'a> {
|
||||||
paths.push(texture_path.clone() + path.unwrap().file_name().to_str().unwrap());
|
paths.push(texture_path.clone() + path.unwrap().file_name().to_str().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
error!(format!("{:?}", paths));
|
|
||||||
|
|
||||||
self.set_texture_atlas(paths);
|
self.set_texture_atlas(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,10 +553,10 @@ impl<'a> Renderer<'a> {
|
||||||
((dim_x as f32/ self.config.width as f32) * 0.5, (dim_y as f32/ self.config.height as f32) * 0.5);
|
((dim_x as f32/ self.config.width as f32) * 0.5, (dim_y as f32/ self.config.height as f32) * 0.5);
|
||||||
|
|
||||||
let vertices: &mut Vec<Vertex> = &mut vec![
|
let vertices: &mut Vec<Vertex> = &mut vec![
|
||||||
Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0 + position.z()], [region.x0(), region.y0()] ),
|
Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0 + position.z()], [region.x0(), region.y0()], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [-bound_x + position.x(), -bound_y + position.y(), 0.0 + position.z()], [region.x0(), region.y1()] ),
|
Vertex :: new ( [-bound_x + position.x(), -bound_y + position.y(), 0.0 + position.z()], [region.x0(), region.y1()], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
Vertex :: new ( [ bound_x + position.x(), -bound_y + position.y(), 0.0 + position.z()], [region.x1(), region.y1()] ) ,
|
Vertex :: new ( [ bound_x + position.x(), -bound_y + position.y(), 0.0 + position.z()], [region.x1(), region.y1()], [0.0, 0.0, 0.0, 0.0] ) ,
|
||||||
Vertex :: new ( [ bound_x + position.x(), bound_y + position.y(), 0.0 + position.z()], [region.x1(), region.y0()] )
|
Vertex :: new ( [ bound_x + position.x(), bound_y + position.y(), 0.0 + position.z()], [region.x1(), region.y0()], [0.0, 0.0, 0.0, 0.0] )
|
||||||
];
|
];
|
||||||
|
|
||||||
let buffer_size = self.vertex_data.len() as u16;
|
let buffer_size = self.vertex_data.len() as u16;
|
||||||
|
|
@ -588,6 +569,45 @@ impl<'a> Renderer<'a> {
|
||||||
self.push_to_buffers(vertices, indices)
|
self.push_to_buffers(vertices, indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_scene_2d(&mut self, world: &World) {
|
||||||
|
let entities = world.get_entities_with(ComponentSet::from_ids(vec![Renderer2D::type_id()]));
|
||||||
|
let mut vertex_buffer: Vec<Vertex> = Vec::new();
|
||||||
|
let mut index_buffer: Vec<u16> = Vec::new();
|
||||||
|
|
||||||
|
for entity in entities {
|
||||||
|
let renderer_component = world.get_component::<Renderer2D>(entity as usize);
|
||||||
|
let transform_component = world.get_component::<Transform2D>(entity as usize);
|
||||||
|
|
||||||
|
if renderer_component.is_visible() {
|
||||||
|
//renderer.draw_texture_at(renderer_component.get_texture(), Point3::new(transform_component.position().x(), transform_component.position().y(), 0.0));
|
||||||
|
let mut position = transform_component.position().clone();
|
||||||
|
position.set_x(position.x() / self.config().width as f32);
|
||||||
|
position.set_y(position.y() / self.config().height as f32);
|
||||||
|
let region = self.get_texture(renderer_component.get_texture().to_string());
|
||||||
|
let (dim_x, dim_y) = region.dimensions();
|
||||||
|
|
||||||
|
let (bound_x, bound_y) =
|
||||||
|
((dim_x as f32/ self.config().width as f32) * 0.5, (dim_y as f32/ self.config().height as f32) * 0.5);
|
||||||
|
|
||||||
|
let buffer_size = vertex_buffer.len() as u16;
|
||||||
|
|
||||||
|
vertex_buffer.append(&mut vec![
|
||||||
|
Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0], [region.x0(), region.y0()], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
|
Vertex :: new ( [-bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x0(), region.y1()], [0.0, 0.0, 0.0, 0.0] ),
|
||||||
|
Vertex :: new ( [ bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x1(), region.y1()], [0.0, 0.0, 0.0, 0.0] ) ,
|
||||||
|
Vertex :: new ( [ bound_x + position.x(), bound_y + position.y(), 0.0], [region.x1(), region.y0()], [0.0, 0.0, 0.0, 0.0] )
|
||||||
|
]);
|
||||||
|
|
||||||
|
index_buffer.append(&mut vec![
|
||||||
|
0 + buffer_size, 1 + buffer_size, 3 + buffer_size,
|
||||||
|
1 + buffer_size, 2 + buffer_size, 3 + buffer_size
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_buffers(vertex_buffer, index_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn window(&self) -> &Window {
|
pub fn window(&self) -> &Window {
|
||||||
&self.window
|
&self.window
|
||||||
}
|
}
|
||||||
|
|
@ -606,10 +626,11 @@ impl<'a> Renderer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) -> f32 {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
self.deltatime = now.duration_since(self.last_frame_time).as_secs_f32(); // Time delta in seconds
|
self.deltatime = now.duration_since(self.last_frame_time).as_secs_f32(); // Time delta in seconds
|
||||||
self.last_frame_time = now;
|
self.last_frame_time = now;
|
||||||
|
self.deltatime
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
||||||
|
|
@ -642,7 +663,7 @@ impl<'a> Renderer<'a> {
|
||||||
|
|
||||||
render_pass.set_pipeline(&self.render_pipeline);
|
render_pass.set_pipeline(&self.render_pipeline);
|
||||||
render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
|
render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
|
||||||
//render_pass.set_bind_group(1, &self.camera_bind_group, &[]);
|
render_pass.set_bind_group(1, &self.camera_bind_group, &[]);
|
||||||
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
||||||
render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
||||||
render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
|
render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
// Vertex shader
|
// Vertex shader
|
||||||
/*struct CameraUniform {
|
struct CameraUniform {
|
||||||
view_proj: mat4x4<f32>,
|
view_proj: mat4x4<f32>,
|
||||||
};
|
};
|
||||||
@group(1) @binding(0) // 1.
|
@group(1) @binding(0) // 1.
|
||||||
var<uniform> camera: CameraUniform;*/
|
var<uniform> camera: CameraUniform;
|
||||||
|
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
@location(0) position: vec3<f32>,
|
@location(0) position: vec3<f32>,
|
||||||
@location(1) tex_coords: vec2<f32>,
|
@location(1) tex_coords: vec2<f32>,
|
||||||
|
@location(2) color: vec4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
@builtin(position) clip_position: vec4<f32>,
|
@builtin(position) clip_position: vec4<f32>,
|
||||||
@location(0) tex_coords: vec2<f32>,
|
@location(0) tex_coords: vec2<f32>,
|
||||||
|
@location(1) color: vec4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
|
|
@ -21,7 +23,8 @@ fn vs_main(
|
||||||
) -> VertexOutput {
|
) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.tex_coords = model.tex_coords;
|
out.tex_coords = model.tex_coords;
|
||||||
out.clip_position = /*camera.view_proj **/ vec4<f32>(model.position, 1.0);
|
out.color = model.color;
|
||||||
|
out.clip_position = camera.view_proj * vec4<f32>(model.position, 1.0);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use chrono::Local;
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use image::{DynamicImage, GenericImage, GenericImageView, ImageFormat};
|
use image::{DynamicImage, GenericImage, GenericImageView, ImageFormat};
|
||||||
use comet_log::*;
|
use comet_log::*;
|
||||||
|
|
@ -165,7 +164,7 @@ impl TextureAtlas {
|
||||||
//base.save_with_format(output_path, ImageFormat::Png).expect("Failed to save texture atlas");
|
//base.save_with_format(output_path, ImageFormat::Png).expect("Failed to save texture atlas");
|
||||||
|
|
||||||
info!("Texture atlas created!");
|
info!("Texture atlas created!");
|
||||||
debug!(format!("{:?}", regions));
|
//debug!(format!("{:?}", regions));
|
||||||
|
|
||||||
/*let t1 = Instant::now();
|
/*let t1 = Instant::now();
|
||||||
let delta = t1.duration_since(t0);
|
let delta = t1.duration_since(t0);
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,15 @@ use wgpu::Color;
|
||||||
pub struct Vertex {
|
pub struct Vertex {
|
||||||
position: [f32; 3],
|
position: [f32; 3],
|
||||||
tex_coords: [f32; 2],
|
tex_coords: [f32; 2],
|
||||||
|
color: [f32; 4]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
pub fn new(position: [f32; 3], tex_coords: [f32; 2]) -> Self {
|
pub fn new(position: [f32; 3], tex_coords: [f32; 2], color: [f32; 4]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
position,
|
position,
|
||||||
tex_coords
|
tex_coords,
|
||||||
|
color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,6 +25,10 @@ impl Vertex {
|
||||||
self.tex_coords = new_tex_coords
|
self.tex_coords = new_tex_coords
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_color(&mut self, new_color: [f32; 4]) {
|
||||||
|
self.color = new_color
|
||||||
|
}
|
||||||
|
|
||||||
pub fn desc() -> wgpu::VertexBufferLayout<'static> {
|
pub fn desc() -> wgpu::VertexBufferLayout<'static> {
|
||||||
wgpu::VertexBufferLayout {
|
wgpu::VertexBufferLayout {
|
||||||
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
|
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
|
||||||
|
|
@ -37,6 +43,11 @@ impl Vertex {
|
||||||
offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
||||||
shader_location: 1,
|
shader_location: 1,
|
||||||
format: wgpu::VertexFormat::Float32x2,
|
format: wgpu::VertexFormat::Float32x2,
|
||||||
|
},
|
||||||
|
wgpu::VertexAttribute {
|
||||||
|
offset: std::mem::size_of::<[f32; 5]>() as wgpu::BufferAddress,
|
||||||
|
shader_location: 2,
|
||||||
|
format: wgpu::VertexFormat::Float32x4,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,7 @@ pub use comet_app as app;
|
||||||
pub use comet_colors as colors;
|
pub use comet_colors as colors;
|
||||||
pub use comet_input as input;
|
pub use comet_input as input;
|
||||||
pub use comet_log as log;
|
pub use comet_log as log;
|
||||||
|
|
||||||
|
pub mod prelude {
|
||||||
|
pub use comet_app::App;
|
||||||
|
}
|
||||||
122
src/main.rs
122
src/main.rs
|
|
@ -4,64 +4,89 @@ use comet::{
|
||||||
ApplicationType::*
|
ApplicationType::*
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
renderer::Renderer,
|
||||||
ecs::World,
|
ecs::*,
|
||||||
math::*,
|
math::*,
|
||||||
input::keyboard::*,
|
input::keyboard::*,
|
||||||
log::*
|
log::*
|
||||||
};
|
};
|
||||||
use winit::event::{WindowEvent};
|
|
||||||
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D};
|
|
||||||
use comet_input::mouse::{mouse_entered, mouse_pressed, Button};
|
|
||||||
|
|
||||||
fn input(event: &WindowEvent, app: &mut App, renderer: &mut Renderer) {
|
use winit_input_helper::WinitInputHelper;
|
||||||
match event {
|
use comet_input::input_handler::InputHandler;
|
||||||
_ if key_pressed(event, Key::Escape) => app.quit(),
|
|
||||||
_ if key_pressed(event, Key::KeyC) => { renderer.clear_buffers() }
|
fn update_position(input: WinitInputHelper, transform: &mut Transform2D, dt: f32) {
|
||||||
_ if key_pressed(event, Key::KeyE) => {
|
let mut direction = Vec2::ZERO;
|
||||||
|
let previous = transform.position().clone();
|
||||||
|
|
||||||
|
if input.key_held(Key::KeyW) {
|
||||||
|
direction += Vec2::Y;
|
||||||
|
}
|
||||||
|
if input.key_held(Key::KeyA) {
|
||||||
|
direction -= Vec2::X;
|
||||||
|
}
|
||||||
|
if input.key_held(Key::KeyS) {
|
||||||
|
direction -= Vec2::Y;
|
||||||
|
}
|
||||||
|
if input.key_held(Key::KeyD) {
|
||||||
|
direction += Vec2::X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if direction != Vec2::ZERO {
|
||||||
|
let normalized_dir = direction.normalize();
|
||||||
|
if normalized_dir.x().is_nan() || normalized_dir.y().is_nan() {
|
||||||
|
error!("Direction is NaN! X: {}, Y: {}", normalized_dir.x(), normalized_dir.y());
|
||||||
|
}
|
||||||
|
let displacement = normalized_dir * 777.7 * dt;
|
||||||
|
transform.translate(displacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transform.position().as_vec() - previous.as_vec()).x() > 13.0 {
|
||||||
|
debug!("Actual Displacement: {:?}", transform.position().as_vec() - previous.as_vec());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(world: &mut World) {
|
||||||
|
world.register_component::<Renderer2D>();
|
||||||
|
//world.register_component::<Rectangle2D>();
|
||||||
|
|
||||||
let mut renderer2d = Renderer2D::new();
|
let mut renderer2d = Renderer2D::new();
|
||||||
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
||||||
renderer2d.set_visibility(true);
|
renderer2d.set_visibility(true);
|
||||||
|
|
||||||
let id = app.world_mut().new_entity();
|
|
||||||
app.world_mut().add_component(id as usize, renderer2d.clone());
|
|
||||||
app.world_mut().add_component(0, renderer2d);
|
|
||||||
|
|
||||||
let transform = app.world_mut().get_component_mut::<Transform2D>(id as usize);
|
|
||||||
transform.position_mut().set_x(0.5);
|
|
||||||
|
|
||||||
debug!(format!("{:?}", app.world().components().get_component::<Renderer2D>(0)));
|
|
||||||
},
|
|
||||||
_ if key_pressed(event, Key::KeyW) => {
|
|
||||||
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
|
||||||
let y = transform.position().y();
|
|
||||||
transform.position_mut().set_y(y + 0.1);
|
|
||||||
},
|
|
||||||
_ if key_pressed(event, Key::KeyA) => {
|
|
||||||
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
|
||||||
let x = transform.position().x();
|
|
||||||
transform.position_mut().set_x(x - 0.1);
|
|
||||||
},
|
|
||||||
_ if key_pressed(event, Key::KeyS) => {
|
|
||||||
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
|
||||||
let y = transform.position().y();
|
|
||||||
transform.position_mut().set_y(y - 0.1);
|
|
||||||
},
|
|
||||||
_ if key_pressed(event, Key::KeyD) => {
|
|
||||||
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
|
||||||
let x = transform.position().x();
|
|
||||||
transform.position_mut().set_x(x + 0.1);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(world: &mut World, renderer: &mut Renderer) {
|
|
||||||
if !world.components().contains_components(ComponentSet::from_ids(vec![Transform2D::type_id(), Renderer2D::type_id()])) {
|
|
||||||
world.register_component::<Renderer2D>();
|
|
||||||
}
|
|
||||||
if world.entities().len() == 0 {
|
|
||||||
let id = world.new_entity();
|
let id = world.new_entity();
|
||||||
|
world.add_component(id as usize, renderer2d.clone());
|
||||||
|
|
||||||
|
let transform = world.get_component_mut::<Transform2D>(id as usize);
|
||||||
|
transform.translate(Vec2::X*5.0);
|
||||||
|
|
||||||
|
world.add_component(id as usize, renderer2d);
|
||||||
|
|
||||||
|
/*let rectangle2d = Rectangle2D::new(*tranform.position(), Vec2::new(0.1, 0.1));
|
||||||
|
world.add_component(id as usize, rectangle2d);
|
||||||
|
|
||||||
|
let id2 = world.new_entity();
|
||||||
|
let tranform2 = world.get_component_mut::<Transform2D>(id as usize);
|
||||||
|
let rectangle = Rectangle2D::new(*tranform2.position(), Vec2::new(0.1, 0.1));
|
||||||
|
|
||||||
|
world.add_component(id2 as usize, rectangle);*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update(app: &mut App, renderer: &mut Renderer, dt: f32) {
|
||||||
|
if app.key_pressed(Key::Escape) { app.quit() }
|
||||||
|
if app.key_pressed(Key::KeyC) { app.set_time_step(0.0016667) }
|
||||||
|
if app.key_pressed(Key::KeyV) { app.set_time_step(0.0166667) }
|
||||||
|
if app.key_pressed(Key::KeyE) { app.world_mut().get_component_mut::<Transform2D>(0).translate([0f32,0f32].into()) }
|
||||||
|
if app.key_held(Key::KeyW)
|
||||||
|
|| app.key_held(Key::KeyA)
|
||||||
|
|| app.key_held(Key::KeyS)
|
||||||
|
|| app.key_held(Key::KeyD)
|
||||||
|
{
|
||||||
|
update_position(app.input_manager().clone(), app.world_mut().get_component_mut::<Transform2D>(0), dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
@ -69,6 +94,7 @@ fn main() {
|
||||||
.with_title("Comet App")
|
.with_title("Comet App")
|
||||||
.with_icon(r"resources/textures/comet_icon.png")
|
.with_icon(r"resources/textures/comet_icon.png")
|
||||||
.with_size(1920, 1080)
|
.with_size(1920, 1080)
|
||||||
.run(input, update)
|
.with_setup(setup)
|
||||||
|
.run(update)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue