wip: fixing Bsp

This commit is contained in:
🪞👃🪞 2025-01-01 17:26:54 +01:00
parent d17d20e7db
commit 8454b95df8
2 changed files with 56 additions and 67 deletions

View file

@ -60,6 +60,34 @@ impl<E: Engine, X: Content<E>, Y: Content<E>> Bsp<E, X, Y> {
pub fn w (x: X, y: Y) -> Self { Self::West(None, Some(x), Some(y)) }
pub fn a (x: X, y: Y) -> Self { Self::Above(Some(x), Some(y)) }
pub fn b (x: X, y: Y) -> Self { Self::Below(Some(x), Some(y)) }
pub fn areas (&self, outer: E::Area) -> [E::Area;2] {
let [x, y, w, h] = outer.xywh();
match self {
Self::Null(_) => [[x, y, 0.into(), 0.into()].into(), [x, y, 0.into(), 0.into()].into()],
Self::Above(a, b) | Self::Below(a, b) => [a.layout(outer), b.layout(outer)],
Self::North(_, a, b) => {
let a = a.layout(outer);
let b = b.layout([x, y, w, h.minus(a.h())].into());
[a, b]
}
Self::South(_, a, b) => {
let a = a.layout(outer);
let b = b.layout([x, y + a.h(), w, h.minus(a.h())].into());
[a, b]
},
Self::East(_, a, b) => {
let a = a.layout(outer);
let b = b.layout([x + a.w(), y, w.minus(a.w()), h].into());
[a, b]
},
Self::West(_, a, b) => {
let a = a.layout(outer);
let b = b.layout([x, y, w.minus(a.w()), h].into());
[a, b]
},
}
}
}
impl<E: Engine, X: Content<E>, Y: Content<E>> Default for Bsp<E, X, Y> {
@ -70,75 +98,36 @@ impl<E: Engine, X: Content<E>, Y: Content<E>> Default for Bsp<E, X, Y> {
impl<E: Engine, X: Content<E>, Y: Content<E>> Content<E> for Bsp<E, X, Y> {
fn layout (&self, outer: E::Area) -> E::Area {
let [a, b] = self.areas(outer);
let [x, y] = outer.center();
match self {
Self::Null(_) => [0.into(), 0.into(), 0.into(), 0.into()].into(),
Self::North(_, a, b) => {
let a = a.layout(outer);
let b = b.layout(North.split_fixed(outer, a.y() + a.h()).1.into());
[a.x().min(b.x()), a.y().min(b.y()), a.w().max(b.w()), a.h() + b.h()].into()
}
Self::South(_, a, b) => {
let a = a.layout(outer);
let b = b.layout(South.split_fixed(outer, a.y() + a.h()).1.into());
[a.x().min(b.x()), a.y().min(b.y()), a.w().max(b.w()), a.h() + b.h()].into()
},
Self::East(_, a, b) => {
let a = a.layout(outer);
let b = b.layout(East.split_fixed(outer, a.x() + a.w()).1.into());
[a.x().min(b.x()), a.y().min(b.y()), a.w() + b.w(), a.h().max(b.h())].into()
},
Self::West(_, a, b) => {
let a = a.layout(outer);
let b = b.layout(West.split_fixed(outer, a.x() + a.w()).1.into());
[a.x().min(b.x()), a.y().min(b.y()), a.w() + b.w(), a.h().max(b.h())].into()
},
Self::Above(a, b) | Self::Below(a, b) => {
let a = a.layout(outer);
let b = b.layout(outer);
[a.x().min(b.x()), a.y().min(b.y()), a.w().max(b.w()), a.h().max(b.h())].into()
}
}
Self::Null(_) =>
[x, y, 0.into(), 0.into()],
Self::North(_, _, _) =>
[a.x().min(b.x()), a.y().min(b.y()), a.w().max(b.w()), a.h() + b.h()],
Self::South(_, _, _) =>
[a.x().min(b.x()), a.y().min(b.y()), a.w().max(b.w()), a.h() + b.h()],
Self::East(_, _, _) =>
[a.x().min(b.x()), a.y().min(b.y()), a.w() + b.w(), a.h().max(b.h())],
Self::West(_, _, _) =>
[a.x().min(b.x()), a.y().min(b.y()), a.w() + b.w(), a.h().max(b.h())],
Self::Above(_, _) | Self::Below(_, _) =>
[a.x().min(b.x()), a.y().min(b.y()), a.w().max(b.w()), a.h().max(b.h())]
}.into()
}
fn render (&self, to: &mut E::Output) {
let area = to.area().clone();
let [area_a, area_b] = self.areas(to.area());
match self {
Self::North(_, a, b) => {
let area_a = a.layout(area);
let area_b = b.layout(North.split_fixed(area, area_a.y() + area_a.h()).1.into());
to.place(area_a, a);
to.place(area_b, b);
},
Self::South(_, a, b) => {
let area_a = a.layout(area).clone();
let area_b = b.layout(South.split_fixed(area, area_a.y() + area_a.h()).1.into()).clone();
to.place(area_a, a);
to.place(area_b, b);
},
Self::East(_, a, b) => {
let area_a = a.layout(area);
let area_b = b.layout(East.split_fixed(area, area_a.x() + area_a.w()).1.into());
to.place(area_a, a);
to.place(area_b, b);
},
Self::West(_, a, b) => {
let area_a = a.layout(area);
let area_b = b.layout(West.split_fixed(area, area_a.x() + area_a.w()).1.into());
to.place(area_a, a);
to.place(area_b, b);
},
Self::Above(a, b) => {
let area_a = a.layout(area);
let area_b = b.layout(area);
to.place(area_b, b);
to.place(area_a, a);
},
Self::North(_, a, b) |
Self::South(_, a, b) |
Self::East(_, a, b) |
Self::West(_, a, b) |
Self::Above(a, b) |
Self::Below(a, b) => {
let area_a = a.layout(area);
let area_b = b.layout(area);
to.place(area_a, a);
to.place(area_b, b);
},
Self::Null(_) => {}
_ => {},
}
}
}