载入中...
搜索中...
未找到
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
28 glm::vec3 lo(n.bminX, n.bminY, n.bminZ);
30 glm::vec3 hi(n.bmaxX, n.bmaxY, n.bmaxZ);
32 glm::vec3 mn(std::numeric_limits<float>::max());
34 glm::vec3 mx(std::numeric_limits<float>::lowest());
35 for (int i = 0; i < 8; ++i) {
37 glm::vec3 p((i & 1) ? hi.x : lo.x, (i & 2) ? hi.y : lo.y,
38 (i & 4) ? hi.z : lo.z);
39 glm::vec4 w = n.world * glm::vec4(p, 1.f);
40 for (int c = 0; c < 3; ++c) {
41 mn[c] = std::min(mn[c], w[c]);
42 mx[c] = std::max(mx[c], w[c]);
43 }
44 }
45 return {mn, mx};
46}
47
49inline bool rayAABB(const glm::vec3 &o, const glm::vec3 &d, const AABB3f &b, float &t0,
50 float &t1) {
51 t0 = -std::numeric_limits<float>::max();
52 t1 = std::numeric_limits<float>::max();
53 for (int axis = 0; axis < 3; ++axis) {
54 const float oa = o[axis];
55 const float da = d[axis];
56 const float mn = b.min[axis];
57 const float mx = b.max[axis];
58 if (std::fabs(da) < 1e-12f) {
59 if (oa < mn || oa > mx) return false;
60 } else {
61 const float inv = 1.f / da;
62 float tA = (mn - oa) * inv;
63 float tB = (mx - oa) * inv;
64 if (tA > tB) std::swap(tA, tB);
65 t0 = std::max(t0, tA);
66 t1 = std::min(t1, tB);
67 if (t0 > t1) return false;
68 }
69 }
70 return true;
71}
72
74inline bool cornerInsideClip(const glm::mat4 &m, const glm::vec3 &p) {
75 const glm::vec4 c = m * glm::vec4(p, 1.f);
76 return c.w > 1e-8f && std::fabs(c.x) <= c.w && std::fabs(c.y) <= c.w &&
77 c.z >= 0.f && c.z <= c.w;
78}
79
81inline bool aabbIntersectsFrustum(const glm::mat4 &clip, const glm::mat4 &invClip,
82 const AABB3f &b) {
83 for (int i = 0; i < 8; ++i) {
85 const glm::vec3 p((i & 1) ? b.max.x : b.min.x, (i & 2) ? b.max.y : b.min.y,
86 (i & 4) ? b.max.z : b.min.z);
87 if (cornerInsideClip(clip, p)) return true;
88 }
89 for (int i = 0; i < 8; ++i) {
91 const glm::vec3 ndc((i & 1) ? 1.f : -1.f, (i & 2) ? 1.f : -1.f,
92 (i & 4) ? 1.f : 0.f);
93 const glm::vec4 w = invClip * glm::vec4(ndc, 1.f);
94 if (std::fabs(w.w) < 1e-8f) continue;
95 const glm::vec3 q = glm::vec3(w) / w.w;
96 if (q.x >= b.min.x && q.x <= b.max.x && q.y >= b.min.y && q.y <= b.max.y &&
97 q.z >= b.min.z && q.z <= b.max.z) {
98 return true;
99 }
100 }
101 return false;
102}
103
104} // namespace eve::scene
float w
Definition AnimClip.cpp:738
glm::vec4 p[6]
glm::vec4 clip
glm::vec3 n
Definition Grass.cpp:63
std::array< double, 10 > q
std::int32_t c
MeleePoint3 b
Definition MeleeHit.cpp:41
float 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:81
bool cornerInsideClip(const glm::mat4 &m, const glm::vec3 &p)
Corner inside clip.
Definition SceneBounds.h:74
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:49
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:46