diff --git a/editor/.gitignore b/editor/.gitignore deleted file mode 100644 index ccb5166..0000000 --- a/editor/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -.vscode \ No newline at end of file diff --git a/editor/Cargo.lock b/editor/Cargo.lock deleted file mode 100644 index 399e5b4..0000000 --- a/editor/Cargo.lock +++ /dev/null @@ -1,46 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "bitflags" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" - -[[package]] -name = "sdl3" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce0693cede7f7901e968e5539f87174d0fb5fac5d489a3e3be52b2b4a0b49c5" -dependencies = [ - "bitflags", - "lazy_static", - "libc", - "sdl3-sys", -] - -[[package]] -name = "sdl3-sys" -version = "0.6.1+SDL-3.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d73fc820b0b6b9bd0557de7b799ec9da1ca4f35fcd1cb42f7ceb85e640d1477" - -[[package]] -name = "skate-slope" -version = "0.1.0" -dependencies = [ - "sdl3", -] diff --git a/editor/Cargo.toml b/editor/Cargo.toml deleted file mode 100644 index 0ec6a64..0000000 --- a/editor/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "skate-slope" -version = "0.1.0" -edition = "2021" - -[dependencies] -sdl3 = "0.17.3" diff --git a/editor/src/engine/error.rs b/editor/src/engine/error.rs deleted file mode 100644 index 68f6df9..0000000 --- a/editor/src/engine/error.rs +++ /dev/null @@ -1 +0,0 @@ -pub type Error = String; \ No newline at end of file diff --git a/editor/src/engine/game.rs b/editor/src/engine/game.rs deleted file mode 100644 index b7232d3..0000000 --- a/editor/src/engine/game.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::engine::{ - math::{V2, V3}, - Triangle2, -}; -use std::{marker::PhantomData, time::Duration}; - -use super::error::Error; - -pub trait Io> { - fn run(&mut self, game: &mut G); -} - -pub trait Renderer { - fn draw_rect(&mut self, pos: V2, size: V2, color: Color); - fn draw_point(&mut self, pos: V2, color: Color); - fn draw_line(&mut self, from: V2, to: V2, color: Color); - fn draw_triangle(&mut self, triangle: Triangle2, color: Color); - fn draw_triangles(&mut self, triangles: &[Triangle2], color: Color); -} - -#[derive(Clone, Copy)] -pub enum Color { - Hex(u32), - White, - Green, - Red, - Cyan, - Black, -} - -#[derive(PartialEq, Eq, Hash)] -pub enum Key { - R, - Left, - Right, - Down, - Up, - W, - A, - S, - D, -} - -pub enum Event { - KeyUp { key: Key }, - KeyDown { key: Key }, -} - -pub trait Game { - fn update(&mut self, delta_time: Duration); - fn render(&mut self, r: &mut R); - fn event(&mut self, event: Event); -} diff --git a/editor/src/engine/math.rs b/editor/src/engine/math.rs deleted file mode 100644 index 129aedb..0000000 --- a/editor/src/engine/math.rs +++ /dev/null @@ -1,211 +0,0 @@ -use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; - -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct V2(pub f64, pub f64); - -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct V3(pub f64, pub f64, pub f64); - -impl V3 { - pub fn project_2d(&self) -> V2 { - // V2(self.0 / self.2, self.1 / self.2) - let c = V3(0.0, 0.0, -1.0); - let d = *self - c; - let e = V3(0.0, 0.0, 0.0) - c; - V2(e.2 / d.2 * d.0 + e.0, e.2 / d.2 * d.1 + e.1) - } - - pub fn cross(&self, rhs: Self) -> Self { - let V3(ax, ay, az) = self; - let V3(bx, by, bz) = rhs; - Self(ay * bz - az * by, az * bx - ax * bz, ax * by - ay * bx) - } - - pub fn dot(&self, rhs: Self) -> f64 { - let V3(ax, ay, az) = self; - let V3(bx, by, bz) = rhs; - ax * bx + ay * by + az * bz - } - - pub fn len(&self) -> f64 { - f64::sqrt(self.0.powi(2) + self.1.powi(2) + self.2.powi(2)) - } - - pub fn unit(&self) -> Self { - self.map(|v| v / self.len()) - } - - pub fn map f64>(&self, func: F) -> Self { - V3(func(self.0), func(self.1), func(self.2)) - } - - pub fn rotate(&self, rot: Self) -> Self { - M3x3::new_rotate_z(rot.2) - * (M3x3::new_rotate_y(rot.1) * (M3x3::new_rotate_x(rot.0) * *self)) - } - - pub fn distance(&self, rhs: Self) -> f64 { - (*self - rhs).len() - } -} - -impl Add for V3 { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2) - } -} -impl Sub for V3 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self::Output { - Self(self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2) - } -} - -impl Mul for V3 { - type Output = V3; - - fn mul(self, rhs: f64) -> Self::Output { - Self(self.0 * rhs, self.1 * rhs, self.2 * rhs) - } -} - -impl Mul for V3 { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - Self(self.0 * rhs.0, self.1 * rhs.1, self.2 * rhs.2) - } -} - -impl Add<&Self> for V3 { - type Output = Self; - - fn add(self, rhs: &Self) -> Self::Output { - Self(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2) - } -} -impl Sub<&Self> for V3 { - type Output = Self; - - fn sub(self, rhs: &Self) -> Self::Output { - Self(self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2) - } -} - -impl AddAssign for V3 { - fn add_assign(&mut self, rhs: Self) { - *self = *self + rhs; - } -} -impl SubAssign for V3 { - fn sub_assign(&mut self, rhs: Self) { - *self = *self - rhs; - } -} -impl MulAssign for V3 { - fn mul_assign(&mut self, rhs: f64) { - *self = *self * rhs; - } -} - -#[derive(Clone, PartialEq, Debug)] -pub struct Triangle2(pub V2, pub V2, pub V2); - -#[derive(Clone, PartialEq, Debug)] -pub struct Triangle3(pub V3, pub V3, pub V3); - -impl Triangle3 { - pub fn normal(&self) -> V3 { - (self.1 - self.0).cross(self.2 - self.1) - } - - pub fn translate(&self, offset: V3) -> Self { - Self(self.0 + offset, self.1 + offset, self.2 + offset) - } - - pub fn project_2d(&self) -> Triangle2 { - Triangle2( - self.0.project_2d(), - self.1.project_2d(), - self.2.project_2d(), - ) - } - - pub fn middle(&self) -> V3 { - (self.0 + self.1 + self.2).map(|v| v / 3.0) - } - - pub fn points(&self) -> [V3; 3] { - [self.0, self.1, self.2] - } -} - -struct M3x3([f64; 9]); - -impl M3x3 { - #[rustfmt::skip] - pub fn new_rotate_x(angle: f64) -> Self { - Self([ - 1.0, 0.0, 0.0, - 0.0, f64::cos(angle), -f64::sin(angle), - 0.0, f64::sin(angle), f64::cos(angle), - ]) - } - - #[rustfmt::skip] - pub fn new_rotate_y(angle: f64) -> Self { - Self([ - f64::cos(angle), 0.0, f64::sin(angle), - 0.0, 1.0, 0.0, - -f64::sin(angle), 0.0, f64::cos(angle), - ]) - } - - #[rustfmt::skip] - pub fn new_rotate_z(angle: f64) -> Self { - Self([ - f64::cos(angle), -f64::sin(angle), 0.0, - f64::sin(angle), f64::cos(angle), 0.0, - 0.0, 0.0, 1.0, - ]) - } -} - -impl Mul for M3x3 { - type Output = V3; - - fn mul(self, rhs: V3) -> Self::Output { - let V3(x, y, z) = rhs; - let [xx, xy, xz, yx, yy, yz, zx, zy, zz] = self.0; - V3( - x * xx + y * xy + z * xz, - x * yx + y * yy + z * yz, - x * zx + y * zy + z * zz, - ) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn v3_ops() { - let v3 = |v: f64| V3(v, v, v); - - assert_eq!(v3(1.0) + v3(2.0), v3(3.0)); - assert_eq!(v3(3.0) - v3(2.0), v3(1.0)); - assert_eq!(v3(2.0) * 2.0, v3(4.0)); - - let mut a = v3(1.0); - a += v3(2.0); - assert_eq!(a, v3(3.0)); - - let mut a = v3(2.0); - a *= 2.0; - assert_eq!(a, v3(4.0)); - } -} diff --git a/editor/src/engine/mod.rs b/editor/src/engine/mod.rs deleted file mode 100644 index 91f2d3f..0000000 --- a/editor/src/engine/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![allow(unused_imports)] - -mod error; -mod game; -mod math; -mod r3d; -mod scene; -mod sdl_io; -mod shapes; - -pub use error::*; -pub use game::*; -pub use math::*; -pub use r3d::*; -pub use scene::*; -pub use sdl_io::*; -pub use shapes::*; diff --git a/editor/src/engine/r3d.rs b/editor/src/engine/r3d.rs deleted file mode 100644 index fe09817..0000000 --- a/editor/src/engine/r3d.rs +++ /dev/null @@ -1,72 +0,0 @@ -use crate::engine::{game::Renderer, Color, Shape, Triangle2, Triangle3, V2, V3}; - -pub struct R3d<'r, R: Renderer> { - r: &'r mut R, - triangle_buffer: Vec, -} - -static CAMERA_POS: V3 = V3(0.0, 0.0, -1.0); - -impl<'r, R: Renderer> R3d<'r, R> { - pub fn new(r: &'r mut R) -> Self { - Self { - r, - triangle_buffer: Vec::new(), - } - } - - pub fn draw_line(&mut self, from: V3, to: V3, color: Color) { - self.r.draw_line(from.project_2d(), to.project_2d(), color); - } - - pub fn draw_triangle(&mut self, triangle: Triangle3, color: Color) { - let triangle = triangle.translate(CAMERA_POS).project_2d(); - - self.r.draw_line(triangle.0, triangle.1, color); - self.r.draw_line(triangle.1, triangle.2, color); - self.r.draw_line(triangle.2, triangle.0, color); - } - - pub fn draw_shape(&mut self, pos: V3, shape: &Shape, outline_color: Color, fill_color: Color) { - self.triangle_buffer.clear(); - self.triangle_buffer - .extend(shape.faces().map(|tri| tri.translate(pos).project_2d())); - - self.r.draw_triangles(&self.triangle_buffer, fill_color); - - for face in shape.faces() { - if face.normal().dot(face.0 - CAMERA_POS + pos) >= 0.0 { - continue; - } - // let pxyz = face.middle() + face.normal(); - // self.draw_line( - // face.middle() + pos, - // face.middle() + (face.1 - face.0).unit() * 0.02 + pos, - // Color::HEX(0xffaa00), - // ); - // self.draw_line( - // face.middle() + pos, - // face.middle() + (face.2 - face.1).unit() * 0.02 + pos, - // Color::HEX(0x00ffaa), - // ); - // self.draw_line( - // face.middle() + pos, - // face.middle() + (face.0 - face.2).unit() * 0.02 + pos, - // Color::HEX(0xaa00ff), - // ); - // self.draw_line(face.middle() + pos, pxyz + pos, Color::HEX(0xffffff)); - - // self.draw_triangle(face.translate(pos - CAMERA_POS), outline_color); - self.r.draw_line( - (face.0 + pos).project_2d(), - (face.1 + pos).project_2d(), - outline_color, - ); - self.r.draw_line( - (face.2 + pos).project_2d(), - (face.0 + pos).project_2d(), - outline_color, - ); - } - } -} diff --git a/editor/src/engine/scene.rs b/editor/src/engine/scene.rs deleted file mode 100644 index 993282c..0000000 --- a/editor/src/engine/scene.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::engine::{Color, Renderer, Shape, Triangle3, V3}; - -pub struct DrawnTriangle { - triangle: Triangle3, - outline_color: Color, - fill_color: Color, -} - -pub struct Scene { - objects: Vec, -} - -impl Scene { - pub fn new() -> Self { - Self { - objects: Vec::new(), - } - } - - pub fn render(&mut self, r: &mut R, camera: V3) { - let mut indices_with_scores = self - .objects - .iter() - .enumerate() - .map(|(i, object)| { - let mut point_scores = object.triangle.points().map(|p| p.distance(camera)); - point_scores.sort_by(|a, b| a.total_cmp(b)); - - (i, point_scores[0]) - }) - .rev() - .collect::>(); - - indices_with_scores.sort_by(|a, b| b.1.total_cmp(&a.1)); - - for (i, _) in indices_with_scores { - let object = &self.objects[i]; - - // check if behind camera - if !(object.triangle.0 .2 >= -1.0 - && object.triangle.1 .2 >= -1.0 - && object.triangle.2 .2 >= -1.0) - { - continue; - } - - if object.triangle.normal().dot(object.triangle.0 - camera) >= 0.0 { - continue; - } - - let triangle = object.triangle.project_2d(); - - r.draw_triangle(triangle.clone(), object.fill_color); - r.draw_line(triangle.0, triangle.1, object.outline_color); - r.draw_line(triangle.0, triangle.2, object.outline_color); - } - } - - pub fn draw_shape(&mut self, pos: V3, shape: &Shape, outline_color: Color, fill_color: Color) { - for triangle in shape.faces() { - self.objects.push(DrawnTriangle { - triangle: triangle.translate(pos), - outline_color, - fill_color, - }) - } - } -} diff --git a/editor/src/engine/sdl_io.rs b/editor/src/engine/sdl_io.rs deleted file mode 100644 index f5c64fe..0000000 --- a/editor/src/engine/sdl_io.rs +++ /dev/null @@ -1,280 +0,0 @@ -use std::time::{Duration, Instant}; - -use sdl3::{ - event::Event, - keyboard::Keycode, - pixels::{Color as SdlColor, FColor, PixelFormat}, - rect::Point, - render::{Canvas, FPoint, FRect, Vertex, VertexIndices}, - video::Window, - Sdl, VideoSubsystem, -}; - -use crate::engine::{ - error::Error, - game, - math::{V2, V3}, - Color, Renderer, Triangle2, -}; - -pub static WIDTH: f64 = 1280.0; -pub static HEIGHT: f64 = 720.0; - -pub struct SdlIo { - sdl_context: Sdl, - video_subsystem: VideoSubsystem, - canvas: Canvas, -} - -impl SdlIo { - pub fn new() -> Result { - let sdl_context = sdl3::init().unwrap(); - let video_subsystem = sdl_context.video().unwrap(); - let window = video_subsystem - .window("Game", WIDTH as u32, HEIGHT as u32) - .position_centered() - .build() - .unwrap(); - let mut canvas = window.into_canvas(); - - canvas.set_draw_color(SdlColor::BLACK); - canvas.clear(); - canvas.present(); - - Ok(Self { - sdl_context, - video_subsystem, - canvas, - }) - } - - pub fn run(&mut self, game: &mut impl game::Game) { - let mut event_pump = self.sdl_context.event_pump().unwrap(); - - let mut time_before = Instant::now(); - let time_per_frame = Duration::from_secs_f64(1.0 / 60.0); - let mut print_fps_timer = Instant::now(); - let mut fps_count = 0; - - 'running: loop { - for event in event_pump.poll_iter() { - match event { - Event::Quit { .. } - | Event::KeyDown { - keycode: Some(Keycode::Escape), - .. - } => break 'running, - Event::KeyDown { keycode, .. } => match keycode { - Some(key) => match key { - Keycode::R => { - game.event(game::Event::KeyDown { key: game::Key::R }); - } - Keycode::W => { - game.event(game::Event::KeyDown { key: game::Key::W }); - } - Keycode::A => { - game.event(game::Event::KeyDown { key: game::Key::A }); - } - Keycode::S => { - game.event(game::Event::KeyDown { key: game::Key::S }); - } - Keycode::D => { - game.event(game::Event::KeyDown { key: game::Key::D }); - } - Keycode::Down => { - game.event(game::Event::KeyDown { - key: game::Key::Down, - }); - } - Keycode::Up => { - game.event(game::Event::KeyDown { key: game::Key::Up }); - } - Keycode::Left => { - game.event(game::Event::KeyDown { - key: game::Key::Left, - }); - } - Keycode::Right => { - game.event(game::Event::KeyDown { - key: game::Key::Right, - }); - } - _ => {} - }, - None => {} - }, - Event::KeyUp { keycode, .. } => match keycode { - Some(key) => match key { - Keycode::R => { - game.event(game::Event::KeyUp { key: game::Key::R }); - } - Keycode::W => { - game.event(game::Event::KeyUp { key: game::Key::W }); - } - Keycode::A => { - game.event(game::Event::KeyUp { key: game::Key::A }); - } - Keycode::S => { - game.event(game::Event::KeyUp { key: game::Key::S }); - } - Keycode::D => { - game.event(game::Event::KeyUp { key: game::Key::D }); - } - Keycode::Down => { - game.event(game::Event::KeyUp { - key: game::Key::Down, - }); - } - Keycode::Up => { - game.event(game::Event::KeyUp { key: game::Key::Up }); - } - Keycode::Left => { - game.event(game::Event::KeyUp { - key: game::Key::Left, - }); - } - Keycode::Right => { - game.event(game::Event::KeyUp { - key: game::Key::Right, - }); - } - _ => {} - }, - None => {} - }, - - _ => {} - } - } - - let time_now = Instant::now(); - let delta_time = time_now - time_before; - time_before = time_now; - game.update(delta_time); - - self.canvas.set_draw_color(SdlColor::BLACK); - self.canvas.clear(); - game.render(self); - self.canvas.present(); - - fps_count += 1; - if (time_now - print_fps_timer).as_secs_f64() > 1.0 { - println!("fps: {fps_count}"); - fps_count = 0; - print_fps_timer = time_now; - } - if delta_time < time_per_frame { - std::thread::sleep(time_per_frame - delta_time); - } - } - } - - /// world space to screen space - fn scale_w2s(&self, v: V2) -> V2 { - let factor = WIDTH / 2.0; - V2(v.0 * factor, v.1 * factor) - } - /// world space to screen space. - fn translate_w2s(&self, v: V2) -> V2 { - let middle = V2(WIDTH / 2.0, HEIGHT / 2.0); - V2(v.0 + middle.0, middle.1 - v.1) - } - - /// scale -> translate - fn point_w2s(&self, v: V2) -> V2 { - self.translate_w2s(self.scale_w2s(v)) - } -} - -impl Renderer for SdlIo { - fn draw_rect(&mut self, pos: V2, size: V2, color: Color) { - let pos = self.point_w2s(pos); - let size = self.scale_w2s(size); - self.canvas.set_draw_color(color); - self.canvas - .fill_rect(FRect::new(pos.0 as _, pos.1 as _, size.0 as _, size.1 as _)) - .unwrap(); - } - - fn draw_point(&mut self, pos: V2, color: Color) { - let pos = self.point_w2s(pos); - let size = 4.0; - self.canvas.set_draw_color(color); - self.canvas - .fill_rect(FRect::new( - (pos.0 - size / 2.0) as _, - (pos.1 - size / 2.0) as _, - size as _, - size as _, - )) - .unwrap(); - } - - fn draw_line(&mut self, from: V2, to: V2, color: Color) { - self.canvas.set_draw_color(color); - self.canvas - .draw_line(self.point_w2s(from), self.point_w2s(to)) - .unwrap(); - } - - fn draw_triangles(&mut self, triangles: &[Triangle2], color: Color) { - let vertices = triangles - .iter() - .flat_map(|t| [t.0, t.1, t.2]) - .map(|p| self.point_w2s(p)) - .map(|p| Vertex { - position: p.into(), - color: color.into(), - tex_coord: FPoint::new(0.0, 0.0), - }) - .collect::>(); - - self.canvas - .render_geometry(&vertices, None, VertexIndices::Sequential) - .unwrap(); - } - - fn draw_triangle(&mut self, triangle: Triangle2, color: Color) { - let vertices = [triangle.0, triangle.1, triangle.2] - .into_iter() - .map(|p| self.point_w2s(p)) - .map(|p| Vertex { - position: p.into(), - color: color.into(), - tex_coord: FPoint::new(0.0, 0.0), - }) - .collect::>(); - self.canvas - .render_geometry(&vertices, None, VertexIndices::Sequential) - .unwrap(); - } -} - -impl From for FPoint { - fn from(value: V2) -> Self { - FPoint::new(value.0 as _, value.1 as _) - } -} - -impl From for SdlColor { - fn from(value: Color) -> Self { - match value { - Color::Hex(v) => SdlColor::RGB( - ((v >> 16) & 0xff) as u8, - ((v >> 8) & 0xff) as u8, - (v & 0xff) as u8, - ), - Color::White => SdlColor::WHITE, - Color::Green => SdlColor::GREEN, - Color::Red => SdlColor::RED, - Color::Cyan => SdlColor::CYAN, - Color::Black => SdlColor::BLACK, - } - } -} - -impl From for FColor { - fn from(value: Color) -> Self { - FColor::from(>::into(value)) - } -} diff --git a/editor/src/engine/shapes.rs b/editor/src/engine/shapes.rs deleted file mode 100644 index dc3f0cf..0000000 --- a/editor/src/engine/shapes.rs +++ /dev/null @@ -1,134 +0,0 @@ -use crate::engine::{math::V3, Triangle3, V2}; - -static CUBE_VERTICES: [(i8, i8, i8); 8] = [ - (0, 1, 0), // 0 front top left - (1, 1, 0), // 1 front top right - (0, 0, 0), // 2 front bottom left - (1, 0, 0), // 3 front bottom right - (0, 1, 1), // 4 back top left - (1, 1, 1), // 5 back top right - (0, 0, 1), // 6 back bottom left - (1, 0, 1), // 7 back bottom right -]; - -static CUBE_EDGES: [(usize, usize); 12] = [ - (0, 1), // ftl -> ftr - (2, 3), // fbl -> fbr - (4, 5), // btl -> btr - (6, 7), // bbl -> bbr - (0, 2), // ftl -> fbl - (1, 3), // ftr -> fbr - (4, 6), // btl -> bbl - (5, 7), // btr -> bbr - (0, 4), // ftl -> btl - (1, 5), // ftr -> btr - (2, 6), // fbl -> bbl - (3, 7), // fbr -> bbr -]; - -static CUBE_FACES: [(usize, usize, usize); 12] = [ - // front - (0, 1, 2), - (3, 2, 1), - // top - (0, 4, 1), - (5, 1, 4), - // right - (7, 3, 5), - (1, 5, 3), - // back - (5, 4, 7), - (6, 7, 4), - // bottom - (3, 7, 2), - (6, 2, 7), - // left - (4, 0, 6), - (2, 6, 0), -]; - -static PLANE_VERTICES: [(i8, i8, i8); 4] = [ - // - (0, 0, 0), - (0, 0, 1), - (1, 0, 0), - (1, 0, 1), -]; -static PLANE_EDGES: [(usize, usize); 4] = [ - // - (0, 1), - (2, 3), - (0, 2), - (1, 3), -]; -static PLANE_FACES: [(usize, usize, usize); 2] = [ - // - (0, 1, 2), - (3, 2, 1), -]; - -pub struct Shape { - vertices: Vec, - edges: Vec<(usize, usize)>, - faces: Vec<(usize, usize, usize)>, -} - -impl Shape { - pub fn new_plane(dim: V3) -> Self { - Self { - vertices: PLANE_VERTICES - .iter() - .map(|p| scale_i8_vertex(*p, &dim)) - .collect(), - edges: Vec::from_iter(PLANE_EDGES), - faces: Vec::from_iter(PLANE_FACES), - } - } - - pub fn new_cube(dim: V3) -> Self { - Self { - vertices: CUBE_VERTICES - .iter() - .map(|p| scale_i8_vertex(*p, &dim)) - .collect(), - edges: Vec::from_iter(CUBE_EDGES), - faces: Vec::from_iter(CUBE_FACES), - } - } - - pub fn vertices<'a>(&'a self) -> impl Iterator + 'a { - self.vertices.iter().cloned() - } - - pub fn edges<'a>(&'a self) -> impl Iterator + 'a { - let verts: &[V3] = &self.vertices; - self.edges.iter().map(|(a, b)| (verts[*a], verts[*b])) - } - - pub fn faces<'a>(&'a self) -> impl Iterator + 'a { - let verts: &[V3] = &self.vertices; - self.faces - .iter() - .map(|(a, b, c)| Triangle3(verts[*a], verts[*b], verts[*c])) - } - - pub fn rotate(&self, rot: V3) -> Self { - Self { - vertices: self.vertices.iter().map(|v| v.rotate(rot)).collect(), - edges: self.edges.clone(), - faces: self.faces.clone(), - } - } - - pub fn translate(&self, trans: V3) -> Self { - Self { - vertices: self.vertices.iter().map(|v| *v + trans).collect(), - edges: self.edges.clone(), - faces: self.faces.clone(), - } - } -} - -fn scale_i8_vertex(p: (i8, i8, i8), s: &V3) -> V3 { - V3(p.0 as f64 * s.0, p.1 as f64 * s.1, p.2 as f64 * s.2) -} diff --git a/editor/src/main.rs b/editor/src/main.rs deleted file mode 100644 index 0200d33..0000000 --- a/editor/src/main.rs +++ /dev/null @@ -1,361 +0,0 @@ -#![allow(dead_code)] - -use std::{collections::HashSet, f64::consts::PI, time::Duration}; - -use crate::engine::{Color, Key, Renderer, Scene, Shape, V3}; - -mod engine; - -struct Game { - objects: Vec, - next_object_id: u32, - keys_pressed: HashSet, -} - -impl Game { - fn new() -> Self { - Self { - objects: Vec::new(), - next_object_id: 0, - keys_pressed: HashSet::new(), - } - } - - fn spawn(&mut self, object_kind: ObjectKind) { - let object = Object { - kind: object_kind, - id: self.next_object_id, - }; - self.objects.push(object); - self.next_object_id += 1 - } - - fn despawn(&mut self, id: u32) { - let index = self - .objects - .iter() - .position(|o| o.id == id) - .expect("doesn't exist"); - self.objects.remove(index); - } -} - -impl engine::Game for Game { - fn update(&mut self, delta_time: Duration) { - for object in &mut self.objects { - if self.keys_pressed.contains(&Key::A) { - match &mut object.kind { - ObjectKind::SkateBoard { pivot_deg, .. } => { - *pivot_deg -= 18.0 * delta_time.as_secs_f64(); - if *pivot_deg < -12.5 { - *pivot_deg = -12.5; - } - } - } - } - if self.keys_pressed.contains(&Key::D) { - match &mut object.kind { - ObjectKind::SkateBoard { - pivot_deg: pivot_factor, - .. - } => { - *pivot_factor += 18.0 * delta_time.as_secs_f64(); - if *pivot_factor > 12.5 { - *pivot_factor = 12.5; - } - } - } - } - if !(self.keys_pressed.contains(&Key::A) || self.keys_pressed.contains(&Key::D)) { - match &mut object.kind { - ObjectKind::SkateBoard { - pivot_deg: pivot_factor, - .. - } => { - let decay_rate = 1.0 - (2.0 * delta_time.as_secs_f64()); - *pivot_factor *= decay_rate; - } - } - } - if self.keys_pressed.contains(&Key::R) { - match &mut object.kind { - ObjectKind::SkateBoard { rot, pos, .. } => { - *pos = V3(0.0, -0.1, -0.6); - *rot = V3(0.0, 0.5 * PI, 0.0); - } - } - } - if self.keys_pressed.contains(&Key::W) { - match &mut object.kind { - ObjectKind::SkateBoard { rot, .. } => rot.0 += 1.0 * delta_time.as_secs_f64(), - } - } - if self.keys_pressed.contains(&Key::S) { - match &mut object.kind { - ObjectKind::SkateBoard { rot, .. } => rot.0 -= 1.0 * delta_time.as_secs_f64(), - } - } - if self.keys_pressed.contains(&Key::Left) { - match &mut object.kind { - ObjectKind::SkateBoard { rot, .. } => rot.1 -= 1.0 * delta_time.as_secs_f64(), - } - } - if self.keys_pressed.contains(&Key::Right) { - match &mut object.kind { - ObjectKind::SkateBoard { rot, .. } => rot.1 += 1.0 * delta_time.as_secs_f64(), - } - } - if self.keys_pressed.contains(&Key::Down) { - match &mut object.kind { - ObjectKind::SkateBoard { pos, .. } => pos.1 -= 0.5 * delta_time.as_secs_f64(), - } - } - if self.keys_pressed.contains(&Key::Up) { - match &mut object.kind { - ObjectKind::SkateBoard { pos, .. } => pos.1 += 0.5 * delta_time.as_secs_f64(), - } - } - object.update(delta_time); - } - } - - fn render(&mut self, r: &mut R) { - let mut scene = Scene::new(); - for object in &self.objects { - object.render(&mut scene); - } - scene.render(r, V3(0.0, 0.0, -1.0)); - } - - fn event(&mut self, event: engine::Event) { - match event { - engine::Event::KeyDown { key } => self.keys_pressed.insert(key), - engine::Event::KeyUp { key } => self.keys_pressed.remove(&key), - }; - } -} - -struct Object { - kind: ObjectKind, - id: u32, -} - -enum ObjectKind { - SkateBoard { - pos: V3, - vel: V3, - rot: V3, - nyoom_factor: f64, - pivot_deg: f64, - }, -} - -struct ShapeGroupShape { - shape: Shape, - offset: V3, -} - -struct ShapeGroup { - pub shapes: Vec, -} - -impl ShapeGroup { - pub fn new(shapes: Vec) -> Self { - Self { shapes } - } - pub fn rotate(mut self, rot: V3) -> Self { - for shape in &mut self.shapes { - shape.shape = shape - .shape - .translate(shape.offset) - .rotate(rot) - .translate(shape.offset * -1.0); - } - self - } - pub fn translate(mut self, offset: V3) -> Self { - for shape in &mut self.shapes { - shape.shape = shape.shape.translate(offset); - } - self - } - pub fn draw(self, pos: V3, scene: &mut Scene, outline_color: Color, fill_color: Color) { - for shape in self.shapes { - scene.draw_shape( - pos, - &shape.shape.translate(shape.offset), - outline_color, - fill_color, - ); - } - } -} - -impl Object { - fn update(&mut self, delta_time: Duration) { - match &mut self.kind { - ObjectKind::SkateBoard { - pos, - vel, - nyoom_factor, - pivot_deg: pivot_factor, - .. - } => { - vel.0 = *pivot_factor * delta_time.as_secs_f64(); - *pos += *vel * delta_time.as_secs_f64(); - *nyoom_factor += 16.0 * delta_time.as_secs_f64(); - - // rot.0 += delta_time.as_secs_f64() * PI * 1.0; - // rot.1 += delta_time.as_secs_f64() * PI * 0.2; - // rot.2 += delta_time.as_secs_f64() * PI * 2.0; - } - } - } - - fn render(&self, scene: &mut Scene) { - match self.kind { - ObjectKind::SkateBoard { - pos, - rot, - nyoom_factor, - pivot_deg: pivot_factor, - .. - } => { - let board_size = V3(0.175, 0.005, 0.05); - let trucks = { - let anchor_size = V3(0.005, 0.01, 0.005); - let anchor_y = -anchor_size.1 - board_size.1 * 0.5; - let pivot = vec![ - ShapeGroupShape { - shape: Shape::new_cube(anchor_size), - offset: V3( - anchor_size.0 * -0.5 + board_size.0 * 0.4, - anchor_y, - anchor_size.2 * -0.5, - ), - }, - ShapeGroupShape { - shape: Shape::new_cube(anchor_size), - offset: V3( - anchor_size.0 * -0.5 - board_size.0 * 0.4, - anchor_y, - anchor_size.2 * -0.5, - ), - }, - ]; - let wheel_rail_size = V3(anchor_size.0, anchor_size.0, board_size.2 * 0.8); - let wheel_rail_y = anchor_y - wheel_rail_size.1; - let wheel_rail = vec![ - ShapeGroupShape { - shape: Shape::new_cube(wheel_rail_size), - offset: V3( - wheel_rail_size.0 * -0.5 + board_size.0 * 0.4, - wheel_rail_y, - wheel_rail_size.2 * -0.5, - ), - }, - ShapeGroupShape { - shape: Shape::new_cube(wheel_rail_size), - offset: V3( - wheel_rail_size.0 * -0.5 - board_size.0 * 0.4, - wheel_rail_y, - wheel_rail_size.2 * -0.5, - ), - }, - ]; - let wheel_size = V3(0.01, 0.01, 0.0025); - let wheel_y = wheel_rail_y - wheel_size.1 * 0.25; - let wheel_rot = V3(0.0, 0.0, nyoom_factor); - let wheel_rot_trans = V3(0.5, 0.5, 0.0); - let wheel = vec![ - ShapeGroupShape { - shape: Shape::new_cube(wheel_size) - .translate(wheel_size * wheel_rot_trans * -1.0) - .rotate(wheel_rot) - .translate(wheel_size * wheel_rot_trans), - offset: V3( - wheel_size.0 * -0.5 + board_size.0 * 0.4, - wheel_y, - wheel_rail_size.2 * -0.5 - wheel_size.2, - ), - }, - ShapeGroupShape { - shape: Shape::new_cube(wheel_size) - .translate(wheel_size * wheel_rot_trans * -1.0) - .rotate(wheel_rot) - .translate(wheel_size * wheel_rot_trans), - - offset: V3( - wheel_size.0 * -0.5 - board_size.0 * 0.4, - wheel_y, - wheel_rail_size.2 * -0.5 - wheel_size.2, - ), - }, - ShapeGroupShape { - shape: Shape::new_cube(wheel_size) - .translate(wheel_size * wheel_rot_trans * -1.0) - .rotate(wheel_rot) - .translate(wheel_size * wheel_rot_trans), - - offset: V3( - wheel_size.0 * -0.5 + board_size.0 * 0.4, - wheel_y, - wheel_rail_size.2 * 0.5, - ), - }, - ShapeGroupShape { - shape: Shape::new_cube(wheel_size) - .translate(wheel_size * wheel_rot_trans * -1.0) - .rotate(wheel_rot) - .translate(wheel_size * wheel_rot_trans), - - offset: V3( - wheel_size.0 * -0.5 - board_size.0 * 0.4, - wheel_y, - wheel_rail_size.2 * 0.5, - ), - }, - ]; - vec![pivot, wheel_rail, wheel].into_iter().flatten() - }; - let board_pivot_trans = V3(0.0, 0.5, 0.5); - let mut board = vec![ShapeGroupShape { - shape: Shape::new_cube(board_size) - .translate(board_size * board_pivot_trans * -1.0) - .rotate(V3(pivot_factor * (PI / 180.0), 0.0, 0.0)) - .translate(board_size * board_pivot_trans), - offset: board_size * -0.5, - }]; - board.extend(trucks); - let board = ShapeGroup::new(board).rotate(rot); - board.draw(pos, scene, Color::Green, Color::Black); - scene.draw_shape( - V3(-0.5, -5.0, 0.0), - &Shape::new_cube(V3(1.0, 0.0, 100.0)), - Color::Red, - Color::Red, - ); - } - } - } -} - -fn main() -> Result<(), Box> { - let mut sdl_io = engine::SdlIo::new()?; - let mut game = Game::new(); - let mut objects: Vec = Vec::new(); - objects.push(ObjectKind::SkateBoard { - pos: V3(0.0, -0.1, -0.6), - vel: V3(0.0, 0.0, 0.0), - rot: V3(0.0, PI * 0.5, 0.0), - nyoom_factor: 0.0, - pivot_deg: 0.0, - }); - - for object in objects { - game.spawn(object) - } - - sdl_io.run(&mut game); - Ok(()) -}