vkmEngine 1.0.0
A C++ game engine · vkmengine.com
Loading...
Searching...
No Matches
bounds.h
1#pragma once
2
3#include <glm/glm.hpp>
4
5namespace Vkm::Engine::Math {
6
7// Minimum squared extent for a valid AABB (1e-4 squared). glm::epsilon is too
8// small for world coordinates in [-1000, 1000].
9inline constexpr float BOUNDS_EPSILON_SQ = 1e-8f;
10
14struct AABB {
15 glm::vec3 min{0.0f};
16 glm::vec3 max{0.0f};
17
23 bool valid() const noexcept {
24 const glm::vec3 extent = max - min;
25 return glm::dot(extent, extent) > BOUNDS_EPSILON_SQ;
26 }
27
28 glm::vec3 center() const noexcept { return (min + max) * 0.5f; }
29
30 glm::vec3 halfExtent() const noexcept { return (max - min) * 0.5f; }
31};
32
40inline AABB transform(const glm::mat4& matrix, const AABB& local) {
41 AABB world;
42 world.min = glm::vec3(matrix[3]);
43 world.max = glm::vec3(matrix[3]);
44
45 for (int j = 0; j < 3; ++j) {
46 const glm::vec3 col(matrix[j]);
47 const glm::vec3 a = col * local.min[j];
48 const glm::vec3 b = col * local.max[j];
49 world.min += glm::min(a, b);
50 world.max += glm::max(a, b);
51 }
52 return world;
53}
54
58struct Ray {
59 glm::vec3 origin{0.0f};
60 glm::vec3 direction{0.0f, 0.0f, -1.0f};
61};
62
73inline Ray rayThroughNdc(const glm::mat4& invViewProj, const glm::vec2& ndc) {
74 glm::vec4 nearPoint = invViewProj * glm::vec4(ndc, -1.0f, 1.0f);
75 glm::vec4 farPoint = invViewProj * glm::vec4(ndc, 1.0f, 1.0f);
76 nearPoint /= nearPoint.w;
77 farPoint /= farPoint.w;
78 return Ray{glm::vec3(nearPoint), glm::normalize(glm::vec3(farPoint - nearPoint))};
79}
80
91inline bool rayIntersectsAABB(
92 const glm::vec3& origin,
93 const glm::vec3& invDir,
94 const AABB& box,
95 float& tHit
96) noexcept {
97 const glm::vec3 t0 = (box.min - origin) * invDir;
98 const glm::vec3 t1 = (box.max - origin) * invDir;
99
100 const glm::vec3 tMinV = glm::min(t0, t1);
101 const glm::vec3 tMaxV = glm::max(t0, t1);
102
103 float tMin = glm::max(glm::max(tMinV.x, tMinV.y), tMinV.z);
104 float tMax = glm::min(glm::min(tMaxV.x, tMaxV.y), tMaxV.z);
105
106 // Inside the box tMin is behind, so the hit is the exit; a negative tMin would
107 // let a box enclosing the camera undercut every genuine hit in a ranking.
108 tHit = tMin > 0.0f ? tMin : tMax;
109 return tMax >= tMin && tMax >= 0.0f;
110}
111
112} // namespace Vkm::Engine::Math
An axis-aligned box.
Definition bounds.h:14
bool valid() const noexcept
True when the box has non-degenerate extent.
Definition bounds.h:23
A half-line in world space.
Definition bounds.h:58
glm::vec3 direction
Unit length.
Definition bounds.h:60