diff options
Diffstat (limited to 'Common/interface')
| -rw-r--r-- | Common/interface/AdvancedMath.hpp | 34 | ||||
| -rw-r--r-- | Common/interface/BasicMath.hpp | 14 |
2 files changed, 48 insertions, 0 deletions
diff --git a/Common/interface/AdvancedMath.hpp b/Common/interface/AdvancedMath.hpp index ee72217b..23160554 100644 --- a/Common/interface/AdvancedMath.hpp +++ b/Common/interface/AdvancedMath.hpp @@ -427,6 +427,40 @@ inline void GetFrustumMinimumBoundingSphere(float Proj_00, // cot(HorzFOV / } } +/// Intersects a ray with the axis-aligned bounding box and returns distances to intersections +inline bool IntersectRayAABB(const float3& RayOrigin, + const float3& RayDirection, + BoundBox AABB, + float& EnterDist, + float& ExitDist) +{ + AABB.Min -= RayOrigin; + AABB.Max -= RayOrigin; + + static constexpr float Epsilon = 1e-20f; + + float3 AbsRayDir = abs(RayDirection); + float3 t_min // + { + AbsRayDir.x > Epsilon ? AABB.Min.x / RayDirection.x : +FLT_MAX, + AbsRayDir.y > Epsilon ? AABB.Min.y / RayDirection.y : +FLT_MAX, + AbsRayDir.z > Epsilon ? AABB.Min.z / RayDirection.z : +FLT_MAX // + }; + float3 t_max // + { + AbsRayDir.x > Epsilon ? AABB.Max.x / RayDirection.x : -FLT_MAX, + AbsRayDir.y > Epsilon ? AABB.Max.y / RayDirection.y : -FLT_MAX, + AbsRayDir.z > Epsilon ? AABB.Max.z / RayDirection.z : -FLT_MAX // + }; + + EnterDist = max3(std::min(t_min.x, t_max.x), std::min(t_min.y, t_max.y), std::min(t_min.z, t_max.z)); + ExitDist = min3(std::max(t_min.x, t_max.x), std::max(t_min.y, t_max.y), std::max(t_min.z, t_max.z)); + + // if ExitDist < 0, the ray intersects AABB, but the whole AABB is behind it + // if EnterDist > ExitDist, the ray doesn't intersect AABB + return ExitDist >= 0 && EnterDist <= ExitDist; +} + } // namespace Diligent namespace std diff --git a/Common/interface/BasicMath.hpp b/Common/interface/BasicMath.hpp index d28ee9ab..81f646fb 100644 --- a/Common/interface/BasicMath.hpp +++ b/Common/interface/BasicMath.hpp @@ -1907,8 +1907,22 @@ T SmoothStep(T Left, T Right, T w) return t * t * (static_cast<T>(3) - static_cast<T>(2) * t); } +template <typename T> +T max3(const T& x, const T& y, const T& z) +{ + return std::max(std::max(x, y), z); +} + +template <typename T> +T min3(const T& x, const T& y, const T& z) +{ + return std::min(std::min(x, y), z); +} + } // namespace Diligent + + namespace std { template <typename T> |
