From e7a72d02b11b8069bef9978fa859021c2a4fde83 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Fri, 20 Jan 2017 21:57:34 -0800 Subject: [PATCH 1/2] Add CAABox::booleanIntersection --- include/zeus/CAABox.hpp | 49 +++++++++++++++++++++++++++++++++--- include/zeus/COBBox.hpp | 2 +- include/zeus/CQuaternion.hpp | 19 ++++++-------- include/zeus/CVector3f.hpp | 1 + include/zeus/Math.hpp | 9 ++++--- src/Math.cpp | 10 ++++++++ test/main.cpp | 10 ++++++++ 7 files changed, 80 insertions(+), 20 deletions(-) diff --git a/include/zeus/CAABox.hpp b/include/zeus/CAABox.hpp index 74767b3..ab02743 100644 --- a/include/zeus/CAABox.hpp +++ b/include/zeus/CAABox.hpp @@ -59,7 +59,7 @@ public: min.readBig(in); max.readBig(in); } - static inline CAABox ReadBoundingBoxBig(athena::io::IStreamReader &in) + static inline CAABox ReadBoundingBoxBig(athena::io::IStreamReader& in) { CAABox ret; ret.readBoundingBoxBig(in); @@ -100,11 +100,44 @@ public: bool z2 = (min[2] < other.max[2]); return x1 && x2 && y1 && y2 && z1 && z2; } + bool intersects(const CSphere& other) const { return distanceFromPointSquared(other.position) <= other.radius * other.radius; } + inline CAABox booleanIntersection(const CAABox& other) const + { + CVector3f minVec = CVector3f::skZero; + CVector3f maxVec = CVector3f::skZero; + + for (int i = 0; i < 3; ++i) + { + if (min[i] <= other.min[i] && max[i] >= other.max[i]) + { + minVec[i] = other.min[i]; + maxVec[i] = other.max[i]; + } + else if (other.min[i] <= min[i] && other.max[i] >= max[i]) + { + minVec[i] = min[i]; + maxVec[i] = max[i]; + } + else if (other.min[i] <= min[i] && other.max[i] >= min[i]) + { + minVec[i] = min[i]; + maxVec[i] = other.max[i]; + } + else if (other.min[i] <= max[i] && other.max[i] >= max[i]) + { + minVec[i] = other.min[i]; + maxVec[i] = max[i]; + } + } + + return {minVec, maxVec}; + } + inline bool inside(const CAABox& other) const { bool x = min[0] >= other.min[0] && max[0] <= other.max[0]; @@ -157,7 +190,9 @@ public: CVector3f center() const { return (min + max) * 0.5f; } - CVector3f volume() const { return (max - min) * 0.5f; } + CVector3f extents() const { return (max - min) * 0.5f; } + + float volume() const { return (max.x - min.x) * (max.y - min.y) * (max.z - min.z); } inline CLineSeg getEdge(EBoxEdgeId id) { @@ -312,8 +347,14 @@ public: inline bool invalid() { return (max.x < min.x || max.y < min.y || max.z < min.z); } }; -inline bool operator==(const CAABox& left, const CAABox& right) { return (left.min == right.min && left.max == right.max); } -inline bool operator!=(const CAABox& left, const CAABox& right) { return (left.min != right.min || left.max != right.max); } +inline bool operator==(const CAABox& left, const CAABox& right) +{ + return (left.min == right.min && left.max == right.max); +} +inline bool operator!=(const CAABox& left, const CAABox& right) +{ + return (left.min != right.min || left.max != right.max); +} } #endif // CAABOX_HPP diff --git a/include/zeus/COBBox.hpp b/include/zeus/COBBox.hpp index 25e909b..1244536 100644 --- a/include/zeus/COBBox.hpp +++ b/include/zeus/COBBox.hpp @@ -32,7 +32,7 @@ public: COBBox() {} - COBBox(const CAABox& aabb) : extents(aabb.volume()) { transform.origin = aabb.center(); } + COBBox(const CAABox& aabb) : extents(aabb.extents()) { transform.origin = aabb.center(); } COBBox(const CTransform& xf, const CVector3f& extents) : transform(xf), extents(extents) {} diff --git a/include/zeus/CQuaternion.hpp b/include/zeus/CQuaternion.hpp index 2c5bc4e..b91b2e8 100644 --- a/include/zeus/CQuaternion.hpp +++ b/include/zeus/CQuaternion.hpp @@ -205,7 +205,8 @@ public: targetCpy.normalize(); upCpy.normalize(); - CRelAngle angleBetween = normalize_angle(std::atan2(targetCpy.x, targetCpy.y) - std::atan2(upCpy.x, upCpy.y)); + CRelAngle angleBetween = + normalize_angle(std::atan2(targetCpy.x, targetCpy.y) - std::atan2(upCpy.x, upCpy.y)); CRelAngle realAngle = zeus::clamp(-c, angleBetween, c); CQuaternion tmpQ; tmpQ.rotateZ(realAngle); @@ -233,6 +234,7 @@ public: CQuaternion exp() const; inline CTransform toTransform() const { return CTransform(CMatrix3f(*this)); } + inline CTransform toTransform(const zeus::CVector3f& origin) const { return CTransform(CMatrix3f(*this), origin); } float dot(const CQuaternion& quat) const; static CQuaternion lerp(const CQuaternion& a, const CQuaternion& b, double t); @@ -248,7 +250,8 @@ public: inline float& operator[](size_t idx) { return (&w)[idx]; } inline const float& operator[](size_t idx) const { return (&w)[idx]; } - union { + union + { __m128 mVec128; struct { @@ -263,17 +266,9 @@ class alignas(16) CNUQuaternion : public CQuaternion { public: CNUQuaternion() = default; - CNUQuaternion(const CMatrix3f& mtx) - : CQuaternion(mtx) - { - normalize(); - } + CNUQuaternion(const CMatrix3f& mtx) : CQuaternion(mtx) { normalize(); } - CNUQuaternion(const CQuaternion& other) - : CQuaternion(other) - { - normalize(); - } + CNUQuaternion(const CQuaternion& other) : CQuaternion(other) { normalize(); } }; CQuaternion operator+(float lhs, const CQuaternion& rhs); diff --git a/include/zeus/CVector3f.hpp b/include/zeus/CVector3f.hpp index 353dc82..d1fe135 100644 --- a/include/zeus/CVector3f.hpp +++ b/include/zeus/CVector3f.hpp @@ -253,6 +253,7 @@ public: #endif return *this; } + inline void normalize() { float mag = magnitude(); diff --git a/include/zeus/Math.hpp b/include/zeus/Math.hpp index 8713aac..5734995 100644 --- a/include/zeus/Math.hpp +++ b/include/zeus/Math.hpp @@ -51,21 +51,24 @@ class CVector2f; class CTransform; template -inline T min(T a, T b) +inline T min(const T& a, const T& b) { return a < b ? a : b; } template -inline T max(T a, T b) +inline T max(const T& a, const T& b) { return a > b ? a : b; } +template <> CVector3f min(const CVector3f& a, const CVector3f& b); +template <> CVector3f max(const CVector3f& a, const CVector3f& b); template -inline T clamp(T a, T val, T b) +inline T clamp(const T& a, const T& val, const T& b) { return max(a, min(b, val)); } + inline float radToDeg(float rad) { return rad * (180.f / M_PIF); } inline float degToRad(float deg) { return deg * (M_PIF / 180.f); } inline double radToDeg(double rad) { return rad * (180.0 / M_PI); } diff --git a/src/Math.cpp b/src/Math.cpp index d39ef01..ff35fb3 100644 --- a/src/Math.cpp +++ b/src/Math.cpp @@ -327,4 +327,14 @@ bool close_enough(const CVector2f& a, const CVector2f& b, float epsilon) return true; return false; } + +template <> CVector3f min(const CVector3f& a, const CVector3f& b) +{ + return {min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)}; +} + +template <> CVector3f max(const CVector3f& a, const CVector3f& b) +{ + return {max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)}; +} } diff --git a/test/main.cpp b/test/main.cpp index 3a31ea2..f89890f 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -33,6 +33,16 @@ int main() CVector3f point(-90, 67, -105); CVector3f closestPoint = test.closestPointAlongVector(point); CVector3d doubleVec(100, -100, -200); + zeus::CAABox aabb1{208.9f, -83.9f, 17.7f, 211.9f, -80.9f, 25.7f}; + zeus::CVector3f center1 = aabb1.center(); + zeus::CVector3f extents1 = aabb1.extents() * 2.f; + zeus::CAABox aabb2{211.8f, -81.4f, 22.3f, 212.8, -80.4f, 25.0f}; + zeus::CVector3f center2 = aabb2.center(); + zeus::CVector3f extents2 = aabb2.extents() * 2.f; + + zeus::CAABox diffAABB = aabb1.booleanIntersection(aabb2); + zeus::CVector3f centerDiff = aabb2.center(); + zeus::CVector3f extentsDiff = aabb2.extents() * 2.f; assert(t.isEqu(t)); assert(test.inside(test)); From eb9326c7e0534745dc296135ac3a515fa95e0773 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Fri, 20 Jan 2017 22:20:34 -0800 Subject: [PATCH 2/2] Fix windows build --- test/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/main.cpp b/test/main.cpp index f89890f..c0a5b38 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -36,7 +36,7 @@ int main() zeus::CAABox aabb1{208.9f, -83.9f, 17.7f, 211.9f, -80.9f, 25.7f}; zeus::CVector3f center1 = aabb1.center(); zeus::CVector3f extents1 = aabb1.extents() * 2.f; - zeus::CAABox aabb2{211.8f, -81.4f, 22.3f, 212.8, -80.4f, 25.0f}; + zeus::CAABox aabb2{211.8f, -81.4f, 22.3f, 212.8f, -80.4f, 25.0f}; zeus::CVector3f center2 = aabb2.center(); zeus::CVector3f extents2 = aabb2.extents() * 2.f;