Browse Source

Refactored calculation of positions related to different coordinate systems

master
Bergmann89 3 years ago
parent
commit
cf1c473c87
12 changed files with 230 additions and 79 deletions
  1. +8
    -5
      glc/src/matrix.rs
  2. +76
    -1
      glc/src/vector.rs
  3. +7
    -6
      space-crush-app/src/debug/summary.rs
  4. +9
    -10
      space-crush-app/src/render/init.rs
  5. +39
    -39
      space-crush-app/src/render/select_fleet.rs
  6. +50
    -4
      space-crush-app/src/resources/camera.rs
  7. +4
    -2
      space-crush-app/src/resources/input_state.rs
  8. +6
    -6
      space-crush-app/src/resources/mod.rs
  9. +3
    -6
      space-crush-app/src/systems/state_update.rs
  10. +8
    -0
      space-crush-common/src/components/ship.rs
  11. +1
    -0
      space-crush-common/src/lib.rs
  12. +19
    -0
      space-crush-common/src/macros.rs

+ 8
- 5
glc/src/matrix.rs View File

@@ -284,7 +284,8 @@ where
} }


#[inline] #[inline]
pub fn translate(v: Vector2<T>) -> Self {
pub fn translate<V: Into<Vector2<T>>>(v: V) -> Self {
let v = V::into(v);
let one = T::one(); let one = T::one();
let zro = T::zero(); let zro = T::zero();


@@ -378,7 +379,8 @@ where
T: Float, T: Float,
{ {
#[inline] #[inline]
pub fn translate(v: Vector3<T>) -> Self {
pub fn translate<V: Into<Vector3<T>>>(v: V) -> Self {
let v = V::into(v);
let one = T::one(); let one = T::one();
let zero = T::zero(); let zero = T::zero();


@@ -391,7 +393,8 @@ where
} }


#[inline] #[inline]
pub fn scale(v: Vector3<T>) -> Self {
pub fn scale<V: Into<Vector3<T>>>(v: V) -> Self {
let v = V::into(v);
let one = T::one(); let one = T::one();
let zero = T::zero(); let zero = T::zero();


@@ -405,8 +408,8 @@ where


#[inline] #[inline]
#[allow(clippy::many_single_char_names)] #[allow(clippy::many_single_char_names)]
pub fn rotate(axis: Vector3<T>, angle: Angle<T>) -> Self {
let axis = axis.normalize();
pub fn rotate<V: Into<Vector3<T>>>(axis: V, angle: Angle<T>) -> Self {
let axis = V::into(axis).normalize();
let x = axis.x; let x = axis.x;
let y = axis.y; let y = axis.y;
let z = axis.z; let z = axis.z;


+ 76
- 1
glc/src/vector.rs View File

@@ -2,7 +2,7 @@


use std::convert::{AsMut, AsRef}; use std::convert::{AsMut, AsRef};
use std::fmt::{Debug, Formatter, Result as FmtResult}; use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::ops::{Add, Deref, DerefMut, Mul, Sub};
use std::ops::{Add, Deref, DerefMut, Mul, Neg, Sub};


#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{ use serde::{
@@ -296,6 +296,21 @@ where
} }
} }


impl<T> Neg for Vector2<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn neg(self) -> Self::Output {
Self {
x: -self.x,
y: -self.y,
}
}
}

impl<T> Add for Vector2<T> impl<T> Add for Vector2<T>
where where
T: Numeric, T: Numeric,
@@ -350,6 +365,15 @@ where
} }
} }


impl<T> From<Vector3<T>> for Vector2<T>
where
T: Numeric,
{
fn from(vec3: Vector3<T>) -> Self {
vec3.into_vec2()
}
}

impl<T> From<Vector4<T>> for Vector2<T> impl<T> From<Vector4<T>> for Vector2<T>
where where
T: Numeric, T: Numeric,
@@ -408,6 +432,19 @@ where
z: self.x * other.y - self.y * other.x, z: self.x * other.y - self.y * other.x,
} }
} }

#[inline]
pub fn as_vec2(&self) -> &Vector2<T> {
unsafe { &*(self as *const Vector3<T> as *const Vector2<T>) }
}

