diff --git a/game/src/engine/game.rs b/game/src/engine/game.rs index 01fcf6c..7183d76 100644 --- a/game/src/engine/game.rs +++ b/game/src/engine/game.rs @@ -1,6 +1,6 @@ use sdl3::pixels::Color; -use crate::engine::math::{V2, V3}; +use crate::engine::math::{Vertex, V2, V3}; use std::{marker::PhantomData, time::Duration}; use super::error::Error; @@ -19,6 +19,7 @@ pub trait Renderer { fn point(&mut self, pos: V2, color: Color); fn draw_line(&mut self, from: V2, to: V2, color: Color); fn draw_cube(&mut self, pos: V3, size: V3, outline_colors: Color, fill_color: Color); + fn draw_triangle(&mut self, triangle: Vertex, color: Color); } pub enum Event { diff --git a/game/src/engine/math.rs b/game/src/engine/math.rs index 6e11ace..20415b6 100644 --- a/game/src/engine/math.rs +++ b/game/src/engine/math.rs @@ -35,14 +35,31 @@ impl MulAssign for V3 { } impl V3 { - pub fn as_2d(&self) -> V2 { + pub fn project(&self) -> V2 { V2(self.0 / self.2, self.1 / self.2) } + + pub fn delta(&self, v: V3) -> V3 { + V3(v.0 - self.0, v.1 - self.1, v.2 - self.2) + } } #[derive(Clone, PartialEq, Debug)] pub struct Vertex(pub V3, pub V3, pub V3); +impl Vertex { + pub fn normal_vector(&self) -> V3 { + let vector_a = self.1.delta(self.0); + let vector_b = self.1.delta(self.2); + + V3( + vector_a.1 * vector_b.2 - vector_a.2 * vector_b.1, + vector_a.2 * vector_b.0 - vector_a.0 * vector_b.2, + vector_a.0 * vector_b.1 - vector_a.1 * vector_b.0, + ) + } +} + #[cfg(test)] mod test { use super::*; diff --git a/game/src/engine/sdl_io.rs b/game/src/engine/sdl_io.rs index 9379d9c..0754428 100644 --- a/game/src/engine/sdl_io.rs +++ b/game/src/engine/sdl_io.rs @@ -4,7 +4,8 @@ use sdl3::{ event::Event, keyboard::Keycode, pixels::{Color, PixelFormat}, - render::{Canvas, FRect}, + rect::Point, + render::{Canvas, FPoint, FRect}, video::Window, Sdl, VideoSubsystem, }; @@ -12,12 +13,12 @@ use sdl3::{ use crate::engine::{ error::Error, game, - math::{V2, V3}, + math::{Vertex, V2, V3}, Object, }; -static WIDTH: f64 = 1280.0; -static HEIGHT: f64 = 720.0; +pub static WIDTH: f64 = 1280.0; +pub static HEIGHT: f64 = 720.0; pub struct SdlIo { sdl_context: Sdl, @@ -111,24 +112,90 @@ impl game::Renderer for SdlIo { } fn draw_line(&mut self, from: V2, to: V2, color: Color) { - todo!() + self.canvas.set_draw_color(color); + self.canvas + .draw_line( + FPoint::new(from.0 as f32, from.1 as f32), + FPoint::new(to.0 as f32, to.1 as f32), + ) + .unwrap(); + } + + fn draw_triangle(&mut self, triangle: Vertex, color: Color) { + self.draw_line( + self.world_to_screen(triangle.0.project()), + self.world_to_screen(triangle.1.project()), + color, + ); + self.draw_line( + self.world_to_screen(triangle.1.project()), + self.world_to_screen(triangle.2.project()), + color, + ); + self.draw_line( + self.world_to_screen(triangle.2.project()), + self.world_to_screen(triangle.0.project()), + color, + ); } fn draw_cube(&mut self, pos: V3, size: V3, outline_color: Color, fill_color: Color) { let V3(x, y, z) = pos; - let V3(w, h, d) = size; + let V3(w, h, mut d) = size; + d /= 200.0; let points = [ pos, V3(x + w, y, z), V3(x, y + h, z), V3(x + w, y + h, z), - V3(x, y, z + d / 100.0), - V3(x + w, y, z + d / 100.0), - V3(x, y + h, z + d / 100.0), - V3(x + w, y + h, z + d / 100.0), + V3(x, y, z + d), + V3(x + w, y, z + d), + V3(x, y + h, z + d), + V3(x + w, y + h, z + d), ]; + + let vertices = [ + // south + Vertex(points[0], points[2], points[3]), + Vertex(points[0], points[3], points[1]), + // east + Vertex(points[1], points[3], points[7]), + Vertex(points[1], points[7], points[5]), + // north + Vertex(points[5], points[7], points[6]), + Vertex(points[5], points[6], points[4]), + // west + Vertex(points[4], points[6], points[2]), + Vertex(points[4], points[2], points[0]), + // top + Vertex(points[2], points[6], points[7]), + Vertex(points[2], points[7], points[3]), + // bottom + Vertex(points[5], points[4], points[0]), + Vertex(points[5], points[0], points[1]), + ]; + println!("current triangles"); + + for vertex in vertices { + let normal_vector = vertex.normal_vector(); + + // self.draw_triangle(vertex, outline_color); + println!("{}", normal_vector.2); + + if normal_vector.2 > 0.0 { + self.draw_triangle( + Vertex( + vertex.0, + vertex.1, + V3(vertex.2 .0, vertex.2 .1, vertex.2 .2), + ), + outline_color, + ); + } + } + for point in points { - self.point(point.as_2d(), outline_color); + self.point(point.project(), outline_color); } } } diff --git a/game/src/engine/shapes.rs b/game/src/engine/shapes.rs index 8ecf818..c4925e9 100644 --- a/game/src/engine/shapes.rs +++ b/game/src/engine/shapes.rs @@ -41,6 +41,10 @@ impl Shape { } } + pub fn points<'a>(&'a self) -> impl Iterator + 'a { + self.vertices.iter().cloned() + } + pub fn vertices<'a>(&'a self) -> impl Iterator + 'a { let verts: &[V3] = &self.vertices; self.fragments diff --git a/game/src/main.rs b/game/src/main.rs index 1fc203a..1d36f1d 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -36,8 +36,8 @@ fn main() -> Result<(), Box> { let mut game = engine::Game::::new()?; let player = Object::Player { - pos: V3(-50.0, -50.0, 0.0), - vel: V3(0.0, 0.0, 1.0), + pos: V3(200.0, 100.0, 0.0), + vel: V3(0.0, 0.0, 0.1), }; game.spawn(player);