bsp_pathfinding/tree/
portal.rs1use std::ops::Deref;
2
3use glam::Vec2;
4
5use crate::{util::face_intersect, Face, NodeIndex};
6
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct Portal<'a> {
10 pub(crate) face: &'a Face,
11
12 pub(crate) portal_ref: PortalRef,
13}
14
15impl<'a> Portal<'a> {
16 pub fn portal_ref(&self) -> PortalRef {
18 self.portal_ref
19 }
20
21 pub fn dst(&self) -> NodeIndex {
22 self.portal_ref.dst
23 }
24
25 pub fn src(&self) -> NodeIndex {
27 self.portal_ref.src
28 }
29
30 pub fn normal(&self) -> Vec2 {
32 self.portal_ref.normal
33 }
34
35 pub fn face(&self) -> &Face {
37 self.face
38 }
39
40 pub(crate) fn try_clip(&self, start: Vec2, end: Vec2, margin: f32) -> Option<Vec2> {
42 let (l, r) = self.apply_margin(margin).into_tuple();
43 let p = face_intersect((l, r), start, (end - start).perp());
44
45 if p.distance > 0.0 && p.distance < 1.0 {
47 Some(p.point)
48 } else {
49 None
50 }
51 }
52
53 pub(crate) fn clip(&self, start: Vec2, end: Vec2, margin: f32) -> Vec2 {
54 let (l, r) = self.apply_margin(margin).into_tuple();
55 let p = face_intersect((l, r), start, (end - start).perp());
56
57 if p.distance < 0.0 {
59 l
60 } else if p.distance > 1.0 {
61 r
62 } else {
63 p.point
64 }
65 }
66
67 pub fn apply_margin(&self, margin: f32) -> Face {
68 let dir = self.face.dir();
69 let l = self.face.vertices[0] + margin * dir * self.adjacent[0] as i32 as f32;
70 let r = self.face.vertices[1] - margin * dir * self.adjacent[1] as i32 as f32;
71 Face::new([l, r])
72 }
73}
74
75impl<'a> Deref for Portal<'a> {
76 type Target = PortalRef;
77
78 fn deref(&self) -> &Self::Target {
79 &self.portal_ref
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq)]
84#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
86pub struct PortalRef {
87 pub(crate) src: NodeIndex,
88 pub(crate) dst: NodeIndex,
89 pub(crate) face: usize,
90 pub(crate) adjacent: [bool; 2],
91 pub(crate) normal: Vec2,
94}
95
96impl PortalRef {
97 pub fn normal(&self) -> Vec2 {
99 self.normal
100 }
101
102 pub fn src(&self) -> NodeIndex {
104 self.src
105 }
106
107 pub fn dst(&self) -> NodeIndex {
109 self.dst
110 }
111
112 pub fn normal_mut(&mut self) -> &mut Vec2 {
114 &mut self.normal
115 }
116
117 pub fn adjacent(&self) -> [bool; 2] {
119 self.adjacent
120 }
121}