blob: 30ed6ead185382727d3cad3c36d5ecbedd495dab [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_ESCHER_GEOMETRY_INTERSECTION_H_
#define LIB_ESCHER_GEOMETRY_INTERSECTION_H_
#include <cfloat>
#include "lib/escher/geometry/bounding_box.h"
#include "lib/escher/geometry/types.h"
namespace escher {
// Returns whether a ray intersects an axis-aligned bounding box. Upon return,
// |out_distance| contains the distance from the ray origin to the intersection
// point in units of ray length.
bool IntersectRayBox(const escher::ray4& ray, const escher::BoundingBox& box,
float* out_distance);
// Return the distance from the ray origin to the intersection point in units
// of ray length, or FLT_MAX if the line and plane are (nearly) parallel. This
// can be used to test line, ray, and line-segment intersection:
// - lines intersect the plane when the return value is < FLT_MAX.
// - rays intersect when the return value is >= 0 and < FLT_MAX.
// - line segments intersect when the return value is >= 0 and <= 1.
template <typename VecT>
float IntersectLinePlane(const VecT& ray_origin, const VecT& ray_direction,
const planeN<VecT>& plane) {
float denominator = glm::dot(ray_direction, plane.dir());
return std::abs(denominator) <
kEpsilon * glm::dot(ray_direction, ray_direction)
? FLT_MAX
: (plane.dist() - glm::dot(ray_origin, plane.dir())) / denominator;
}
} // namespace escher
#endif // LIB_ESCHER_GEOMETRY_INTERSECTION_H_