Files
somaesque-native/src/world/scene.cpp
Daniel Ledda 6958228da7 update
2025-02-17 20:06:23 +01:00

92 lines
2.9 KiB
C++

#include "scene.h"
Entity *getEntity(Scene *s, uint32 id) {
return &s->entities[id - 1];
}
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle) {
return &s->graphNodes[s->entities[entityHandle - 1].graphNodeHandle - 1];
}
SceneGraphNode *getSceneGraphNode(Scene *s, uint32 sceneGraphNodeHandle) {
return &s->graphNodes[sceneGraphNodeHandle - 1];
}
uint32 createEntity(Scene *s) {
s->entities.emplace_back();
s->graphNodes.emplace_back();
s->entities.back().graphNodeHandle = (uint32)s->graphNodes.size();
s->graphNodes.back().entityHandle = (uint32)s->entities.size();
uint32 handle = (uint32)s->entities.size();
uint32 graphNodeHandle = (uint32)s->graphNodes.size();
initGraphNode(getSceneGraphNode(s, graphNodeHandle));
return handle;
}
uint32 createSceneGraphNode(Scene *s) {
s->graphNodes.emplace_back();
return (uint32)s->graphNodes.size();
}
void initGraphNode(SceneGraphNode *n) {
n->scale = glm::vec3(1.0f, 1.0f, 1.0f);
n->translation = glm::vec3(0.0f, 0.0f, 0.0f);
n->rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
n->local = glm::mat4(1.0f);
n->world = n->local;
}
void recalcGraphNode(SceneGraphNode *n) {
n->local = glm::scale(
glm::translate(
glm::mat4(1.0f),
n->translation
) * glm::toMat4(n->rotation),
n->scale
);
}
Scene createScene() {
Scene result = {};
result.sceneRoot = createSceneGraphNode(&result);
return result;
}
void recalcSceneGraphNode(Scene *s, uint32 parentHandle) {
SceneGraphNode *node = getSceneGraphNode(s, parentHandle);
if (node->entityHandle) {
getEntity(s, node->entityHandle)->flags |= EntityFlags_Render;
}
for (uint32 &nodeId : node->children) {
SceneGraphNode *graphNode = getSceneGraphNode(s, nodeId);
graphNode->parentHandle = parentHandle;
recalcGraphNode(graphNode);
graphNode->world = node->world * graphNode->local;
recalcSceneGraphNode(s, nodeId);
}
}
void recalcScene(Scene *s) {
recalcSceneGraphNode(s, s->sceneRoot);
}
void removeEntity(Scene *s, uint32 entityHandle) {
Entity *entity = getEntity(s, entityHandle);
entity->flags |= EntityFlags_Dead;
SceneGraphNode *graphNode = getSceneGraphNode(s, entity->graphNodeHandle);
if (graphNode->parentHandle) {
SceneGraphNode *parentNode = getSceneGraphNode(s, graphNode->parentHandle);
for (int i = 0; i < parentNode->children.size(); i++) {
if (parentNode->children.at(i) == entity->graphNodeHandle) {
parentNode->children.erase(parentNode->children.begin() + i);
graphNode->parentHandle = 0;
break;
}
}
}
}
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle) {
getSceneGraphNode(s, graphNodeHandle)->children.push_back(getEntity(s, entityHandle)->graphNodeHandle);
}