#pragma once #include "config/types.h" #include "ray.h" #include #include #include #include class GeometricPlane { public: enum class PlaneRelation { Above, Below, On }; static bool isIntersect(PlaneRelation a, PlaneRelation b); }; template class GeometricPlaneT : public GeometricPlane { public: GeometricPlaneT() = default; GeometricPlaneT(PositionType origin, Normal3D normal) : origin(std::move(origin)), normal(normal) { } struct DistAndPosition { PositionType::value_type dist; PositionType position; }; PositionType origin {}; Normal3D normal {}; [[nodiscard]] inline PlaneRelation getRelation(PositionType point) const { const auto d = glm::dot(normal, RelativePosition3D(point - origin)); return d < 0.F ? PlaneRelation::Below : d > 0.F ? PlaneRelation::Above : PlaneRelation::On; } [[nodiscard]] inline std::optional getRayIntersectPosition(const Ray & ray) const { float dist {}; if (!glm::intersectRayPlane(ray.start, ray.direction, origin, normal, dist)) { return {}; } return DistAndPosition {dist, ray.start + (ray.direction * dist)}; } };