diff --git a/rust/src/geometry.rs b/rust/src/geometry.rs index 1b5b33b26..10850f198 100644 --- a/rust/src/geometry.rs +++ b/rust/src/geometry.rs @@ -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)] @@ -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; @@ -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(); @@ -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; } } @@ -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; } } @@ -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; } } diff --git a/rust/src/wow/wmo.rs b/rust/src/wow/wmo.rs index 6fde9c099..31a7e243c 100644 --- a/rust/src/wow/wmo.rs +++ b/rust/src/wow/wmo.rs @@ -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 diff --git a/src/Geometry.ts b/src/Geometry.ts index 1a8c21026..333cb12a7 100644 --- a/src/Geometry.ts +++ b/src/Geometry.ts @@ -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 {