Skip to content

Commit

Permalink
Geometry: Make frustum planes face inwards rather than outwards
Browse files Browse the repository at this point in the history
This is much more standard than what I was doing before.
  • Loading branch information
magcius committed Oct 29, 2024
1 parent a7da874 commit dcb3ea2
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 50 deletions.
61 changes: 21 additions & 40 deletions rust/src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::f32;

use nalgebra_glm::{make_mat4, make_vec3, triangle_normal, vec2, vec3, vec4, Mat4, Vec3, Vec2};
use nalgebra_glm::{make_mat4, make_vec3, triangle_normal, vec2, vec4, Mat4, Vec3, Vec2};
use wasm_bindgen::prelude::*;

#[derive(Default, Debug, Clone)]
Expand All @@ -10,6 +10,11 @@ pub struct Plane {
}

impl Plane {
pub fn normalized(&self) -> Plane {
let mag = self.normal.magnitude();
Plane { normal: self.normal / mag, d: self.d / mag }
}

pub fn negate(&mut self) {
self.normal.neg_mut();
self.d *= -1.0;
Expand Down Expand Up @@ -86,6 +91,13 @@ impl AABB {
}
}

pub fn get_closest_point_along_direction(&self, dir: &Vec3) -> Vec3 {
let x = if dir.x >= 0.0 { self.max.x } else { self.min.x };
let y = if dir.y >= 0.0 { self.max.y } else { self.min.y };
let z = if dir.z >= 0.0 { self.max.z } else { self.min.z };
Vec3::new(x, y, z)
}

pub fn transform(&mut self, mat: &Mat4) {
// Transforming Axis-Aligned Bounding Boxes from Graphics Gems.
let min = self.min.clone();
Expand Down Expand Up @@ -160,7 +172,7 @@ pub struct ConvexHull {
impl ConvexHull {
pub fn contains_point(&self, p: &Vec3) -> bool {
for plane in &self.planes {
if plane.distance(p) > 0.0 {
if plane.distance(p) < 0.0 {
return false;
}
}
Expand All @@ -170,44 +182,13 @@ impl ConvexHull {
pub fn intersect_aabb(&self, aabb: &AABB) -> IntersectionState {
let mut result = IntersectionState::Inside;
for plane in &self.planes {
let nearest = vec3(
if plane.normal.x >= 0.0 {
aabb.min.x
} else {
aabb.max.x
},
if plane.normal.y >= 0.0 {
aabb.min.y
} else {
aabb.max.y
},
if plane.normal.z >= 0.0 {
aabb.min.z
} else {
aabb.max.z
},
);
if plane.distance(&nearest) > 0.0 {
let nearest = aabb.get_closest_point_along_direction(&plane.normal);
if plane.distance(&nearest) < 0.0 {
return IntersectionState::Outside;
}
let farthest = vec3(
if plane.normal.x >= 0.0 {
aabb.max.x
} else {
aabb.min.x
},
if plane.normal.y >= 0.0 {
aabb.max.y
} else {
aabb.min.y
},
if plane.normal.z >= 0.0 {
aabb.max.z
} else {
aabb.min.z
},
);
if plane.distance(&farthest) > 0.0 {

let farthest = aabb.get_closest_point_along_direction(&-plane.normal);
if plane.distance(&farthest) < 0.0 {
result = IntersectionState::Intersection;
}
}
Expand All @@ -218,9 +199,9 @@ impl ConvexHull {
let mut result = IntersectionState::Inside;
for plane in &self.planes {
let dist = plane.distance(center);
if dist > radius {
if dist < radius {
return IntersectionState::Outside;
} else if dist > -radius {
} else if dist < -radius {
result = IntersectionState::Intersection;
}
}
Expand Down
4 changes: 2 additions & 2 deletions rust/src/wow/wmo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,10 @@ impl PortalData {

let mut plane = Plane::default();
plane.set_tri(eye, &a, &b);
if plane.distance(&test_point) > 0.0 {
if plane.distance(&test_point) < 0.0 {
plane.negate();
}
assert!(plane.distance(&test_point) <= 0.0);
assert!(plane.distance(&test_point) >= 0.0);
result.planes.push(plane);
}
result
Expand Down
15 changes: 7 additions & 8 deletions src/Geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,22 +315,21 @@ export class Frustum {

public updateClipFrustum(m: ReadonlyMat4, clipSpaceNearZ: GfxClipSpaceNearZ): void {
// http://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf
// Note that we look down the -Z axis, rather than the +Z axis, so we have to invert all of our planes...

const h = this.convexHull;
h.clear();
h.push_plane(-(m[3] + m[0]), -(m[7] + m[4]), -(m[11] + m[8]) , -(m[15] + m[12])); // Left
h.push_plane(-(m[3] + m[1]), -(m[7] + m[5]), -(m[11] + m[9]) , -(m[15] + m[13])); // Top
h.push_plane(-(m[3] - m[0]), -(m[7] - m[4]), -(m[11] - m[8]) , -(m[15] - m[12])); // Right
h.push_plane(-(m[3] - m[1]), -(m[7] - m[5]), -(m[11] - m[9]) , -(m[15] - m[13])); // Bottom
h.push_plane(m[3] + m[0], m[7] + m[4], m[11] + m[8], m[15] + m[12]); // Left
h.push_plane(m[3] + m[1], m[7] + m[5], m[11] + m[9], m[15] + m[13]); // Top
h.push_plane(m[3] - m[0], m[7] - m[4], m[11] - m[8], m[15] - m[12]); // Right
h.push_plane(m[3] - m[1], m[7] - m[5], m[11] - m[9], m[15] - m[13]); // Bottom

if (clipSpaceNearZ === GfxClipSpaceNearZ.NegativeOne) {
h.push_plane(-(m[3] + m[2]), -(m[7] + m[6]), -(m[11] + m[10]), -(m[15] + m[14])); // Near
h.push_plane(m[3] + m[2], m[7] + m[6], m[11] + m[10], m[15] + m[14]); // Near
} else if (clipSpaceNearZ === GfxClipSpaceNearZ.Zero) {
h.push_plane(-(m[2]), -(m[6]), -(m[10]), -(m[14])); // Near
h.push_plane(m[2], m[6], m[10], m[14]); // Near
}

h.push_plane(-(m[3] - m[2]), -(m[7] - m[6]), -(m[11] - m[10]), -(m[15] - m[14])); // Far
h.push_plane(m[3] - m[2], m[7] - m[6], m[11] - m[10], m[15] - m[14]); // Far
}

public copy(o: Frustum): void {
Expand Down

0 comments on commit dcb3ea2

Please sign in to comment.