载入中...
搜索中...
未找到
SceneBounds.h
浏览该文件的文档.
1#pragma once
2
3// Internal bounds math shared between the scene module and the scene-picking
4// entry points that live in graphics (graphics/ScenePicking.cpp). This is not
5// a public API: scene is the owner of node bounds, graphics just consumes it.
6// Keeping the helpers here (instead of duplicating them in both modules) means
7// scene/Scene.cpp and graphics/ScenePicking.cpp stay in step.
8
9#include "scene/SceneHost.h"
10
11#include <glm/glm.hpp>
12
13#include <algorithm>
14#include <cmath>
15#include <limits>
16
17namespace eve::scene {
18
20struct AABB3f {
21 glm::vec3 min;
22 glm::vec3 max;
23};
24
27 glm::vec3 lo(n.bminX, n.bminY, n.bminZ);
28 glm::vec3 hi(n.bmaxX, n.bmaxY, n.bmaxZ);
29 glm::vec3 mn(std::numeric_limits<float>::max());
30 glm::vec3 mx(std::numeric_limits<float>::lowest());
31 for (int i = 0; i < 8; ++i) {
32 glm::vec3 p((i & 1) ? hi.x : lo.x, (i & 2) ? hi.y : lo.y,
33 (i & 4) ? hi.z : lo.z);
34 glm::vec4 w = n.world * glm::vec4(p, 1.f);
35 for (int c = 0; c < 3; ++c) {
36 mn[c] = std::min(mn[c], w[c]);
37 mx[c] = std::max(mx[c], w[c]);
38 }
39 }
40 return {mn, mx};
41}
42
44inline bool rayAABB(const glm::vec3 &o, const glm::vec3 &d, const AABB3f &b, float &t0,
45 float &t1) {
46 t0 = -std::numeric_limits<float>::max();
47 t1 = std::numeric_limits<float>::max();
48 for (int axis = 0; axis < 3; ++axis) {
49 const float oa = o[axis];
50 const float da = d[axis];
51 const float mn = b.min[axis];
52 const float mx = b.max[axis];
53 if (std::fabs(da) < 1e-12f) {
54 if (oa < mn || oa > mx) return false;
55 } else {
56 const float inv = 1.f / da;
57 float tA = (mn - oa) * inv;
58 float tB = (mx - oa) * inv;
59 if (tA > tB) std::swap(tA, tB);
60 t0 = std::max(t0, tA);
61 t1 = std::min(t1, tB);
62 if (t0 > t1) return false;
63 }
64 }
65 return true;
66}
67
68inline bool cornerInsideClip(const glm::mat4 &m, const glm::vec3 &p) {
69 const glm::vec4 c = m * glm::vec4(p, 1.f);
70 return c.w > 1e-8f && std::fabs(c.x) <= c.w && std::fabs(c.y) <= c.w &&
71 c.z >= 0.f && c.z <= c.w;
72}
73
75inline bool aabbIntersectsFrustum(const glm::mat4 &clip, const glm::mat4 &invClip,
76 const AABB3f &b) {
77 for (int i = 0; i < 8; ++i) {
78 const glm::vec3 p((i & 1) ? b.max.x : b.min.x, (i & 2) ? b.max.y : b.min.y,
79 (i & 4) ? b.max.z : b.min.z);
80 if (cornerInsideClip(clip, p)) return true;
81 }
82 for (int i = 0; i < 8; ++i) {
83 const glm::vec3 ndc((i & 1) ? 1.f : -1.f, (i & 2) ? 1.f : -1.f,
84 (i & 4) ? 1.f : 0.f);
85 const glm::vec4 w = invClip * glm::vec4(ndc, 1.f);
86 if (std::fabs(w.w) < 1e-8f) continue;
87 const glm::vec3 q = glm::vec3(w) / w.w;
88 if (q.x >= b.min.x && q.x <= b.max.x && q.y >= b.min.y && q.y <= b.max.y &&
89 q.z >= b.min.z && q.z <= b.max.z) {
90 return true;
91 }
92 }
93 return false;
94}
95
96} // namespace eve::scene
glm::vec3 n
Definition Grass.cpp:64
int w
uint32_t b
uint32_t c
glm::vec4 p[6]
int d
float m[16]
bool aabbIntersectsFrustum(const glm::mat4 &clip, const glm::mat4 &invClip, const AABB3f &b)
Conservative AABB ↔ frustum overlap (AABB corners + frustum corners).
Definition SceneBounds.h:75
bool cornerInsideClip(const glm::mat4 &m, const glm::vec3 &p)
Definition SceneBounds.h:68
bool rayAABB(const glm::vec3 &o, const glm::vec3 &d, const AABB3f &b, float &t0, float &t1)
Slab ray-AABB intersection; fills entry/exit t (t0 <= t1).
Definition SceneBounds.h:44
AABB3f worldBoundsOf(const SceneNode &n)
World-space AABB of a node's local bounds (8 corners through world matrix).
Definition SceneBounds.h:26
Axis-aligned box in world space.
Definition SceneBounds.h:20
Retained scene node (arena). Conceptual GameObject; isomorphic to eve::ui::UINode.
Definition SceneHost.h:39