summaryrefslogtreecommitdiff
path: root/Runtime/Geometry/AABB.h
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Geometry/AABB.h
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Geometry/AABB.h')
-rw-r--r--Runtime/Geometry/AABB.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/Runtime/Geometry/AABB.h b/Runtime/Geometry/AABB.h
new file mode 100644
index 0000000..8b80cf1
--- /dev/null
+++ b/Runtime/Geometry/AABB.h
@@ -0,0 +1,202 @@
+#ifndef AABB_H
+#define AABB_H
+
+#include "Runtime/Math/Vector3.h"
+#include "Runtime/Math/Matrix4x4.h"
+
+class MinMaxAABB;
+class Quaternionf;
+class Matrix3x3f;
+
+
+class AABB
+{
+public:
+ static const AABB zero;
+
+public:
+ Vector3f m_Center;
+ Vector3f m_Extent;
+
+
+ AABB () {}
+ AABB (const Vector3f& c, const Vector3f& e) { m_Center = c; m_Extent = e; }
+ DECLARE_SERIALIZE_OPTIMIZE_TRANSFER (AABB)
+
+ AABB (const MinMaxAABB& aabb) { FromMinMaxAABB (aabb); }
+ AABB& operator = (const MinMaxAABB& aabb) { FromMinMaxAABB (aabb); return *this; }
+
+ bool operator == (const AABB& b) const { return m_Center == b.m_Center && m_Extent == b.m_Extent; }
+
+ void SetCenterAndExtent( const Vector3f& c, const Vector3f& e ) { m_Center = c; m_Extent = e; }
+
+ Vector3f& GetCenter () { return m_Center; }
+ Vector3f& GetExtent () { return m_Extent; }
+ float& GetExtent (int i) { return m_Extent[i]; }
+ const Vector3f& GetCenter ()const { return m_Center; }
+ const Vector3f& GetExtent ()const { return m_Extent; }
+ float GetExtent (int i)const { return m_Extent[i]; }
+
+ Vector3f GetMin () const { return m_Center - m_Extent; }
+ Vector3f GetMax () const { return m_Center + m_Extent; }
+
+ void Expand (float inValue);
+
+ bool IsValid () const;
+
+ bool IsInside (const Vector3f& inPoint) const;
+
+ void GetVertices (Vector3f* outVertices) const;
+ void EXPORT_COREMODULE Encapsulate (const Vector3f& inPoint);
+
+ private:
+
+ void FromMinMaxAABB (const MinMaxAABB& aabb);
+};
+
+bool IsContainedInAABB (const AABB& inside, const AABB& bigBounds);
+
+
+// Find minimum AABB which includes both AABBs
+MinMaxAABB AddAABB (const MinMaxAABB& lhs, const MinMaxAABB& rhs);
+
+// Transforms AABB.
+// Can be thought of as Converting OBB to an AABB:
+// rotate the center and extents of the OBB And find the smallest enclosing AABB around it.
+void TransformAABB (const AABB& aabb, const Vector3f& position, const Quaternionf& rotation, AABB& result);
+
+/// This is not mathematically correct for non-uniform scaled objects. But it seems to work well enough.
+/// If you use it with non-uniform scale make sure to verify it extensively.
+EXPORT_COREMODULE void TransformAABB (const AABB& aabb, const Matrix4x4f& transform, AABB& result);
+
+/// This version is much slower but works correctly with non-uniform scale
+void TransformAABBSlow (const AABB& aabb, const Matrix4x4f& transform, AABB& result);
+
+void InverseTransformAABB (const AABB& aabb, const Vector3f& position, const Quaternionf& rotation, AABB& result);
+
+
+/// The closest distance to the surface or inside the aabb.
+float CalculateSqrDistance (const Vector3f& rkPoint, const AABB& rkBox);
+
+
+/// Returns the sqr distance and the closest point inside or on the surface of the aabb.
+/// If inside the aabb, distance will be zero and rkPoint will be returned.
+EXPORT_COREMODULE void CalculateClosestPoint (const Vector3f& rkPoint, const AABB& rkBox, Vector3f& outPoint, float& outSqrDistance);
+
+class MinMaxAABB
+{
+public:
+
+ Vector3f m_Min;
+ Vector3f m_Max;
+
+ MinMaxAABB () { Init (); }
+ MinMaxAABB (Vector3f min, Vector3f max) : m_Min(min), m_Max(max) { };
+ MinMaxAABB (const AABB& aabb) { FromAABB (aabb); }
+ MinMaxAABB& operator = (const AABB& aabb) { FromAABB (aabb); return *this; }
+ //DECLARE_SERIALIZE_OPTIMIZE_TRANSFER (MinMaxAABB)
+
+ void Init ();
+
+ const Vector3f& GetMin () const { return m_Min; }
+ const Vector3f& GetMax () const { return m_Max; }
+ Vector3f GetCenter () const { return 0.5F * (m_Max + m_Min); }
+ Vector3f GetExtent () const { return 0.5F * (m_Max - m_Min); }
+ Vector3f GetSize () const { return (m_Max - m_Min); }
+
+ void Encapsulate (const Vector3f& inPoint);
+ void Encapsulate (const AABB& aabb);
+ void Encapsulate (const MinMaxAABB& other);
+
+ void Expand (float inValue);
+ void Expand (const Vector3f& inOffset);
+
+ // TODO : rename - it has different meaning than AABB::IsValid
+ bool IsValid () const;
+
+ bool IsInside (const Vector3f& inPoint) const;
+
+ void GetVertices( Vector3f outVertices[8] ) const;
+
+private:
+
+ void FromAABB (const AABB& inAABB);
+};
+
+inline void AABB::Expand (float inValue)
+{
+ m_Extent += Vector3f (inValue, inValue, inValue);
+}
+
+inline void AABB::FromMinMaxAABB (const MinMaxAABB& inAABB)
+{
+ m_Center = (inAABB.GetMax () + inAABB.GetMin ()) * 0.5F;
+ m_Extent = (inAABB.GetMax () - inAABB.GetMin ()) * 0.5F;
+}
+
+inline bool AABB::IsValid () const
+{
+ return IsFinite(m_Center) && IsFinite(m_Extent);
+}
+
+inline void MinMaxAABB::Encapsulate (const Vector3f& inPoint)
+{
+ m_Min = min (m_Min, inPoint);
+ m_Max = max (m_Max, inPoint);
+}
+
+inline void MinMaxAABB::Encapsulate (const AABB& aabb)
+{
+ Encapsulate (aabb.GetCenter()+aabb.GetExtent());
+ Encapsulate (aabb.GetCenter()-aabb.GetExtent());
+}
+
+inline void MinMaxAABB::Encapsulate (const MinMaxAABB& other)
+{
+ m_Min = min (m_Min, other.m_Min);
+ m_Max = max (m_Max, other.m_Max);
+}
+
+inline void MinMaxAABB::Expand (float inValue)
+{
+ Vector3f offset = Vector3f (inValue, inValue, inValue);
+ m_Min -= offset;
+ m_Max += offset;
+}
+
+inline void MinMaxAABB::Expand (const Vector3f& inOffset)
+{
+ m_Min -= inOffset;
+ m_Max += inOffset;
+}
+
+inline bool MinMaxAABB::IsValid () const
+{
+ return !(m_Min == Vector3f::infinityVec || m_Max == -Vector3f::infinityVec);
+}
+
+inline void MinMaxAABB::Init ()
+{
+ m_Min = Vector3f::infinityVec;
+ m_Max = -Vector3f::infinityVec;
+}
+
+inline void MinMaxAABB::FromAABB (const AABB& inAABB)
+{
+ m_Min = inAABB.GetCenter () - inAABB.GetExtent ();
+ m_Max = inAABB.GetCenter () + inAABB.GetExtent ();
+}
+template<class TransferFunction> inline
+void AABB::Transfer (TransferFunction& transfer)
+{
+ TRANSFER (m_Center);
+ TRANSFER (m_Extent);
+}
+/*template<class TransferFunction> inline
+void MinMaxAABB::Transfer (TransferFunction& transfer)
+{
+ TRANSFER (m_Min);
+ TRANSFER (m_Max);
+}*/
+
+#endif