Add CAABox::booleanIntersection

This commit is contained in:
Phillip Stephens 2017-01-20 21:57:34 -08:00
parent caff50dfa5
commit e7a72d02b1
7 changed files with 80 additions and 20 deletions

View File

@ -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

View File

@ -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) {}

View File

@ -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<CRelAngle>(-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);

View File

@ -253,6 +253,7 @@ public:
#endif
return *this;
}
inline void normalize()
{
float mag = magnitude();

View File

@ -51,21 +51,24 @@ class CVector2f;
class CTransform;
template <typename T>
inline T min(T a, T b)
inline T min(const T& a, const T& b)
{
return a < b ? a : b;
}
template <typename T>
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 <typename T>
inline T clamp(T a, T val, T b)
inline T clamp(const T& a, const T& val, const T& b)
{
return max<T>(a, min<T>(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); }

View File

@ -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)};
}
}

View File

@ -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));