载入中...
搜索中...
未找到
ScenePicking.cpp
浏览该文件的文档.
1// Scene picking entry points that need a complete Camera3D.
2//
3// scene/Scene.cpp used to implement pickScreenAt / collectFrustumIdsAt, which
4// forced scene (L1) to include graphics headers (L3) — an upward dependency.
5// The two entry points still belong to the Scene script API, but the camera
6// projection they need is graphics' business, so the implementations live
7// here, in the graphics module (graphics -> scene is a legal downward edge).
8// The file is excluded from the build when scene is disabled (same rule as
9// SceneLinks.cpp), so graphics keeps working without scene.
10
11#include "graphics/ClipSpace.h"
13#include "scene/Scene.h"
14#include "scene/SceneBounds.h"
15
16#include <glm/gtc/matrix_transform.hpp>
17
18#include <limits>
19#include <string>
20#include <vector>
21
22namespace eve::scene {
23
24std::string Scene::pickScreenAt(const std::string &hostName, graphics::Camera3D *cam,
25 float screenX, float screenY, float viewW,
26 float viewH) const {
27 if (!cam) return {};
28 cam->screenToRay(screenX, screenY, viewW, viewH);
29 return pickRayAt(hostName, cam->getScreenRayOriginX(), cam->getScreenRayOriginY(),
31 cam->getScreenRayDirY(), cam->getScreenRayDirZ());
32}
33
34std::vector<std::string> Scene::collectFrustumIdsAt(const std::string &hostName,
35 graphics::Camera3D *cam, float viewW,
36 float viewH) const {
37 SceneHost *h = resolveHost(hostName);
38 std::vector<std::string> out;
39 if (!h || !cam || viewW <= 0.f || viewH <= 0.f) return out;
40 auto d = cam->data();
41 const glm::vec3 eye(d->eyeX, d->eyeY, d->eyeZ);
42 const glm::vec3 target(d->targetX, d->targetY, d->targetZ);
43 const glm::vec3 up(d->upX, d->upY, d->upZ);
44 const glm::mat4 viewM = glm::lookAtRH(eye, target, up);
45 const glm::mat4 projM =
46 graphics::perspectiveVulkanRH_ZO(glm::radians(d->fovYDeg), viewW / viewH,
47 d->nearZ, d->farZ);
48 const glm::mat4 clip = projM * viewM;
49 const glm::mat4 invClip = glm::inverse(clip);
50
51 h->walkDepthFirst([&](SceneHost *, int, SceneNode &n) {
52 if (!n.hasBounds) return;
53 if (aabbIntersectsFrustum(clip, invClip, worldBoundsOf(n))) {
54 out.push_back(n.id);
55 }
56 });
57 return out;
58}
59
60} // namespace eve::scene
glm::vec3 n
Definition Grass.cpp:64
int h
glm::vec3 eye
int d
void screenToRay(float screenX, float screenY, float viewW, float viewH)
Build a world-space picking ray from a screen pixel. Stores origin (camera eye) and normalized direct...
ECS mount point for one scene graph (full scene or nested subtree root). Isomorphic to eve::ui::UIHos...
Definition SceneHost.h:80
SceneHost * resolveHost(const std::string &hostName) const
Host-qualified resolution: empty hostName → currently selected host.
Definition Scene.cpp:807
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).
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 "".
glm::mat4 perspectiveVulkanRH_ZO(float fovyRad, float aspect, float zNear, float zFar)
Right-handed, zero-to-one depth perspective for Vulkan swapchains.
Definition ClipSpace.h:20
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
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:39