#[inline]
pub fn into_vec2(self) -> Vector2<T> {
Vector2 {
x: self.x,
y: self.y,
}
}
} }


impl<T> Vector3<T> impl<T> Vector3<T>
@@ -424,6 +461,22 @@ where
} }
} }


impl<T> Neg for Vector3<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn neg(self) -> Self::Output {
Self {
x: -self.x,
y: -self.y,
z: -self.z,
}
}
}

impl<T> Add for Vector3<T> impl<T> Add for Vector3<T>
where where
T: Numeric, T: Numeric,
@@ -480,6 +533,28 @@ where
} }
} }


impl<T> From<Vector2<T>> for Vector3<T>
where
T: Numeric,
{
fn from(vec2: Vector2<T>) -> Self {
Self {
x: vec2.x,
y: vec2.y,
z: T::zero(),
}
}
}

impl<T> From<Vector4<T>> for Vector3<T>
where
T: Numeric,
{
fn from(vec4: Vector4<T>) -> Self {
vec4.into_vec3()
}
}

/* Vector4 */ /* Vector4 */


impl<T> Vector4<T> impl<T> Vector4<T>


+ 7
- 6
space-crush-app/src/debug/summary.rs View File

@@ -1,5 +1,6 @@
use std::string::ToString; use std::string::ToString;


use glc::vector::Vector2f;
use space_crush_common::{misc::LogResult, resources::Global}; use space_crush_common::{misc::LogResult, resources::Global};
use specs::{prelude::*, Entities, ReadExpect, System}; use specs::{prelude::*, Entities, ReadExpect, System};


@@ -15,8 +16,8 @@ pub struct Summary {
cache: TextCache, cache: TextCache,
text: Text, text: Text,
fps: usize, fps: usize,
resolution: (u32, u32),
mouse_pos: (f32, f32),
resolution: Vector2f,
mouse_pos: Vector2f,
entity_count: usize, entity_count: usize,
} }


