Minimap view outline is cut at the map border instead of squeezing its corners; beds grow out of the floor while their creature sets them up
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
468fa03db9
commit
1696297ac3
2 files changed
+94
-15
No files matched your search
@@ -707,12 +707,11 @@ impl Ui {
|
||||
// camera footprint on the ground (the 3D camera works in CSS pixels)
|
||||
let (lw, lh) = (screen_width(), screen_height());
|
||||
let corners = [cam.ground_point(0.0, 0.0), cam.ground_point(lw, 0.0), cam.ground_point(lw, lh), cam.ground_point(0.0, lh)];
|
||||
// the edges are cut off at the map border (moving the corners would distort the shape)
|
||||
for k in 0..4 {
|
||||
let a = corners[k];
|
||||
let b = corners[(k + 1) % 4];
|
||||
let clampp = |p: Vec2| vec2(mrx + p.x.clamp(0.0, mw() as f32) * ms, mry + p.y.clamp(0.0, mh() as f32) * ms);
|
||||
let (pa, pb) = (clampp(a), clampp(b));
|
||||
draw_line(pa.x, pa.y, pb.x, pb.y, px, WHITE);
|
||||
if let Some((a, b)) = clip_segment(corners[k], corners[(k + 1) % 4], mw() as f32, mh() as f32) {
|
||||
draw_line(mrx + a.x * ms, mry + a.y * ms, mrx + b.x * ms, mry + b.y * ms, px, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- mission goals (campaign)
|
||||
@@ -1209,3 +1208,44 @@ pub fn hover_info(g: &Game, ent: Option<usize>, tile: Option<(i32, i32)>) -> Vec
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
// the part of the segment a-b inside the rectangle (0, 0)-(w, h) (Liang-Barsky)
|
||||
fn clip_segment(a: Vec2, b: Vec2, w: f32, h: f32) -> Option<(Vec2, Vec2)> {
|
||||
let d = b - a;
|
||||
let (mut t0, mut t1) = (0.0f32, 1.0f32);
|
||||
for (p, q) in [(-d.x, a.x), (d.x, w - a.x), (-d.y, a.y), (d.y, h - a.y)] {
|
||||
if p == 0.0 {
|
||||
if q < 0.0 {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
let r = q / p;
|
||||
if p < 0.0 {
|
||||
t0 = t0.max(r);
|
||||
} else {
|
||||
t1 = t1.min(r);
|
||||
}
|
||||
if t0 > t1 {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some((a + d * t0, a + d * t1))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod clip_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn view_edges_are_cut_at_the_border() {
|
||||
// inside: unchanged
|
||||
let (a, b) = clip_segment(vec2(1.0, 1.0), vec2(5.0, 5.0), 10.0, 10.0).unwrap();
|
||||
assert_eq!((a, b), (vec2(1.0, 1.0), vec2(5.0, 5.0)));
|
||||
// crossing the left border: cut at x = 0, same direction
|
||||
let (a, b) = clip_segment(vec2(-4.0, 2.0), vec2(4.0, 6.0), 10.0, 10.0).unwrap();
|
||||
assert!((a.x - 0.0).abs() < 1e-5 && (a.y - 4.0).abs() < 1e-5 && b == vec2(4.0, 6.0));
|
||||
// completely outside: nothing
|
||||
assert!(clip_segment(vec2(-5.0, -1.0), vec2(-1.0, 20.0), 10.0, 10.0).is_none());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user