diff --git a/engine/inc/math/vec4.hpp b/engine/inc/math/vec4.hpp index 29cbf42..f688f92 100644 --- a/engine/inc/math/vec4.hpp +++ b/engine/inc/math/vec4.hpp @@ -56,6 +56,7 @@ class Vec4 { Vec4 operator*(const Vec4& v) const; Vec4 operator*(const float& v) const; Vec4 operator/(const float& v) const; + Vec4 operator/(const Vec4& v) const; Vec4 operator-(void) const; void operator=(const Vec4& v); void operator+=(const Vec4& v); diff --git a/engine/src/math/vec4.cpp b/engine/src/math/vec4.cpp index 559edf0..a01fc6f 100644 --- a/engine/src/math/vec4.cpp +++ b/engine/src/math/vec4.cpp @@ -77,6 +77,10 @@ Vec4 Vec4::operator/(const float& v) const { return Vec4(x / v, y / v, z / v, w); } +Vec4 Vec4::operator/(const Vec4& v) const { + return Vec4(x / v.x, y / v.y, z / v.z, w); +} + void Vec4::operator+=(const Vec4& v) { asm volatile( "lqc2 $vf4, 0x0(%0) \n\t" diff --git a/engine/src/physics/ray.cpp b/engine/src/physics/ray.cpp index 6fafbaa..ab4b4e3 100644 --- a/engine/src/physics/ray.cpp +++ b/engine/src/physics/ray.cpp @@ -33,41 +33,42 @@ float Ray::distanceToPoint(const Vec4& point) const { bool Ray::intersectBox(const Vec4& minCorner, const Vec4& maxCorner, float* outputDistance) const { - auto inv = invDir(); - inv.normalize(); + Vec4 _min = (minCorner - this->origin) / this->invDir(); + Vec4 _max = (minCorner - this->origin) / this->invDir(); - float tmin = (minCorner.x - this->origin.x) * inv.x; - float tmax = (maxCorner.x - this->origin.x) * inv.x; - float tymin = (minCorner.y - this->origin.y) * inv.y; - float tymax = (maxCorner.y - this->origin.y) * inv.y; - - if ((tmin > tymax) || (tymin > tmax)) { - return false; - } - - if (tymin > tmin) tmin = tymin; - - if (tymax < tmax) tmax = tymax; - - float tzmin = (minCorner.z - this->origin.z) * inv.z; - float tzmax = (maxCorner.z - this->origin.z) * inv.z; - - if ((tmin > tzmax) || (tzmin > tmax)) { - return false; - } - - if (tzmin > tmin) tmin = tzmin; - - if (tzmax < tmax) tmax = tzmax; + float tmin = + std::max(std::max(std::min(_min.x, _max.x), std::min(_min.y, _max.y)), + std::min(_min.z, _max.z)); + float tmax = + std::min(std::min(std::max(_min.x, _max.x), std::max(_min.y, _max.y)), + std::max(_min.z, _max.z)); + // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us if (tmax < 0) { + if (outputDistance != nullptr) { + *outputDistance = -1.0f; + } return false; } + // if tmin > tmax, ray doesn't intersect AABB + if (tmin > tmax) { + if (outputDistance != nullptr) { + *outputDistance = -1.0f; + } + return false; + } + + if (tmin < 0) { + if (outputDistance != nullptr) { + *outputDistance = tmax; + } + return true; + } + if (outputDistance != nullptr) { - *outputDistance = tmin >= 0 ? tmin : tmax; + *outputDistance = tmin; } - return true; }