@@ -44,8 +45,8 @@ impl Summary {
cache, cache,
text, text,
fps: 0, fps: 0,
resolution: (0, 0),
mouse_pos: (0.0, 0.0),
resolution: Default::default(),
mouse_pos: Default::default(),
entity_count: 0, entity_count: 0,
}) })
} }
@@ -83,14 +84,14 @@ impl<'a> System<'a> for Summary {
4, 4,
&mut self.resolution, &mut self.resolution,
&input_state.resolution, &input_state.resolution,
|(w, h)| format!("{} | {}", w, h),
|v| unsafe { format!("{:.0} | {:.0}", v.x, v.y) },
); );
update_text( update_text(
&mut self.text, &mut self.text,
6, 6,
&mut self.mouse_pos, &mut self.mouse_pos,
&input_state.mouse_pos, &input_state.mouse_pos,
|(x, y)| format!("{:.2} | {:.2}", x, y),
|v| unsafe { format!("{:.2} | {:.2}", v.x, v.y) },
); );
update_text( update_text(
&mut self.text, &mut self.text,


+ 9
- 10
space-crush-app/src/render/init.rs View File

@@ -2,7 +2,7 @@ use glc::{
matrix::Matrix4f, matrix::Matrix4f,
misc::Bindable, misc::Bindable,
shader::{Program, Type}, shader::{Program, Type},
vector::Vector3f,
vector::{Vector2f, Vector3f},
}; };
use shrev::{EventChannel, ReaderId}; use shrev::{EventChannel, ReaderId};
use space_crush_common::{ use space_crush_common::{
@@ -20,7 +20,7 @@ use crate::{


pub struct Init { pub struct Init {
program: Program, program: Program,
resolution: (u32, u32),
resolution: Vector2f,
mouse_event_id: ReaderId<MouseEvent>, mouse_event_id: ReaderId<MouseEvent>,
} }


@@ -30,7 +30,7 @@ impl Init {
(Type::Vertex, "resources/shader/noise/vert.glsl"), (Type::Vertex, "resources/shader/noise/vert.glsl"),
(Type::Fragment, "resources/shader/noise/frag.glsl"), (Type::Fragment, "resources/shader/noise/frag.glsl"),
])?; ])?;
let resolution = (0, 0);
let resolution = Vector2f::default();
let mouse_event_id = world.register_event_reader::<MouseEvent>()?; let mouse_event_id = world.register_event_reader::<MouseEvent>()?;


world world
@@ -80,31 +80,30 @@ impl<'a> System<'a> for Init {
if self.resolution != input_state.resolution { if self.resolution != input_state.resolution {
self.resolution = input_state.resolution; self.resolution = input_state.resolution;


gl::viewport(0, 0, self.resolution.0 as _, self.resolution.1 as _);
gl::viewport(0, 0, self.resolution.x as _, self.resolution.y as _);


camera camera
.resize(self.resolution.0 as _, self.resolution.1 as _)
.resize(self.resolution.x, self.resolution.y)
.error("Error while updating camera"); .error("Error while updating camera");
} }


/* zoom */ /* zoom */
let mouse_pos = &input_state.mouse_pos;
let events = mouse_events.read(&mut self.mouse_event_id); let events = mouse_events.read(&mut self.mouse_event_id);
for event in events { for event in events {
match event { match event {
MouseEvent::ScrollY(delta) => { MouseEvent::ScrollY(delta) => {
let s = config.input.camera_zoom_speed; let s = config.input.camera_zoom_speed;
let z = s / (s - delta); let z = s / (s - delta);
let m = Matrix4f::translate((mouse_pos.0, mouse_pos.1, 0.0).into())
* Matrix4f::scale(z.into())
* Matrix4f::translate((-mouse_pos.0, -mouse_pos.1, 0.0).into());
let m = Matrix4f::translate(input_state.mouse_pos)
* Matrix4f::scale(z)
* Matrix4f::translate(-input_state.mouse_pos);


camera camera
.update_with(move |v| m * v) .update_with(move |v| m * v)
.error("Error while zooming camera"); .error("Error while zooming camera");
} }
MouseEvent::Delta(x, y) if input_state.button_state(&[MouseButton::Right]) => { MouseEvent::Delta(x, y) if input_state.button_state(&[MouseButton::Right]) => {
let m = Matrix4f::translate((*x, -*y, 0.0).into());
let m = Matrix4f::translate((*x, -*y, 0.0));


camera camera
.update_with(move |v| m * v) .update_with(move |v| m * v)


+ 39
- 39
space-crush-app/src/render/select_fleet.rs View File

@@ -14,6 +14,7 @@ use space_crush_common::{
constants::VECTOR_2F_POS_X, constants::VECTOR_2F_POS_X,
misc::{LogResult, WorldHelper as _}, misc::{LogResult, WorldHelper as _},
resources::Global, resources::Global,
return_if_none,
}; };
use specs::{prelude::*, Entities, ReadExpect, ReadStorage, System, World}; use specs::{prelude::*, Entities, ReadExpect, ReadStorage, System, World};


@@ -44,9 +45,9 @@ pub struct SelectFleet {
mouse_event_id: ReaderId<MouseEvent>, mouse_event_id: ReaderId<MouseEvent>,
select_mode: SelectMode, select_mode: SelectMode,
camera_counter: usize, camera_counter: usize,
camera_view_invert: Matrix4f,
need_value_update: bool, need_value_update: bool,
values_changed_once: bool, values_changed_once: bool,
is_new_selection: bool,


mouse_pos: Vector2f, mouse_pos: Vector2f,
count: ShipCount, count: ShipCount,
@@ -69,7 +70,7 @@ enum SelectMode {
} }


#[derive(SystemData)] #[derive(SystemData)]
pub struct SelectFleetData<'a> {
pub struct FleetSelectData<'a> {
player_state: WriteExpect<'a, PlayerState>, player_state: WriteExpect<'a, PlayerState>,
camera: ReadExpect<'a, Camera>, camera: ReadExpect<'a, Camera>,


@@ -85,33 +86,24 @@ pub struct SelectFleetData<'a> {
fleets: ReadStorage<'a, Fleet>, fleets: ReadStorage<'a, Fleet>,
} }


macro_rules! unwrap {
($value:expr) => {
match $value {
Some(value) => value,
None => return,
}
};
}

macro_rules! selection { macro_rules! selection {
(&$data:expr) => { (&$data:expr) => {
unwrap!(&$data.player_state.selection)
return_if_none!(&$data.player_state.selection)
}; };
(&mut $data:expr) => { (&mut $data:expr) => {
unwrap!(&mut $data.player_state.selection)
return_if_none!(&mut $data.player_state.selection)
}; };
} }


macro_rules! fleet_info { macro_rules! fleet_info {
(&$data:expr, $id:expr) => { (&$data:expr, $id:expr) => {
unwrap!($data.fleet_infos.get($id))
return_if_none!($data.fleet_infos.get($id))
}; };
} }


macro_rules! position { macro_rules! position {
(&$data:expr, $id:expr) => { (&$data:expr, $id:expr) => {
unwrap!($data.positions.get($id))
return_if_none!($data.positions.get($id))
}; };
} }


@@ -157,9 +149,9 @@ impl SelectFleet {
mouse_event_id, mouse_event_id,
select_mode, select_mode,
camera_counter: 0, camera_counter: 0,
camera_view_invert: Default::default(),
need_value_update: true, need_value_update: true,
values_changed_once: false, values_changed_once: false,
is_new_selection: true,


mouse_pos: Default::default(), mouse_pos: Default::default(),
count: Default::default(), count: Default::default(),
@@ -172,39 +164,46 @@ impl SelectFleet {
}) })
} }


fn update_camera(&mut self, d: &SelectFleetData<'_>) {
fn update_camera(&mut self, d: &FleetSelectData<'_>) {
let camera_counter = d.camera.update_counter(); let camera_counter = d.camera.update_counter();


if self.camera_counter != camera_counter { if self.camera_counter != camera_counter {
self.camera_counter = camera_counter; self.camera_counter = camera_counter;
self.need_value_update = true; self.need_value_update = true;
self.camera_view_invert = d.camera.view().invert();
} }
} }


fn handle_events(&mut self, d: &mut SelectFleetData<'_>) {
fn handle_events(&mut self, d: &mut FleetSelectData<'_>) {
let events = d.mouse_events.read(&mut self.mouse_event_id); let events = d.mouse_events.read(&mut self.mouse_event_id);
for event in events { for event in events {
match event { match event {
MouseEvent::ButtonDown(button) if button == &d.config.input.fleet_select_button => { MouseEvent::ButtonDown(button) if button == &d.config.input.fleet_select_button => {
let pos = self.window_to_world(d.input_state.mouse_pos);
let pos = d.camera.view_to_world(d.input_state.mouse_pos);
let selection = d.player_state.selection.take(); let selection = d.player_state.selection.take();
for (id, position, fleet) in (&d.entities, &d.positions, &d.fleets).join() { for (id, position, fleet) in (&d.entities, &d.positions, &d.fleets).join() {
let r = fleet.orbit_max * fleet.orbit_max; let r = fleet.orbit_max * fleet.orbit_max;
if (position.pos - pos).length_sqr() <= r { if (position.pos - pos).length_sqr() <= r {
d.player_state.selection = match selection { d.player_state.selection = match selection {
Some(s) if s.fleet == id => Some(s),
_ => Some(Selection {
fleet: id,
count: ShipCount::all(),
}),
Some(s) if s.fleet == id => {
self.is_new_selection = false;

Some(s)
}
_ => {
self.is_new_selection = true;

Some(Selection {
fleet: id,
count: ShipCount::none(),
})
}
}; };


let selection = selection!(&d); let selection = selection!(&d);
let fleet_info = fleet_info!(&d, selection.fleet); let fleet_info = fleet_info!(&d, selection.fleet);
let timeout = Instant::now() + FLEET_SELECT_DETAIL_TIMEOUT; let timeout = Instant::now() + FLEET_SELECT_DETAIL_TIMEOUT;


self.mouse_pos = d.input_state.mouse_pos.into();
self.mouse_pos = d.input_state.mouse_pos;
self.select_mode = SelectMode::Init(timeout); self.select_mode = SelectMode::Init(timeout);
self.values_changed_once = false; self.values_changed_once = false;
self.set_count(selection.count, &fleet_info.count); self.set_count(selection.count, &fleet_info.count);
@@ -218,36 +217,41 @@ impl SelectFleet {
SelectMode::Simple(progress) => { SelectMode::Simple(progress) => {
selection!(&mut d).count = self.count; selection!(&mut d).count = self.count;


self.mouse_pos = d.input_state.mouse_pos.into();
self.mouse_pos = d.input_state.mouse_pos;


SelectMode::SimpleClose(progress) SelectMode::SimpleClose(progress)
} }
SelectMode::Detail(progress) => { SelectMode::Detail(progress) => {
selection!(&mut d).count = self.count; selection!(&mut d).count = self.count;


self.mouse_pos = d.input_state.mouse_pos.into();
self.mouse_pos = d.input_state.mouse_pos;


SelectMode::DetailClose(progress) SelectMode::DetailClose(progress)
} }
SelectMode::Init(_) if self.is_new_selection => {
selection!(&mut d).count = ShipCount::all();

SelectMode::None
}
_ => SelectMode::None, _ => SelectMode::None,
} }
} }
MouseEvent::Move(_, _) if self.select_mode.is_init() => { MouseEvent::Move(_, _) if self.select_mode.is_init() => {
self.need_value_update = true; self.need_value_update = true;
self.values_changed_once = false; self.values_changed_once = false;
self.mouse_pos = d.input_state.mouse_pos.into();
self.mouse_pos = d.input_state.mouse_pos;
self.select_mode = SelectMode::Simple(0.0); self.select_mode = SelectMode::Simple(0.0);
} }
MouseEvent::Move(_, _) if self.select_mode.is_active() => { MouseEvent::Move(_, _) if self.select_mode.is_active() => {
self.need_value_update = true; self.need_value_update = true;
self.mouse_pos = d.input_state.mouse_pos.into();
self.mouse_pos = d.input_state.mouse_pos;
} }
_ => (), _ => (),
} }
} }
} }


fn update(&mut self, d: &SelectFleetData<'_>) {
fn update(&mut self, d: &FleetSelectData<'_>) {
if !self.select_mode.is_active() { if !self.select_mode.is_active() {
return; return;
} }
@@ -261,7 +265,7 @@ impl SelectFleet {
let position = position!(&d, selection.fleet); let position = position!(&d, selection.fleet);
let fleet_info = fleet_info!(&d, selection.fleet); let fleet_info = fleet_info!(&d, selection.fleet);


self.marker = self.window_to_world(self.mouse_pos) - position.pos;
self.marker = d.camera.view_to_world(self.mouse_pos) - position.pos;
self.zoom = d.camera.view().axis_x.as_vec3().length(); self.zoom = d.camera.view().axis_x.as_vec3().length();
self.shape_size = position.shape.radius().unwrap_or(0.0); self.shape_size = position.shape.radius().unwrap_or(0.0);
self.ring0 = self.shape_size + FLEET_SELECT_OFFSET / self.zoom; self.ring0 = self.shape_size + FLEET_SELECT_OFFSET / self.zoom;
@@ -400,7 +404,7 @@ impl SelectFleet {
} }
} }


fn render(&mut self, progress: f32, d: &SelectFleetData<'_>) {
fn render(&mut self, progress: f32, d: &FleetSelectData<'_>) {
/* select program */ /* select program */
let is_simple = self.select_mode.is_simple(); let is_simple = self.select_mode.is_simple();
let program = if is_simple { let program = if is_simple {
@@ -500,15 +504,11 @@ impl SelectFleet {
self.values[3] = sum / total_max; self.values[3] = sum / total_max;
} }


fn window_to_world<T: Into<Vector2f>>(&self, pos: T) -> Vector2f {
(self.camera_view_invert * T::into(pos).into_vec4()).into_vec2()
}

fn text_pos<T: Into<Vector2f>>( fn text_pos<T: Into<Vector2f>>(
&self, &self,
dir: T, dir: T,
fleet_pos: Vector2f, fleet_pos: Vector2f,
d: &SelectFleetData<'_>,
d: &FleetSelectData<'_>,
) -> Vector2f { ) -> Vector2f {
let text_offset = self.ring1 + FLEET_SELECT_TEXT_OFFSET / self.zoom.sqrt(); let text_offset = self.ring1 + FLEET_SELECT_TEXT_OFFSET / self.zoom.sqrt();
let pos = fleet_pos + T::into(dir).normalize() * text_offset; let pos = fleet_pos + T::into(dir).normalize() * text_offset;
@@ -518,7 +518,7 @@ impl SelectFleet {
} }


impl<'a> System<'a> for SelectFleet { impl<'a> System<'a> for SelectFleet {
type SystemData = SelectFleetData<'a>;
type SystemData = FleetSelectData<'a>;


fn run(&mut self, mut data: Self::SystemData) { fn run(&mut self, mut data: Self::SystemData) {
self.update_camera(&data); self.update_camera(&data);


+ 50
- 4
space-crush-app/src/resources/camera.rs View File

@@ -10,6 +10,8 @@ use glc::{
pub struct Camera { pub struct Camera {
buffer: ArrayBuffer, buffer: ArrayBuffer,
data: Data, data: Data,
view_invert: Matrix4f,
projection_invert: Matrix4f,
update_counter: usize, update_counter: usize,
} }


@@ -34,6 +36,8 @@ impl Camera {
Ok(Self { Ok(Self {
buffer, buffer,
data, data,
view_invert: Default::default(),
projection_invert: Default::default(),
update_counter: 0, update_counter: 0,
}) })
} }
@@ -42,10 +46,18 @@ impl Camera {
&self.data.projection &self.data.projection
} }


pub fn projection_invert(&self) -> &Matrix4f {
&self.projection_invert
}

pub fn view(&self) -> &Matrix4f { pub fn view(&self) -> &Matrix4f {
&self.data.view &self.data.view
} }


pub fn view_invert(&self) -> &Matrix4f {
&self.view_invert
}

pub fn update_counter(&self) -> usize { pub fn update_counter(&self) -> usize {
self.update_counter self.update_counter
} }
@@ -63,6 +75,7 @@ impl Camera {
data[0].size = self.data.size; data[0].size = self.data.size;


self.update_counter = self.update_counter.wrapping_add(1); self.update_counter = self.update_counter.wrapping_add(1);
self.projection_invert = self.data.projection.invert();


Ok(()) Ok(())
} }
@@ -81,6 +94,7 @@ impl Camera {
data[0].view = self.data.view; data[0].view = self.data.view;


self.update_counter = self.update_counter.wrapping_add(1); self.update_counter = self.update_counter.wrapping_add(1);
self.view_invert = self.data.view.invert();


Ok(()) Ok(())
} }
@@ -89,11 +103,43 @@ impl Camera {
Error::checked(|| self.buffer.bind_buffer_base(index)) Error::checked(|| self.buffer.bind_buffer_base(index))
} }


pub fn world_to_view<T: Into<Vector2f>>(&self, pos: T) -> Vector2f {
self.data.view.transform(T::into(pos)).into()
}

pub fn view_to_world<T: Into<Vector2f>>(&self, pos: T) -> Vector2f {
self.view_invert.transform(T::into(pos)).into()
}

pub fn view_to_window<T: Into<Vector2f>>(&self, pos: T) -> Vector2f {
view_to_window(&self.data.size, pos)
}

pub fn window_to_view<T: Into<Vector2f>>(&self, pos: T) -> Vector2f {
window_to_view(&self.data.size, pos)
}

pub fn world_to_window<T: Into<Vector2f>>(&self, pos: T) -> Vector2f { pub fn world_to_window<T: Into<Vector2f>>(&self, pos: T) -> Vector2f {
let mut pos = self.data.view.transform(T::into(pos)).into_vec2();
pos.x += self.data.size.x / 2.0;
pos.y = self.data.size.y / 2.0 - pos.y;
self.view_to_window(self.world_to_view(pos))
}


pos
pub fn window_to_world<T: Into<Vector2f>>(&self, pos: T) -> Vector2f {
self.view_to_world(self.window_to_view(pos))
} }
} }

pub fn view_to_window<T: Into<Vector2f>>(res: &Vector2f, pos: T) -> Vector2f {
let mut pos = T::into(pos);
pos.x += res.x / 2.0;
pos.y = res.y / 2.0 - pos.y;

pos
}

pub fn window_to_view<T: Into<Vector2f>>(res: &Vector2f, pos: T) -> Vector2f {
let mut pos = T::into(pos);
pos.x -= res.x / 2.0;
pos.y = res.y / 2.0 - pos.y;

pos
}

+ 4
- 2
space-crush-app/src/resources/input_state.rs View File

@@ -3,12 +3,14 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::iter::IntoIterator; use std::iter::IntoIterator;


use glc::vector::Vector2f;

use crate::misc::{MouseButton, VirtualKeyCode}; use crate::misc::{MouseButton, VirtualKeyCode};


#[derive(Default)] #[derive(Default)]
pub struct InputState { pub struct InputState {
pub mouse_pos: (f32, f32),
pub resolution: (u32, u32),
pub mouse_pos: Vector2f,
pub resolution: Vector2f,
pub close_requested: bool, pub close_requested: bool,
pub key_states: HashSet<VirtualKeyCode>, pub key_states: HashSet<VirtualKeyCode>,
pub button_states: HashSet<MouseButton>, pub button_states: HashSet<MouseButton>,


+ 6
- 6
space-crush-app/src/resources/mod.rs View File

@@ -1,9 +1,9 @@
mod camera;
mod config;
mod geometry;
mod input_state;
mod player_state;
mod uniform;
pub mod camera;
pub mod config;
pub mod geometry;
pub mod input_state;
pub mod player_state;
pub mod uniform;


pub use camera::Camera; pub use camera::Camera;
pub use config::Config; pub use config::Config;


+ 3
- 6
space-crush-app/src/systems/state_update.rs View File

@@ -4,7 +4,7 @@ use specs::{prelude::*, ReadExpect, System, World, Write};


use crate::{ use crate::{
misc::{KeyboardEvent, MouseEvent, WindowEvent}, misc::{KeyboardEvent, MouseEvent, WindowEvent},
resources::InputState,
resources::{camera::window_to_view, InputState},
Error, Error,
}; };


@@ -51,10 +51,7 @@ impl<'a> System<'a> for StateUpdate {
for event in events { for event in events {
match event { match event {
MouseEvent::Move(x, y) => { MouseEvent::Move(x, y) => {
let x = *x - input_state.resolution.0 as f32 / 2.0;
let y = input_state.resolution.1 as f32 / 2.0 - *y;

input_state.mouse_pos = (x, y);
input_state.mouse_pos = window_to_view(&input_state.resolution, (*x, *y))
} }
MouseEvent::ButtonUp(button) => input_state.set_button_state(*button, false), MouseEvent::ButtonUp(button) => input_state.set_button_state(*button, false),
MouseEvent::ButtonDown(button) => input_state.set_button_state(*button, true), MouseEvent::ButtonDown(button) => input_state.set_button_state(*button, true),
@@ -66,7 +63,7 @@ impl<'a> System<'a> for StateUpdate {
for event in events { for event in events {
match event { match event {
WindowEvent::Resize(w, h) => { WindowEvent::Resize(w, h) => {
input_state.resolution = (*w, *h);
input_state.resolution = (*w as f32, *h as f32).into();
} }
WindowEvent::Close => { WindowEvent::Close => {
input_state.close_requested = true; input_state.close_requested = true;


+ 8
- 0
space-crush-common/src/components/ship.rs View File

@@ -40,6 +40,14 @@ impl Count {
} }
} }


pub fn none() -> Self {
Self {
fighter: 0,
bomber: 0,
transporter: 0,
}
}

pub fn total(&self) -> usize { pub fn total(&self) -> usize {
self.fighter self.fighter
.saturating_add(self.bomber) .saturating_add(self.bomber)


+ 1
- 0
space-crush-common/src/lib.rs View File

@@ -2,6 +2,7 @@ pub mod components;
pub mod constants; pub mod constants;
pub mod dispatcher; pub mod dispatcher;
pub mod error; pub mod error;
pub mod macros;
pub mod misc; pub mod misc;
pub mod resources; pub mod resources;
pub mod systems; pub mod systems;


+ 19
- 0
space-crush-common/src/macros.rs View File

@@ -0,0 +1,19 @@
#[macro_export]
macro_rules! return_if_none {
($value:expr) => {
match $value {
Some(value) => value,
None => return,
}
};
}

#[macro_export]
macro_rules! break_if_none {
($value:expr) => {
match $value {
Some(value) => value,
None => break,
}
};
}

Loading…
Cancel
Save