载入中...
搜索中...
未找到
SceneNodes.cpp
浏览该文件的文档.
1// Scene node / link / bounds / picking implementation.
2//
3// Split out of the original Scene.cpp so the script binding layer
4// (Scene.cpp) and the node manipulation methods live in separate
5// translation units. Pure move: no behavior change.
6
7#include "scene/Scene.h"
8#include "scene/SceneBounds.h"
11#include "spatial/Octree.h"
12
13#include <simplesquirrel/simplesquirrel.hpp>
14
15#include <glm/glm.hpp>
16#include <glm/gtc/matrix_transform.hpp>
17#include <glm/gtc/quaternion.hpp>
18
19#include <limits>
20#include <string>
21#include <vector>
22
23namespace eve::scene {
24
25bool Scene::setNodePosition(const std::string &id, float x, float y, float z) {
26 SceneHost *h = selected_;
27 if (!h) return false;
28 SceneNode *n = h->findById(id);
29 if (!n) return false;
30 n->x = x;
31 n->y = y;
32 n->z = z;
33 h->markSubtreeDirtyById(id);
34 return true;
35}
36
37bool Scene::setNodeRotation(const std::string &id, float yaw, float pitch, float roll) {
38 SceneHost *h = selected_;
39 if (!h) return false;
40 SceneNode *n = h->findById(id);
41 if (!n) return false;
42 n->yaw = yaw;
43 n->pitch = pitch;
44 n->roll = roll;
45 h->markSubtreeDirtyById(id);
46 return true;
47}
48
49bool Scene::setNodeScale(const std::string &id, float sx, float sy, float sz) {
50 SceneHost *h = selected_;
51 if (!h) return false;
52 SceneNode *n = h->findById(id);
53 if (!n) return false;
54 n->sx = sx;
55 n->sy = sy;
56 n->sz = sz;
57 h->markSubtreeDirtyById(id);
58 return true;
59}
60
61bool Scene::setNodeVisible(const std::string &id, bool visible) {
62 SceneHost *h = selected_;
63 if (!h) return false;
64 SceneNode *n = h->findById(id);
65 if (!n) return false;
66 n->visible = visible;
67 h->markSubtreeDirtyById(id); // resync renderable visibility via links
68 return true;
69}
70
71bool Scene::linkRenderable2D(const std::string &nodeId, graphics::Renderable2D *r) {
72 return linkRenderable2DAt(currentHostName(), nodeId, r);
73}
74
75bool Scene::linkRenderable3D(const std::string &nodeId, graphics::Renderable3D *r) {
76 return linkRenderable3DAt(currentHostName(), nodeId, r);
77}
78
79bool Scene::unlinkNode(const std::string &nodeId) {
80 return unlinkNodeAt(currentHostName(), nodeId);
81}
82
83// ---------------------------------------------------------------------------
84// Generic link system (host-scoped primitives)
85// ---------------------------------------------------------------------------
86
87bool Scene::linkRenderable2DAt(const std::string &hostName, const std::string &nodeId,
89 SceneHost *h = resolveHost(hostName);
90 if (!h) return false;
91 if (!h->linkRenderable2D(nodeId, r)) return false;
93 return true;
94}
95
96bool Scene::linkRenderable3DAt(const std::string &hostName, const std::string &nodeId,
98 SceneHost *h = resolveHost(hostName);
99 if (!h) return false;
100 if (!h->linkRenderable3D(nodeId, r)) return false;
102 return true;
103}
104
105bool Scene::linkPhysics2DAt(const std::string &hostName, const std::string &nodeId,
106 physics::Body *b, const std::string &mode) {
107 SceneHost *h = resolveHost(hostName);
108 if (!h) return false;
109 if (!h->linkPhysics2D(nodeId, b, syncModeFromString(mode))) return false;
111 return true;
112}
113
114bool Scene::linkPhysics3DAt(const std::string &hostName, const std::string &nodeId,
115 physics::Body3D *b, const std::string &mode) {
116 SceneHost *h = resolveHost(hostName);
117 if (!h) return false;
118 if (!h->linkPhysics3D(nodeId, b, syncModeFromString(mode))) return false;
120 return true;
121}
122
123bool Scene::linkCamera3DAt(const std::string &hostName, const std::string &nodeId,
125 SceneHost *h = resolveHost(hostName);
126 if (!h) return false;
127 if (!h->linkCamera3D(nodeId, c)) return false;
129 return true;
130}
131
132bool Scene::linkAudio3DAt(const std::string &hostName, const std::string &nodeId,
133 audio::Source *s) {
134 SceneHost *h = resolveHost(hostName);
135 if (!h) return false;
136 if (!h->linkAudio3D(nodeId, s)) return false;
138 return true;
139}
140
141bool Scene::unlinkNodeAt(const std::string &hostName, const std::string &nodeId) {
142 SceneHost *h = resolveHost(hostName);
143 return h ? h->unlink(nodeId) : false;
144}
145
146bool Scene::unlinkNodeKindAt(const std::string &hostName, const std::string &nodeId,
147 const std::string &kind) {
148 SceneHost *h = resolveHost(hostName);
149 if (!h) return false;
150 const int k = linkKindFromString(kind);
151 if (k < 0) return false;
152 const bool removed = h->unlink(nodeId, k);
154 return removed;
155}
156
157int Scene::linkCountAt(const std::string &hostName, const std::string &nodeId) {
158 SceneHost *h = resolveHost(hostName);
159 return h ? h->linkCount(nodeId) : 0;
160}
161
162// ---------------------------------------------------------------------------
163// Script-API completeness: transform getters / hierarchy / math / tags / layer
164// ---------------------------------------------------------------------------
165
166std::vector<float> Scene::getNodePositionAt(const std::string &hostName,
167 const std::string &nodeId) const {
168 SceneHost *h = resolveHost(hostName);
169 SceneNode *n = h ? h->findById(nodeId) : nullptr;
170 if (!n) return {0.f, 0.f, 0.f};
171 return {n->x, n->y, n->z};
172}
173
174std::vector<float> Scene::getNodeRotationAt(const std::string &hostName,
175 const std::string &nodeId) const {
176 SceneHost *h = resolveHost(hostName);
177 SceneNode *n = h ? h->findById(nodeId) : nullptr;
178 if (!n) return {0.f, 0.f, 0.f};
179 return {n->yaw, n->pitch, n->roll};
180}
181
182std::vector<float> Scene::getNodeScaleAt(const std::string &hostName,
183 const std::string &nodeId) const {
184 SceneHost *h = resolveHost(hostName);
185 SceneNode *n = h ? h->findById(nodeId) : nullptr;
186 if (!n) return {0.f, 0.f, 0.f};
187 return {n->sx, n->sy, n->sz};
188}
189
190bool Scene::getNodeVisibleAt(const std::string &hostName,
191 const std::string &nodeId) const {
192 SceneHost *h = resolveHost(hostName);
193 SceneNode *n = h ? h->findById(nodeId) : nullptr;
194 return n ? n->visible : false;
195}
196
197std::vector<float> Scene::getNodeWorldPositionAt(const std::string &hostName,
198 const std::string &nodeId) const {
199 SceneHost *h = resolveHost(hostName);
200 SceneNode *n = h ? h->findById(nodeId) : nullptr;
201 if (!n) return {0.f, 0.f, 0.f};
202 return {n->world[3][0], n->world[3][1], n->world[3][2]};
203}
204
205std::vector<float> Scene::getNodeWorldRotationAt(const std::string &hostName,
206 const std::string &nodeId) const {
207 SceneHost *h = resolveHost(hostName);
208 SceneNode *n = h ? h->findById(nodeId) : nullptr;
209 if (!n) return {0.f, 0.f, 0.f};
210 glm::vec3 pos, euler, scale;
211 decomposeWorld(n->world, pos, euler, scale);
212 return {euler.x, euler.y, euler.z};
213}
214
215std::vector<float> Scene::getNodeWorldScaleAt(const std::string &hostName,
216 const std::string &nodeId) const {
217 SceneHost *h = resolveHost(hostName);
218 SceneNode *n = h ? h->findById(nodeId) : nullptr;
219 if (!n) return {0.f, 0.f, 0.f};
220 glm::vec3 pos, euler, scale;
221 decomposeWorld(n->world, pos, euler, scale);
222 return {scale.x, scale.y, scale.z};
223}
224
225std::vector<float> Scene::localToWorldAt(const std::string &hostName,
226 const std::string &nodeId, float x, float y,
227 float z) const {
228 SceneHost *h = resolveHost(hostName);
229 SceneNode *n = h ? h->findById(nodeId) : nullptr;
230 if (!n) return {x, y, z};
231 glm::vec4 p = n->world * glm::vec4(x, y, z, 1.f);
232 return {p.x, p.y, p.z};
233}
234
235std::vector<float> Scene::worldToLocalAt(const std::string &hostName,
236 const std::string &nodeId, float x, float y,
237 float z) const {
238 SceneHost *h = resolveHost(hostName);
239 SceneNode *n = h ? h->findById(nodeId) : nullptr;
240 if (!n) return {x, y, z};
241 glm::vec4 p = glm::inverse(n->world) * glm::vec4(x, y, z, 1.f);
242 return {p.x, p.y, p.z};
243}
244
245bool Scene::setNodeParentAt(const std::string &hostName, const std::string &childId,
246 const std::string &parentId) {
247 SceneHost *h = resolveHost(hostName);
248 if (!h) return false;
249 const bool ok = h->setParentById(childId, parentId);
251 return ok;
252}
253
254bool Scene::removeNodeAt(const std::string &hostName, const std::string &nodeId) {
255 SceneHost *h = resolveHost(hostName);
256 if (!h) return false;
257 const bool ok = h->setParentById(nodeId, "");
259 return ok;
260}
261
262bool Scene::addChildAt(const std::string &hostName, const std::string &parentId,
263 const std::string &childId) {
264 SceneHost *h = resolveHost(hostName);
265 if (!h) return false;
266 const bool ok = h->setParentById(childId, parentId);
268 return ok;
269}
270
271bool Scene::removeChildAt(const std::string &hostName, const std::string &parentId,
272 const std::string &childId) {
273 SceneHost *h = resolveHost(hostName);
274 if (!h) return false;
275 const bool ok = h->removeChildById(parentId, childId);
277 return ok;
278}
279
280bool Scene::setNodeQuaternionAt(const std::string &hostName, const std::string &nodeId,
281 float qx, float qy, float qz, float qw) {
282 SceneHost *h = resolveHost(hostName);
283 SceneNode *n = h ? h->findById(nodeId) : nullptr;
284 if (!h || !n) return false;
285 glm::quat q(qw, qx, qy, qz);
286 glm::vec3 e = glm::eulerAngles(q); // pitch(x), yaw(y), roll(z)
287 n->yaw = e.y;
288 n->pitch = e.x;
289 n->roll = e.z;
290 h->markSubtreeDirtyById(nodeId);
291 return true;
292}
293
294std::vector<float> Scene::getNodeQuaternionAt(const std::string &hostName,
295 const std::string &nodeId) const {
296 SceneHost *h = resolveHost(hostName);
297 SceneNode *n = h ? h->findById(nodeId) : nullptr;
298 if (!n) return {0.f, 0.f, 0.f, 1.f};
299 glm::quat q = nodeQuaternion(*n);
300 return {q.x, q.y, q.z, q.w};
301}
302
303bool Scene::setNodeLookAtAt(const std::string &hostName, const std::string &nodeId,
304 float tx, float ty, float tz) {
305 SceneHost *h = resolveHost(hostName);
306 SceneNode *n = h ? h->findById(nodeId) : nullptr;
307 if (!h || !n) return false;
308 glm::vec3 pos(n->x, n->y, n->z);
309 glm::vec3 target(tx, ty, tz);
310 glm::vec3 f = target - pos;
311 if (glm::dot(f, f) < 1e-8f) return false;
312 f = glm::normalize(f);
313 glm::vec3 up(0.f, 1.f, 0.f);
314 glm::vec3 right = glm::normalize(glm::cross(up, f));
315 if (glm::dot(right, right) < 1e-8f) right = glm::vec3(1.f, 0.f, 0.f); // f ∥ up
316 glm::vec3 up2 = glm::normalize(glm::cross(f, right));
317 glm::mat3 rot(right, up2, f);
318 glm::quat q = glm::quat_cast(rot);
319 glm::vec3 e = glm::eulerAngles(q);
320 n->yaw = e.y;
321 n->pitch = e.x;
322 n->roll = e.z;
323 h->markSubtreeDirtyById(nodeId);
324 return true;
325}
326
327bool Scene::addNodeTagAt(const std::string &hostName, const std::string &nodeId,
328 const std::string &tag) {
329 SceneHost *h = resolveHost(hostName);
330 SceneNode *n = h ? h->findById(nodeId) : nullptr;
331 return h ? h->addTag(n, tag) : false;
332}
333
334bool Scene::removeNodeTagAt(const std::string &hostName, const std::string &nodeId,
335 const std::string &tag) {
336 SceneHost *h = resolveHost(hostName);
337 SceneNode *n = h ? h->findById(nodeId) : nullptr;
338 return h ? h->removeTag(n, tag) : false;
339}
340
341bool Scene::hasNodeTagAt(const std::string &hostName, const std::string &nodeId,
342 const std::string &tag) const {
343 SceneHost *h = resolveHost(hostName);
344 SceneNode *n = h ? h->findById(nodeId) : nullptr;
345 return h ? h->hasTag(n, tag) : false;
346}
347
348std::vector<std::string> Scene::getNodeTagsAt(const std::string &hostName,
349 const std::string &nodeId) const {
350 SceneHost *h = resolveHost(hostName);
351 SceneNode *n = h ? h->findById(nodeId) : nullptr;
352 if (!n) return {};
353 return n->tags;
354}
355
356std::vector<std::string> Scene::collectIdsByTagAt(const std::string &hostName,
357 const std::string &tag) const {
358 SceneHost *h = resolveHost(hostName);
359 if (!h) return {};
360 std::vector<std::string> out;
361 for (SceneNode *n : h->findAllByTag(tag)) {
362 if (n) out.push_back(n->id);
363 }
364 return out;
365}
366
367bool Scene::setNodeLayerAt(const std::string &hostName, const std::string &nodeId,
368 int layer) {
369 SceneHost *h = resolveHost(hostName);
370 SceneNode *n = h ? h->findById(nodeId) : nullptr;
371 if (!n) return false;
372 n->layer = layer;
373 return true;
374}
375
376int Scene::getNodeLayerAt(const std::string &hostName, const std::string &nodeId) const {
377 SceneHost *h = resolveHost(hostName);
378 SceneNode *n = h ? h->findById(nodeId) : nullptr;
379 return n ? n->layer : 0;
380}
381
382bool Scene::setNodeEventHandlerAt(const std::string &hostName, ssq::Object cb) {
383 if (!vm_) return false;
384 SceneHost *h = resolveHost(hostName);
385 if (!h) return false;
386 const std::string name = hostName.empty() ? h->getName() : hostName;
387
388 auto it = eventCbs_.find(name);
389 if (it != eventCbs_.end()) {
390 sq_release(vm_, &it->second);
391 eventCbs_.erase(it);
392 }
393 HSQOBJECT raw = cb.getRaw();
394 if (raw._type == OT_NULL) { // clear handler
395 h->setEventHandler({});
396 return true;
397 }
398 if (raw._type != OT_CLOSURE && raw._type != OT_NATIVECLOSURE) return false;
399 sq_addref(vm_, &raw);
400 eventCbs_[name] = raw;
401 h->setEventHandler(
402 [this, name](SceneHost *, const std::string &action, const std::string &nodeId,
403 const std::string &parentId) {
404 callEventCallback(name, action, nodeId, parentId);
405 });
406 return true;
407}
408
409void Scene::callEventCallback(const std::string &hostName, const std::string &action,
410 const std::string &nodeId, const std::string &parentId) {
411 if (!vm_) return;
412 auto it = eventCbs_.find(hostName);
413 if (it == eventCbs_.end()) return;
414 const SQInteger top = sq_gettop(vm_);
415 sq_pushobject(vm_, it->second);
416 sq_pushstring(vm_, action.c_str(), -1);
417 sq_pushstring(vm_, nodeId.c_str(), -1);
418 sq_pushstring(vm_, parentId.c_str(), -1);
419 if (SQ_FAILED(sq_call(vm_, 3, SQFalse, SQTrue))) {
420 sq_settop(vm_, top);
421 return;
422 }
423 sq_settop(vm_, top);
424}
425
426// ---------------------------------------------------------------------------
427// Bounds / serialization / picking / culling
428// ---------------------------------------------------------------------------
429
430bool Scene::setNodeBoundsAt(const std::string &hostName, const std::string &nodeId,
431 float minX, float minY, float minZ, float maxX, float maxY,
432 float maxZ) {
433 SceneHost *h = resolveHost(hostName);
434 SceneNode *n = h ? h->findById(nodeId) : nullptr;
435 if (!n) return false;
436 n->bminX = minX;
437 n->bminY = minY;
438 n->bminZ = minZ;
439 n->bmaxX = maxX;
440 n->bmaxY = maxY;
441 n->bmaxZ = maxZ;
442 n->hasBounds = true;
443 return true;
444}
445
446bool Scene::hasNodeBoundsAt(const std::string &hostName, const std::string &nodeId) const {
447 SceneHost *h = resolveHost(hostName);
448 SceneNode *n = h ? h->findById(nodeId) : nullptr;
449 return n ? n->hasBounds : false;
450}
451
452std::vector<float> Scene::getNodeBoundsAt(const std::string &hostName,
453 const std::string &nodeId) const {
454 SceneHost *h = resolveHost(hostName);
455 SceneNode *n = h ? h->findById(nodeId) : nullptr;
456 if (!n || !n->hasBounds) return {0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
457 return {n->bminX, n->bminY, n->bminZ, n->bmaxX, n->bmaxY, n->bmaxZ};
458}
459
460
461std::string Scene::pickRayAt(const std::string &hostName, float ox, float oy, float oz,
462 float dx, float dy, float dz) const {
463 SceneHost *h = resolveHost(hostName);
464 if (!h) return {};
465 const glm::vec3 origin(ox, oy, oz);
466 glm::vec3 dir(dx, dy, dz);
467 if (glm::dot(dir, dir) < 1e-12f) return {};
468 dir = glm::normalize(dir);
469
470 float bestT = std::numeric_limits<float>::max();
471 std::string best;
472 h->walkDepthFirst([&](SceneHost *, int, SceneNode &n) {
473 if (!n.hasBounds) return;
474 const AABB3f w = worldBoundsOf(n);
475 float t0 = 0.f, t1 = 0.f;
476 if (rayAABB(origin, dir, w, t0, t1) && t1 >= 0.f && t0 < bestT) {
477 bestT = std::max(t0, 0.f);
478 best = n.id;
479 }
480 });
481 return best;
482}
483
484bool Scene::syncSpatialIndexAt(const std::string &hostName, spatial::Octree *ot) const {
485 SceneHost *h = resolveHost(hostName);
486 if (!h || !ot) return false;
487 bool any = false;
488 h->walkDepthFirst([&](SceneHost *, int index, SceneNode &n) {
489 if (!n.hasBounds) return;
490 const AABB3f w = worldBoundsOf(n);
491 ot->insert(index, w.min.x, w.min.y, w.min.z, w.max.x, w.max.y, w.max.z);
492 any = true;
493 });
494 return any;
495}
496
497std::string Scene::nodeIdFromSpatialIdAt(const std::string &hostName, int index) const {
498 SceneHost *h = resolveHost(hostName);
499 SceneNode *n = h ? h->getNode(index) : nullptr;
500 return n ? n->id : std::string{};
501}
502
503bool Scene::hasNode(const std::string &id) {
504 SceneHost *h = selected_;
505 return h ? h->hasNode(id) : false;
506}
507
509 SceneHost *h = selected_;
510 return h ? h->getNodeCount() : 0;
511}
512
513std::string Scene::getRootId() {
514 SceneHost *h = selected_;
515 if (!h) return {};
516 SceneNode *r = h->getRoot();
517 return r ? r->id : std::string{};
518}
519
520std::string Scene::getParentId(const std::string &id) {
521 SceneHost *h = selected_;
522 if (!h) return {};
523 SceneNode *p = h->getParentById(id);
524 return p ? p->id : std::string{};
525}
526
527int Scene::getChildCount(const std::string &id) {
528 SceneHost *h = selected_;
529 return h ? h->getChildCountById(id) : 0;
530}
531
532std::string Scene::getChildIdAt(const std::string &parentId, int childOrdinal) {
533 SceneHost *h = selected_;
534 if (!h) return {};
535 SceneNode *c = h->getChildAtById(parentId, childOrdinal);
536 return c ? c->id : std::string{};
537}
538
539std::string Scene::findIdByName(const std::string &name) {
540 SceneHost *h = selected_;
541 if (!h) return {};
542 SceneNode *n = h->findByName(name);
543 return n ? n->id : std::string{};
544}
545
546std::string Scene::findIdByPath(const std::string &path) {
547 SceneHost *h = selected_;
548 if (!h) return {};
549 SceneNode *n = h->findByPath(path);
550 return n ? n->id : std::string{};
551}
552
553std::string Scene::getNodePath(const std::string &id) {
554 SceneHost *h = selected_;
555 return h ? h->getPathById(id) : std::string{};
556}
557
558bool Scene::isAncestor(const std::string &ancestorId, const std::string &nodeId) {
559 SceneHost *h = selected_;
560 return h ? h->isAncestorOfById(ancestorId, nodeId) : false;
561}
562
563bool Scene::isDescendant(const std::string &nodeId, const std::string &ancestorId) {
564 SceneHost *h = selected_;
565 return h ? h->isDescendantOfById(nodeId, ancestorId) : false;
566}
567
568std::vector<std::string> Scene::collectIds() {
569 SceneHost *h = selected_;
570 return h ? h->collectIds() : std::vector<std::string>{};
571}
572
573std::vector<std::string> Scene::collectIdsFrom(const std::string &id) {
574 SceneHost *h = selected_;
575 if (!h) return {};
576 return h->collectIdsFrom(h->findIndexById(id));
577}
578
579std::vector<std::string> Scene::collectIdsByName(const std::string &name) {
580 SceneHost *h = selected_;
581 return h ? h->collectIdsByName(name) : std::vector<std::string>{};
582}
583
584std::vector<std::string> Scene::collectIdsVisible(bool visible) {
585 SceneHost *h = selected_;
586 return h ? h->collectIdsVisible(visible) : std::vector<std::string>{};
587}
588
589std::vector<std::string> Scene::collectChildIds(const std::string &parentId) {
590 SceneHost *h = selected_;
591 return h ? h->getChildIds(parentId) : std::vector<std::string>{};
592}
593
594std::vector<std::string> Scene::walkDepthFirstIds() { return collectIds(); }
595
596std::vector<std::string> Scene::walkBreadthFirstIds() {
597 SceneHost *h = selected_;
598 if (!h) return {};
599 std::vector<std::string> out;
600 h->walkBreadthFirst([&](SceneHost *, int, SceneNode &n) { out.push_back(n.id); });
601 return out;
602}
603
604} // namespace eve::scene
Tok kind
bool removed
int y
Definition Grass.cpp:135
int z
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
glm::vec3 n
Definition Grass.cpp:64
int h
int w
uint32_t b
uint32_t c
TileLayer * layer
float f
glm::vec4 p[6]
const char * name
Definition RockMesh.cpp:21
float scale
Definition TreeMesh.cpp:122
V3 dir
Definition TreeMesh.cpp:121
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 isAncestorOfById(const std::string &ancestorId, const std::string &nodeId)
bool isDescendantOfById(const std::string &nodeId, const std::string &ancestorId)
int getChildCountById(const std::string &id)
std::vector< std::string > collectIdsVisible(bool visible=true)
std::vector< std::string > getChildIds(const std::string &parentId)
std::vector< std::string > collectIdsFrom(int nodeIndex)
std::vector< std::string > collectIdsByName(const std::string &name)
std::string getPathById(const std::string &id)
std::vector< std::string > collectIds()
void walkBreadthFirst(NodeVisitFn fn)
BFS from root (or from nodeIndex), inclusive.
bool hasNode(const std::string &id)
bool linkPhysics3DAt(const std::string &hostName, const std::string &nodeId, physics::Body3D *b, const std::string &mode)
SceneHost * resolveHost(const std::string &hostName) const
Host-qualified resolution: empty hostName → currently selected host.
Definition Scene.cpp:807
std::vector< std::string > collectIdsFrom(const std::string &id)
bool setNodeParentAt(const std::string &hostName, const std::string &childId, const std::string &parentId)
Reparent by id; empty parentId detaches. Cycle-safe.
std::vector< std::string > collectIds()
bool linkCamera3DAt(const std::string &hostName, const std::string &nodeId, graphics::Camera3D *c)
std::vector< std::string > collectIdsByTagAt(const std::string &hostName, const std::string &tag) const
std::vector< float > getNodeRotationAt(const std::string &hostName, const std::string &nodeId) const
std::string findIdByPath(const std::string &path)
bool setNodeQuaternionAt(const std::string &hostName, const std::string &nodeId, float qx, float qy, float qz, float qw)
bool getNodeVisibleAt(const std::string &hostName, const std::string &nodeId) const
std::vector< float > worldToLocalAt(const std::string &hostName, const std::string &nodeId, float x, float y, float z) const
std::vector< float > getNodePositionAt(const std::string &hostName, const std::string &nodeId) const
std::vector< float > getNodeWorldPositionAt(const std::string &hostName, const std::string &nodeId) const
int getNodeLayerAt(const std::string &hostName, const std::string &nodeId) const
bool linkPhysics2DAt(const std::string &hostName, const std::string &nodeId, physics::Body *b, const std::string &mode)
bool removeNodeAt(const std::string &hostName, const std::string &nodeId)
Detach node from its parent (arena node stays; rebuild to delete).
std::vector< std::string > collectChildIds(const std::string &parentId)
bool unlinkNodeAt(const std::string &hostName, const std::string &nodeId)
Remove every link on the node.
bool setNodePosition(const std::string &id, float x, float y, float z)
Script-friendly TRS setters on the current host; each marks the transform dirty.
std::vector< std::string > collectIdsVisible(bool visible)
bool linkAudio3DAt(const std::string &hostName, const std::string &nodeId, audio::Source *s)
bool setNodeLookAtAt(const std::string &hostName, const std::string &nodeId, float tx, float ty, float tz)
Orient node so its local +Z axis points at (tx,ty,tz).
std::string currentHostName() const
Definition Scene.cpp:917
std::vector< float > getNodeWorldRotationAt(const std::string &hostName, const std::string &nodeId) const
bool hasNode(const std::string &id)
std::string getNodePath(const std::string &id)
std::string findIdByName(const std::string &name)
int getChildCount(const std::string &id)
bool removeNodeTagAt(const std::string &hostName, const std::string &nodeId, const std::string &tag)
bool linkRenderable3DAt(const std::string &hostName, const std::string &nodeId, graphics::Renderable3D *r)
bool isAncestor(const std::string &ancestorId, const std::string &nodeId)
bool setNodeScale(const std::string &id, float sx, float sy, float sz)
Sets the local scale of a node.
std::string getParentId(const std::string &id)
std::vector< std::string > collectIdsByName(const std::string &name)
bool unlinkNodeKindAt(const std::string &hostName, const std::string &nodeId, const std::string &kind)
Remove links of one kind ("renderable2d"|"renderable3d"|"physics2d"|...).
std::vector< float > getNodeScaleAt(const std::string &hostName, const std::string &nodeId) const
std::string nodeIdFromSpatialIdAt(const std::string &hostName, int index) const
Map a spatial-index id (arena index) back to a node id.
std::vector< std::string > getNodeTagsAt(const std::string &hostName, const std::string &nodeId) const
int linkCountAt(const std::string &hostName, const std::string &nodeId)
bool hasNodeBoundsAt(const std::string &hostName, const std::string &nodeId) const
std::vector< std::string > walkBreadthFirstIds()
bool linkRenderable3D(const std::string &nodeId, graphics::Renderable3D *r)
Links a 3D renderable to a node in the current host.
bool setNodeLayerAt(const std::string &hostName, const std::string &nodeId, int layer)
bool setNodeRotation(const std::string &id, float yaw, float pitch, float roll)
Sets the local rotation (yaw/pitch/roll in degrees) of a node.
bool unlinkNode(const std::string &nodeId)
Removes every link on a node in the current host.
bool syncSpatialIndexAt(const std::string &hostName, spatial::Octree *ot) const
Insert every bounded node's world AABB into an octree (id = arena index).
bool setNodeEventHandlerAt(const std::string &hostName, ssq::Object cb)
Register a script callback for node lifecycle events on a host: cb(action, nodeId,...
std::vector< float > getNodeQuaternionAt(const std::string &hostName, const std::string &nodeId) const
bool removeChildAt(const std::string &hostName, const std::string &parentId, const std::string &childId)
bool setNodeBoundsAt(const std::string &hostName, const std::string &nodeId, float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
bool setNodeVisible(const std::string &id, bool visible)
Shows/hides a node.
std::string getRootId()
bool addChildAt(const std::string &hostName, const std::string &parentId, const std::string &childId)
std::string getChildIdAt(const std::string &parentId, int childOrdinal)
bool linkRenderable2DAt(const std::string &hostName, const std::string &nodeId, graphics::Renderable2D *r)
std::vector< float > localToWorldAt(const std::string &hostName, const std::string &nodeId, float x, float y, float z) const
std::vector< float > getNodeWorldScaleAt(const std::string &hostName, const std::string &nodeId) const
bool isDescendant(const std::string &nodeId, const std::string &ancestorId)
bool hasNodeTagAt(const std::string &hostName, const std::string &nodeId, const std::string &tag) const
std::vector< std::string > walkDepthFirstIds()
DFS order of ids under root (same as collectIds). Kept for script naming clarity.
std::vector< float > getNodeBoundsAt(const std::string &hostName, const std::string &nodeId) const
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 addNodeTagAt(const std::string &hostName, const std::string &nodeId, const std::string &tag)
bool linkRenderable2D(const std::string &nodeId, graphics::Renderable2D *r)
Links a 2D renderable to a node in the current host.
static void updateHost(SceneHost *host)
Region octree for 3D AABB broad-phase / scene culling. Same storage rules as QuadTree (smallest fully...
Definition Octree.h:16
bool insert(int id, float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
插入一个 AABB 对象;false 表示越界或已存在。
Definition Octree.cpp:37
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
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