aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock151
-rw-r--r--Cargo.toml2
-rw-r--r--src/dimension_indicator.rs123
-rw-r--r--src/main.rs6
-rw-r--r--src/math/vec2.rs23
-rw-r--r--src/tool/room_tool.rs11
6 files changed, 312 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f1d751f..fe4742b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,15 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
+name = "aho-corasick"
+version = "0.7.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "alga"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -30,6 +39,17 @@ dependencies = [
]
[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -69,6 +89,19 @@ dependencies = [
]
[[package]]
+name = "env_logger"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
name = "float-cmp"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -106,8 +139,10 @@ name = "graf_karto"
version = "0.1.1"
dependencies = [
"alga",
+ "log",
"nalgebra",
"num-traits",
+ "pretty_env_logger",
"raylib",
"ron",
"serde",
@@ -116,6 +151,24 @@ dependencies = [
]
[[package]]
+name = "hermit-abi"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "humantime"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
+dependencies = [
+ "quick-error",
+]
+
+[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -134,6 +187,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]]
+name = "log"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
name = "matrixmultiply"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -143,6 +205,12 @@ dependencies = [
]
[[package]]
+name = "memchr"
+version = "2.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+
+[[package]]
name = "nalgebra"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -223,6 +291,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
[[package]]
+name = "pretty_env_logger"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
+dependencies = [
+ "env_logger",
+ "log",
+]
+
+[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -232,6 +310,12 @@ dependencies = [
]
[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -320,6 +404,24 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+ "thread_local",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
+
+[[package]]
name = "ron"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -390,6 +492,24 @@ dependencies = [
]
[[package]]
+name = "termcolor"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
name = "typenum"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -414,6 +534,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
name = "xml-rs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 8c76fb0..5094fa3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,3 +13,5 @@ alga = "*"
num-traits = "*"
svgtypes = "*"
xmltree = "*"
+pretty_env_logger = "*"
+log = "*"
diff --git a/src/dimension_indicator.rs b/src/dimension_indicator.rs
new file mode 100644
index 0000000..a08d22c
--- /dev/null
+++ b/src/dimension_indicator.rs
@@ -0,0 +1,123 @@
+use crate::math::Vec2;
+use crate::transform::Transform;
+use raylib::drawing::RaylibDraw;
+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>)>,
+}
+
+impl DimensionIndicator {
+ pub fn new() -> Self {
+ Self {
+ length_lines: Vec::new(),
+ }
+ }
+
+ pub fn from_corner_points(corner_points: &Vec<Vec2<f32>>) -> Self {
+ let mut this = Self::new();
+ this.update_dimensions(corner_points);
+
+ this
+ }
+
+ /// 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>]) {
+ if corner_points.len() < 2 {
+ warn!("Cannot discern dimensions when not at least two points are given. The dimensions were not updated.");
+ return;
+ }
+
+ // Discern the bounding box for the given corner points.
+ let mut min = corner_points[0];
+ let mut max = corner_points[0];
+ for point in corner_points.iter().skip(1) {
+ if point.x < min.x {
+ min.x = point.x;
+ }
+ if point.x > max.x {
+ max.x = point.x;
+ }
+
+ if point.y < min.y {
+ min.y = point.y;
+ }
+ if point.y > max.y {
+ max.y = point.y;
+ }
+ }
+
+ // For now, only use the width and height vectors.
+ // TODO: Change to a more sophisticated approach.
+ self.length_lines.clear();
+ // Horizontal dimensions, left to right.
+ self.length_lines
+ .push((Vec2::new(min.x, max.y), Vec2::new(max.x, max.y)));
+ // Vertical dimensions, bottom to top.
+ self.length_lines
+ .push((Vec2::new(max.x, max.y), Vec2::new(max.x, min.y)));
+ }
+
+ pub fn draw(&self, rld: &mut impl RaylibDraw, transform: &Transform) {
+ // Draw all the dimension lines.
+ for (start, end) in &self.length_lines {
+ // Don't draw anything if the length is zero.
+ if start == end {
+ continue;
+ }
+
+ /* Get the vector that is perpendicular and points right/down from the line, assuming
+ * the lines prefer left as start over right and bottom over top.
+ */
+ let line_normal = {
+ // Start with the direction of the line vector.
+ let dir = *start - *end;
+ // Calculate perpendicular vec and normalise.
+ dir.rotated_90_clockwise() / dir.len()
+ };
+
+ // 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.;
+
+ /* Draw the indicator line, with stubs at both ends. */
+ let line_colour = Color {
+ r: 200,
+ g: 200,
+ b: 200,
+ a: 255,
+ };
+ // First the two stubs.
+ rld.draw_line_ex(
+ start_px - line_normal * 5.,
+ start_px + line_normal * 5.,
+ 2.,
+ line_colour,
+ );
+ rld.draw_line_ex(
+ end_px - line_normal * 5.,
+ end_px + line_normal * 5.,
+ 2.,
+ line_colour,
+ );
+ // Then the actual indicator line.
+ rld.draw_line_ex(start_px, end_px, 2., line_colour);
+
+ /* Draw the indicator text showing how long this line is in meters.
+ * 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.;
+ rld.draw_text(
+ &format!("{}m", &(*end - *start).len()),
+ text_pos.x as i32,
+ text_pos.y as i32,
+ 20,
+ line_colour,
+ );
+ }
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index a0d8a13..e40a40e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,9 @@
+#[macro_use]
+extern crate log;
+
pub mod button;
pub mod config;
+pub mod dimension_indicator;
pub mod editor;
pub mod grid;
pub mod map_data;
@@ -17,6 +21,8 @@ use transform::Transform;
pub const CONFIG_FILE: &str = "config.ron";
fn main() {
+ pretty_env_logger::init();
+
let (mut rl, thread) = raylib::init().resizable().title("Hello there!").build();
rl.set_target_fps(120);
rl.set_exit_key(None);
diff --git a/src/math/vec2.rs b/src/math/vec2.rs
index ea549d7..7834ffc 100644
--- a/src/math/vec2.rs
+++ b/src/math/vec2.rs
@@ -1,11 +1,12 @@
use crate::math::Rect;
use alga::general::{ClosedAdd, ClosedSub};
use nalgebra::{RealField, Scalar};
+use num_traits::One;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::convert::{From, Into};
-use std::fmt;
-use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
+use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign};
+use std::{fmt, mem};
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Serialize, Deserialize, Eq)]
pub struct Vec2<T: Scalar + Copy> {
@@ -24,6 +25,24 @@ impl<T: Scalar + Copy> Vec2<T> {
{
(self.x * self.x + self.y * self.y).sqrt()
}
+
+ pub fn rotated_90_clockwise(mut self) -> Vec2<T>
+ where
+ T: One + Neg<Output = T> + MulAssign,
+ {
+ mem::swap(&mut self.x, &mut self.y);
+ self.y *= -T::one();
+ self
+ }
+
+ pub fn rotated_90_counterclockwise(mut self) -> Vec2<T>
+ where
+ T: One + Neg<Output = T> + MulAssign,
+ {
+ mem::swap(&mut self.x, &mut self.y);
+ self.x *= -T::one();
+ self
+ }
}
// This is sad, but also sadly necessary :/
diff --git a/src/tool/room_tool.rs b/src/tool/room_tool.rs
index 1bfb225..52748fc 100644
--- a/src/tool/room_tool.rs
+++ b/src/tool/room_tool.rs
@@ -1,6 +1,7 @@
use super::Tool;
use crate::button::Button;
use crate::config::{RoomToolKeybindings, ToolKeybindings};
+use crate::dimension_indicator::DimensionIndicator;
use crate::grid::snap_to_grid;
use crate::map_data::MapData;
use crate::math::{Rect, Vec2};
@@ -14,6 +15,7 @@ pub struct RoomTool {
/// 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>)>,
+ dimension_indicator: DimensionIndicator,
}
impl RoomTool {
@@ -22,6 +24,7 @@ impl RoomTool {
Self {
keybindings,
unfinished_rect: None,
+ dimension_indicator: DimensionIndicator::new(),
}
}
}
@@ -29,9 +32,11 @@ impl RoomTool {
impl Tool for RoomTool {
fn active_update(&mut self, map_data: &mut MapData, rl: &RaylibHandle, transform: &Transform) {
let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into());
- // Update the currently drawn rectangle, if it exists
- if let Some((_, ref mut pos2)) = &mut self.unfinished_rect {
+ // 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, 0.5);
+
+ self.dimension_indicator.update_dimensions(&[*pos1, *pos2]);
}
// Start or finish drawing the currently unfinished rectangle
@@ -73,6 +78,8 @@ impl Tool for RoomTool {
a: 255,
},
);
+
+ self.dimension_indicator.draw(rld, transform);
}
}