载入中...
搜索中...
未找到
SceneCameraQueries.cpp
浏览该文件的文档.
1// Picking / culling entry points whose camera math belongs to graphics.
2//
3// The traversal and mutation stay here because the scene owns them; only the
4// screen ray and the clip matrix come from the ISceneCameraProjection
5// capability (graphics/ScenePicking.cpp registers it). Querying a capability
6// instead of calling graphics keeps this module free of an upward include while
7// still defining these symbols in scene, which a per-layer DLL split needs:
8// graphics (L4) cannot be imported by scene (L1).
9//
10// Split out of Scene.cpp (already past the ~1000 line limit) rather than
11// appended to it.
12
13#include "scene/Scene.h"
14
15#include "common/Capability.h"
16#include "scene/SceneBounds.h"
18#include "scene/SceneHost.h"
19
20#include <algorithm>
21#include <cmath>
22#include <string>
23#include <utility>
24#include <vector>
25
26namespace eve::scene {
27
28std::string Scene::pickScreenAt(const std::string &hostName, graphics::Camera3D *cam, float screenX, float screenY,
29 float viewW, float viewH) const {
30 if (!cam) return {};
31 auto *projection = eve::cap::query<ISceneCameraProjection>();
32 if (!projection) return {};
33 const auto ray = projection->screenRay(*cam, screenX, screenY, viewW, viewH);
34 if (!ray) return {};
35 return pickRayAt(hostName, ray->origin.x, ray->origin.y, ray->origin.z, ray->direction.x, ray->direction.y,
36 ray->direction.z);
37}
38
39std::vector<std::string> Scene::collectFrustumIdsAt(const std::string &hostName, graphics::Camera3D *cam, float viewW,
40 float viewH) const {
41 SceneHost *h = resolveHost(hostName);
42 std::vector<std::string> out;
43 if (!h || !cam || viewW <= 0.f || viewH <= 0.f) return out;
44 auto *projection = eve::cap::query<ISceneCameraProjection>();
45 if (!projection) return out;
46 const auto clip = projection->clipForViewport(*cam, viewW, viewH);
47 if (!clip) return out;
48
49 h->walkDepthFirst([&](SceneHost *, int, SceneNode &n) {
50 if (!n.hasBounds) return;
51 if (aabbIntersectsFrustum(clip->clip, clip->inverse, worldBoundsOf(n))) {
52 out.push_back(n.id);
53 }
54 });
55 return out;
56}
57
58Result<int> Scene::applyPcgTerrainCullingAt(const std::string &hostName, graphics::Camera3D *cam, float viewW,
59 float viewH, const std::string &tag) {
60 SceneHost *host = resolveHost(hostName);
61 if (!host || !cam || !std::isfinite(viewW) || !std::isfinite(viewH) || viewW <= 0.f || viewH <= 0.f || tag.empty())
63 DiagnosticCode::InvalidArgument, "Pcg terrain culling requires host, camera, positive viewport and tag",
64 "scene.pcgTerrainCulling"));
65 auto *projection = eve::cap::query<ISceneCameraProjection>();
66 if (!projection)
68 DiagnosticCode::Unsupported, "Pcg terrain culling needs the graphics camera projection capability",
69 "scene.pcgTerrainCulling"));
70 const auto clip = projection->clipForViewport(*cam, viewW, viewH);
71 if (!clip)
73 "Pcg terrain culling requires a usable camera viewport",
74 "scene.pcgTerrainCulling"));
75
76 std::vector<std::pair<std::string, bool>> changes;
77 host->walkDepthFirst([&](SceneHost *, int, SceneNode &node) {
78 if (!node.hasBounds || std::find(node.tags.begin(), node.tags.end(), tag) == node.tags.end()) return;
79 const bool visible = aabbIntersectsFrustum(clip->clip, clip->inverse, worldBoundsOf(node));
80 if (node.visible != visible) changes.emplace_back(node.id, visible);
81 });
82 for (const auto &[id, visible] : changes) {
83 auto node = host->findById(id);
84 if (!node) continue;
85 node.value()->visible = visible;
86 host->markSubtreeDirtyById(id);
87 }
88 return Result<int>::success(static_cast<int>(changes.size()));
89}
90
91} // namespace eve::scene
glm::vec4 clip
glm::vec3 n
Definition Grass.cpp:63
int h
const std::string * tag
const RoadNode * node
bool visible
UIHostHandle host
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
EVENGINE_API_BACKENDS public API.
ECS mount point for one scene graph (full scene or nested subtree root). Isomorphic to eve::ui::UIHos...
Definition SceneHost.h:89
SceneHost * resolveHost(const std::string &hostName) const
Host-qualified resolution: empty hostName → currently selected host.
Definition Scene.cpp:948
std::string pickScreenAt(const std::string &hostName, graphics::Camera3D *cam, float screenX, float screenY, float viewW, float viewH) const
Screen-space picking through a Camera3D (camera.screenToRay).
Result< int > applyPcgTerrainCullingAt(const std::string &hostName, graphics::Camera3D *cam, float viewW, float viewH, const std::string &tag)
Apply PcgScenePlayer frustum visibility to bounded nodes carrying a tag.
std::vector< std::string > collectFrustumIdsAt(const std::string &hostName, graphics::Camera3D *cam, float viewW, float viewH) const
Ids of nodes whose world AABB intersects the camera frustum.
std::string pickRayAt(const std::string &hostName, float ox, float oy, float oz, float dx, float dy, float dz) const
Nearest node id hit by a world ray (nodes with bounds), or "".
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
AABB3f worldBoundsOf(const SceneNode &n)
World-space AABB of a node's local bounds (8 corners through world matrix).
Definition SceneBounds.h:26
Retained scene node (arena). Conceptual GameObject; isomorphic to eve::ui::UINode.
Definition SceneHost.h:46