#ifndef BLANK_GEOMETRY_PRIMITIVE_HPP_
#define BLANK_GEOMETRY_PRIMITIVE_HPP_
+#include "../graphics/glm.hpp"
+
#include <algorithm>
#include <iosfwd>
-#include <glm/glm.hpp>
+#include <glm/gtx/norm.hpp>
namespace blank {
/// return distance between origin and farthest vertex
float OriginRadius() const noexcept {
- glm::vec3 high(glm::max(abs(min), abs(max)));
- return length(high);
+ glm::vec3 high(glm::max(glm::abs(min), glm::abs(max)));
+ return glm::length(high);
}
};
std::ostream &operator <<(std::ostream &, const AABB &);
+// TODO: this should really use setters/getters for dir and inv_dir so
+// manipulating code doesn't "forget" to call Update()
struct Ray {
glm::vec3 orig;
glm::vec3 dir;
+
+ glm::vec3 inv_dir;
+
+ void Update() noexcept {
+ inv_dir = 1.0f / dir;
+ }
+
+ /// get shortest distance of this ray's line to given point
+ float Distance(const glm::vec3 &point) const noexcept {
+ // d = |(x2-x1)×(x1-x0)|/|x2-x1|
+ // where x0 is point, and x1 and x2 are points on the line
+ // for derivation, see http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
+ // x1 = orig
+ // x2-x1 = dir, which means |x2-x1| is 1.0
+ return glm::length(glm::cross(dir, orig - point));
+ }
+ float DistanceSquared(const glm::vec3 &point) const noexcept {
+ return glm::length2(glm::cross(dir, orig - point));
+ }
};
std::ostream &operator <<(std::ostream &, const Ray &);
+/// axis aligned boolean ray/box intersection test
+/// if true, dist constains distance from ray's origin to intersection point
+bool Intersection(
+ const Ray &,
+ const AABB &,
+ float &dist) noexcept;
+
+/// detailed oriented ray/box intersection test
bool Intersection(
const Ray &,
const AABB &,
: normal(abcd), dist(abcd.w) { }
void Normalize() noexcept {
- const float l = length(normal);
+ const float l = glm::length(normal);
normal /= l;
dist /= l;
}