mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38: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"] }
|
||||
chrono = "0.4.38"
|
||||
colored = "2.1.0"
|
||||
|
||||
winit_input_helper = "0.16.0"
|
||||
spin_sleep = "1.2.1"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0"
|
||||
|
@ -43,7 +44,7 @@ members = [
|
|||
"./crates/comet_ecs",
|
||||
"./crates/comet_input",
|
||||
"./crates/comet_log"
|
||||
]
|
||||
, "crates/comet_ui"]
|
||||
|
||||
[workspace.dependencies]
|
||||
comet_app = { path = "./crates/comet_app", workspace = true }
|
||||
|
@ -53,4 +54,4 @@ comet_renderer = { path = "./crates/comet_renderer", workspace = true }
|
|||
comet_resources = { path = "./crates/comet_resources", workspace = true }
|
||||
comet_ecs = { path = "./crates/comet_ecs", workspace = true }
|
||||
comet_input = { path = "./crates/comet_input", workspace = true }
|
||||
comet_log = { path = "./crates/comet_log", workspace = true }
|
||||
comet_log = { path = "./crates/comet_log", workspace = true }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "comet_app"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
@ -9,6 +9,7 @@ comet_renderer = { path = "../comet_renderer" }
|
|||
comet_resources = { path = "../comet_resources" }
|
||||
comet_colors = { path = "../comet_colors" }
|
||||
comet_log = { path = "../comet_log" }
|
||||
comet_input = { path = "../comet_input" }
|
||||
|
||||
winit = { version = "0.29", features = ["rwh_05"] }
|
||||
env_logger = "0.10"
|
||||
|
@ -18,6 +19,8 @@ log = "0.4.22"
|
|||
anyhow = "1.0.89"
|
||||
bytemuck = "1.18.0"
|
||||
chrono = "0.4.0"
|
||||
winit_input_helper = "0.16.0"
|
||||
spin_sleep = "1.2.1"
|
||||
|
||||
[dependencies.image]
|
||||
version = "0.24"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
||||
use comet_resources::{ResourceManager, Vertex};
|
||||
use comet_renderer::{Renderer};
|
||||
|
@ -13,6 +14,11 @@ use comet_colors::LinearRgba;
|
|||
use comet_ecs::math::Point3;
|
||||
use comet_log::*;
|
||||
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 {
|
||||
App2D,
|
||||
|
@ -24,6 +30,10 @@ pub struct App<'a> {
|
|||
icon: Option<Icon>,
|
||||
size: Option<LogicalSize<u32>>,
|
||||
clear_color: Option<LinearRgba>,
|
||||
setup: Option<fn(&mut World)>,
|
||||
input_manager: WinitInputHelper,
|
||||
delta_time: f32,
|
||||
update_timer: f32,
|
||||
world: World,
|
||||
fullscreen: bool,
|
||||
should_quit: bool
|
||||
|
@ -41,6 +51,10 @@ impl<'a> App<'a> {
|
|||
icon: None,
|
||||
size: None,
|
||||
clear_color: None,
|
||||
setup: None,
|
||||
input_manager: WinitInputHelper::new(),
|
||||
delta_time: 0.0,
|
||||
update_timer: 0.0166667,
|
||||
world,
|
||||
fullscreen: false,
|
||||
should_quit: false
|
||||
|
@ -67,6 +81,11 @@ impl<'a> App<'a> {
|
|||
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> {
|
||||
let image = image::open(path).expect("Failed to open icon image");
|
||||
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())
|
||||
}
|
||||
|
||||
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 {
|
||||
&self.world
|
||||
}
|
||||
|
@ -127,10 +101,37 @@ impl<'a> App<'a> {
|
|||
&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) {
|
||||
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 {
|
||||
let winit_window = winit::window::WindowBuilder::new()
|
||||
.with_title(app_title);
|
||||
|
@ -141,6 +142,13 @@ impl<'a> App<'a> {
|
|||
else {
|
||||
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() {
|
||||
winit_window.with_inner_size(size)
|
||||
}
|
||||
|
@ -151,66 +159,64 @@ impl<'a> App<'a> {
|
|||
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) {
|
||||
env_logger::init();
|
||||
async fn run_app<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
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 surface_configured = false;
|
||||
|
||||
window.set_maximized(true);
|
||||
|
||||
if let Some(setup) = self.setup {
|
||||
setup(&mut self.world);
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == renderer.window().id() => {
|
||||
Event::WindowEvent { ref event, window_id, }
|
||||
if window_id == renderer.window().id() => {
|
||||
match event {
|
||||
WindowEvent::CloseRequested {} => control_flow.exit(),
|
||||
WindowEvent::CloseRequested {} => elwt.exit(),
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
surface_configured = true;
|
||||
renderer.resize(*physical_size);
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
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() {
|
||||
Ok(_) => {}
|
||||
Err(
|
||||
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
|
||||
) => renderer.resize(renderer.size()),
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||
log::error!("OutOfMemory");
|
||||
control_flow.exit();
|
||||
error!("OutOfMemory");
|
||||
elwt.exit();
|
||||
}
|
||||
Err(wgpu::SurfaceError::Timeout) => {
|
||||
warn!("Surface timeout")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
input_manager(event, &mut self, &mut renderer);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -218,7 +224,7 @@ impl<'a> App<'a> {
|
|||
}).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) {
|
||||
pollster::block_on(self.run_app(input_manager, game_manager));
|
||||
pub fn run<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
||||
pollster::block_on(self.run_app(update));
|
||||
}
|
||||
}
|
|
@ -4,9 +4,10 @@ version = "0.2.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bit-set = "0.8.0"
|
||||
component_derive = { path = "./component_derive" }
|
||||
comet_math = { path = "../comet_math" }
|
||||
comet_resources = { path = "../comet_resources" }
|
||||
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::{
|
||||
Vec2,
|
||||
Vec3
|
||||
};
|
||||
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 #
|
||||
// ##################################################
|
||||
|
@ -43,6 +32,12 @@ pub struct Rotation3D {
|
|||
theta_z: f32
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Rectangle2D{
|
||||
position: Position2D,
|
||||
size: Vec2
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Renderer2D {
|
||||
is_visible: bool,
|
||||
|
@ -50,6 +45,53 @@ pub struct Renderer2D {
|
|||
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 {
|
||||
pub fn from_vec(vec: Vec2) -> Self {
|
||||
Self {
|
||||
|
@ -114,12 +156,44 @@ impl Position3D {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
//fn get_vertex_data(&self) -> Vec<Vertex>;
|
||||
impl Rectangle2D {
|
||||
pub fn new(position: Position2D, size: Vec2) -> Self {
|
||||
Self {
|
||||
position,
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -141,31 +215,6 @@ impl Render for Renderer2D {
|
|||
fn set_texture(&mut self, texture: &'static str) {
|
||||
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 {
|
||||
|
@ -184,6 +233,13 @@ impl Transform2D {
|
|||
pub fn rotation_mut(&mut self) -> &mut Rotation2D {
|
||||
&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 {
|
||||
|
@ -202,6 +258,4 @@ impl Transform3D {
|
|||
pub fn rotation_mut(&mut self) -> &mut Rotation3D {
|
||||
&mut self.rotation
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -23,16 +23,16 @@ pub struct World {
|
|||
}
|
||||
|
||||
impl World {
|
||||
pub fn new(dimension: &str) -> Self {
|
||||
pub fn new(application: &str) -> Self {
|
||||
let mut component_storage = ComponentStorage::new();
|
||||
match dimension {
|
||||
match application {
|
||||
"2D" => component_storage.register_component::<Transform2D>(0),
|
||||
"3D" => component_storage.register_component::<Transform3D>(0),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Self {
|
||||
dimension: dimension.to_string(),
|
||||
dimension: application.to_string(),
|
||||
id_queue: IdQueue::new(),
|
||||
next_id: 0,
|
||||
entities: Vec::new(),
|
||||
|
@ -118,7 +118,7 @@ impl World {
|
|||
self.id_queue.sorted_enqueue(entity_id as u32);
|
||||
self.get_next_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) {
|
||||
|
@ -179,12 +179,12 @@ impl World {
|
|||
pub fn register_component<T: Component + 'static>(&mut self) {
|
||||
self.components.register_component::<T>(self.entities.len());
|
||||
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) {
|
||||
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) {
|
||||
|
@ -201,14 +201,13 @@ impl World {
|
|||
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));
|
||||
}
|
||||
info!(format!("Added component {} to entity {}", T::type_name(), entity_id));
|
||||
debug!(format!("{:?}", self.archetypes));
|
||||
info!("Added component {} to entity {}", T::type_name(), entity_id);
|
||||
}
|
||||
|
||||
pub fn remove_component<T: Component + 'static>(&mut self, entity_id: usize) {
|
||||
self.components.remove_component::<T>(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 {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
[package]
|
||||
name = "comet_input"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
[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))
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use winit::event::{ElementState, KeyEvent, WindowEvent};
|
||||
use winit::keyboard::{ KeyCode, PhysicalKey};
|
||||
use winit::keyboard::{ KeyCode, PhysicalKey };
|
||||
|
||||
pub type Key = KeyCode;
|
||||
|
||||
|
@ -29,4 +29,18 @@ pub fn key_released(event: &WindowEvent, key_code: Key) -> bool {
|
|||
} => *code == key_code,
|
||||
_ => 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 mouse;
|
||||
pub mod input_handler;
|
||||
|
|
|
@ -1,47 +1,83 @@
|
|||
#[macro_export]
|
||||
macro_rules! info {
|
||||
($msg:expr) => {
|
||||
println!(
|
||||
"{} {} : {}",
|
||||
($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[32m\x1b[1mINFO\x1b[0m",
|
||||
$msg
|
||||
format!($fmt $(, $args)*)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($msg:expr) => {
|
||||
println!(
|
||||
"{} {} : {}",
|
||||
($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[34m\x1b[1mDEBUG\x1b[0m",
|
||||
$msg
|
||||
format!($fmt $(, $args)*)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! warn {
|
||||
($msg:expr) => {
|
||||
println!(
|
||||
"{} {} : {}",
|
||||
($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[33m\x1b[1mWARNING\x1b[0m",
|
||||
$msg
|
||||
format!($fmt $(, $args)*)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error {
|
||||
($msg:expr) => {
|
||||
println!(
|
||||
"{} {} : {}",
|
||||
($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[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]
|
||||
name = "comet_math"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
comet_log = { path = "../comet_log" }
|
||||
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)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[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 {
|
||||
x00: row1.x(), x01: row1.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> {
|
||||
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);
|
||||
|
@ -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) {
|
||||
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);
|
||||
|
@ -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 {
|
||||
self.x00 * self.x11
|
||||
- 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(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 {
|
||||
|
@ -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 {
|
||||
fn into(self) -> [[f32; 2]; 2] {
|
||||
[
|
||||
[self.x00, self.x01],
|
||||
[self.x10, self.x11],
|
||||
[self.x00, self.x10],
|
||||
[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 {
|
||||
x00: row1.x(), x01: row1.y(), x02: row1.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> {
|
||||
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);
|
||||
|
@ -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) {
|
||||
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);
|
||||
|
@ -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 {
|
||||
self.x00 * self.x11 * self.x22
|
||||
+ 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(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 {
|
||||
|
@ -412,9 +479,9 @@ impl Div<f32> for Mat3 {
|
|||
impl Into<[[f32; 3]; 3]> for Mat3 {
|
||||
fn into(self) -> [[f32; 3]; 3] {
|
||||
[
|
||||
[self.x00, self.x01, self.x02],
|
||||
[self.x10, self.x11, self.x12],
|
||||
[self.x20, self.x21, self.x22],
|
||||
[self.x00, self.x10, self.x20],
|
||||
[self.x01, self.x11, self.x21],
|
||||
[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 {
|
||||
x00: row1.x(), x01: row1.y(), x02: row1.z(), x03: row1.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 {
|
||||
let f = dir.normalize();
|
||||
let s = cross(f, up).normalize();
|
||||
|
@ -486,19 +562,19 @@ impl Mat4 {
|
|||
let cam = camera.to_vec();
|
||||
|
||||
|
||||
/*Mat4::new(
|
||||
Mat4::new(
|
||||
s.x().clone(), u.x().clone(), -f.x().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,
|
||||
-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,
|
||||
u.x().clone(), u.y().clone(), u.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
|
||||
)
|
||||
)*/
|
||||
|
||||
}
|
||||
|
||||
|
@ -524,22 +600,31 @@ impl Mat4 {
|
|||
let bottom = -ymax;
|
||||
let top = ymax;
|
||||
|
||||
/*Mat4::new(
|
||||
Mat4::new(
|
||||
(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, 0.0, -(far + near) / (far - near), -(2.0 * far * near) / (far - near),
|
||||
0.0, 0.0, -1.0, 0.0
|
||||
)*/
|
||||
)
|
||||
|
||||
Mat4::new(
|
||||
/*Mat4::new(
|
||||
(2.0 * near) / (right - left), 0.0, 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,
|
||||
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> {
|
||||
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);
|
||||
|
@ -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) {
|
||||
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);
|
||||
|
@ -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 {
|
||||
self.x00 * (self.x11 * (self.x22* self.x33 - self.x23 * 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
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -715,10 +834,10 @@ impl Mul<Mat4> for Mat4 {
|
|||
impl Into<[[f32; 4]; 4]> for Mat4 {
|
||||
fn into(self) -> [[f32; 4]; 4] {
|
||||
[
|
||||
[self.x00, self.x01, self.x02, self.x03],
|
||||
[self.x10, self.x11, self.x12, self.x13],
|
||||
[self.x20, self.x21, self.x22, self.x23],
|
||||
[self.x30, self.x31, self.x32, self.x33],
|
||||
[self.x00, self.x10, self.x20, self.x30],
|
||||
[self.x01, self.x11, self.x21, self.x31],
|
||||
[self.x02, self.x12, self.x22, self.x32],
|
||||
[self.x03, self.x13, self.x23, self.x33],
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::point::{Point2, Point3};
|
||||
use crate::quaternion::Quat;
|
||||
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 {
|
||||
fn dot(&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 {
|
||||
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 {
|
||||
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 #
|
||||
// ##################################################
|
||||
|
@ -181,17 +418,6 @@ impl Vec3 {
|
|||
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 {
|
||||
(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 {
|
||||
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 {
|
||||
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 #
|
||||
// ##################################################
|
||||
|
@ -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 {
|
||||
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 {
|
||||
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 {
|
||||
fn dot(&self, other: &Self) -> f32 {
|
||||
self.x * other.x + self.y * other.y
|
||||
|
@ -2607,7 +3069,8 @@ impl InnerSpace for Vec2 {
|
|||
.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()))
|
||||
}
|
||||
}
|
||||
|
@ -2626,7 +3089,7 @@ impl InnerSpace for Vec3 {
|
|||
.length()
|
||||
}
|
||||
|
||||
fn vAngle(&self, other: &Self) -> f32 {
|
||||
fn v_angle(&self, other: &Self) -> f32 {
|
||||
acos(dot(self, other) / (self.length() * other.length()))
|
||||
}
|
||||
}
|
||||
|
@ -2646,7 +3109,7 @@ impl InnerSpace for Vec4 {
|
|||
.length()
|
||||
}
|
||||
|
||||
fn vAngle(&self, other: &Self) -> f32 {
|
||||
fn v_angle(&self, other: &Self) -> f32 {
|
||||
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 {
|
||||
v1.vAngle(v2)
|
||||
v1.v_angle(v2)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
[package]
|
||||
name = "comet_renderer"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
comet_ecs = { path = "../comet_ecs" }
|
||||
comet_math = { path = "../comet_math" }
|
||||
comet_resources = { path = "../comet_resources" }
|
||||
comet_colors = { path = "../comet_colors" }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use comet_math::Point3;
|
||||
use comet_math::{Point3, Vec2, Vec3};
|
||||
|
||||
#[rustfmt::skip]
|
||||
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;
|
||||
|
||||
pub struct Camera {
|
||||
eye: cgmath::Point3<f32>,
|
||||
target: cgmath::Point3<f32>,
|
||||
up: cgmath::Vector3<f32>,
|
||||
aspect: f32,
|
||||
fovy: f32,
|
||||
znear: f32,
|
||||
zfar: f32,
|
||||
zoom: f32,
|
||||
dimension: Vec2,
|
||||
position: Vec3
|
||||
}
|
||||
|
||||
impl Camera {
|
||||
pub fn new(
|
||||
eye: cgmath::Point3<f32>,
|
||||
target: cgmath::Point3<f32>,
|
||||
up: cgmath::Vector3<f32>,
|
||||
aspect: f32,
|
||||
fovy: f32,
|
||||
znear: f32,
|
||||
zfar: f32,
|
||||
zoom: f32,
|
||||
dimension: Vec2,
|
||||
position: Vec3
|
||||
) -> Self {
|
||||
Self {
|
||||
eye,
|
||||
target,
|
||||
up,
|
||||
aspect,
|
||||
fovy,
|
||||
znear,
|
||||
zfar,
|
||||
zoom,
|
||||
dimension,
|
||||
position
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_view_projection_matrix(&self) -> cgmath::Matrix4<f32> {
|
||||
// 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.
|
||||
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 cgmath::num_traits::FloatConst;
|
||||
use image::GenericImageView;
|
||||
use log::info;
|
||||
use wgpu::Color;
|
||||
use wgpu::util::DeviceExt;
|
||||
use winit::{
|
||||
|
@ -16,9 +15,10 @@ use winit::{
|
|||
};
|
||||
use winit::dpi::Position;
|
||||
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::{Mat4, Point3, Vec3};
|
||||
use comet_math::{Mat4, Point3, Vec2, Vec3};
|
||||
use comet_resources::{ResourceManager, texture, Vertex, Texture};
|
||||
use comet_resources::texture_atlas::TextureRegion;
|
||||
use crate::camera::{Camera, CameraUniform};
|
||||
|
@ -67,10 +67,10 @@ pub struct Renderer<'a> {
|
|||
diffuse_texture: texture::Texture,
|
||||
diffuse_bind_group: wgpu::BindGroup,
|
||||
resource_manager: ResourceManager,
|
||||
/*camera: Camera,
|
||||
camera: Camera,
|
||||
camera_uniform: CameraUniform,
|
||||
camera_buffer: wgpu::Buffer,
|
||||
camera_bind_group: wgpu::BindGroup,*/
|
||||
camera_bind_group: wgpu::BindGroup,
|
||||
}
|
||||
|
||||
impl<'a> Renderer<'a> {
|
||||
|
@ -199,64 +199,47 @@ impl<'a> Renderer<'a> {
|
|||
label: Some("diffuse_bind_group"),
|
||||
});
|
||||
|
||||
/*let camera = Camera::new(
|
||||
// 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 camera = Camera::new(1.0, Vec2::new(2.0, 2.0), Vec3::new(0.0, 0.0, 0.0));
|
||||
|
||||
let mut camera_uniform = CameraUniform::new();
|
||||
camera_uniform.update_view_proj(&camera);
|
||||
let mut camera_uniform = CameraUniform::new();
|
||||
camera_uniform.update_view_proj(&camera);
|
||||
|
||||
let camera_buffer = device.create_buffer_init(
|
||||
&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Camera Buffer"),
|
||||
contents: bytemuck::cast_slice(&[camera_uniform]),
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
}
|
||||
);
|
||||
let camera_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Camera Buffer"),
|
||||
contents: bytemuck::cast_slice(&[camera_uniform]),
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
|
||||
let camera_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::VERTEX,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}
|
||||
],
|
||||
label: Some("camera_bind_group_layout"),
|
||||
});
|
||||
let camera_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::VERTEX,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
label: Some("camera_bind_group_layout"),
|
||||
});
|
||||
|
||||
let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &camera_bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: camera_buffer.as_entire_binding(),
|
||||
}
|
||||
],
|
||||
label: Some("camera_bind_group"),
|
||||
});*/
|
||||
let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &camera_bind_group_layout,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: camera_buffer.as_entire_binding(),
|
||||
}],
|
||||
label: Some("camera_bind_group"),
|
||||
});
|
||||
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Render Pipeline Layout"),
|
||||
bind_group_layouts: &[
|
||||
&texture_bind_group_layout,
|
||||
//&camera_bind_group_layout,
|
||||
&camera_bind_group_layout,
|
||||
],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
@ -347,10 +330,10 @@ impl<'a> Renderer<'a> {
|
|||
diffuse_texture,
|
||||
diffuse_bind_group,
|
||||
resource_manager,
|
||||
/*camera,
|
||||
camera,
|
||||
camera_uniform,
|
||||
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);
|
||||
|
||||
vec![
|
||||
Vertex :: new ( [-bound_x, bound_y, 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], [1.0, 1.0]) ,
|
||||
Vertex :: new ( [ bound_x, bound_y, 0.0], [1.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], [0.0, 0.0, 0.0, 0.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], [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);
|
||||
|
||||
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, 1.0] ),
|
||||
Vertex :: new ( [ bound_x, -bound_y, 0.0], [1.0, 1.0]) ,
|
||||
Vertex :: new ( [ bound_x, bound_y, 0.0], [1.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], [0.0, 0.0, 0.0, 0.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], [0.0, 0.0, 0.0, 0.0] )
|
||||
];
|
||||
|
||||
/*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());
|
||||
}
|
||||
|
||||
error!(format!("{:?}", 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);
|
||||
|
||||
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.y1()] ),
|
||||
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.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()], [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()], [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()], [0.0, 0.0, 0.0, 0.0] )
|
||||
];
|
||||
|
||||
let buffer_size = self.vertex_data.len() as u16;
|
||||
|
@ -588,6 +569,45 @@ impl<'a> Renderer<'a> {
|
|||
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 {
|
||||
&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();
|
||||
self.deltatime = now.duration_since(self.last_frame_time).as_secs_f32(); // Time delta in seconds
|
||||
self.last_frame_time = now;
|
||||
self.deltatime
|
||||
}
|
||||
|
||||
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_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_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
||||
render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
// Vertex shader
|
||||
/*struct CameraUniform {
|
||||
struct CameraUniform {
|
||||
view_proj: mat4x4<f32>,
|
||||
};
|
||||
@group(1) @binding(0) // 1.
|
||||
var<uniform> camera: CameraUniform;*/
|
||||
var<uniform> camera: CameraUniform;
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) tex_coords: vec2<f32>,
|
||||
@location(2) color: vec4<f32>,
|
||||
}
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) tex_coords: vec2<f32>,
|
||||
@location(1) color: vec4<f32>,
|
||||
}
|
||||
|
||||
@vertex
|
||||
|
@ -21,7 +23,8 @@ fn vs_main(
|
|||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use chrono::Local;
|
||||
use std::time::Instant;
|
||||
use image::{DynamicImage, GenericImage, GenericImageView, ImageFormat};
|
||||
use comet_log::*;
|
||||
|
@ -165,7 +164,7 @@ impl TextureAtlas {
|
|||
//base.save_with_format(output_path, ImageFormat::Png).expect("Failed to save texture atlas");
|
||||
|
||||
info!("Texture atlas created!");
|
||||
debug!(format!("{:?}", regions));
|
||||
//debug!(format!("{:?}", regions));
|
||||
|
||||
/*let t1 = Instant::now();
|
||||
let delta = t1.duration_since(t0);
|
||||
|
|
|
@ -5,13 +5,15 @@ use wgpu::Color;
|
|||
pub struct Vertex {
|
||||
position: [f32; 3],
|
||||
tex_coords: [f32; 2],
|
||||
color: [f32; 4]
|
||||
}
|
||||
|
||||
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 {
|
||||
position,
|
||||
tex_coords
|
||||
tex_coords,
|
||||
color
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +25,10 @@ impl Vertex {
|
|||
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> {
|
||||
wgpu::VertexBufferLayout {
|
||||
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,
|
||||
shader_location: 1,
|
||||
format: wgpu::VertexFormat::Float32x2,
|
||||
},
|
||||
wgpu::VertexAttribute {
|
||||
offset: std::mem::size_of::<[f32; 5]>() as wgpu::BufferAddress,
|
||||
shader_location: 2,
|
||||
format: wgpu::VertexFormat::Float32x4,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6,4 +6,8 @@ pub use comet_ecs as ecs;
|
|||
pub use comet_app as app;
|
||||
pub use comet_colors as colors;
|
||||
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;
|
||||
}
|
118
src/main.rs
118
src/main.rs
|
@ -4,64 +4,89 @@ use comet::{
|
|||
ApplicationType::*
|
||||
},
|
||||
renderer::Renderer,
|
||||
ecs::World,
|
||||
ecs::*,
|
||||
math::*,
|
||||
input::keyboard::*,
|
||||
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) {
|
||||
match event {
|
||||
_ if key_pressed(event, Key::Escape) => app.quit(),
|
||||
_ if key_pressed(event, Key::KeyC) => { renderer.clear_buffers() }
|
||||
_ if key_pressed(event, Key::KeyE) => {
|
||||
let mut renderer2d = Renderer2D::new();
|
||||
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
||||
renderer2d.set_visibility(true);
|
||||
use winit_input_helper::WinitInputHelper;
|
||||
use comet_input::input_handler::InputHandler;
|
||||
|
||||
let id = app.world_mut().new_entity();
|
||||
app.world_mut().add_component(id as usize, renderer2d.clone());
|
||||
app.world_mut().add_component(0, renderer2d);
|
||||
fn update_position(input: WinitInputHelper, transform: &mut Transform2D, dt: f32) {
|
||||
let mut direction = Vec2::ZERO;
|
||||
let previous = transform.position().clone();
|
||||
|
||||
let transform = app.world_mut().get_component_mut::<Transform2D>(id as usize);
|
||||
transform.position_mut().set_x(0.5);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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 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();
|
||||
fn setup(world: &mut World) {
|
||||
world.register_component::<Renderer2D>();
|
||||
//world.register_component::<Rectangle2D>();
|
||||
|
||||
let mut renderer2d = Renderer2D::new();
|
||||
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
||||
renderer2d.set_visibility(true);
|
||||
|
||||
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() {
|
||||
|
@ -69,6 +94,7 @@ fn main() {
|
|||
.with_title("Comet App")
|
||||
.with_icon(r"resources/textures/comet_icon.png")
|
||||
.with_size(1920, 1080)
|
||||
.run(input, update)
|
||||
.with_setup(setup)
|
||||
.run(update)
|
||||
;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue