#pragma once #include #include "zeus/CVector3f.hpp" #include "zeus/Global.hpp" #include "zeus/Math.hpp" namespace zeus { class CPlane { public: constexpr CPlane() : mSimd(1.f, 0.f, 0.f, 0.f) {} constexpr CPlane(float a, float b, float c, float d) : mSimd(a, b, c, d) {} CPlane(const CVector3f& a, const CVector3f& b, const CVector3f& c) { mSimd = (b - a).cross(c - a).normalized().mSimd; mSimd[3] = a.dot(normal()); } CPlane(const CVector3f& point, float displacement) { mSimd = point.mSimd; mSimd[3] = displacement; } [[nodiscard]] float clipLineSegment(const CVector3f& a, const CVector3f& b) { const float mag = (b - a).dot(normal()); const float dis = (-(y() - d())) / mag; return clamp(0.0f, dis, 1.0f); } void normalize() { float nd = d(); auto norm = normal(); float mag = norm.magnitude(); mag = 1.f / mag; mSimd = (norm * mag).mSimd; mSimd[3] = nd * mag; } [[nodiscard]] float pointToPlaneDist(const CVector3f& pos) const { return normal().dot(pos) - d(); } [[nodiscard]] bool rayPlaneIntersection(const CVector3f& from, const CVector3f& to, CVector3f& point) const; [[nodiscard]] CVector3f normal() const { return mSimd; } [[nodiscard]] zeus::simd::reference operator[](size_t idx) { assert(idx < 4); return mSimd[idx]; } [[nodiscard]] float operator[](size_t idx) const { assert(idx < 4); return mSimd[idx]; } [[nodiscard]] float x() const { return mSimd[0]; } [[nodiscard]] float y() const { return mSimd[1]; } [[nodiscard]] float z() const { return mSimd[2]; } [[nodiscard]] float d() const { return mSimd[3]; } [[nodiscard]] simd::reference x() { return mSimd[0]; } [[nodiscard]] simd::reference y() { return mSimd[1]; } [[nodiscard]] simd::reference z() { return mSimd[2]; } [[nodiscard]] simd::reference d() { return mSimd[3]; } zeus::simd mSimd; }; } // namespace zeus