aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dimension_indicator.rs12
-rw-r--r--src/grid.rs55
-rw-r--r--src/main.rs6
-rw-r--r--src/map_data.rs18
-rw-r--r--src/math/mod.rs10
-rw-r--r--src/math/rect.rs42
-rw-r--r--src/math/vec2.rs47
-rw-r--r--src/tool/deletion_tool.rs8
-rw-r--r--src/tool/icon_tool.rs30
-rw-r--r--src/tool/polygon_room_tool.rs52
-rw-r--r--src/tool/room_tool.rs8
-rw-r--r--src/tool/wall_tool.rs10
-rw-r--r--src/transform.rs52
13 files changed, 169 insertions, 181 deletions
diff --git a/src/dimension_indicator.rs b/src/dimension_indicator.rs
index 2eb3eee..cc12f0b 100644
--- a/src/dimension_indicator.rs
+++ b/src/dimension_indicator.rs
@@ -6,7 +6,7 @@ use raylib::ffi::Color;
pub struct DimensionIndicator {
/// The lines that are used to draw the Dimension Indicator. For a rectangle for instance these
/// would be two. One for width and one for height.
- length_lines: Vec<(Vec2<f32>, Vec2<f32>)>,
+ length_lines: Vec<(Vec2<f64>, Vec2<f64>)>,
}
impl DimensionIndicator {
@@ -17,7 +17,7 @@ impl DimensionIndicator {
}
}
- pub fn from_corner_points(corner_points: &[Vec2<f32>]) -> Self {
+ pub fn from_corner_points(corner_points: &[Vec2<f64>]) -> Self {
let mut this = Self::new();
this.update_dimensions(corner_points);
@@ -30,7 +30,7 @@ impl DimensionIndicator {
/// Update the dimensions by analysing a given set of points and adjusting the internal
/// (measured) dimensions.
- pub fn update_dimensions(&mut self, corner_points: &[Vec2<f32>]) {
+ pub fn update_dimensions(&mut self, corner_points: &[Vec2<f64>]) {
if corner_points.len() < 2 {
warn!("Cannot discern dimensions when not at least two points are given. The dimensions were not updated.");
return;
@@ -85,8 +85,8 @@ impl DimensionIndicator {
};
// To not have the line directly in the rect, move start and end outside a bit.
- let start_px = transform.point_m_to_px(*start) + line_normal * 10.;
- let end_px = transform.point_m_to_px(*end) + line_normal * 10.;
+ let start_px = transform.point_m_to_px(start) + line_normal * 10.;
+ let end_px = transform.point_m_to_px(end) + line_normal * 10.;
/* Draw the indicator line, with stubs at both ends. */
let line_colour = Color {
@@ -115,7 +115,7 @@ impl DimensionIndicator {
* It should be placed in the middle of the line, but not into the line directly, so it
* will be moved out by the normal.
*/
- let text_pos = transform.point_m_to_px((*end + *start) / 2.) + line_normal * 20.;
+ let text_pos = transform.point_m_to_px(&((*end + *start) / 2.)) + line_normal * 20.;
rld.draw_text(
&format!("{}m", &(*end - *start).length()),
text_pos.x as i32,
diff --git a/src/grid.rs b/src/grid.rs
index 72a849a..ec27fa7 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -4,7 +4,7 @@ use raylib::drawing::RaylibDraw;
use raylib::ffi::Color;
/// The internal grid length which will be used to snap things to it.
-pub const SNAP_SIZE: f32 = 0.5;
+pub const SNAP_SIZE: f64 = 0.5;
pub const LINE_COLOUR: Color = Color {
r: 255,
@@ -15,7 +15,7 @@ pub const LINE_COLOUR: Color = Color {
/// Snap a vector to the grid with the factor being the sub-grid accuracy. For instance, 0.5 will
/// snap to half a grid cell, while 2.0 would snap to every second grid cell
-pub fn snap_to_grid(mut vec: Vec2<f32>, snap_fraction: f32) -> Vec2<f32> {
+pub fn snap_to_grid(mut vec: Vec2<f64>, snap_fraction: f64) -> Vec2<f64> {
vec.x = math::round(vec.x, snap_fraction);
vec.y = math::round(vec.y, snap_fraction);
@@ -27,46 +27,35 @@ pub fn draw_grid<D>(rld: &mut D, screen_width: i32, screen_height: i32, transfor
where
D: RaylibDraw,
{
- /* Calculate the actual screen offset of the grid, by modulo-ing the translation of the
- * transform.
+ /* Calculate the first whole meter that can be seen on the grid. This is the first meter that
+ * will be seen on screen.
*/
- let translation_x_px: i32 =
- transform.translation_px().x as i32 % transform.pixels_per_m() as i32;
- let translation_y_px: i32 =
- transform.translation_px().y as i32 % transform.pixels_per_m() as i32;
+ let mut first_cell = *transform.translation_px() / -transform.pixels_per_m();
+ first_cell.x = first_cell.x.floor();
+ first_cell.y = first_cell.y.floor();
- /*
- let mut row = 0;
+ let mut cell = first_cell;
+ let mut draw_y = transform.point_m_to_px(&cell).y;
loop {
- let line_y = translation_y_px + (transform.pixels_per_m() * row as f32) as i32;
- if line_y > screen_height {
+ draw_y = math::round(draw_y, 1.);
+ rld.draw_line(0, draw_y as i32, screen_width, draw_y as i32, LINE_COLOUR);
+ cell.y += 1.;
+ draw_y = transform.point_m_to_px(&cell).y;
+
+ if draw_y as i32 > screen_height {
break;
}
- rld.draw_line(0, line_y as i32, screen_width, line_y as i32, LINE_COLOUR);
- row += 1;
}
- let mut column = 0;
+ let mut draw_x = transform.point_m_to_px(&cell).x;
loop {
- let line_x = translation_x_px + (transform.pixels_per_m() * column as f32) as i32;
- if line_x > screen_width {
+ draw_x = math::round(draw_x, 1.);
+ rld.draw_line(draw_x as i32, 0, draw_x as i32, screen_height, LINE_COLOUR);
+ cell.x += 1.;
+ draw_x = transform.point_m_to_px(&cell).x;
+
+ if draw_x as i32 > screen_width {
break;
}
- rld.draw_line(line_x as i32, 0, line_x as i32, screen_height, LINE_COLOUR);
- column += 1;
- }
- */
-
- // Draw the row lines.
- let mut line_y: f32 = translation_y_px as f32;
- while line_y <= screen_height as f32 {
- rld.draw_line(0, line_y as i32, screen_width, line_y as i32, LINE_COLOUR);
- line_y += transform.pixels_per_m();
- }
- // Draw the column lines.
- let mut line_x: f32 = translation_x_px as f32;
- while line_x <= screen_width as f32 {
- rld.draw_line(line_x as i32, 0, line_x as i32, screen_height, LINE_COLOUR);
- line_x += transform.pixels_per_m();
}
}
diff --git a/src/main.rs b/src/main.rs
index f669ec6..7e04456 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -73,7 +73,7 @@ fn main() {
// Move the canvas together with the mouse
if rl.is_mouse_button_down(MouseButton::MOUSE_MIDDLE_BUTTON) {
- transform.move_by_px((rl.get_mouse_position() - last_mouse_pos).into());
+ transform.move_by_px(&(rl.get_mouse_position() - last_mouse_pos).into());
}
let mouse_wheel_move = rl.get_mouse_wheel_move();
@@ -81,8 +81,8 @@ fn main() {
// Zoom in for positive and zoom out for negative mouse wheel rotations.
let scale_factor = if mouse_wheel_move > 0 { 1.2 } else { 1. / 1.2 };
transform.try_zoom(
- rl.get_mouse_position().into(),
- mouse_wheel_move.abs() as f32 * scale_factor,
+ &rl.get_mouse_position().into(),
+ mouse_wheel_move.abs() as f64 * scale_factor,
);
}
diff --git a/src/map_data.rs b/src/map_data.rs
index b17d779..a6ce5a0 100644
--- a/src/map_data.rs
+++ b/src/map_data.rs
@@ -12,9 +12,9 @@ use std::path::Path;
/// transform, or the zoom-level
#[derive(Serialize, Deserialize)]
pub struct MapData {
- rooms: Vec<Rect<f32>>,
- polygons: Vec<Polygon<f32>>,
- walls: Vec<(Vec2<f32>, Vec2<f32>)>,
+ rooms: Vec<Rect<f64>>,
+ polygons: Vec<Polygon<f64>>,
+ walls: Vec<(Vec2<f64>, Vec2<f64>)>,
icons: Vec<IconInfo>,
}
@@ -67,24 +67,24 @@ impl MapData {
file.write_all(&string.as_bytes())
}
- pub fn rooms(&self) -> &Vec<Rect<f32>> {
+ pub fn rooms(&self) -> &Vec<Rect<f64>> {
&self.rooms
}
- pub fn rooms_mut(&mut self) -> &mut Vec<Rect<f32>> {
+ pub fn rooms_mut(&mut self) -> &mut Vec<Rect<f64>> {
&mut self.rooms
}
- pub fn polygons(&self) -> &Vec<Polygon<f32>> {
+ pub fn polygons(&self) -> &Vec<Polygon<f64>> {
&self.polygons
}
- pub fn polygons_mut(&mut self) -> &mut Vec<Polygon<f32>> {
+ pub fn polygons_mut(&mut self) -> &mut Vec<Polygon<f64>> {
&mut self.polygons
}
- pub fn walls(&self) -> &Vec<(Vec2<f32>, Vec2<f32>)> {
+ pub fn walls(&self) -> &Vec<(Vec2<f64>, Vec2<f64>)> {
&self.walls
}
- pub fn walls_mut(&mut self) -> &mut Vec<(Vec2<f32>, Vec2<f32>)> {
+ pub fn walls_mut(&mut self) -> &mut Vec<(Vec2<f64>, Vec2<f64>)> {
&mut self.walls
}
diff --git a/src/math/mod.rs b/src/math/mod.rs
index b84d270..279affc 100644
--- a/src/math/mod.rs
+++ b/src/math/mod.rs
@@ -11,6 +11,7 @@ pub use self::triangle::*;
pub use self::vec2::*;
use nalgebra::Scalar;
+use num_traits::Float;
use std::cmp::Ordering;
/// Trait that describes an area in the vector space on the field of T
@@ -31,11 +32,14 @@ pub trait Surface<T: Scalar + Copy> {
/// Round a floating point number to the nearest step given by the step argument. For instance, if
/// the step is 0.5, then all numbers from 0.0 to 0.24999... will be 0., while all numbers from
/// 0.25 to 0.74999... will be 0.5 and so on.
-pub fn round(num: f32, step: f32) -> f32 {
+pub fn round<T>(num: T, step: T) -> T
+where
+ T: Float,
+{
// Only positive steps will be accepted.
- assert!(step > 0.);
+ assert!(step > T::zero());
- let lower_bound = ((num / step) as i32) as f32 * step;
+ let lower_bound = (num / step).floor() * step;
let upper_bound = lower_bound + step;
// Compare the distances and prefer the smaller. If they are the same, prefer the upper bound.
diff --git a/src/math/rect.rs b/src/math/rect.rs
index 5f4e5f5..5603642 100644
--- a/src/math/rect.rs
+++ b/src/math/rect.rs
@@ -2,6 +2,7 @@ use super::{LineSegment, Polygon, Surface, Vec2};
//use alga::general::{Additive, Identity};
use nalgebra::{ClosedAdd, ClosedSub, RealField, Scalar};
use num_traits::identities::Zero;
+use num_traits::{NumCast, ToPrimitive};
use serde::{Deserialize, Serialize};
use std::ops::{Add, AddAssign};
@@ -147,16 +148,6 @@ impl<T: Scalar + Copy + PartialOrd + ClosedAdd + ClosedSub + Zero> Surface<T> fo
}
// This is sad, but also sadly necessary :/
-impl<T: Into<f32> + Scalar + Copy> Into<raylib::ffi::Rectangle> for Rect<T> {
- fn into(self) -> raylib::ffi::Rectangle {
- raylib::ffi::Rectangle {
- x: self.x.into(),
- y: self.y.into(),
- width: self.w.into(),
- height: self.h.into(),
- }
- }
-}
impl<T: From<f32> + Scalar + Copy> From<raylib::ffi::Rectangle> for Rect<T> {
fn from(r: raylib::ffi::Rectangle) -> Self {
Self {
@@ -167,16 +158,6 @@ impl<T: From<f32> + Scalar + Copy> From<raylib::ffi::Rectangle> for Rect<T> {
}
}
}
-impl<T: Into<f32> + Scalar + Copy> Into<raylib::math::Rectangle> for Rect<T> {
- fn into(self) -> raylib::math::Rectangle {
- raylib::math::Rectangle {
- x: self.x.into(),
- y: self.y.into(),
- width: self.w.into(),
- height: self.h.into(),
- }
- }
-}
impl<T: From<f32> + Scalar + Copy> From<raylib::math::Rectangle> for Rect<T> {
fn from(r: raylib::math::Rectangle) -> Self {
Self {
@@ -188,6 +169,27 @@ impl<T: From<f32> + Scalar + Copy> From<raylib::math::Rectangle> for Rect<T> {
}
}
+impl<T: Scalar + Copy + ToPrimitive> Into<raylib::math::Rectangle> for Rect<T> {
+ fn into(self) -> raylib::math::Rectangle {
+ raylib::math::Rectangle {
+ x: NumCast::from(self.x).expect("Unable to cast Rect into raylib Rect"),
+ y: NumCast::from(self.y).expect("Unable to cast Rect into raylib Rect"),
+ width: NumCast::from(self.w).expect("Unable to cast Rect into raylib Rect"),
+ height: NumCast::from(self.h).expect("Unable to cast Rect into raylib Rect"),
+ }
+ }
+}
+impl<T: Scalar + Copy + ToPrimitive> Into<raylib::ffi::Rectangle> for Rect<T> {
+ fn into(self) -> raylib::ffi::Rectangle {
+ raylib::ffi::Rectangle {
+ x: NumCast::from(self.x).expect("Unable to cast Rect into raylib Rect"),
+ y: NumCast::from(self.y).expect("Unable to cast Rect into raylib Rect"),
+ width: NumCast::from(self.w).expect("Unable to cast Rect into raylib Rect"),
+ height: NumCast::from(self.h).expect("Unable to cast Rect into raylib Rect"),
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use super::*;
diff --git a/src/math/vec2.rs b/src/math/vec2.rs
index cd38889..d591f1d 100644
--- a/src/math/vec2.rs
+++ b/src/math/vec2.rs
@@ -1,7 +1,7 @@
use crate::math::Rect;
use alga::general::{ClosedAdd, ClosedSub};
use nalgebra::{RealField, Scalar};
-use num_traits::One;
+use num_traits::{NumCast, One, ToPrimitive};
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::convert::{From, Into};
@@ -46,18 +46,6 @@ impl<T: Scalar + Copy> Vec2<T> {
}
// This is sad, but also sadly necessary :/
-impl<T> Into<raylib::ffi::Vector2> for Vec2<T>
-where
- T: Into<f32> + Scalar + Copy,
-{
- fn into(self) -> raylib::ffi::Vector2 {
- raylib::ffi::Vector2 {
- x: self.x.into(),
- y: self.y.into(),
- }
- }
-}
-
impl<T> From<raylib::ffi::Vector2> for Vec2<T>
where
T: From<f32> + Scalar + Copy,
@@ -69,21 +57,9 @@ where
}
}
}
-impl<T: Scalar + Copy> Into<raylib::math::Vector2> for Vec2<T>
-where
- T: Into<f32>,
-{
- fn into(self) -> raylib::math::Vector2 {
- raylib::math::Vector2 {
- x: self.x.into(),
- y: self.y.into(),
- }
- }
-}
-
-impl<T: Scalar + Copy> From<raylib::math::Vector2> for Vec2<T>
+impl<T> From<raylib::math::Vector2> for Vec2<T>
where
- T: From<f32>,
+ T: From<f32> + Scalar + Copy,
{
fn from(v: raylib::math::Vector2) -> Self {
Self {
@@ -93,6 +69,23 @@ where
}
}
+impl<T: Scalar + Copy + ToPrimitive> Into<raylib::ffi::Vector2> for Vec2<T> {
+ fn into(self) -> raylib::ffi::Vector2 {
+ raylib::ffi::Vector2 {
+ x: NumCast::from(self.x).expect("Unable to cast Vec2 into raylib Vector"),
+ y: NumCast::from(self.y).expect("Unable to cast Vec2 into raylib Vector"),
+ }
+ }
+}
+impl<T: Scalar + Copy + ToPrimitive> Into<raylib::math::Vector2> for Vec2<T> {
+ fn into(self) -> raylib::math::Vector2 {
+ raylib::math::Vector2 {
+ x: NumCast::from(self.x).expect("Unable to cast Vec2 into raylib Vector"),
+ y: NumCast::from(self.y).expect("Unable to cast Vec2 into raylib Vector"),
+ }
+ }
+}
+
// Begin mathematical operators -----------------------------------------------
// Addition
diff --git a/src/tool/deletion_tool.rs b/src/tool/deletion_tool.rs
index 17dd949..74a8f92 100644
--- a/src/tool/deletion_tool.rs
+++ b/src/tool/deletion_tool.rs
@@ -10,7 +10,7 @@ use raylib::RaylibHandle;
pub struct DeletionTool {
keybindings: DeletionToolKeybindings,
- deletion_rect: Option<(Vec2<f32>, Vec2<f32>)>,
+ deletion_rect: Option<(Vec2<f64>, Vec2<f64>)>,
}
impl DeletionTool {
@@ -22,7 +22,7 @@ impl DeletionTool {
}
/// Delete all map-data that is contained inside the provided rectangular space.
- pub fn delete_rect(map_data: &mut MapData, rect: Rect<f32>) {
+ pub fn delete_rect(map_data: &mut MapData, rect: Rect<f64>) {
map_data
.rooms_mut()
.retain(|&room| !rect.contains_rect(&room));
@@ -50,7 +50,7 @@ impl Tool for DeletionTool {
transform: &Transform,
mouse_blocked: bool,
) {
- let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into());
+ let mouse_pos_m = transform.point_px_to_m(&rl.get_mouse_position().into());
if let Some((_, ref mut pos2)) = &mut self.deletion_rect {
*pos2 = mouse_pos_m;
}
@@ -72,7 +72,7 @@ impl Tool for DeletionTool {
fn draw(&self, _map_data: &MapData, rld: &mut RaylibDrawHandle, transform: &Transform) {
if let Some((pos1, pos2)) = self.deletion_rect {
- let rect_px = transform.rect_m_to_px(Rect::bounding_rect(pos1, pos2));
+ let rect_px = transform.rect_m_to_px(&Rect::bounding_rect(pos1, pos2));
rld.draw_rectangle_rec(
rect_px,
Color {
diff --git a/src/tool/icon_tool.rs b/src/tool/icon_tool.rs
index 4b3a1eb..e972c1c 100644
--- a/src/tool/icon_tool.rs
+++ b/src/tool/icon_tool.rs
@@ -19,9 +19,9 @@ pub const ICON_DIR: &str = "assets/icons";
struct IconFileInfo {
/// The position the icon should be anchored in pixels. This is the Vector it will be moved by
/// relative to the mouse pointer (to the left and up).
- anchor: Vec2<f32>,
+ anchor: Vec2<f64>,
/// The scale of the icon as expressed in image pixels per real meter.
- pixels_per_m: f32,
+ pixels_per_m: f64,
}
#[derive(Clone, Serialize, Deserialize)]
@@ -29,9 +29,9 @@ pub struct IconInfo {
/// The id of the icon is the icons position in the currently loaded icon_data vector.
pub icon_id: usize,
/// The position of the icon on the map, given by the vector in meters.
- pub position: Vec2<f32>,
+ pub position: Vec2<f64>,
/// Rotation of the icon texture in degrees.
- pub rotation: f32,
+ pub rotation: f64,
}
pub struct IconTool {
@@ -132,7 +132,7 @@ impl Tool for IconTool {
) {
// Update the position of the icon that should be drawn to the current mouse position.
let snapped_mouse_pos_m = snap_to_grid(
- transform.point_px_to_m(rl.get_mouse_position().into()),
+ transform.point_px_to_m(&rl.get_mouse_position().into()),
SNAP_SIZE,
);
self.current_icon.position = snapped_mouse_pos_m;
@@ -161,14 +161,14 @@ impl Tool for IconTool {
let (texture, info) = &self.icon_data[icon.icon_id];
// Round the position to whole pixels to fix rotation problems.
let mut position_px =
- transform.point_m_to_px(icon.position - (info.anchor / info.pixels_per_m));
- position_px.x = position_px.x as i32 as f32;
- position_px.y = position_px.y as i32 as f32;
+ transform.point_m_to_px(&(icon.position - (info.anchor / info.pixels_per_m)));
+ position_px.x = position_px.x.floor();
+ position_px.y = position_px.y.floor();
rld.draw_texture_ex(
texture,
position_px,
- icon.rotation,
- transform.pixels_per_m() / info.pixels_per_m,
+ icon.rotation as f32,
+ (transform.pixels_per_m() / info.pixels_per_m) as f32,
Color {
r: 255,
g: 255,
@@ -183,14 +183,14 @@ impl Tool for IconTool {
let (texture, info) = &self.icon_data[self.current_icon.icon_id];
// Round the position to whole pixels to fix rotation problems.
let mut position_px = transform
- .point_m_to_px(self.current_icon.position - (info.anchor / info.pixels_per_m));
- position_px.x = position_px.x as i32 as f32;
- position_px.y = position_px.y as i32 as f32;
+ .point_m_to_px(&(self.current_icon.position - (info.anchor / info.pixels_per_m)));
+ position_px.x = position_px.x.floor();
+ position_px.y = position_px.y.floor();
rld.draw_texture_ex(
texture,
position_px,
- self.current_icon.rotation,
- transform.pixels_per_m() / info.pixels_per_m,
+ self.current_icon.rotation as f32,
+ (transform.pixels_per_m() / info.pixels_per_m) as f32,
Color {
r: 120,
g: 200,
diff --git a/src/tool/polygon_room_tool.rs b/src/tool/polygon_room_tool.rs
index 42874e8..8cd2c25 100644
--- a/src/tool/polygon_room_tool.rs
+++ b/src/tool/polygon_room_tool.rs
@@ -11,8 +11,8 @@ use raylib::ffi::Color;
use raylib::RaylibHandle;
struct UnfinishedPolygon {
- pub corners: Vec<Vec2<f32>>,
- pub working_corner: Vec2<f32>,
+ pub corners: Vec<Vec2<f64>>,
+ pub working_corner: Vec2<f64>,
}
pub struct PolygonRoomTool {
@@ -23,13 +23,13 @@ pub struct PolygonRoomTool {
impl UnfinishedPolygon {
// Check the validity of the already completed corners only
- pub fn check_validity_completed(&self) -> Result<(), PolygonError<f32>> {
+ pub fn check_validity_completed(&self) -> Result<(), PolygonError<f64>> {
Polygon::check_validity(&self.corners)
}
// Check the validity of the already completed corners, but with the working corner wedged
// between the last and first corner (making it the new last corner).
- pub fn check_validity_all(&self) -> Result<(), PolygonError<f32>> {
+ pub fn check_validity_all(&self) -> Result<(), PolygonError<f64>> {
// TODO: Is this possible without changing the mutability of self and without reallocation?
let mut corners = self.corners.clone();
corners.push(self.working_corner);
@@ -37,7 +37,7 @@ impl UnfinishedPolygon {
Polygon::check_validity(&corners)
}
- pub fn try_into_completed(&mut self) -> Option<Polygon<f32>> {
+ pub fn try_into_completed(&mut self) -> Option<Polygon<f64>> {
match self.check_validity_completed() {
Ok(()) => Some(Polygon::new_unchecked(self.corners.drain(..).collect())),
Err(e) => {
@@ -47,7 +47,7 @@ impl UnfinishedPolygon {
}
}
- pub fn try_into_all(&mut self) -> Option<Polygon<f32>> {
+ pub fn try_into_all(&mut self) -> Option<Polygon<f64>> {
match self.check_validity_all() {
Ok(()) => {
self.corners.push(self.working_corner);
@@ -63,7 +63,7 @@ impl UnfinishedPolygon {
}
}
- pub fn try_push_working(&mut self) -> Result<(), PolygonError<f32>> {
+ pub fn try_push_working(&mut self) -> Result<(), PolygonError<f64>> {
assert!(!self.corners.is_empty());
if self.corners.len() == 1 {
@@ -106,7 +106,7 @@ impl Tool for PolygonRoomTool {
transform: &Transform,
mouse_blocked: bool,
) {
- let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into());
+ let mouse_pos_m = transform.point_px_to_m(&rl.get_mouse_position().into());
let snapped_mouse_pos_m = snap_to_grid(mouse_pos_m, SNAP_SIZE);
// Update the position of the node that would be placed into the polygon next.
@@ -170,11 +170,11 @@ impl Tool for PolygonRoomTool {
for polygon in map.polygons() {
let triangles = math::triangulate(polygon.clone());
for triangle in triangles {
- let triangle: [Vec2<f32>; 3] = triangle.into();
+ let triangle: [Vec2<f64>; 3] = triangle.into();
rld.draw_triangle(
- transform.point_m_to_px(triangle[0]),
- transform.point_m_to_px(triangle[1]),
- transform.point_m_to_px(triangle[2]),
+ transform.point_m_to_px(&triangle[0]),
+ transform.point_m_to_px(&triangle[1]),
+ transform.point_m_to_px(&triangle[2]),
Color {
r: 180,
g: 180,
@@ -189,9 +189,9 @@ impl Tool for PolygonRoomTool {
// The first corner is guaranteed to be set, so we can at least draw a line.
if polygon.corners.len() == 1 {
rld.draw_line_ex(
- transform.point_m_to_px(polygon.corners[0]),
- transform.point_m_to_px(polygon.working_corner),
- transform.length_m_to_px(0.1),
+ transform.point_m_to_px(&polygon.corners[0]),
+ transform.point_m_to_px(&polygon.working_corner),
+ transform.length_m_to_px(0.1) as f32,
Color {
r: 150,
g: 200,
@@ -202,9 +202,9 @@ impl Tool for PolygonRoomTool {
} else if polygon.corners.len() == 2 {
// We have three valid corners, so we can draw a triangle.
rld.draw_triangle(
- transform.point_m_to_px(polygon.corners[0]),
- transform.point_m_to_px(polygon.corners[1]),
- transform.point_m_to_px(polygon.working_corner),
+ transform.point_m_to_px(&polygon.corners[0]),
+ transform.point_m_to_px(&polygon.corners[1]),
+ transform.point_m_to_px(&polygon.working_corner),
Color {
r: 150,
g: 200,
@@ -220,11 +220,11 @@ impl Tool for PolygonRoomTool {
let polygon = Polygon::new_unchecked(corners);
let triangles = math::triangulate(polygon);
for triangle in triangles {
- let triangle: [Vec2<f32>; 3] = triangle.into();
+ let triangle: [Vec2<f64>; 3] = triangle.into();
rld.draw_triangle(
- transform.point_m_to_px(triangle[0]),
- transform.point_m_to_px(triangle[1]),
- transform.point_m_to_px(triangle[2]),
+ transform.point_m_to_px(&triangle[0]),
+ transform.point_m_to_px(&triangle[1]),
+ transform.point_m_to_px(&triangle[2]),
Color {
r: 150,
g: 200,
@@ -237,11 +237,11 @@ impl Tool for PolygonRoomTool {
let polygon = Polygon::new_unchecked(polygon.corners.clone());
let triangles = math::triangulate(polygon);
for triangle in triangles {
- let triangle: [Vec2<f32>; 3] = triangle.into();
+ let triangle: [Vec2<f64>; 3] = triangle.into();
rld.draw_triangle(
- transform.point_m_to_px(triangle[0]),
- transform.point_m_to_px(triangle[1]),
- transform.point_m_to_px(triangle[2]),
+ transform.point_m_to_px(&triangle[0]),
+ transform.point_m_to_px(&triangle[1]),
+ transform.point_m_to_px(&triangle[2]),
Color {
r: 150,
g: 200,
diff --git a/src/tool/room_tool.rs b/src/tool/room_tool.rs
index c4a8b8c..6a283e3 100644
--- a/src/tool/room_tool.rs
+++ b/src/tool/room_tool.rs
@@ -14,7 +14,7 @@ pub struct RoomTool {
keybindings: RoomToolKeybindings,
/// The rectangle that is currently being drawn by the user. Once it is finished, it will be
/// pushed into the room_rects.
- unfinished_rect: Option<(Vec2<f32>, Vec2<f32>)>,
+ unfinished_rect: Option<(Vec2<f64>, Vec2<f64>)>,
dimension_indicator: DimensionIndicator,
}
@@ -42,7 +42,7 @@ impl Tool for RoomTool {
transform: &Transform,
mouse_blocked: bool,
) {
- let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into());
+ let mouse_pos_m = transform.point_px_to_m(&rl.get_mouse_position().into());
// Update the currently drawn rectangle, if it exists, and also its dimension indicator.
if let Some((ref pos1, ref mut pos2)) = &mut self.unfinished_rect {
*pos2 = snap_to_grid(mouse_pos_m, SNAP_SIZE);
@@ -71,7 +71,7 @@ impl Tool for RoomTool {
// Draw all finished rectangles.
for &rect in map_data.rooms() {
rld.draw_rectangle_rec(
- transform.rect_m_to_px(rect),
+ transform.rect_m_to_px(&rect),
Color {
r: 180,
g: 180,
@@ -84,7 +84,7 @@ impl Tool for RoomTool {
// Do the same for the unfinished rectangle
if let Some((pos1, pos2)) = self.unfinished_rect {
rld.draw_rectangle_rec(
- transform.rect_m_to_px(Rect::bounding_rect(pos1, pos2)),
+ transform.rect_m_to_px(&Rect::bounding_rect(pos1, pos2)),
Color {
r: 150,
g: 200,
diff --git a/src/tool/wall_tool.rs b/src/tool/wall_tool.rs
index 715a8b9..35b2458 100644
--- a/src/tool/wall_tool.rs
+++ b/src/tool/wall_tool.rs
@@ -11,7 +11,7 @@ use raylib::RaylibHandle;
pub struct WallTool {
keybindings: WallToolKeybindings,
- unfinished_wall: Option<(Vec2<f32>, Vec2<f32>)>,
+ unfinished_wall: Option<(Vec2<f64>, Vec2<f64>)>,
}
impl WallTool {
@@ -35,7 +35,7 @@ impl Tool for WallTool {
transform: &Transform,
mouse_blocked: bool,
) {
- let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into());
+ let mouse_pos_m = transform.point_px_to_m(&rl.get_mouse_position().into());
if let Some((_, ref mut pos2)) = &mut self.unfinished_wall {
*pos2 = snap_to_grid(mouse_pos_m, SNAP_SIZE);
}
@@ -103,12 +103,12 @@ impl Tool for WallTool {
}
if let Some((pos1, pos2)) = self.unfinished_wall {
- let pos1: Vector2 = transform.point_m_to_px(pos1).into();
- let pos2: Vector2 = transform.point_m_to_px(pos2).into();
+ let pos1: Vector2 = transform.point_m_to_px(&pos1).into();
+ let pos2: Vector2 = transform.point_m_to_px(&pos2).into();
rld.draw_line_ex(
pos1,
pos2,
- transform.length_m_to_px(0.1),
+ transform.length_m_to_px(0.1) as f32,
Color {
r: 150,
g: 200,
diff --git a/src/transform.rs b/src/transform.rs
index bd80bc1..7c1adbf 100644
--- a/src/transform.rs
+++ b/src/transform.rs
@@ -5,15 +5,15 @@
use crate::math::{Rect, Vec2};
-const STANDARD_PIXELS_PER_M: f32 = 64.;
-const MIN_PIXELS_PER_M: f32 = 5.;
-const MAX_PIXELS_PER_M: f32 = 10_000.;
+const STANDARD_PIXELS_PER_M: f64 = 64.;
+const MIN_PIXELS_PER_M: f64 = 5.;
+const MAX_PIXELS_PER_M: f64 = 10_000.;
pub struct Transform {
/// The (not necessarily natural) number of pixels per m, i.e. the current scale of the map
- pixels_per_m: f32,
+ pixels_per_m: f64,
/// The vector the entire on-screen map is moved by in pixels
- translation_px: Vec2<f32>,
+ translation_px: Vec2<f64>,
}
impl Transform {
@@ -27,36 +27,36 @@ impl Transform {
/// Convert a point that is given in meters into the corresponding point in pixels.
#[inline]
- pub fn point_m_to_px(&self, point: Vec2<f32>) -> Vec2<f32> {
+ pub fn point_m_to_px(&self, point: &Vec2<f64>) -> Vec2<f64> {
// Start by converting the absolute position in meters into the absolute position in
// pixels, then add the translation of the screen.
- (point * self.pixels_per_m) + self.translation_px
+ (*point * self.pixels_per_m) + self.translation_px
}
/// Convert an on-screen point into an absolute point with values in meters.
#[inline]
- pub fn point_px_to_m(&self, point: Vec2<f32>) -> Vec2<f32> {
+ pub fn point_px_to_m(&self, point: &Vec2<f64>) -> Vec2<f64> {
// Start by subtracting the pixel translation and afterwards convert these absolute pixel
// measurements into meters.
- (point - self.translation_px) / self.pixels_per_m
+ (*point - self.translation_px) / self.pixels_per_m
}
/// Convert a length given in meters into a length in pixels
#[inline]
- pub fn length_m_to_px(&self, length: f32) -> f32 {
+ pub fn length_m_to_px(&self, length: f64) -> f64 {
length * self.pixels_per_m
}
/// Convert a length given in pixels into a length in meters
#[inline]
- pub fn length_px_to_m(&self, length: f32) -> f32 {
+ pub fn length_px_to_m(&self, length: f64) -> f64 {
length / self.pixels_per_m
}
/// Convert a rectangle which has measurements in meters into one of pixels
#[inline]
- pub fn rect_m_to_px(&self, rect: Rect<f32>) -> Rect<f32> {
- let left_upper = self.point_m_to_px(Vec2::new(rect.x, rect.y));
+ pub fn rect_m_to_px(&self, rect: &Rect<f64>) -> Rect<f64> {
+ let left_upper = self.point_m_to_px(&Vec2::new(rect.x, rect.y));
Rect::new(
left_upper.x,
left_upper.y,
@@ -67,8 +67,8 @@ impl Transform {
/// Convert a rectangle which has measurements in pixels into one of meters
#[inline]
- pub fn rect_px_to_m(&self, rect: Rect<f32>) -> Rect<f32> {
- let left_upper = self.point_px_to_m(Vec2::new(rect.x, rect.y));
+ pub fn rect_px_to_m(&self, rect: &Rect<f64>) -> Rect<f64> {
+ let left_upper = self.point_px_to_m(&Vec2::new(rect.x, rect.y));
Rect::new(
left_upper.x,
left_upper.y,
@@ -84,7 +84,7 @@ impl Transform {
/// zoom with a negative factor you'll have to figure out yourself.
/// `mouse_pos_px`: Position of the mouse cursor, this time not in meters, but in screen
/// pixels. This will be used to tether zoom on that point.
- pub fn try_zoom(&mut self, mouse_pos_px: Vec2<f32>, factor: f32) -> bool {
+ pub fn try_zoom(&mut self, mouse_pos_px: &Vec2<f64>, factor: f64) -> bool {
// Abort zooming when the scale would not be in the min-max-bounds anymore.
let desired_px_per_m = self.pixels_per_m * factor;
if (factor < 1. && desired_px_per_m <= MIN_PIXELS_PER_M)
@@ -94,36 +94,36 @@ impl Transform {
}
// Save the absolute mouse position in meters for tethering later
- let mouse_pos_m = self.point_px_to_m(mouse_pos_px);
+ let mouse_pos_m = self.point_px_to_m(&mouse_pos_px);
// Make sure the desired scale stays within the bounds and in whole numbers
let desired_px_per_m = if desired_px_per_m < MIN_PIXELS_PER_M {
- MIN_PIXELS_PER_M as u32 as f32
+ MIN_PIXELS_PER_M as u32 as f64
} else if desired_px_per_m > MAX_PIXELS_PER_M {
- MAX_PIXELS_PER_M as u32 as f32
+ MAX_PIXELS_PER_M as u32 as f64
} else {
- desired_px_per_m as u32 as f32
+ desired_px_per_m as u32 as f64
};
/* Adjust to the desired scale and bring the map back to its desired position according to
* the mouse pointer position.
*/
self.pixels_per_m = desired_px_per_m;
- self.translation_px += mouse_pos_px - self.point_m_to_px(mouse_pos_m);
+ self.translation_px += *mouse_pos_px - self.point_m_to_px(&mouse_pos_m);
true
}
/// Move the canvas by the vector in pixels.
- pub fn move_by_px(&mut self, by: Vec2<f32>) {
- self.translation_px += by;
+ pub fn move_by_px(&mut self, by: &Vec2<f64>) {
+ self.translation_px += *by;
}
- pub fn pixels_per_m(&self) -> f32 {
+ pub fn pixels_per_m(&self) -> f64 {
self.pixels_per_m
}
- pub fn translation_px(&self) -> Vec2<f32> {
- self.translation_px
+ pub fn translation_px(&self) -> &Vec2<f64> {
+ &self.translation_px
}
}