#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); }