Skip to content

Commit

Permalink
more inline and Obb goodies
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass committed Jun 5, 2024
1 parent eaefcff commit 0352d5a
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
55 changes: 55 additions & 0 deletions geom/src/obb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::aabb::AABB;
use crate::{vec2, Circle, Intersect, Polygon, Segment, Shape, Vec2};
use serde::{Deserialize, Serialize};
use std::hint::unreachable_unchecked;
use std::ops::Add;

/// Oriented bounding box
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
Expand All @@ -15,6 +16,7 @@ impl OBB {
};

/// cossin of `UNIT_X` makes this an AABB
#[inline]
pub fn new(center: Vec2, cossin: Vec2, w: f32, h: f32) -> Self {
let up = cossin * w * 0.5;
let right = cossin.perpendicular() * h * 0.5;
Expand All @@ -28,10 +30,23 @@ impl OBB {
}
}

#[inline]
pub fn new_corners(corners: [Vec2; 4]) -> Self {
Self { corners }
}

#[inline]
pub fn from_rotated_aabb(aabb: AABB, cossin: Vec2) -> Self {
Self {
corners: [
aabb.ll.rotated_by(cossin),
vec2(aabb.ur.x, aabb.ll.y).rotated_by(cossin),
aabb.ur.rotated_by(cossin),
vec2(aabb.ll.x, aabb.ur.y).rotated_by(cossin),
],
}
}

