Files
EVEngine/src/modules/scene/SceneNodeRef.cpp
T
西风逍遥游 1c755f8940 feat(scene): scene/script-ECS integration, generic links, serialization & picking
Scene module overhaul: per-node script entities (SceneObject/SceneEntity/NodeRef), script ECS view-cache perf, generic multi-link system (renderable/physics/camera/audio), API completeness (transform getters, hierarchy ops, quaternions, tags/layer), incremental transforms, id index, reconcile moves, node events, JSON serialization, ray/frustum picking, spatial-index sync and SceneLoader auto AABB. Includes Cmdline/PhysFS argv0 robustness fix for unit tests.
2026-08-17 22:45:18 +08:00

226 lines
6.2 KiB
C++

#include "scene/SceneNodeRef.h"
#include "scene/Scene.h"
#include "scene/SceneHost.h"
#include <glm/glm.hpp>
#include <cmath>
namespace eve::scene {
namespace {
SceneHost *resolveHost(const std::string &hostName) {
Scene *s = Scene::create();
if (!s) return nullptr;
if (hostName.empty()) return s->current();
return s->findHost(hostName);
}
SceneNode *resolveNode(const std::string &hostName, const std::string &nodeId) {
if (nodeId.empty()) return nullptr;
SceneHost *h = resolveHost(hostName);
return h ? h->findById(nodeId) : nullptr;
}
glm::vec3 normalizedColumn(const glm::mat4 &m, int col) {
glm::vec3 v(m[col]);
const float len = glm::length(v);
if (len > 1e-8f) v /= len;
return v;
}
} // namespace
bool SceneNodeRef::isValid() const { return resolveNode(hostName_, nodeId_) != nullptr; }
Scene *SceneNodeRef::getScene() const { return Scene::create(); }
bool SceneNodeRef::setPosition(float x, float y, float z) {
SceneHost *h = resolveHost(hostName_);
SceneNode *n = resolveNode(hostName_, nodeId_);
if (!h || !n) return false;
n->x = x;
n->y = y;
n->z = z;
h->markSubtreeDirtyById(nodeId_);
return true;
}
float SceneNodeRef::getPositionX() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->x : 0.f;
}
float SceneNodeRef::getPositionY() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->y : 0.f;
}
float SceneNodeRef::getPositionZ() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->z : 0.f;
}
std::vector<float> SceneNodeRef::getPosition() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return {0.f, 0.f, 0.f};
return {n->x, n->y, n->z};
}
bool SceneNodeRef::setRotation(float yaw, float pitch, float roll) {
SceneHost *h = resolveHost(hostName_);
SceneNode *n = resolveNode(hostName_, nodeId_);
if (!h || !n) return false;
n->yaw = yaw;
n->pitch = pitch;
n->roll = roll;
h->markSubtreeDirtyById(nodeId_);
return true;
}
float SceneNodeRef::getRotationYaw() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->yaw : 0.f;
}
float SceneNodeRef::getRotationPitch() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->pitch : 0.f;
}
float SceneNodeRef::getRotationRoll() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->roll : 0.f;
}
std::vector<float> SceneNodeRef::getRotation() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return {0.f, 0.f, 0.f};
return {n->yaw, n->pitch, n->roll};
}
bool SceneNodeRef::setScale(float sx, float sy, float sz) {
SceneHost *h = resolveHost(hostName_);
SceneNode *n = resolveNode(hostName_, nodeId_);
if (!h || !n) return false;
n->sx = sx;
n->sy = sy;
n->sz = sz;
h->markSubtreeDirtyById(nodeId_);
return true;
}
float SceneNodeRef::getScaleX() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->sx : 0.f;
}
float SceneNodeRef::getScaleY() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->sy : 0.f;
}
float SceneNodeRef::getScaleZ() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->sz : 0.f;
}
std::vector<float> SceneNodeRef::getScale() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return {0.f, 0.f, 0.f};
return {n->sx, n->sy, n->sz};
}
bool SceneNodeRef::setVisible(bool v) {
SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return false;
n->visible = v;
SceneHost *h = resolveHost(hostName_);
if (h) h->markSubtreeDirtyById(nodeId_);
return true;
}
bool SceneNodeRef::isVisible() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->visible : false;
}
float SceneNodeRef::getWorldPositionX() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->world[3][0] : 0.f;
}
float SceneNodeRef::getWorldPositionY() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->world[3][1] : 0.f;
}
float SceneNodeRef::getWorldPositionZ() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
return n ? n->world[3][2] : 0.f;
}
std::vector<float> SceneNodeRef::getWorldPosition() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return {0.f, 0.f, 0.f};
return {n->world[3][0], n->world[3][1], n->world[3][2]};
}
std::vector<float> SceneNodeRef::getWorldMatrix() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return std::vector<float>(16, 0.f);
std::vector<float> out;
out.reserve(16);
for (int c = 0; c < 4; ++c)
for (int r = 0; r < 4; ++r) out.push_back(n->world[c][r]);
return out;
}
std::vector<float> SceneNodeRef::getForward() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return {0.f, 0.f, 1.f};
glm::vec3 v = normalizedColumn(n->world, 2);
return {v.x, v.y, v.z};
}
std::vector<float> SceneNodeRef::getRight() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return {1.f, 0.f, 0.f};
glm::vec3 v = normalizedColumn(n->world, 0);
return {v.x, v.y, v.z};
}
std::vector<float> SceneNodeRef::getUp() const {
const SceneNode *n = resolveNode(hostName_, nodeId_);
if (!n) return {0.f, 1.f, 0.f};
glm::vec3 v = normalizedColumn(n->world, 1);
return {v.x, v.y, v.z};
}
std::string SceneNodeRef::getParentId() const {
SceneHost *h = resolveHost(hostName_);
if (!h) return {};
SceneNode *p = h->getParentById(nodeId_);
return p ? p->id : std::string{};
}
int SceneNodeRef::getChildCount() const {
SceneHost *h = resolveHost(hostName_);
return h ? h->getChildCountById(nodeId_) : 0;
}
std::string SceneNodeRef::getChildIdAt(int ordinal) const {
SceneHost *h = resolveHost(hostName_);
if (!h) return {};
SceneNode *c = h->getChildAtById(nodeId_, ordinal);
return c ? c->id : std::string{};
}
std::string SceneNodeRef::getPath() const {
SceneHost *h = resolveHost(hostName_);
return h ? h->getPathById(nodeId_) : std::string{};
}
} // namespace eve::scene