From 6e13c91d375a89752d0bbffb18a1af74d653965e Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 22 Dec 2023 17:24:53 -0800 Subject: [PATCH] Vector cleanup --- src/doodad.rs | 18 +++--- src/inputstatus.rs | 1 - src/main.rs | 40 ++++++++------ src/physics/body.rs | 47 +++++++++------- src/physics/cartesian.rs | 116 --------------------------------------- src/physics/mod.rs | 5 +- src/physics/polar.rs | 21 +++---- src/render/gpu.rs | 15 ++--- src/ship.rs | 18 +++--- src/system.rs | 13 +++-- 10 files changed, 97 insertions(+), 197 deletions(-) delete mode 100644 src/physics/cartesian.rs diff --git a/src/doodad.rs b/src/doodad.rs index c6ae0ae..a4277dd 100644 --- a/src/doodad.rs +++ b/src/doodad.rs @@ -1,17 +1,19 @@ -use crate::{physics::Cartesian, Camera, Sprite}; +use cgmath::{Deg, Point2}; + +use crate::{physics::Pfloat, Camera, Sprite, Spriteable}; + pub struct Doodad { pub sprite: String, - pub pos: Cartesian, + pub pos: Point2, } -impl Doodad { - pub fn sprite(&self, camera: &Camera) -> Sprite { - let p = self.pos - camera.pos; - +impl Spriteable for Doodad { + fn sprite(&self, camera: &Camera) -> Sprite { return Sprite { - position: (p.x, p.y), + position: self.pos, + camera: camera.pos, name: self.sprite.clone(), - angle: 0.0, + angle: Deg { 0: 0.0 }, }; } } diff --git a/src/inputstatus.rs b/src/inputstatus.rs index a0070f3..78cf808 100644 --- a/src/inputstatus.rs +++ b/src/inputstatus.rs @@ -1,6 +1,5 @@ use winit::event::{ElementState, VirtualKeyCode}; -// TODO: no boolean modification (no pub) pub struct InputStatus { pub key_left: bool, pub key_right: bool, diff --git a/src/main.rs b/src/main.rs index f47aa5f..eb35450 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use physics::Cartesian; +use cgmath::{Deg, Point2}; use winit::{ event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, event_loop::{ControlFlow, EventLoop}, @@ -16,29 +16,33 @@ mod system; use crate::{ doodad::Doodad, inputstatus::InputStatus, + physics::Pfloat, render::GPUState, ship::{Ship, ShipKind}, system::System, }; struct Camera { - pos: Cartesian, + pos: Point2, } -impl Camera { - fn new() -> Self { - Camera { - pos: Cartesian::new(0.0, 0.0), - } - } +trait Spriteable { + fn sprite(&self, camera: &Camera) -> Sprite; } struct Sprite { - // Image to use + // Name of the sprite to draw name: String, - // World position - position: (f64, f64), - angle: f32, + + // This object's position, in world coordinates. + position: Point2, + + // This sprite's rotation + // (relative to north, measured ccw) + angle: Deg, + + // The camera we want to draw this sprite from, in world coordinates + camera: Point2, } struct Game { @@ -54,8 +58,10 @@ impl Game { Game { last_update: Instant::now(), input: InputStatus::new(), - player: Ship::new(ShipKind::Gypsum, Cartesian::new(0.0, 0.0)), - camera: Camera::new(), + player: Ship::new(ShipKind::Gypsum, (0.0, 0.0).into()), + camera: Camera { + pos: (0.0, 0.0).into(), + }, system: System::new(), } } @@ -65,7 +71,7 @@ impl Game { } fn update(&mut self) { - let t = self.last_update.elapsed().as_secs_f64(); + let t: Pfloat = self.last_update.elapsed().as_secs_f32(); println!("{:.02}", 1.0 / t); if self.input.key_thrust { @@ -73,11 +79,11 @@ impl Game { } if self.input.key_right { - self.player.body.rot(15.0 * t); + self.player.body.rot(Deg { 0: 15.0 } * t); } if self.input.key_left { - self.player.body.rot(-15.0 * t); + self.player.body.rot(Deg { 0: -15.0 } * t); } self.player.body.tick(t); diff --git a/src/physics/body.rs b/src/physics/body.rs index 5e432b1..0892f94 100644 --- a/src/physics/body.rs +++ b/src/physics/body.rs @@ -1,46 +1,51 @@ -use crate::physics::Cartesian; +use super::Pfloat; +use cgmath::{Angle, Deg, Point2, Vector2}; pub struct PhysBody { - pub pos: Cartesian, - pub vel: Cartesian, - pub mass: f64, - pub angle: f64, // In degrees + pub pos: Point2, + pub vel: Vector2, + pub mass: Pfloat, + pub angle: Deg, } impl PhysBody { - pub fn new(pos: Cartesian) -> Self { + pub fn new(pos: Point2) -> Self { return PhysBody { pos, - vel: Cartesian::new(0.0, 0.0), + vel: (0.0, 0.0).into(), mass: 0.3, - angle: 0.0, + angle: Deg { 0: 0.0 }, }; } - /// Calculate the state of this body after t seconds. - pub fn tick(&mut self, t: f64) { + /// Calculate the position of this body after t seconds. + pub fn tick(&mut self, t: Pfloat) { self.pos += self.vel * t; } /// Apply an instantaneous force to this object - pub fn force(&mut self, v: Cartesian) { + pub fn force(&mut self, v: Vector2) { self.vel += v / self.mass; } - /// Apply force in the direction this object is pointing. - pub fn thrust(&mut self, f: f64) { - let l = Cartesian::new( - -self.angle.to_radians().sin(), - self.angle.to_radians().cos(), - ) * f; + /// Apply a force in the direction this object is pointing. + pub fn thrust(&mut self, f: Pfloat) { + let l = Vector2 { + x: -self.angle.sin(), + y: self.angle.cos(), + } * f; self.force(l); } - // Rotate this object by `a` radians. - pub fn rot(&mut self, a: f64) { + // Rotate this object + pub fn rot(&mut self, a: Deg) { self.angle -= a; - if self.angle.abs() > 180.0 { - self.angle -= self.angle.signum() * 360.0; + + // Wrap angles + if self.angle.0.abs() > 180.0 { + self.angle -= Deg { + 0: self.angle.0.signum() * 360.0, + }; } } } diff --git a/src/physics/cartesian.rs b/src/physics/cartesian.rs deleted file mode 100644 index fb8f2c7..0000000 --- a/src/physics/cartesian.rs +++ /dev/null @@ -1,116 +0,0 @@ -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; - -#[derive(Debug, Clone, Copy)] -pub struct Cartesian { - pub x: f64, - pub y: f64, -} - -impl Cartesian { - pub fn new(x: f64, y: f64) -> Self { - Cartesian { x, y } - } - - /* - pub fn norm(&self) -> f64 { - return (self.x * self.x + self.y * self.y).sqrt(); - } - */ -} - -impl From<(u32, u32)> for Cartesian { - fn from(value: (u32, u32)) -> Self { - Cartesian { - x: value.0 as f64, - y: value.1 as f64, - } - } -} - -impl Add for Cartesian { - type Output = Self; - - fn add(self, other: Self) -> Self { - Self { - x: self.x + other.x, - y: self.y + other.y, - } - } -} - -impl AddAssign for Cartesian { - fn add_assign(&mut self, rhs: Self) { - self.x += rhs.x; - self.y += rhs.y; - } -} - -impl Sub for Cartesian { - type Output = Self; - - fn sub(self, other: Self) -> Self { - Self { - x: self.x - other.x, - y: self.y - other.y, - } - } -} - -impl SubAssign for Cartesian { - fn sub_assign(&mut self, rhs: Self) { - self.x += rhs.x; - self.y += rhs.y; - } -} - -impl Mul for Cartesian { - type Output = Self; - - fn mul(self, other: Self) -> Self { - Self { - x: self.x * other.x, - y: self.y * other.y, - } - } -} - -impl MulAssign for Cartesian { - fn mul_assign(&mut self, rhs: Self) { - self.x *= rhs.x; - self.y *= rhs.y; - } -} - -impl Mul for Cartesian { - type Output = Cartesian; - fn mul(self, rhs: f64) -> Self::Output { - Self { - x: self.x * rhs, - y: self.y * rhs, - } - } -} - -impl MulAssign for Cartesian { - fn mul_assign(&mut self, rhs: f64) { - self.x *= rhs; - self.y *= rhs; - } -} - -impl Div for Cartesian { - type Output = Cartesian; - fn div(self, rhs: f64) -> Self::Output { - Self { - x: self.x / rhs, - y: self.y / rhs, - } - } -} - -impl DivAssign for Cartesian { - fn div_assign(&mut self, rhs: f64) { - self.x /= rhs; - self.y /= rhs; - } -} diff --git a/src/physics/mod.rs b/src/physics/mod.rs index c0430fe..1b8365c 100644 --- a/src/physics/mod.rs +++ b/src/physics/mod.rs @@ -1,7 +1,8 @@ mod body; -mod cartesian; mod polar; +// What kind of float shoud we use for physics? +pub type Pfloat = f32; + pub use body::PhysBody; -pub use cartesian::Cartesian; pub use polar::Polar; diff --git a/src/physics/polar.rs b/src/physics/polar.rs index 5a47c8e..ed56f0b 100644 --- a/src/physics/polar.rs +++ b/src/physics/polar.rs @@ -1,17 +1,18 @@ -use super::Cartesian; +use super::Pfloat; +use cgmath::{Angle, Deg, EuclideanSpace, Point2}; #[derive(Debug, Clone, Copy)] pub struct Polar { - pub center: Cartesian, - pub radius: f64, - pub angle: f64, + pub center: Point2, + pub radius: Pfloat, + pub angle: Deg, } -impl Into for Polar { - fn into(self) -> Cartesian { - return Cartesian::new( - self.radius * self.angle.sin(), - self.radius * self.angle.cos(), - ) + self.center; +impl Polar { + pub fn to_cartesian(self) -> Point2 { + return Point2 { + x: self.radius * self.angle.sin(), + y: self.radius * self.angle.cos(), + } + self.center.to_vec(); } } diff --git a/src/render/gpu.rs b/src/render/gpu.rs index 141c32e..2bd1b0c 100644 --- a/src/render/gpu.rs +++ b/src/render/gpu.rs @@ -1,6 +1,6 @@ use anyhow::Result; use bytemuck; -use cgmath::{Deg, Matrix4, Point2, Vector3}; +use cgmath::{Deg, EuclideanSpace, Matrix4, Point2, Vector3}; use std::{iter, mem}; use wgpu::{self, util::DeviceExt}; use winit::{self, window::Window}; @@ -104,7 +104,7 @@ struct Transform { pos: Point2, aspect: f32, // width / height scale: f32, - rotate: f32, // Around this object's center, in degrees measured ccw from vertical + rotate: Deg, // Around this object's center, in degrees measured ccw from vertical } impl Transform { @@ -115,7 +115,7 @@ impl Transform { // Our mesh starts at (0, 0), so this will rotate around the object's center. // Note that we translate AFTER scaling. - let rotate = Matrix4::from_angle_z(Deg { 0: self.rotate }); + let rotate = Matrix4::from_angle_z(self.rotate); let translate = Matrix4::from_translation(Vector3 { x: self.pos.x, @@ -402,17 +402,14 @@ impl GPUState { // TODO: warning when too many sprites are drawn. let mut instances: Vec = Vec::new(); for s in sprites { - let mut pos: Point2 = (s.position.0 as f32, s.position.1 as f32).into(); - - // TODO: dynamic - pos.x /= 400.0; - pos.y /= 400.0; + // Compute position on screen + let screen_pos: Point2 = (s.position - s.camera.to_vec()) / 400.0; let texture = self.texture_array.get_texture(&s.name[..]); instances.push(Instance { transform: Transform { - pos, + pos: screen_pos, aspect: texture.aspect / screen_aspect, scale: 0.25, rotate: s.angle, diff --git a/src/ship.rs b/src/ship.rs index 1a4ba24..969405e 100644 --- a/src/ship.rs +++ b/src/ship.rs @@ -1,7 +1,10 @@ -use crate::physics::Cartesian; +use cgmath::Point2; + +use crate::physics::Pfloat; use crate::physics::PhysBody; use crate::Camera; use crate::Sprite; +use crate::Spriteable; pub enum ShipKind { Gypsum, @@ -21,20 +24,21 @@ pub struct Ship { } impl Ship { - pub fn new(kind: ShipKind, pos: Cartesian) -> Self { + pub fn new(kind: ShipKind, pos: Point2) -> Self { Ship { body: PhysBody::new(pos), kind, } } +} - pub fn sprite(&self, camera: &Camera) -> Sprite { - let p = self.body.pos - camera.pos; - +impl Spriteable for Ship { + fn sprite(&self, camera: &Camera) -> Sprite { return Sprite { - position: (p.x, p.y), + position: self.body.pos, + camera: camera.pos, name: self.kind.sprite().to_owned(), - angle: self.body.angle as f32, + angle: self.body.angle, }; } } diff --git a/src/system.rs b/src/system.rs index d8a81b4..9600b9d 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,4 +1,5 @@ -use crate::{physics::Cartesian, physics::Polar, Camera, Doodad, Sprite}; +use crate::{physics::Polar, Camera, Doodad, Sprite, Spriteable}; +use cgmath::Deg; pub struct System { bodies: Vec, @@ -9,22 +10,22 @@ impl System { let mut s = System { bodies: Vec::new() }; s.bodies.push(Doodad { - pos: Cartesian::new(0.0, 0.0), + pos: (0.0, 0.0).into(), sprite: "a0".to_owned(), }); s.bodies.push(Doodad { pos: Polar { - center: Cartesian::new(0.0, 0.0), + center: (0.0, 0.0).into(), radius: 300.0, - angle: 31.0, + angle: Deg { 0: 31.0 }, } - .into(), + .to_cartesian(), sprite: "earth".to_owned(), }); s.bodies.push(Doodad { - pos: Cartesian::new(1000.0, 1000.0), + pos: (1000.0, 1000.0).into(), sprite: "small".to_owned(), });