#[inline]
pub fn axis(&self) -> [Vec2; 2] {
[
Expand All @@ -45,6 +60,7 @@ impl OBB {
(self.corners[2] + self.corners[0]) * 0.5
}

#[inline]
pub fn expand(&self, w: f32) -> Self {
let [a, b] = self.axis();
let a = match a.try_normalize() {
Expand All @@ -65,6 +81,17 @@ impl OBB {
}
}

pub fn map(&self, f: impl Fn(Vec2) -> Vec2) -> Self {
Self {
corners: [
f(self.corners[0]),
f(self.corners[1]),
f(self.corners[2]),
f(self.corners[3]),
],
}
}

/// Returns true if other overlaps one dimension of this.
/// Taken from <https://www.flipcode.com/archives/2D_OBB_Intersection.shtml>
fn intersects1way(&self, other: &OBB) -> bool {
Expand Down Expand Up @@ -117,6 +144,7 @@ impl OBB {
ok0 & ok1 & ok2 & ok3
}

#[inline]
pub fn is_close(&self, p: Vec2, dist: f32) -> bool {
if self.contains(p) {
return true;
Expand Down Expand Up @@ -151,6 +179,7 @@ impl OBB {
/// 4 v ^ 2
/// +-->--+
/// 1
#[inline]
pub fn segments(&self) -> [Segment; 4] {
[
Segment::new(self.corners[0], self.corners[1]),
Expand All @@ -161,6 +190,31 @@ impl OBB {
}
}

impl Add<Vec2> for OBB {
type Output = OBB;

#[inline]
fn add(self, rhs: Vec2) -> Self::Output {
Self {
corners: [
self.corners[0] + rhs,
self.corners[1] + rhs,
self.corners[2] + rhs,
self.corners[3] + rhs,
],
}
}
}

impl Add<OBB> for Vec2 {
type Output = OBB;

#[inline]
fn add(self, rhs: OBB) -> Self::Output {
rhs + self
}
}

impl Shape for OBB {
#[inline]
fn bbox(&self) -> AABB {
Expand Down Expand Up @@ -201,6 +255,7 @@ impl Intersect<Circle> for OBB {
}

impl Intersect<AABB> for OBB {
#[inline]
fn intersects(&self, shape: &AABB) -> bool {
let Vec2 {
x: mut min_x,
Expand Down
1 change: 1 addition & 0 deletions geom/src/plane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub struct Plane {
impl Plane {
pub const X: Self = Self { n: Vec3::X, o: 0.0 };

#[inline]
pub const fn new(n: Vec3, o: f32) -> Self {
Self { n, o }
}
Expand Down
14 changes: 14 additions & 0 deletions geom/src/polyline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl From<Vec<Vec2>> for PolyLine {
}

impl PolyLine {
#[inline]
pub fn new(x: Vec<Vec2>) -> Self {
if x.is_empty() {
panic!("Vec must have at least one point")
Expand All @@ -31,6 +32,7 @@ impl PolyLine {
}
}

#[inline]
pub fn clear_push(&mut self, x: Vec2) {
self.points.clear();
self.points.push(x);
Expand All @@ -47,6 +49,7 @@ impl PolyLine {
self.l += length(&self.points[old_l - 1..]);
}

#[inline]
pub fn pop(&mut self) -> Vec2 {
let v = match self.points.pop() {
Some(x) => x,
Expand All @@ -57,6 +60,7 @@ impl PolyLine {
v
}

#[inline]
pub fn push(&mut self, item: Vec2) {
self.l += (self.last() - item).mag();
self.points.push(item);
Expand Down Expand Up @@ -168,6 +172,7 @@ impl PolyLine {
self.points_dirs_along(std::iter::once(l)).next().unwrap() // Unwrap ok: std::iter::once
}

#[inline]
pub fn length(&self) -> f32 {
self.l
}
Expand Down Expand Up @@ -286,6 +291,7 @@ impl PolyLine {
}
}

#[inline]
pub fn bbox(&self) -> AABB {
let (min, max) = match super::minmax(self.points.iter().copied()) {
Some(x) => x,
Expand All @@ -295,25 +301,30 @@ impl PolyLine {
AABB::new_ll_ur(min, max)
}

#[inline]
pub fn n_points(&self) -> usize {
self.points.len()
}

#[inline]
pub fn is_empty(&self) -> bool {
self.points.is_empty()
}

#[inline]
pub fn get<I>(&self, index: I) -> Option<&I::Output>
where
I: SliceIndex<[Vec2]>,
{
self.points.get(index)
}

#[inline]
pub fn first(&self) -> Vec2 {
unsafe { *self.points.get_unchecked(0) }
}

#[inline]
pub fn last(&self) -> Vec2 {
unsafe { *self.points.get_unchecked(self.points.len() - 1) }
}
Expand Down Expand Up @@ -345,6 +356,7 @@ impl PolyLine {
impl Index<Range<usize>> for PolyLine {
type Output = [Vec2];

#[inline]
fn index(&self, r: Range<usize>) -> &[Vec2] {
&self.points[r]
}
Expand All @@ -353,6 +365,7 @@ impl Index<Range<usize>> for PolyLine {
impl Index<usize> for PolyLine {
type Output = Vec2;

#[inline]
fn index(&self, index: usize) -> &Vec2 {
&self.points[index]
}
Expand All @@ -367,6 +380,7 @@ pub struct PointsAlongs<'a> {
}

impl<'a> PointsAlongs<'a> {
#[inline]
pub fn next(&mut self, d: f32) -> Option<(Vec2, Vec2)> {
while d > self.partial + self.dist {
let w = self.windows.next()?;
Expand Down
16 changes: 16 additions & 0 deletions geom/src/polyline3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl From<Vec<Vec3>> for PolyLine3 {
}

impl PolyLine3 {
#[inline]
pub fn new(x: Vec<Vec3>) -> Self {
if x.is_empty() {
panic!("Vec must have at least one point")
Expand All @@ -31,6 +32,7 @@ impl PolyLine3 {

/// # Safety
/// Must not be used with advanced functions if passed vector is empty, as it would lead to UB
#[inline]
pub unsafe fn new_unchecked(x: Vec<Vec3>) -> Self {
Self {
l: length(&x),
Expand All @@ -42,12 +44,14 @@ impl PolyLine3 {
PolyLine::new(self.points.iter().copied().map(Vec3::xy).collect())
}

#[inline]
pub fn clear_push(&mut self, x: Vec3) {
self.points.clear();
self.points.push(x);
self.l = 0.0;
}

#[inline]
pub fn len(&self) -> usize {
self.points.len()
}
Expand Down Expand Up @@ -154,6 +158,7 @@ impl PolyLine3 {
self.l += length(&self.points[old_l - 1..]);
}

#[inline]
pub fn pop(&mut self) -> Vec3 {
let v = match self.points.pop() {
Some(x) => x,
Expand All @@ -164,11 +169,13 @@ impl PolyLine3 {
v
}

#[inline]
pub fn push(&mut self, item: Vec3) {
self.l += (self.last() - item).mag();
self.points.push(item);
}

#[inline]
pub fn pop_first(&mut self) -> Vec3 {
let v = self.points.remove(0);
self.check_empty();
Expand Down Expand Up @@ -274,6 +281,7 @@ impl PolyLine3 {
Some(self.get(id + 1)? - self.get(id)?)
}

#[inline]
pub fn first_dir(&self) -> Option<Vec3> {
if self.points.len() >= 2 {
(self[1] - self[0]).try_normalize()
Expand All @@ -282,6 +290,7 @@ impl PolyLine3 {
}
}

#[inline]
pub fn last_dir(&self) -> Option<Vec3> {
let l = self.points.len();
if l >= 2 {
Expand Down Expand Up @@ -313,6 +322,7 @@ impl PolyLine3 {
)
}

#[inline]
pub fn length(&self) -> f32 {
self.l
}
Expand Down Expand Up @@ -447,6 +457,7 @@ impl PolyLine3 {
}
}

#[inline]
pub fn bbox(&self) -> AABB3 {
let (min, max) = match super::minmax3(self.points.iter().copied()) {
Some(x) => x,
Expand All @@ -456,25 +467,30 @@ impl PolyLine3 {
AABB3::new(min, max)
}

#[inline]
pub fn n_points(&self) -> usize {
self.points.len()
}

#[inline]
pub fn is_empty(&self) -> bool {
self.points.is_empty()
}

#[inline]
pub fn get<I>(&self, index: I) -> Option<&I::Output>
where
I: SliceIndex<[Vec3]>,
{
self.points.get(index)
}

#[inline]
pub fn first(&self) -> Vec3 {
unsafe { *self.points.get_unchecked(0) }
}

#[inline]
pub fn last(&self) -> Vec3 {
unsafe { *self.points.get_unchecked(self.points.len() - 1) }
}
Expand Down

0 comments on commit 0352d5a

Please sign in to comment.