载入中...
搜索中...
未找到
SceneHost.h
浏览该文件的文档.
1#pragma once
2
3#include "common/ECS.h"
4
5#include <cstdint>
6#include <functional>
7#include <string>
8#include <unordered_map>
9#include <utility>
10#include <vector>
11
12#include <glm/mat4x4.hpp>
13
14#include "scene/NodeDesc.h"
15#include "scene/SceneLink.h"
16
17// Only pointers to these cross the interface, so a forward declaration is
18// enough: scene links carry them as void* and the owning module does the casts.
19namespace eve::graphics {
20class Renderable2D;
21class Renderable3D;
22class Camera3D;
23}
24
25namespace eve::physics {
26class Body;
27class Body3D;
28}
29
30namespace eve::audio {
31class Source;
32}
33
34namespace eve::scene {
35
39struct SceneNode {
40 std::string id;
41 std::string key;
42 std::string name;
43 std::string space = "3d"; // "2d" | "3d"
44 bool visible = true;
46 std::vector<std::string> tags;
47 int layer = 0;
49 float bminX = 0.f, bminY = 0.f, bminZ = 0.f;
50 float bmaxX = 0.f, bmaxY = 0.f, bmaxZ = 0.f;
51 bool hasBounds = false;
52
53 float x = 0.f, y = 0.f, z = 0.f;
54 float yaw = 0.f, pitch = 0.f, roll = 0.f;
55 float sx = 1.f, sy = 1.f, sz = 1.f;
56
57 bool localDirty = true;
59 bool subtreeDirty = true;
60 glm::mat4 world{1.f};
61
63 std::vector<SceneLink> links;
64
66 uint32_t objectId = 0;
67
68 int firstChild = -1;
69 int nextSibling = -1;
70 int parent = -1;
71};
72
75
80class SceneHost : public ecs::Entity {
81public:
82 ENTITY(SceneHost, ecs::Entity)
83
84 void release() override {}
85
86 struct Meta {
87 bool visible = true;
88 int layer = 0;
89 std::string name;
90 uint32_t ownerId = 0;
91 SceneHost *entity = nullptr;
92 };
93
94 struct Tree {
95 bool dirty = true;
96 bool transformDirty = true;
97 bool indexValid = false;
98 std::unordered_map<std::string, int> idIndex;
99 std::vector<SceneNode> nodes;
100 int root = -1;
101 };
102
103 COMPONENT(Meta, meta)
104 COMPONENT(Tree, tree)
105
106 static SceneHost *createHost(const std::string &name = "");
107
108 void setName(const std::string &name);
109 const std::string &getName();
110 void setOwnerId(uint32_t id) { meta()->ownerId = id; }
111 uint32_t getOwnerId() { return meta()->ownerId; }
112
114 void setTree(NodeDesc root);
116 bool setTreeReconcile(NodeDesc root);
117
118 SceneNode *findById(const std::string &id);
119 SceneNode *findByKey(const std::string &key);
121 SceneNode *findByName(const std::string &name);
123 SceneNode *findByPath(const std::string &path);
124 int findIndexById(const std::string &id);
125 int findIndexByKey(const std::string &key);
126 int findIndexByName(const std::string &name);
127 int findIndexByPath(const std::string &path);
128
129 bool hasNode(const std::string &id);
130 int getNodeCount();
131 int getRootIndex();
133 SceneNode *getNode(int index);
134
135 int getParentIndex(int nodeIndex);
136 SceneNode *getParent(int nodeIndex);
137 SceneNode *getParentById(const std::string &id);
138 int getChildCount(int nodeIndex);
139 int getChildCountById(const std::string &id);
141 int getChildIndexAt(int parentIndex, int childOrdinal);
142 SceneNode *getChildAt(int parentIndex, int childOrdinal);
143 SceneNode *getChildAtById(const std::string &parentId, int childOrdinal);
144 std::vector<int> getChildIndices(int nodeIndex);
145 std::vector<SceneNode *> getChildren(int nodeIndex);
146 std::vector<std::string> getChildIds(const std::string &parentId);
147
149 std::string getPath(int nodeIndex);
150 std::string getPathById(const std::string &id);
151
152 bool isAncestorOf(int ancestorIndex, int nodeIndex);
153 bool isAncestorOfById(const std::string &ancestorId, const std::string &nodeId);
154 bool isDescendantOf(int nodeIndex, int ancestorIndex);
155 bool isDescendantOfById(const std::string &nodeId, const std::string &ancestorId);
156
157 void markDirty() { tree()->dirty = true; }
158 void markTransformDirty() { tree()->transformDirty = true; }
160 void markSubtreeDirty(int nodeIndex);
161 void markSubtreeDirtyById(const std::string &id) {
163 }
164 void invalidateIndex() { tree()->indexValid = false; }
165
166 // --- Node lifecycle events ---
167 using SceneEventFn = std::function<void(SceneHost *host, const std::string &action,
168 const std::string &nodeId,
169 const std::string &parentId)>;
170 void setEventHandler(SceneEventFn fn) { eventHandler_ = std::move(fn); }
172 void fireEvent(const std::string &action, const std::string &nodeId,
173 const std::string &parentId = {});
174
175 void setVisible(bool v) { meta()->visible = v; }
176 void setLayer(int layer) { meta()->layer = layer; }
177
182 bool setParent(int childIndex, int parentIndex);
183 bool addChild(int parentIndex, int childIndex);
184 bool removeChild(int parentIndex, int childIndex);
185
187 void forEachDepthFirst(int nodeIndex, void (*fn)(SceneHost *, int, void *), void *user);
188
189 using NodeVisitFn = std::function<void(SceneHost *host, int index, SceneNode &node)>;
190 using NodePredFn = std::function<bool(SceneHost *host, int index, const SceneNode &node)>;
191
194 void walkDepthFirstFrom(int nodeIndex, NodeVisitFn fn);
197 void walkBreadthFirstFrom(int nodeIndex, NodeVisitFn fn);
199 void walkChildren(int parentIndex, NodeVisitFn fn);
201 void walkAncestors(int nodeIndex, NodeVisitFn fn);
202
205 SceneNode *findIfFrom(int nodeIndex, NodePredFn pred);
206 std::vector<SceneNode *> filter(NodePredFn pred);
207 std::vector<SceneNode *> filterFrom(int nodeIndex, NodePredFn pred);
208 std::vector<int> filterIndices(NodePredFn pred);
209 std::vector<int> filterIndicesFrom(int nodeIndex, NodePredFn pred);
210
211 std::vector<SceneNode *> findAllByName(const std::string &name);
212 std::vector<SceneNode *> findAllByKey(const std::string &key);
213 std::vector<SceneNode *> findAllVisible(bool visible = true);
214 std::vector<SceneNode *> findAllBySpace(const std::string &space);
215 std::vector<SceneNode *> findAllLinked();
216
217 std::vector<std::string> collectIds();
218 std::vector<std::string> collectIdsFrom(int nodeIndex);
219 std::vector<std::string> collectIdsWhere(NodePredFn pred);
220 std::vector<std::string> collectIdsByName(const std::string &name);
221 std::vector<std::string> collectIdsVisible(bool visible = true);
222
231 bool link(const std::string &nodeId, int kind, void *target, int syncMode = 0);
232
233 bool linkRenderable2D(const std::string &nodeId, graphics::Renderable2D *r);
234 bool linkRenderable3D(const std::string &nodeId, graphics::Renderable3D *r);
235 bool linkPhysics2D(const std::string &nodeId, physics::Body *b, int syncMode = 0);
236 bool linkPhysics3D(const std::string &nodeId, physics::Body3D *b, int syncMode = 0);
237 bool linkCamera3D(const std::string &nodeId, graphics::Camera3D *c);
238 bool linkAudio3D(const std::string &nodeId, audio::Source *s);
239
241 bool unlink(const std::string &nodeId, int kind);
243 bool unlink(const std::string &nodeId);
244
246 const SceneLink *findLink(const SceneNode *node, int kind) const;
247 int linkCount(const std::string &nodeId);
248
250 bool setParentById(const std::string &childId, const std::string &parentId);
251 bool removeChildById(const std::string &parentId, const std::string &childId);
252
253 bool addTag(SceneNode *node, const std::string &tag);
254 bool removeTag(SceneNode *node, const std::string &tag);
255 bool hasTag(const SceneNode *node, const std::string &tag) const;
256 std::vector<SceneNode *> findAllByTag(const std::string &tag);
257
258private:
259 SceneEventFn eventHandler_;
260};
261
262} // namespace eve::scene
Tok kind
std::string id
uint32_t b
uint32_t c
TileLayer * layer
const char * name
Definition RockMesh.cpp:21
std::string filter
SettlementPipeline::Stage fn
int v
uint32_t s
Definition Weather.cpp:28
A playable audio source (static buffer or streaming decoder). Not thread-safe for playback control ex...
Definition Source.h:30
Default renderable entity for declarative 2D sprites / solid quads.
3D rigid body (Box3D) in meter-space coordinates (+Y up by convention). Owned by a World3D; create sh...
Definition Body3D.h:16
2D rigid body (Box2D) in pixel-space coordinates. Owned by a World; create shapes with newRectangleFi...
Definition Body.h:16
ECS mount point for one scene graph (full scene or nested subtree root). Isomorphic to eve::ui::UIHos...
Definition SceneHost.h:80
bool isDescendantOf(int nodeIndex, int ancestorIndex)
bool isAncestorOfById(const std::string &ancestorId, const std::string &nodeId)
std::vector< SceneNode * > getChildren(int nodeIndex)
std::function< void(SceneHost *host, const std::string &action, const std::string &nodeId, const std::string &parentId)> SceneEventFn
Definition SceneHost.h:169
void walkBreadthFirstFrom(int nodeIndex, NodeVisitFn fn)
bool isDescendantOfById(const std::string &nodeId, const std::string &ancestorId)
int findIndexByName(const std::string &name)
void setLayer(int layer)
Definition SceneHost.h:176
int findIndexById(const std::string &id)
void setEventHandler(SceneEventFn fn)
Definition SceneHost.h:170
void walkDepthFirstFrom(int nodeIndex, NodeVisitFn fn)
bool setParent(int childIndex, int parentIndex)
Imperative parent link. Returns false on invalid indices or cycle. Prefer declarative NodeDesc + reco...
void setTree(NodeDesc root)
Full replace.
bool removeChild(int parentIndex, int childIndex)
bool link(const std::string &nodeId, int kind, void *target, int syncMode=0)
Attach an external object to a node id. Survives reconcile/rebuild by id. After TransformSystem the l...
uint32_t getOwnerId()
Definition SceneHost.h:111
std::vector< int > filterIndices(NodePredFn pred)
bool removeChildById(const std::string &parentId, const std::string &childId)
int getChildIndexAt(int parentIndex, int childOrdinal)
Child ordinal 0..count-1; -1 if out of range.
bool setTreeReconcile(NodeDesc root)
Key-aware patch when structure matches; else full replace.
std::vector< SceneNode * > findAllBySpace(const std::string &space)
int getChildCountById(const std::string &id)
bool linkRenderable3D(const std::string &nodeId, graphics::Renderable3D *r)
bool linkPhysics3D(const std::string &nodeId, physics::Body3D *b, int syncMode=0)
bool isAncestorOf(int ancestorIndex, int nodeIndex)
std::vector< int > filterIndicesFrom(int nodeIndex, NodePredFn pred)
SceneNode * getChildAt(int parentIndex, int childOrdinal)
void setVisible(bool v)
Definition SceneHost.h:175
void setOwnerId(uint32_t id)
Definition SceneHost.h:110
std::vector< std::string > collectIdsVisible(bool visible=true)
std::vector< SceneNode * > filterFrom(int nodeIndex, NodePredFn pred)
std::vector< std::string > getChildIds(const std::string &parentId)
std::function< bool(SceneHost *host, int index, const SceneNode &node)> NodePredFn
Definition SceneHost.h:190
std::vector< std::string > collectIdsFrom(int nodeIndex)
std::vector< std::string > collectIdsWhere(NodePredFn pred)
std::vector< std::string > collectIdsByName(const std::string &name)
void forEachDepthFirst(int nodeIndex, void(*fn)(SceneHost *, int, void *), void *user)
Depth-first visit of arena indices under nodeIndex (inclusive). C callback.
SceneNode * findIf(NodePredFn pred)
First DFS match; nullptr if none.
std::vector< SceneNode * > findAllLinked()
void setName(const std::string &name)
bool linkPhysics2D(const std::string &nodeId, physics::Body *b, int syncMode=0)
SceneNode * getParentById(const std::string &id)
std::string getPathById(const std::string &id)
int getParentIndex(int nodeIndex)
SceneNode * findByName(const std::string &name)
First node whose name equals name (DFS from root).
std::vector< int > getChildIndices(int nodeIndex)
void markSubtreeDirty(int nodeIndex)
Mark a node's subtree for world recompute (recompute it + descendants).
bool addChild(int parentIndex, int childIndex)
void markSubtreeDirtyById(const std::string &id)
Definition SceneHost.h:161
int findIndexByKey(const std::string &key)
bool addTag(SceneNode *node, const std::string &tag)
std::vector< std::string > collectIds()
SceneNode * findById(const std::string &id)
std::vector< SceneNode * > findAllVisible(bool visible=true)
static SceneHost * createHost(const std::string &name="")
void walkAncestors(int nodeIndex, NodeVisitFn fn)
Parent chain upward, excluding self.
int findIndexByPath(const std::string &path)
std::vector< SceneNode * > findAllByTag(const std::string &tag)
SceneNode * getParent(int nodeIndex)
int linkCount(const std::string &nodeId)
bool hasTag(const SceneNode *node, const std::string &tag) const
SceneNode * findIfFrom(int nodeIndex, NodePredFn pred)
bool linkAudio3D(const std::string &nodeId, audio::Source *s)
SceneNode * findByKey(const std::string &key)
bool removeTag(SceneNode *node, const std::string &tag)
const std::string & getName()
bool unlink(const std::string &nodeId, int kind)
Remove all links of a kind; returns true if a link was removed.
std::string getPath(int nodeIndex)
Id path "a/b/c" from root to node; empty if invalid.
std::vector< SceneNode * > findAllByKey(const std::string &key)
void walkChildren(int parentIndex, NodeVisitFn fn)
Direct children only.
bool linkCamera3D(const std::string &nodeId, graphics::Camera3D *c)
std::function< void(SceneHost *host, int index, SceneNode &node)> NodeVisitFn
Definition SceneHost.h:189
void walkDepthFirst(NodeVisitFn fn)
DFS from root (or from nodeIndex), inclusive.
void walkBreadthFirst(NodeVisitFn fn)
BFS from root (or from nodeIndex), inclusive.
bool hasNode(const std::string &id)
SceneNode * findByPath(const std::string &path)
Path of ids joined by '/', e.g. "root/player/weapon". Relative to host root.
bool linkRenderable2D(const std::string &nodeId, graphics::Renderable2D *r)
std::vector< SceneNode * > findAllByName(const std::string &name)
SceneNode * getRoot()
SceneLink * findLink(SceneNode *node, int kind)
int getChildCount(int nodeIndex)
void release() override
Definition SceneHost.h:84
SceneNode * getChildAtById(const std::string &parentId, int childOrdinal)
SceneNode * getNode(int index)
void fireEvent(const std::string &action, const std::string &nodeId, const std::string &parentId={})
Fire "node_added" / "node_removed" / "node_moved" / "node_changed".
bool setParentById(const std::string &childId, const std::string &parentId)
Reparent by id; empty parentId detaches (parent = -1). Cycle-safe.
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition AnimTrail.h:6
NodeDesc node(std::string id, std::vector< NodeDesc > children, std::string name)
Definition NodeDesc.cpp:214
Declarative scene-node description (build once / on dirty → flatten into SceneHost::Tree)....
Definition NodeDesc.h:15
std::vector< SceneNode > nodes
Definition SceneHost.h:99
std::unordered_map< std::string, int > idIndex
Definition SceneHost.h:98
Retained scene node (arena). Conceptual GameObject; isomorphic to eve::ui::UINode.
Definition SceneHost.h:39
uint32_t objectId
Lazy companion SceneObject ECS entity id; 0 = none.
Definition SceneHost.h:66
float bminX
Local-space AABB (for picking / culling / spatial index).
Definition SceneHost.h:49
std::vector< std::string > tags
Gameplay groups (Godot-style): multiple string tags per node.
Definition SceneHost.h:46
bool subtreeDirty
Subtree needs world recompute (API edits mark node + ancestors).
Definition SceneHost.h:59
std::vector< SceneLink > links
Generic links (renderable / physics / camera / audio). Target owned elsewhere.
Definition SceneHost.h:63
std::string space
Definition SceneHost.h:43