Vector cleanup
parent
a511a06709
commit
6e13c91d37
|
@ -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 struct Doodad {
|
||||||
pub sprite: String,
|
pub sprite: String,
|
||||||
pub pos: Cartesian,
|
pub pos: Point2<Pfloat>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Doodad {
|
impl Spriteable for Doodad {
|
||||||
pub fn sprite(&self, camera: &Camera) -> Sprite {
|
fn sprite(&self, camera: &Camera) -> Sprite {
|
||||||
let p = self.pos - camera.pos;
|
|
||||||
|
|
||||||
return Sprite {
|
return Sprite {
|
||||||
position: (p.x, p.y),
|
position: self.pos,
|
||||||
|
camera: camera.pos,
|
||||||
name: self.sprite.clone(),
|
name: self.sprite.clone(),
|
||||||
angle: 0.0,
|
angle: Deg { 0: 0.0 },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use winit::event::{ElementState, VirtualKeyCode};
|
use winit::event::{ElementState, VirtualKeyCode};
|
||||||
|
|
||||||
// TODO: no boolean modification (no pub)
|
|
||||||
pub struct InputStatus {
|
pub struct InputStatus {
|
||||||
pub key_left: bool,
|
pub key_left: bool,
|
||||||
pub key_right: bool,
|
pub key_right: bool,
|
||||||
|
|
40
src/main.rs
40
src/main.rs
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use physics::Cartesian;
|
use cgmath::{Deg, Point2};
|
||||||
use winit::{
|
use winit::{
|
||||||
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
|
@ -16,29 +16,33 @@ mod system;
|
||||||
use crate::{
|
use crate::{
|
||||||
doodad::Doodad,
|
doodad::Doodad,
|
||||||
inputstatus::InputStatus,
|
inputstatus::InputStatus,
|
||||||
|
physics::Pfloat,
|
||||||
render::GPUState,
|
render::GPUState,
|
||||||
ship::{Ship, ShipKind},
|
ship::{Ship, ShipKind},
|
||||||
system::System,
|
system::System,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Camera {
|
struct Camera {
|
||||||
pos: Cartesian,
|
pos: Point2<Pfloat>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
trait Spriteable {
|
||||||
fn new() -> Self {
|
fn sprite(&self, camera: &Camera) -> Sprite;
|
||||||
Camera {
|
|
||||||
pos: Cartesian::new(0.0, 0.0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Sprite {
|
struct Sprite {
|
||||||
// Image to use
|
// Name of the sprite to draw
|
||||||
name: String,
|
name: String,
|
||||||
// World position
|
|
||||||
position: (f64, f64),
|
// This object's position, in world coordinates.
|
||||||
angle: f32,
|
position: Point2<Pfloat>,
|
||||||
|
|
||||||
|
// This sprite's rotation
|
||||||
|
// (relative to north, measured ccw)
|
||||||
|
angle: Deg<Pfloat>,
|
||||||
|
|
||||||
|
// The camera we want to draw this sprite from, in world coordinates
|
||||||
|
camera: Point2<Pfloat>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Game {
|
struct Game {
|
||||||
|
@ -54,8 +58,10 @@ impl Game {
|
||||||
Game {
|
Game {
|
||||||
last_update: Instant::now(),
|
last_update: Instant::now(),
|
||||||
input: InputStatus::new(),
|
input: InputStatus::new(),
|
||||||
player: Ship::new(ShipKind::Gypsum, Cartesian::new(0.0, 0.0)),
|
player: Ship::new(ShipKind::Gypsum, (0.0, 0.0).into()),
|
||||||
camera: Camera::new(),
|
camera: Camera {
|
||||||
|
pos: (0.0, 0.0).into(),
|
||||||
|
},
|
||||||
system: System::new(),
|
system: System::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +71,7 @@ impl Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self) {
|
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);
|
println!("{:.02}", 1.0 / t);
|
||||||
|
|
||||||
if self.input.key_thrust {
|
if self.input.key_thrust {
|
||||||
|
@ -73,11 +79,11 @@ impl Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.input.key_right {
|
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 {
|
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);
|
self.player.body.tick(t);
|
||||||
|
|
|
@ -1,46 +1,51 @@
|
||||||
use crate::physics::Cartesian;
|
use super::Pfloat;
|
||||||
|
use cgmath::{Angle, Deg, Point2, Vector2};
|
||||||
|
|
||||||
pub struct PhysBody {
|
pub struct PhysBody {
|
||||||
pub pos: Cartesian,
|
pub pos: Point2<Pfloat>,
|
||||||
pub vel: Cartesian,
|
pub vel: Vector2<Pfloat>,
|
||||||
pub mass: f64,
|
pub mass: Pfloat,
|
||||||
pub angle: f64, // In degrees
|
pub angle: Deg<Pfloat>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PhysBody {
|
impl PhysBody {
|
||||||
pub fn new(pos: Cartesian) -> Self {
|
pub fn new(pos: Point2<Pfloat>) -> Self {
|
||||||
return PhysBody {
|
return PhysBody {
|
||||||
pos,
|
pos,
|
||||||
vel: Cartesian::new(0.0, 0.0),
|
vel: (0.0, 0.0).into(),
|
||||||
mass: 0.3,
|
mass: 0.3,
|
||||||
angle: 0.0,
|
angle: Deg { 0: 0.0 },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the state of this body after t seconds.
|
/// Calculate the position of this body after t seconds.
|
||||||
pub fn tick(&mut self, t: f64) {
|
pub fn tick(&mut self, t: Pfloat) {
|
||||||
self.pos += self.vel * t;
|
self.pos += self.vel * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply an instantaneous force to this object
|
/// Apply an instantaneous force to this object
|
||||||
pub fn force(&mut self, v: Cartesian) {
|
pub fn force(&mut self, v: Vector2<Pfloat>) {
|
||||||
self.vel += v / self.mass;
|
self.vel += v / self.mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply force in the direction this object is pointing.
|
/// Apply a force in the direction this object is pointing.
|
||||||
pub fn thrust(&mut self, f: f64) {
|
pub fn thrust(&mut self, f: Pfloat) {
|
||||||
let l = Cartesian::new(
|
let l = Vector2 {
|
||||||
-self.angle.to_radians().sin(),
|
x: -self.angle.sin(),
|
||||||
self.angle.to_radians().cos(),
|
y: self.angle.cos(),
|
||||||
) * f;
|
} * f;
|
||||||
self.force(l);
|
self.force(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate this object by `a` radians.
|
// Rotate this object
|
||||||
pub fn rot(&mut self, a: f64) {
|
pub fn rot(&mut self, a: Deg<Pfloat>) {
|
||||||
self.angle -= a;
|
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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<f64> for Cartesian {
|
|
||||||
type Output = Cartesian;
|
|
||||||
fn mul(self, rhs: f64) -> Self::Output {
|
|
||||||
Self {
|
|
||||||
x: self.x * rhs,
|
|
||||||
y: self.y * rhs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MulAssign<f64> for Cartesian {
|
|
||||||
fn mul_assign(&mut self, rhs: f64) {
|
|
||||||
self.x *= rhs;
|
|
||||||
self.y *= rhs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Div<f64> for Cartesian {
|
|
||||||
type Output = Cartesian;
|
|
||||||
fn div(self, rhs: f64) -> Self::Output {
|
|
||||||
Self {
|
|
||||||
x: self.x / rhs,
|
|
||||||
y: self.y / rhs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DivAssign<f64> for Cartesian {
|
|
||||||
fn div_assign(&mut self, rhs: f64) {
|
|
||||||
self.x /= rhs;
|
|
||||||
self.y /= rhs;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,8 @@
|
||||||
mod body;
|
mod body;
|
||||||
mod cartesian;
|
|
||||||
mod polar;
|
mod polar;
|
||||||
|
|
||||||
|
// What kind of float shoud we use for physics?
|
||||||
|
pub type Pfloat = f32;
|
||||||
|
|
||||||
pub use body::PhysBody;
|
pub use body::PhysBody;
|
||||||
pub use cartesian::Cartesian;
|
|
||||||
pub use polar::Polar;
|
pub use polar::Polar;
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
use super::Cartesian;
|
use super::Pfloat;
|
||||||
|
use cgmath::{Angle, Deg, EuclideanSpace, Point2};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Polar {
|
pub struct Polar {
|
||||||
pub center: Cartesian,
|
pub center: Point2<Pfloat>,
|
||||||
pub radius: f64,
|
pub radius: Pfloat,
|
||||||
pub angle: f64,
|
pub angle: Deg<Pfloat>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Cartesian> for Polar {
|
impl Polar {
|
||||||
fn into(self) -> Cartesian {
|
pub fn to_cartesian(self) -> Point2<Pfloat> {
|
||||||
return Cartesian::new(
|
return Point2 {
|
||||||
self.radius * self.angle.sin(),
|
x: self.radius * self.angle.sin(),
|
||||||
self.radius * self.angle.cos(),
|
y: self.radius * self.angle.cos(),
|
||||||
) + self.center;
|
} + self.center.to_vec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bytemuck;
|
use bytemuck;
|
||||||
use cgmath::{Deg, Matrix4, Point2, Vector3};
|
use cgmath::{Deg, EuclideanSpace, Matrix4, Point2, Vector3};
|
||||||
use std::{iter, mem};
|
use std::{iter, mem};
|
||||||
use wgpu::{self, util::DeviceExt};
|
use wgpu::{self, util::DeviceExt};
|
||||||
use winit::{self, window::Window};
|
use winit::{self, window::Window};
|
||||||
|
@ -104,7 +104,7 @@ struct Transform {
|
||||||
pos: Point2<f32>,
|
pos: Point2<f32>,
|
||||||
aspect: f32, // width / height
|
aspect: f32, // width / height
|
||||||
scale: f32,
|
scale: f32,
|
||||||
rotate: f32, // Around this object's center, in degrees measured ccw from vertical
|
rotate: Deg<f32>, // Around this object's center, in degrees measured ccw from vertical
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transform {
|
impl Transform {
|
||||||
|
@ -115,7 +115,7 @@ impl Transform {
|
||||||
|
|
||||||
// Our mesh starts at (0, 0), so this will rotate around the object's center.
|
// Our mesh starts at (0, 0), so this will rotate around the object's center.
|
||||||
// Note that we translate AFTER scaling.
|
// 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 {
|
let translate = Matrix4::from_translation(Vector3 {
|
||||||
x: self.pos.x,
|
x: self.pos.x,
|
||||||
|
@ -402,17 +402,14 @@ impl GPUState {
|
||||||
// TODO: warning when too many sprites are drawn.
|
// TODO: warning when too many sprites are drawn.
|
||||||
let mut instances: Vec<Instance> = Vec::new();
|
let mut instances: Vec<Instance> = Vec::new();
|
||||||
for s in sprites {
|
for s in sprites {
|
||||||
let mut pos: Point2<f32> = (s.position.0 as f32, s.position.1 as f32).into();
|
// Compute position on screen
|
||||||
|
let screen_pos: Point2<f32> = (s.position - s.camera.to_vec()) / 400.0;
|
||||||
// TODO: dynamic
|
|
||||||
pos.x /= 400.0;
|
|
||||||
pos.y /= 400.0;
|
|
||||||
|
|
||||||
let texture = self.texture_array.get_texture(&s.name[..]);
|
let texture = self.texture_array.get_texture(&s.name[..]);
|
||||||
|
|
||||||
instances.push(Instance {
|
instances.push(Instance {
|
||||||
transform: Transform {
|
transform: Transform {
|
||||||
pos,
|
pos: screen_pos,
|
||||||
aspect: texture.aspect / screen_aspect,
|
aspect: texture.aspect / screen_aspect,
|
||||||
scale: 0.25,
|
scale: 0.25,
|
||||||
rotate: s.angle,
|
rotate: s.angle,
|
||||||
|
|
18
src/ship.rs
18
src/ship.rs
|
@ -1,7 +1,10 @@
|
||||||
use crate::physics::Cartesian;
|
use cgmath::Point2;
|
||||||
|
|
||||||
|
use crate::physics::Pfloat;
|
||||||
use crate::physics::PhysBody;
|
use crate::physics::PhysBody;
|
||||||
use crate::Camera;
|
use crate::Camera;
|
||||||
use crate::Sprite;
|
use crate::Sprite;
|
||||||
|
use crate::Spriteable;
|
||||||
|
|
||||||
pub enum ShipKind {
|
pub enum ShipKind {
|
||||||
Gypsum,
|
Gypsum,
|
||||||
|
@ -21,20 +24,21 @@ pub struct Ship {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ship {
|
impl Ship {
|
||||||
pub fn new(kind: ShipKind, pos: Cartesian) -> Self {
|
pub fn new(kind: ShipKind, pos: Point2<Pfloat>) -> Self {
|
||||||
Ship {
|
Ship {
|
||||||
body: PhysBody::new(pos),
|
body: PhysBody::new(pos),
|
||||||
kind,
|
kind,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sprite(&self, camera: &Camera) -> Sprite {
|
impl Spriteable for Ship {
|
||||||
let p = self.body.pos - camera.pos;
|
fn sprite(&self, camera: &Camera) -> Sprite {
|
||||||
|
|
||||||
return Sprite {
|
return Sprite {
|
||||||
position: (p.x, p.y),
|
position: self.body.pos,
|
||||||
|
camera: camera.pos,
|
||||||
name: self.kind.sprite().to_owned(),
|
name: self.kind.sprite().to_owned(),
|
||||||
angle: self.body.angle as f32,
|
angle: self.body.angle,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
pub struct System {
|
||||||
bodies: Vec<Doodad>,
|
bodies: Vec<Doodad>,
|
||||||
|
@ -9,22 +10,22 @@ impl System {
|
||||||
let mut s = System { bodies: Vec::new() };
|
let mut s = System { bodies: Vec::new() };
|
||||||
|
|
||||||
s.bodies.push(Doodad {
|
s.bodies.push(Doodad {
|
||||||
pos: Cartesian::new(0.0, 0.0),
|
pos: (0.0, 0.0).into(),
|
||||||
sprite: "a0".to_owned(),
|
sprite: "a0".to_owned(),
|
||||||
});
|
});
|
||||||
|
|
||||||
s.bodies.push(Doodad {
|
s.bodies.push(Doodad {
|
||||||
pos: Polar {
|
pos: Polar {
|
||||||
center: Cartesian::new(0.0, 0.0),
|
center: (0.0, 0.0).into(),
|
||||||
radius: 300.0,
|
radius: 300.0,
|
||||||
angle: 31.0,
|
angle: Deg { 0: 31.0 },
|
||||||
}
|
}
|
||||||
.into(),
|
.to_cartesian(),
|
||||||
sprite: "earth".to_owned(),
|
sprite: "earth".to_owned(),
|
||||||
});
|
});
|
||||||
|
|
||||||
s.bodies.push(Doodad {
|
s.bodies.push(Doodad {
|
||||||
pos: Cartesian::new(1000.0, 1000.0),
|
pos: (1000.0, 1000.0).into(),
|
||||||
sprite: "small".to_owned(),
|
sprite: "small".to_owned(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue