#include "geometry.hpp"
#include <limits>
+#include <glm/gtx/matrix_cross_product.hpp>
+#include <glm/gtx/optimum_pow.hpp>
+#include <glm/gtx/transform.hpp>
namespace blank {
+glm::mat3 find_rotation(const glm::vec3 &a, const glm::vec3 &b) noexcept {
+ glm::vec3 v(cross(a, b));
+ if (iszero(v)) {
+ // a and b are parallel
+ if (iszero(a - b)) {
+ // a and b are identical
+ return glm::mat3(1.0f);
+ } else {
+ // a and b are opposite
+ // create arbitrary unit vector perpendicular to a and
+ // rotate 180° around it
+ glm::vec3 arb(a);
+ if (std::abs(a.x - 1.0f) > std::numeric_limits<float>::epsilon()) {
+ arb.x += 1.0f;
+ } else {
+ arb.y += 1.0f;
+ }
+ glm::vec3 axis(normalize(cross(a, arb)));
+ return glm::mat3(glm::rotate(PI, axis));
+ }
+ }
+ float mv = length_squared(v);
+ float c = dot(a, b);
+ float f = (1 - c) / mv;
+ glm::mat3 vx(matrixCross3(v));
+ return glm::mat3(1.0f) + vx + (pow2(vx) * f);
+}
+
bool Intersection(
const Ray &ray,
const AABB &aabb,
*dist = t_min;
}
if (normal) {
- glm::vec4 norm(0.0f);
if (min_all.x > min_all.y) {
if (min_all.x > min_all.z) {
- norm.x = t2.x < t1.x ? 1 : -1;
+ normal->x = t2.x < t1.x ? 1 : -1;
} else {
- norm.z = t2.z < t1.z ? 1 : -1;
+ normal->z = t2.z < t1.z ? 1 : -1;
}
} else if (min_all.y > min_all.z) {
- norm.y = t2.y < t1.y ? 1 : -1;
+ normal->y = t2.y < t1.y ? 1 : -1;
} else {
- norm.z = t2.z < t1.z ? 1 : -1;
+ normal->z = t2.z < t1.z ? 1 : -1;
}
- norm = M * norm;
- *normal = glm::vec3(norm);
}
return true;
}
const AABB &a_box,
const glm::mat4 &a_m,
const AABB &b_box,
- const glm::mat4 &b_m
+ const glm::mat4 &b_m,
+ float &depth,
+ glm::vec3 &normal
) noexcept {
glm::vec3 a_corners[8] = {
glm::vec3(a_m * glm::vec4(a_box.min.x, a_box.min.y, a_box.min.z, 1)),
glm::vec3(b_m * glm::vec4(0, 0, 1, 0)),
};
+ depth = std::numeric_limits<float>::infinity();
+ int min_axis = 0;
+
+ int cur_axis = 0;
for (const glm::vec3 &axis : axes) {
float a_min = std::numeric_limits<float>::infinity();
float a_max = -std::numeric_limits<float>::infinity();
}
if (a_max < b_min || b_max < a_min) return false;
- }
- // TODO: find intersection point and normals
- // normal could be deduced from the axis with the lowest min?
+ float overlap = std::min(a_max, b_max) - std::max(a_min, b_min);
+ if (overlap < depth) {
+ depth = overlap;
+ min_axis = cur_axis;
+ }
+
+ ++cur_axis;
+ }
+ normal = axes[min_axis];
return true;
}