From 0a8019aded3d6bbe8c9af1e403af51aa82e79727 Mon Sep 17 00:00:00 2001 From: sfja Date: Wed, 1 Apr 2026 17:21:28 +0200 Subject: [PATCH] fix camera translation --- game/src/bin/editor.rs | 3 +- game/src/editor.rs | 301 +++++---------------------------------- game/src/engine/math.rs | 16 ++- game/src/engine/r3d.rs | 33 +++-- game/src/engine/scene.rs | 8 +- game/src/game.rs | 6 +- 6 files changed, 72 insertions(+), 295 deletions(-) diff --git a/game/src/bin/editor.rs b/game/src/bin/editor.rs index a74e210..9e2b33d 100644 --- a/game/src/bin/editor.rs +++ b/game/src/bin/editor.rs @@ -1,4 +1,3 @@ - fn main() -> Result<(), Box> { - skate_slope::game::game_main() + skate_slope::editor::editor_main() } diff --git a/game/src/editor.rs b/game/src/editor.rs index ac27d38..d70ddcd 100644 --- a/game/src/editor.rs +++ b/game/src/editor.rs @@ -1,34 +1,25 @@ #![allow(dead_code)] -use std::{ - collections::HashSet, - f64::consts::PI, - sync::{Arc, Mutex}, - time::Duration, -}; +use std::{collections::HashSet, time::Duration}; -use crate::{ - engine::{Color, Key, Renderer, Scene, Shape, V3}, - event_queue::EventQueue, - vermiparous::Server, -}; +use crate::engine::{Color, Key, Renderer, Scene, Shape, V3}; use crate::engine; -struct Game { +struct Editor { objects: Vec, next_object_id: u32, - event_queue: Arc>, keys_pressed: HashSet, + camera_pos: V3, } -impl Game { - fn new(event_queue: Arc>) -> Self { +impl Editor { + fn new() -> Self { Self { objects: Vec::new(), next_object_id: 0, - event_queue, keys_pressed: HashSet::new(), + camera_pos: V3(0.0, 0.0, -1.0), } } @@ -51,34 +42,16 @@ impl Game { } } -impl engine::Game for Game { +impl engine::Game for Editor { fn update(&mut self, delta_time: Duration) { for object in &mut self.objects { - if self.keys_pressed.contains(&Key::Left) == self.keys_pressed.contains(&Key::Right) { - if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind { - let decay_rate = 1.0 - (2.0 * delta_time.as_secs_f64()); - *pivot_deg *= decay_rate; - } - } - if self.keys_pressed.contains(&Key::Left) { - if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind { - *pivot_deg -= 18.0 * delta_time.as_secs_f64(); - if *pivot_deg < -12.5 { - *pivot_deg = -12.5; - } - } - } - if self.keys_pressed.contains(&Key::Right) { - if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind { - *pivot_deg += 18.0 * delta_time.as_secs_f64(); - if *pivot_deg > 12.5 { - *pivot_deg = 12.5; - } - } - } - object.update(delta_time); } + if self.keys_pressed.contains(&Key::Left) { + self.camera_pos.0 += delta_time.as_secs_f64() * 1.0; + } else if self.keys_pressed.contains(&Key::Right) { + self.camera_pos.0 -= delta_time.as_secs_f64() * 1.0; + } } fn render(&mut self, r: &mut R) { @@ -86,7 +59,7 @@ impl engine::Game for Game { for object in &self.objects { object.render(&mut scene); } - scene.render(r, V3(0.0, 0.0, -1.0)); + scene.render(r, self.camera_pos); } fn event(&mut self, event: engine::Event) { @@ -103,26 +76,7 @@ struct Object { } enum ObjectKind { - SkateBoard { - pos: V3, - vel: V3, - rot: V3, - nyoom_factor: f64, - pivot_deg: f64, - }, - Obstacle { - pos: V3, - vel: V3, - }, - Ground { - original_pos: V3, - pos: V3, - vel: V3, - rot: V3, - grid_item_size: f64, - grid_width: i32, - grid_depth: i32, - }, + Box { pos: V3, vel: V3 }, } struct ShapeGroupShape { @@ -169,232 +123,43 @@ impl ShapeGroup { 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; - } - ObjectKind::Obstacle { pos, vel } => { - *pos += *vel * delta_time.as_secs_f64(); - } - ObjectKind::Ground { - pos, - vel, - grid_depth, - grid_item_size, - original_pos, - .. - } => { - *pos += *vel * delta_time.as_secs_f64(); - *vel += V3(vel.0, vel.1, vel.0 - 0.01 * delta_time.as_secs_f64()); - if pos.2 <= original_pos.2 - *grid_depth as f64 * *grid_item_size { - pos.2 += *grid_depth as f64 * *grid_item_size - } - } + ObjectKind::Box { pos, vel } => {} } } fn render(&self, scene: &mut Scene) { match self.kind { - ObjectKind::SkateBoard { - pos, - rot, - nyoom_factor, - pivot_deg, - .. - } => { - 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_deg * (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); - } - ObjectKind::Obstacle { pos, .. } => { + ObjectKind::Box { pos, .. } => { scene.draw_shape( pos, - &Shape::new_cube(V3(0.2, 0.1, 0.2)), + &Shape::new_cube(V3(1.0, 1.0, 1.0)), + Color::Green, + Color::Black, + ); + scene.draw_shape( + pos + V3(0.0, -0.5, 0.0), + &Shape::new_cube(V3(0.5, 0.5, 0.5)), Color::Green, Color::Black, ); - } - ObjectKind::Ground { - pos, - grid_depth, - grid_item_size, - grid_width, - .. - } => { - for grid in 0..5 { - let mut shapes = Vec::new(); - for z in 0..grid_depth { - for x in -grid_width / 2..grid_width / 2 { - shapes.push(ShapeGroupShape { - shape: Shape::new_plane(V3(grid_item_size, 0.0, grid_item_size)), - offset: V3( - x as f64 * grid_item_size, - 0.0, - z as f64 * grid_item_size - + grid as f64 * grid_depth as f64 * grid_item_size, - ), - }); - } - } - let ground = ShapeGroup::new(shapes); - ground.draw(pos, scene, Color::Cyan, Color::Black); - } } } } } -pub fn game_main() -> Result<(), Box> { +pub fn editor_main() -> Result<(), Box> { let mut sdl_io = engine::SdlIo::new()?; - let event_queue = Arc::new(Mutex::new(EventQueue::new())); - let mut game = Game::new(event_queue.clone()); - std::thread::spawn(move || { - let server = Server::bind("10.133.51.127:5000"); - server.start(event_queue); - }); - let objects: Vec = vec![ - ObjectKind::SkateBoard { - pos: V3(0.0, -0.1, -0.7), - 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, - }, - ObjectKind::Ground { - original_pos: V3(0.0, -0.25, -0.6), - pos: V3(0.0, -0.25, -0.6), - vel: V3(0.0, 0.0, -0.1), - rot: V3(0.0, 0.0, 0.0), - grid_item_size: 0.1, - grid_width: 10, - grid_depth: 10, - }, - ObjectKind::Obstacle { - pos: V3(0.5, -0.2, 0.0), - vel: V3(0.0, 0.0, -0.1), - }, - ]; + let mut editor = Editor::new(); + + let objects = [ObjectKind::Box { + pos: V3(0.0, 0.0, 0.0), + vel: V3(0.0, 0.0, 0.0), + }]; for object in objects { - game.spawn(object) + editor.spawn(object) } - sdl_io.run(&mut game); + sdl_io.run(&mut editor); Ok(()) } diff --git a/game/src/engine/math.rs b/game/src/engine/math.rs index 129aedb..c006232 100644 --- a/game/src/engine/math.rs +++ b/game/src/engine/math.rs @@ -7,9 +7,13 @@ pub struct V2(pub f64, pub f64); pub struct V3(pub f64, pub f64, pub f64); impl V3 { - pub fn project_2d(&self) -> V2 { + pub fn filled(v: f64) -> Self { + Self(v, v, v) + } + + pub fn project_2d(&self, camera_pos: V3) -> V2 { // V2(self.0 / self.2, self.1 / self.2) - let c = V3(0.0, 0.0, -1.0); + let c = camera_pos; 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) @@ -126,11 +130,11 @@ impl Triangle3 { Self(self.0 + offset, self.1 + offset, self.2 + offset) } - pub fn project_2d(&self) -> Triangle2 { + pub fn project_2d(&self, camera_pos: V3) -> Triangle2 { Triangle2( - self.0.project_2d(), - self.1.project_2d(), - self.2.project_2d(), + self.0.project_2d(camera_pos), + self.1.project_2d(camera_pos), + self.2.project_2d(camera_pos), ) } diff --git a/game/src/engine/r3d.rs b/game/src/engine/r3d.rs index fe09817..3ba07d4 100644 --- a/game/src/engine/r3d.rs +++ b/game/src/engine/r3d.rs @@ -3,24 +3,30 @@ use crate::engine::{game::Renderer, Color, Shape, Triangle2, Triangle3, V2, V3}; pub struct R3d<'r, R: Renderer> { r: &'r mut R, triangle_buffer: Vec, + camera_pos: V3, } -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 { + pub fn new(r: &'r mut R, camera_pos: V3) -> Self { Self { r, triangle_buffer: Vec::new(), + camera_pos, } } pub fn draw_line(&mut self, from: V3, to: V3, color: Color) { - self.r.draw_line(from.project_2d(), to.project_2d(), color); + self.r.draw_line( + from.project_2d(self.camera_pos), + to.project_2d(self.camera_pos), + color, + ); } pub fn draw_triangle(&mut self, triangle: Triangle3, color: Color) { - let triangle = triangle.translate(CAMERA_POS).project_2d(); + let triangle = triangle + .translate(self.camera_pos) + .project_2d(self.camera_pos); self.r.draw_line(triangle.0, triangle.1, color); self.r.draw_line(triangle.1, triangle.2, color); @@ -29,13 +35,16 @@ impl<'r, R: Renderer> R3d<'r, R> { 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.triangle_buffer.extend( + shape + .faces() + .map(|tri| tri.translate(pos).project_2d(self.camera_pos)), + ); 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 { + if face.normal().dot(face.0 - self.camera_pos + pos) >= 0.0 { continue; } // let pxyz = face.middle() + face.normal(); @@ -58,13 +67,13 @@ impl<'r, R: Renderer> R3d<'r, R> { // self.draw_triangle(face.translate(pos - CAMERA_POS), outline_color); self.r.draw_line( - (face.0 + pos).project_2d(), - (face.1 + pos).project_2d(), + (face.0 + pos).project_2d(self.camera_pos), + (face.1 + pos).project_2d(self.camera_pos), outline_color, ); self.r.draw_line( - (face.2 + pos).project_2d(), - (face.0 + pos).project_2d(), + (face.2 + pos).project_2d(self.camera_pos), + (face.0 + pos).project_2d(self.camera_pos), outline_color, ); } diff --git a/game/src/engine/scene.rs b/game/src/engine/scene.rs index 993282c..2497038 100644 --- a/game/src/engine/scene.rs +++ b/game/src/engine/scene.rs @@ -17,13 +17,13 @@ impl Scene { } } - pub fn render(&mut self, r: &mut R, camera: V3) { + pub fn render(&mut self, r: &mut R, camera_pos: 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)); + let mut point_scores = object.triangle.points().map(|p| p.distance(camera_pos)); point_scores.sort_by(|a, b| a.total_cmp(b)); (i, point_scores[0]) @@ -44,11 +44,11 @@ impl Scene { continue; } - if object.triangle.normal().dot(object.triangle.0 - camera) >= 0.0 { + if object.triangle.normal().dot(object.triangle.0 - camera_pos) >= 0.0 { continue; } - let triangle = object.triangle.project_2d(); + let triangle = object.triangle.project_2d(camera_pos); r.draw_triangle(triangle.clone(), object.fill_color); r.draw_line(triangle.0, triangle.1, object.outline_color); diff --git a/game/src/game.rs b/game/src/game.rs index ac27d38..ce59754 100644 --- a/game/src/game.rs +++ b/game/src/game.rs @@ -56,13 +56,13 @@ impl engine::Game for Game { for object in &mut self.objects { if self.keys_pressed.contains(&Key::Left) == self.keys_pressed.contains(&Key::Right) { if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind { - let decay_rate = 1.0 - (2.0 * delta_time.as_secs_f64()); + let decay_rate = 1.0 - (4.0 * delta_time.as_secs_f64()); *pivot_deg *= decay_rate; } } if self.keys_pressed.contains(&Key::Left) { if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind { - *pivot_deg -= 18.0 * delta_time.as_secs_f64(); + *pivot_deg -= 36.0 * delta_time.as_secs_f64(); if *pivot_deg < -12.5 { *pivot_deg = -12.5; } @@ -70,7 +70,7 @@ impl engine::Game for Game { } if self.keys_pressed.contains(&Key::Right) { if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind { - *pivot_deg += 18.0 * delta_time.as_secs_f64(); + *pivot_deg += 36.0 * delta_time.as_secs_f64(); if *pivot_deg > 12.5 { *pivot_deg = 12.5; }