blob: a49bff0b580149a32c7eafb86a11de91c1d4b6fa [file] [log] [blame]
// Copyright 2016 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_TYPES_H_
#define LIB_ESCHER_GEOMETRY_TYPES_H_
#if defined(countof)
// Workaround for compiler error due to Zircon defining countof() as a macro.
// Redefines countof() using GLM_COUNTOF(), which currently provides a more
// sophisticated implementation anyway.
#undef countof
#include <glm/glm.hpp>
#define countof(X) GLM_COUNTOF(X)
#else
// No workaround required.
#include <glm/glm.hpp>
#endif
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/transform.hpp>
#include "lib/escher/util/debug_print.h"
#include "lib/fxl/logging.h"
namespace escher {
using glm::mat2;
using glm::mat3;
using glm::mat4;
using glm::quat;
using glm::vec2;
using glm::vec3;
using glm::vec4;
ESCHER_DEBUG_PRINTABLE(vec2);
ESCHER_DEBUG_PRINTABLE(vec3);
ESCHER_DEBUG_PRINTABLE(vec4);
ESCHER_DEBUG_PRINTABLE(mat2);
ESCHER_DEBUG_PRINTABLE(mat3);
ESCHER_DEBUG_PRINTABLE(mat4);
ESCHER_DEBUG_PRINTABLE(quat);
// A ray with an origin and a direction of travel.
struct ray4 {
// The ray's origin point in space.
// Must be homogeneous (last component must be non-zero).
glm::vec4 origin;
// The ray's direction vector in space.
// Last component must be zero.
glm::vec4 direction;
};
// Used to compare whether two values are nearly equal.
constexpr float kEpsilon = 0.000001f;
inline ray4 operator*(const glm::mat4& matrix, const ray4& ray) {
return ray4{matrix * ray.origin, matrix * ray.direction};
}
// Oriented plane described by a normal vector and a distance from the origin
// along that vector.
template <typename VecT>
struct planeN {
using VectorType = VecT;
// Default constructor.
planeN() : dir_(0.f), dist_(0.f) { dir_.x = 1.f; }
// |direction| must be normalized.
planeN(VecT direction, float distance) : dir_(direction), dist_(distance) {
FXL_DCHECK(std::abs(glm::dot(direction, direction) - 1.f) < kEpsilon);
}
planeN(VecT point_on_plane, VecT direction)
: dir_(direction), dist_(glm::dot(point_on_plane, direction)) {
FXL_DCHECK(std::abs(glm::dot(direction, direction) - 1.f) < kEpsilon);
}
planeN(const planeN& other) : dir_(other.dir_), dist_(other.dist_) {}
bool operator==(const planeN<VecT>& other) const {
return dir_ == other.dir_ && dist_ == other.dist_;
}
const VecT& dir() const { return dir_; }
float dist() const { return dist_; }
private:
VecT dir_;
float dist_;
};
struct plane2 : public planeN<vec2> {
using planeN::planeN;
plane2(const vec3& direction, float distance)
: planeN<vec2>(vec2(direction), distance) {
// We only want to construct plane2 instead of plane3 when no info will be
// lost. It is up to the caller to guarantee that z == 0.
FXL_DCHECK(direction.z == 0);
}
};
struct plane3 : public planeN<vec3> {
using planeN::planeN;
explicit plane3(const plane2& p)
: planeN<vec3>(vec3(p.dir(), 0.f), p.dist()) {}
};
ESCHER_DEBUG_PRINTABLE(plane2);
ESCHER_DEBUG_PRINTABLE(plane3);
} // namespace escher
#endif // LIB_ESCHER_GEOMETRY_TYPES_H_