diff --git a/CMakeLists.txt b/CMakeLists.txt index 0845e4a..9769e6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,10 @@ add_library(Math include/CVector4f.hpp include/CFrustum.hpp include/CAABox.hpp - include/COBBox.hpp) + include/COBBox.hpp + include/CLine.hpp + include/CSphere.hpp + include/CUnitVector.hpp) add_subdirectory(test) diff --git a/include/CAABox.hpp b/include/CAABox.hpp index bbe96e4..5b56afa 100644 --- a/include/CAABox.hpp +++ b/include/CAABox.hpp @@ -3,6 +3,8 @@ #include "CVector3f.hpp" #include "CTransform.hpp" +#include "CPlane.hpp" +#include "Math.hpp" #include class ZE_ALIGN(16) CAABox @@ -55,12 +57,53 @@ public: inline bool intersects(const CAABox& other) const { - if (m_max[0] < other.m_min[0]) return false; - if (m_min[0] > other.m_max[0]) return false; - if (m_max[1] < other.m_min[1]) return false; - if (m_min[1] > other.m_max[1]) return false; - if (m_max[2] < other.m_min[2]) return false; - if (m_min[2] > other.m_max[2]) return false; + bool x1 = (m_max[0] < other.m_min[0]); + bool x2 = (m_min[0] > other.m_max[0]); + bool y1 = (m_max[1] < other.m_min[1]); + bool y2 = (m_min[1] > other.m_max[1]); + bool z1 = (m_max[2] < other.m_min[2]); + bool z2 = (m_min[2] > other.m_max[2]); + return x1 && x2 && y1 && y2 && z1 && z2; + } + + inline bool inside(const CAABox& other) const + { + bool x = m_min[0] >= other.m_min[0] && m_max[0] <= other.m_max[0]; + bool y = m_min[1] >= other.m_min[1] && m_max[1] <= other.m_max[1]; + bool z = m_min[2] >= other.m_min[2] && m_max[2] <= other.m_max[2]; + return x && y && z; + } + + inline bool insidePlane(const CPlane& plane) const + { + CVector3f vmin, vmax; + /* X axis */ + if (plane.a >= 0) { + vmin[0] = m_min[0]; + vmax[0] = m_max[0]; + } else { + vmin[0] = m_max[0]; + vmax[0] = m_min[0]; + } + /* Y axis */ + if (plane.b >= 0) { + vmin[1] = m_min[1]; + vmax[1] = m_max[1]; + } else { + vmin[1] = m_max[1]; + vmax[1] = m_min[1]; + } + /* Z axis */ + if (plane.c >= 0) { + vmin[2] = m_min[2]; + vmax[2] = m_max[2]; + } else { + vmin[2] = m_max[2]; + vmax[2] = m_min[2]; + } + float dadot = plane.vec.dot(vmax); + if (dadot + plane.d < 0) + return false; return true; } @@ -68,7 +111,7 @@ public: { return (m_min + m_max) * 0.5f; } - CVector3f extents() const + CVector3f volume() const { return (m_max - m_min) * 0.5f; } @@ -113,16 +156,18 @@ public: inline CVector3f closestPointAlongVector(const CVector3f& other) { - return {(other.x >= -0.f) ? m_min.x : m_max.x, - (other.y >= -0.f) ? m_min.y : m_max.y, - (other.z >= -0.f) ? m_min.z : m_max.z}; + CVector3f center = this->center(); + return {(other.x < center.x ? m_min.x : m_max.x), + (other.y < center.y ? m_min.y : m_max.y), + (other.z < center.z ? m_min.z : m_max.z)}; } inline CVector3f furthestPointAlongVector(const CVector3f& other) { - return {(other.x >= -0.f) ? m_max.x : m_min.x, - (other.y >= -0.f) ? m_max.y : m_min.y, - (other.z >= -0.f) ? m_max.z : m_min.z}; + CVector3f center = this->center(); + return {(other.x < center.x ? m_max.x : m_min.x), + (other.y < center.y ? m_max.y : m_min.y), + (other.z < center.z ? m_max.z : m_min.z)}; } inline CVector3f getPoint(const int point) @@ -139,18 +184,9 @@ public: inline CVector3f clampToBox(const CVector3f& vec) { CVector3f ret = vec; - if (ret.x < m_min.x) - ret.x = m_min.x; - if (ret.y < m_min.y) - ret.y = m_min.y; - if (ret.z < m_min.z) - ret.z = m_min.z; - if (ret.x > m_max.x) - ret.x = m_max.x; - if (ret.y > m_max.y) - ret.y = m_max.y; - if (ret.z > m_max.z) - ret.z = m_max.z; + Math::clamp(ret.x, m_min.x, m_max.x); + Math::clamp(ret.y, m_min.y, m_max.y); + Math::clamp(ret.z, m_min.z, m_max.z); return ret; } diff --git a/include/CLine.hpp b/include/CLine.hpp new file mode 100644 index 0000000..e69de29 diff --git a/include/COBBox.hpp b/include/COBBox.hpp index 7ceaf06..da81a59 100644 --- a/include/COBBox.hpp +++ b/include/COBBox.hpp @@ -16,7 +16,7 @@ public: {} COBBox(const CAABox& aabb) - : m_extents(aabb.extents()) + : m_extents(aabb.volume()) { m_transform.m_origin = aabb.center(); } diff --git a/include/CSphere.hpp b/include/CSphere.hpp new file mode 100644 index 0000000..15dbdc1 --- /dev/null +++ b/include/CSphere.hpp @@ -0,0 +1,35 @@ +#ifndef CSPHERE_HPP +#define CSPHERE_HPP + +#include "CVector3f.hpp" + +class ZE_ALIGN(16) CSphere +{ +public: + ZE_DECLARE_ALIGNED_ALLOCATOR(); + + CSphere(const CVector3f& position, float radius) + { +#if __SSE__ + mVec128 = position.mVec128; +#endif + r = radius; + } + + inline CVector3f getSurfaceNormal(const CVector3f& coord) + { + return (vec - coord).normalized(); + } + + union + { + struct { float x, y, z, r; }; + float s[4]; + CVector3f vec; +#if __SSE__ + __m128 mVec128; +#endif + }; +}; + +#endif diff --git a/include/CTransform.hpp b/include/CTransform.hpp index a8de86f..9cc2e47 100644 --- a/include/CTransform.hpp +++ b/include/CTransform.hpp @@ -123,6 +123,7 @@ static inline CTransform CTransformFromScaleVector(const CVector3f& scale) return CTransform(CMatrix3f(scale)); } CTransform CTransformFromEditorEuler(const CVector3f& eulerVec); +CTransform CTransformFromEditorEulers(const CVector3f& eulerVec, const CVector3f& origin); CTransform CTransformFromAxisAngle(const CVector3f& axis, float angle); #endif // CTRANSFORM_HPP diff --git a/include/CVector2f.hpp b/include/CVector2f.hpp index c6a24cd..0051c2d 100644 --- a/include/CVector2f.hpp +++ b/include/CVector2f.hpp @@ -198,17 +198,26 @@ class ZE_ALIGN(16) CVector2f inline void normalize() { float mag = length(); - assert(mag != 0.0); - mag = 1.0 / mag; - *this *= mag; + if (mag > 1e-6f) + { + mag = 1.0 / mag; + *this *= mag; + } + else + zeroOut(); } + inline CVector2f normalized() const { float mag = length(); - assert(mag != 0.0); - mag = 1.0 / mag; - return *this * mag; + if (mag > 1e-6f) + { + mag = 1.0 / mag; + return *this * mag; + } + return {1, 0}; } + inline float cross(const CVector2f& rhs) const { return (x * rhs.y) - (y * rhs.x); diff --git a/include/CVector3f.hpp b/include/CVector3f.hpp index 19ae44d..cdcee6d 100644 --- a/include/CVector3f.hpp +++ b/include/CVector3f.hpp @@ -169,7 +169,7 @@ public: *this *= mag; } else - x = 1.0, y = 0.0, z = 0.0; + zeroOut(); } inline CVector3f normalized() const { @@ -179,7 +179,7 @@ public: mag = 1.0 / mag; return *this * mag; } - return {1, 0, 0}; + return {0, 0, 0}; } inline CVector3f cross(const CVector3f& rhs) const { @@ -260,6 +260,11 @@ public: return !isNormalized(); } + inline bool isZero() const + { + return lengthSquared() <= 1e-7; + } + inline void scaleToLength(float newLength) { float length = lengthSquared(); @@ -281,6 +286,12 @@ public: return v; } + inline bool isEqu(const CVector3f& other, float epsilon=1e-7f) + { + CVector3f diffVec = other - *this; + return (diffVec.x <= epsilon && diffVec.y <= epsilon && diffVec.z <= epsilon); + } + inline float& operator[](size_t idx) {return (&x)[idx];} inline const float& operator[](size_t idx) const {return (&x)[idx];} diff --git a/include/CVector4f.hpp b/include/CVector4f.hpp index ec5f4f9..d211d3a 100644 --- a/include/CVector4f.hpp +++ b/include/CVector4f.hpp @@ -222,16 +222,23 @@ class ZE_ALIGN(16) CVector4f inline void normalize() { float mag = length(); - assert(mag != 0.0); - mag = 1.0 / mag; - *this *= mag; + if (mag > 1e-6f) + { + mag = 1.0 / mag; + *this *= mag; + } + else + zeroOut(); } inline CVector4f normalized() const { float mag = length(); - assert(mag != 0.0); - mag = 1.0 / mag; - return *this * mag; + if (mag > 1e-6f) + { + mag = 1.0 / mag; + return *this * mag; + } + return {0, 0, 0, 0}; } inline float dot(const CVector4f& rhs) const diff --git a/include/Global.hpp b/include/Global.hpp index a7afb1d..638d158 100644 --- a/include/Global.hpp +++ b/include/Global.hpp @@ -11,7 +11,7 @@ # define ZE_ALIGN(x) __declspec(align(x)) # else # include -# define ZE_ALIGN(x) __attribute__((aligned(x))) +# define ZE_ALIGN(x) alignas(16) # endif # define ZE_SHUFFLE(x,y,z,w) ((w)<<6 | (z)<<4 | (y)<<2 | (x)) # define zeAlloc(sz, align) _mm_malloc(sz, align) diff --git a/include/Math.hpp b/include/Math.hpp index 41dbdd5..3d6ab70 100644 --- a/include/Math.hpp +++ b/include/Math.hpp @@ -18,15 +18,14 @@ namespace Math { template inline T clamp(T min, T val, T max) {return MAX(min, MIN(max, val));} - inline float radToDeg(float rad) {return rad * 180.f / M_PI;} inline float degToRad(float deg) {return deg * M_PI / 180;} - + extern const CVector3f kRadToDegVec; extern const CVector3f kDegToRadVec; inline CVector3f radToDeg(CVector3f rad) {return rad * kRadToDegVec;} inline CVector3f degToRad(CVector3f deg) {return deg * kDegToRadVec;} - + extern const CVector3f kUpVec; CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3f& up=kUpVec); inline CVector3f baryToWorld(const CVector3f& p0, const CVector3f& p1, const CVector3f& p2, const CVector3f& bary) diff --git a/include/MathLib.hpp b/include/MathLib.hpp index b6a48ca..7c7e323 100644 --- a/include/MathLib.hpp +++ b/include/MathLib.hpp @@ -11,10 +11,12 @@ #include "CVector2f.hpp" #include "CVector3f.hpp" #include "CVector4f.hpp" +#include "CUnitVector.hpp" #include "CRectangle.hpp" #include "CPlane.hpp" #include "CAABox.hpp" #include "COBBox.hpp" +#include "CSphere.hpp" #include "CFrustum.hpp" #include "CColor.hpp" #include "Global.hpp" diff --git a/src/CTransform.cpp b/src/CTransform.cpp index cfd727d..2340347 100644 --- a/src/CTransform.cpp +++ b/src/CTransform.cpp @@ -58,3 +58,9 @@ CTransform CTransformFromAxisAngle(const CVector3f& axis, float angle) return result; } +CTransform CTransformFromEditorEulers(const CVector3f& eulerVec, const CVector3f& origin) +{ + CTransform ret = CTransformFromEditorEuler(eulerVec); + ret.m_origin = origin; + return ret; +}