fucxk
This commit is contained in:
@@ -1,44 +1,60 @@
|
||||
#include "string.h"
|
||||
#include "scene.h"
|
||||
|
||||
Entity *getEntity(Scene *s, uint32 entityHandle) {
|
||||
if (entityHandle) {
|
||||
return &s->entities.data[entityHandle - 1];
|
||||
Entity *getEntity(Scene *s, int32 entityHandle) {
|
||||
return &s->entities.data[entityHandle];
|
||||
}
|
||||
|
||||
SceneGraphNode *getSceneGraphNode(Scene *s, int32 sceneGraphNodeHandle) {
|
||||
return &s->graphNodes.data[sceneGraphNodeHandle];
|
||||
}
|
||||
|
||||
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, int32 entityHandle) {
|
||||
return getSceneGraphNode(s, getEntity(s, entityHandle)->graphNodeHandle);
|
||||
}
|
||||
|
||||
int32 createSceneGraphNode(Scene *s) {
|
||||
SceneGraphNode *newNode;
|
||||
int32 newNodeHandle;
|
||||
if (s->nextFreeNode) {
|
||||
newNodeHandle = s->nextFreeNode;
|
||||
newNode = getSceneGraphNode(s, newNodeHandle);
|
||||
if (newNode->next) {
|
||||
s->nextFreeNode = newNode->next;
|
||||
} else {
|
||||
s->nextFreeNode = 0;
|
||||
}
|
||||
newNode->next = 0;
|
||||
} else {
|
||||
ListAppend(s->graphNodes, (SceneGraphNode){0});
|
||||
newNodeHandle = (int32)s->graphNodes.length - 1;
|
||||
newNode = getSceneGraphNode(s, newNodeHandle);
|
||||
newNode->nextSibling = 0;
|
||||
}
|
||||
return NULL;
|
||||
initGraphNode(newNode);
|
||||
return newNodeHandle;
|
||||
}
|
||||
|
||||
SceneGraphNode *getSceneGraphNode(Scene *s, uint32 sceneGraphNodeHandle) {
|
||||
if (sceneGraphNodeHandle) {
|
||||
return &s->graphNodes.data[sceneGraphNodeHandle - 1];
|
||||
int32 createEntity(Scene *s) {
|
||||
Entity *newEntity;
|
||||
int32 newEntityHandle;
|
||||
println("%d", s->nextFreeEntity);
|
||||
if (s->nextFreeEntity) {
|
||||
newEntityHandle = s->nextFreeEntity;
|
||||
newEntity = getEntity(s, newEntityHandle);
|
||||
if (newEntity->next) {
|
||||
s->nextFreeEntity = newEntity->next;
|
||||
} else {
|
||||
s->nextFreeEntity = 0;
|
||||
}
|
||||
newEntity->next = 0;
|
||||
} else {
|
||||
ListAppend(s->entities, (Entity){0});
|
||||
newEntityHandle = (int32)s->entities.length - 1;
|
||||
newEntity = getEntity(s, newEntityHandle);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle) {
|
||||
Entity *e = getEntity(s, entityHandle);
|
||||
if (e) {
|
||||
return getSceneGraphNode(s, e->graphNodeHandle);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 createSceneGraphNode(Scene *s) {
|
||||
AppendList(&s->graphNodes, (SceneGraphNode){0});
|
||||
SceneGraphNode *node = &s->graphNodes.data[s->graphNodes.length - 1];
|
||||
node->children = PushList(s->arena, HandleList, 1000);
|
||||
initGraphNode(node);
|
||||
return (uint32)s->graphNodes.length;
|
||||
}
|
||||
|
||||
uint32 createEntity(Scene *s) {
|
||||
AppendList(&s->entities, (Entity){0});
|
||||
uint32 graphNodeId = createSceneGraphNode(s);
|
||||
s->entities.data[s->entities.length - 1].graphNodeHandle = graphNodeId;
|
||||
getSceneGraphNode(s, graphNodeId)->entityHandle = (uint32)s->entities.length;
|
||||
uint32 handle = (uint32)s->entities.length;
|
||||
uint32 graphNodeHandle = (uint32)s->graphNodes.length;
|
||||
return handle;
|
||||
newEntity->graphNodeHandle = createSceneGraphNode(s);
|
||||
getSceneGraphNodeForEntity(s, newEntityHandle)->entityHandle = newEntityHandle;
|
||||
return newEntityHandle;
|
||||
}
|
||||
|
||||
void initGraphNode(SceneGraphNode *n) {
|
||||
@@ -49,32 +65,32 @@ void initGraphNode(SceneGraphNode *n) {
|
||||
n->world = n->local;
|
||||
}
|
||||
|
||||
void recalcGraphNode(SceneGraphNode *n) {
|
||||
n->local = MatrixCompose(n->translation, n->rotation, n->scale);
|
||||
}
|
||||
|
||||
Scene createScene(Arena *arena) {
|
||||
Scene result = {
|
||||
.arena = arena,
|
||||
.entities = PushList(arena, EntityList, 100000),
|
||||
.graphNodes = PushList(arena, SceneGraphNodeList, 100000),
|
||||
.entities = PushListZero(arena, EntityList, 100000),
|
||||
.nextFreeEntity = 0,
|
||||
.graphNodes = PushListZero(arena, SceneGraphNodeList, 100000),
|
||||
.nextFreeNode = 0,
|
||||
};
|
||||
int32 handle = createEntity(&result); // Intialise the "zero" nodes
|
||||
getEntity(&result, handle)->flags = EntityFlags_None | EntityFlags_Dead;
|
||||
|
||||
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 (EachIn(node->children, i)) {
|
||||
uint32 nodeId = node->children.data[i];
|
||||
SceneGraphNode *graphNode = getSceneGraphNode(s, nodeId);
|
||||
graphNode->parentHandle = parentHandle;
|
||||
recalcGraphNode(graphNode);
|
||||
graphNode->world = MatrixMultiply(graphNode->local, node->world);
|
||||
recalcSceneGraphNode(s, nodeId);
|
||||
void recalcSceneGraphNode(Scene *s, int32 parentHandle) {
|
||||
if (!parentHandle) return;
|
||||
SceneGraphNode *parentNode = getSceneGraphNode(s, parentHandle);
|
||||
getEntity(s, parentNode->entityHandle)->flags |= EntityFlags_Render;
|
||||
int32 nextChild = parentNode->firstChild;
|
||||
while (nextChild) {
|
||||
SceneGraphNode *childNode = getSceneGraphNode(s, nextChild);
|
||||
childNode->parentHandle = parentHandle;
|
||||
childNode->local = MatrixCompose(childNode->translation, childNode->rotation, childNode->scale);
|
||||
childNode->world = MatrixMultiply(childNode->local, parentNode->world);
|
||||
recalcSceneGraphNode(s, nextChild);
|
||||
nextChild = childNode->nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,31 +98,73 @@ 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 != NULL && graphNode->parentHandle) {
|
||||
function void removeSceneGraphNodeRecursive(Scene *s, int32 graphNodeHandle, bool deletingParent) {
|
||||
if (!graphNodeHandle) return;
|
||||
SceneGraphNode *graphNode = getSceneGraphNode(s, graphNodeHandle);
|
||||
|
||||
int32 nextChild = graphNode->firstChild;
|
||||
while (nextChild) {
|
||||
int32 sibling = getSceneGraphNode(s, nextChild)->nextSibling;
|
||||
removeSceneGraphNodeRecursive(s, nextChild, true);
|
||||
nextChild = sibling;
|
||||
}
|
||||
|
||||
if (graphNode->entityHandle) {
|
||||
Entity *entity = getEntity(s, graphNode->entityHandle);
|
||||
*entity = (Entity){0};
|
||||
if (s->nextFreeEntity) {
|
||||
entity->next = s->nextFreeEntity;
|
||||
}
|
||||
s->nextFreeEntity = graphNode->entityHandle;
|
||||
}
|
||||
|
||||
if (s->nextFreeNode) {
|
||||
graphNode->next = s->nextFreeNode;
|
||||
}
|
||||
s->nextFreeNode = graphNodeHandle;
|
||||
|
||||
if (!deletingParent && graphNode->parentHandle) {
|
||||
SceneGraphNode *parentNode = getSceneGraphNode(s, graphNode->parentHandle);
|
||||
if (parentNode != NULL) {
|
||||
for (EachIn(parentNode->children, i)) {
|
||||
if (parentNode->children.data[i] == entity->graphNodeHandle) {
|
||||
memcpy(parentNode->children.data + i, parentNode->children.data + i + 1, parentNode->children.length - i - 1);
|
||||
//ListRemove(&parentNode->children, i);
|
||||
graphNode->parentHandle = 0;
|
||||
if (parentNode->firstChild == graphNodeHandle) {
|
||||
if (graphNode->nextSibling) {
|
||||
parentNode->firstChild = graphNode->nextSibling;
|
||||
} else {
|
||||
parentNode->firstChild = 0;
|
||||
}
|
||||
} else {
|
||||
int32 prevSibling = parentNode->firstChild;
|
||||
int32 nextSibling = getSceneGraphNode(s, parentNode->firstChild)->nextSibling;
|
||||
while (nextSibling) {
|
||||
SceneGraphNode *siblingNode = getSceneGraphNode(s, nextSibling);
|
||||
if (nextSibling == graphNodeHandle) {
|
||||
SceneGraphNode *prevSiblingNode = getSceneGraphNode(s, prevSibling);
|
||||
prevSiblingNode->nextSibling = graphNode->nextSibling;
|
||||
break;
|
||||
}
|
||||
nextSibling = siblingNode->nextSibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graphNode->firstChild = 0;
|
||||
graphNode->parentHandle = 0;
|
||||
graphNode->entityHandle = 0;
|
||||
graphNode->nextSibling = 0;
|
||||
}
|
||||
|
||||
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle) {
|
||||
HandleList *childList = &getSceneGraphNode(s, graphNodeHandle)->children;
|
||||
AppendList(childList, getEntity(s, entityHandle)->graphNodeHandle);
|
||||
void removeSceneGraphNode(Scene *s, int32 graphNodeHandle) {
|
||||
removeSceneGraphNodeRecursive(s, graphNodeHandle, false);
|
||||
}
|
||||
|
||||
void sceneNodeAddNode(Scene *s, uint32 recipientNodeHandle, uint32 graphNodeHandle) {
|
||||
HandleList *childList = &getSceneGraphNode(s, recipientNodeHandle)->children;
|
||||
AppendList(childList, graphNodeHandle);
|
||||
void removeEntity(Scene *s, int32 entityHandle) {
|
||||
if (!entityHandle) return;
|
||||
removeSceneGraphNode(s, getEntity(s, entityHandle)->graphNodeHandle);
|
||||
}
|
||||
|
||||
void sceneNodeAddNode(Scene *s, int32 parentHandle, int32 childHandle) {
|
||||
SceneGraphNode *parentNode = getSceneGraphNode(s, parentHandle);
|
||||
SceneGraphNode *childNode = getSceneGraphNode(s, childHandle);
|
||||
childNode->nextSibling = parentNode->firstChild;
|
||||
parentNode->firstChild = childHandle;
|
||||
childNode->parentHandle = parentHandle;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../lib/raymath.h"
|
||||
|
||||
DefineList(uint32, Handle);
|
||||
DefineList(int32, Handle);
|
||||
|
||||
enum EntityFlags {
|
||||
EntityFlags_None=0,
|
||||
EntityFlags_Visible=1<<0,
|
||||
EntityFlags_Dead=1<<1,
|
||||
EntityFlags_Render=1<<2,
|
||||
@@ -11,11 +12,14 @@ enum EntityFlags {
|
||||
|
||||
typedef struct Entity Entity;
|
||||
struct Entity {
|
||||
uint32 graphNodeHandle;
|
||||
int32 graphNodeHandle;
|
||||
uint64 flags;
|
||||
RLVector4 color;
|
||||
Mesh *mesh;
|
||||
Texture *tex;
|
||||
|
||||
// Free list
|
||||
int32 next;
|
||||
};
|
||||
DefineList(Entity, Entity);
|
||||
|
||||
@@ -26,30 +30,36 @@ struct SceneGraphNode {
|
||||
RLVector3 translation;
|
||||
Quaternion rotation;
|
||||
RLVector3 scale;
|
||||
HandleList children;
|
||||
uint32 entityHandle;
|
||||
uint32 parentHandle;
|
||||
int32 entityHandle;
|
||||
int32 parentHandle;
|
||||
|
||||
// Free list
|
||||
int32 next;
|
||||
|
||||
// Children
|
||||
int32 nextSibling;
|
||||
int32 firstChild;
|
||||
};
|
||||
DefineList(SceneGraphNode, SceneGraphNode);
|
||||
|
||||
typedef struct Scene Scene;
|
||||
struct Scene {
|
||||
uint32 sceneRoot;
|
||||
int32 sceneRoot;
|
||||
EntityList entities;
|
||||
int32 nextFreeEntity;
|
||||
SceneGraphNodeList graphNodes;
|
||||
Arena *arena;
|
||||
int32 nextFreeNode;
|
||||
};
|
||||
|
||||
uint32 createEntity(Scene *s);
|
||||
Entity *getEntity(Scene *s, uint32 id);
|
||||
SceneGraphNode *getSceneGraphNode(Scene *s, uint32 id);
|
||||
uint32 createSceneGraphNode(Scene *s);
|
||||
int32 createEntity(Scene *s);
|
||||
Entity *getEntity(Scene *s, int32 id);
|
||||
SceneGraphNode *getSceneGraphNode(Scene *s, int32 id);
|
||||
int32 createSceneGraphNode(Scene *s);
|
||||
Scene createScene(Arena *arena);
|
||||
void initGraphNode(SceneGraphNode *n);
|
||||
void recalcGraphNode(SceneGraphNode *n);
|
||||
void recalcSceneGraphNode(Scene *s, uint32 parentHandle);
|
||||
void recalcSceneGraphNode(Scene *s, int32 parentHandle);
|
||||
void recalcScene(Scene *s);
|
||||
void removeEntity(Scene *s, uint32 entityHandle);
|
||||
void sceneNodeAddNode(Scene *s, uint32 recipientNodeHandle, uint32 graphNodeHandle);
|
||||
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle);
|
||||
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle);
|
||||
void removeEntity(Scene *s, int32 entityHandle);
|
||||
void removeSceneGraphNode(Scene *s, int32 graphNodeHandle);
|
||||
void sceneNodeAddNode(Scene *s, int32 recipientNodeHandle, int32 graphNodeHandle);
|
||||
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, int32 entityHandle);
|
||||
|
||||
Reference in New Issue
Block a user