cleaned more stuff
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
# Sources
|
||||
target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
scenetree.c
|
||||
node.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
|
||||
127
src/scene/node.c
Normal file
127
src/scene/node.c
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright (c) 2025 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "node.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
node_t NODE_DATA[ECS_ENTITY_COUNT_MAX] = { 0 };
|
||||
ecscomponent_t NODE_COMPONENT = ecsComponentInit(
|
||||
NODE_DATA,
|
||||
((ecscomponentcallbacks_t){
|
||||
.init = nodeInit,
|
||||
.entityAdd = nodeEntityAdded,
|
||||
.entityRemove = nodeEntityRemoved
|
||||
})
|
||||
);
|
||||
|
||||
ecsid_t nodeParentGet(const ecsid_t child) {
|
||||
assertTrue(child >= 0 && child < ECS_ENTITY_COUNT_MAX, "Invalid child ID");
|
||||
if(!nodeHas(child)) return -1;
|
||||
return NODE_DATA[child].parent;
|
||||
}
|
||||
|
||||
uint8_t nodeChildGetAll(const ecsid_t id, ecsid_t *children) {
|
||||
if(!nodeHas(id)) return 0;
|
||||
if(children == NULL) return NODE_DATA[id].childCount;
|
||||
|
||||
memoryCopy(
|
||||
children,
|
||||
NODE_DATA[id].children,
|
||||
sizeof(ecsid_t) * NODE_DATA[id].childCount
|
||||
);
|
||||
|
||||
return NODE_DATA[id].childCount;
|
||||
}
|
||||
|
||||
void nodeChildAdd(const ecsid_t parent, const ecsid_t child) {
|
||||
if(!nodeHas(parent)) nodeAdd(parent);
|
||||
if(!nodeHas(child)) nodeAdd(child);
|
||||
|
||||
node_t *parentNode = &NODE_DATA[parent];
|
||||
assertTrue(parentNode->childCount < SCENE_ITEM_CHILD_MAX, "Parent full.");
|
||||
|
||||
// Add child to parent's children array
|
||||
parentNode->children[parentNode->childCount] = child;
|
||||
parentNode->childCount++;
|
||||
|
||||
// Set child's parent
|
||||
NODE_DATA[child].parent = parent;
|
||||
}
|
||||
|
||||
void nodeChildRemove(const ecsid_t parent, const ecsid_t child) {
|
||||
assertTrue(nodeHas(parent), "NODE ECS lacks Parent.");
|
||||
assertTrue(nodeHas(child), "NODE ECS lacks Child.");
|
||||
|
||||
node_t *childNode = &NODE_DATA[child];
|
||||
node_t *parentNode = &NODE_DATA[parent];
|
||||
assertTrue(childNode->parent == parent, "Child does not belong to parent");
|
||||
assertTrue(parentNode->childCount > 0, "Parent has no children");
|
||||
|
||||
// Remove child from parent's children array
|
||||
for (uint8_t i = 0; i < parentNode->childCount; i++) {
|
||||
if (parentNode->children[i] == child) {
|
||||
// Shift remaining children down
|
||||
for (uint8_t j = i; j < parentNode->childCount - 1; j++) {
|
||||
parentNode->children[j] = parentNode->children[j + 1];
|
||||
}
|
||||
parentNode->childCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear child's parent
|
||||
childNode->parent = -1;
|
||||
|
||||
if(childNode->childCount == 0) nodeRemove(child);
|
||||
if(parentNode->childCount == 0) nodeRemove(parent);
|
||||
}
|
||||
|
||||
void nodeChildRemoveAll(const ecsid_t parent) {
|
||||
assertTrue(nodeHas(parent), "NODE ECS lacks Parent.");
|
||||
|
||||
node_t *parentNode = &NODE_DATA[parent];
|
||||
for(uint8_t i = 0; i < parentNode->childCount; i++) {
|
||||
ecsid_t child = parentNode->children[i];
|
||||
NODE_DATA[child].parent = -1;
|
||||
|
||||
if(NODE_DATA[child].childCount == 0) nodeRemove(child);
|
||||
}
|
||||
|
||||
nodeRemove(parent);
|
||||
}
|
||||
|
||||
bool_t nodeChildInTree(const ecsid_t parent, const ecsid_t child) {
|
||||
assertTrue(nodeHas(parent), "NODE ECS lacks Parent.");
|
||||
assertTrue(nodeHas(child), "NODE ECS lacks Child.");
|
||||
|
||||
assertTrue(parent >= 0 && parent < ECS_ENTITY_COUNT_MAX, "Invalid parent ID");
|
||||
assertTrue(child >= 0 && child < ECS_ENTITY_COUNT_MAX, "Invalid child ID");
|
||||
assertTrue(parent != child, "Child cannot be a child of itself.");
|
||||
|
||||
node_t *childNode = &NODE_DATA[child];
|
||||
while(childNode) {
|
||||
if(childNode->parent == parent) return true;
|
||||
if(childNode->parent == -1) break; // No parent means we've reached the root
|
||||
childNode = &NODE_DATA[childNode->parent];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void nodeInit(void) {
|
||||
for(ecsid_t i = 0; i < ECS_ENTITY_COUNT_MAX; i++) {
|
||||
NODE_DATA[i].parent = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void nodeEntityAdded(const ecsid_t id) {
|
||||
NODE_DATA[id].parent = -1;
|
||||
}
|
||||
|
||||
void nodeEntityRemoved(const ecsid_t id) {
|
||||
if(NODE_DATA[id].parent == -1) return;
|
||||
nodeChildRemove(NODE_DATA[id].parent, id);
|
||||
}
|
||||
@@ -14,17 +14,21 @@ typedef struct {
|
||||
ecsid_t children[SCENE_ITEM_CHILD_MAX];
|
||||
uint8_t childCount;
|
||||
ecsid_t parent;
|
||||
} scenetreenode_t;
|
||||
|
||||
vec3 position;
|
||||
vec3 rotation;
|
||||
vec3 scale;
|
||||
} node_t;
|
||||
|
||||
extern scenetreenode_t SCENE_TREE_DATA[ECS_ENTITY_COUNT_MAX];
|
||||
extern ecscomponent_t SCENE_TREE_COMPONENT;
|
||||
extern node_t NODE_DATA[ECS_ENTITY_COUNT_MAX];
|
||||
extern ecscomponent_t NODE_COMPONENT;
|
||||
|
||||
/**
|
||||
* Initialize the scene tree.
|
||||
*
|
||||
* This will initialize the ECS system and prepare the scene tree for use.
|
||||
*/
|
||||
void sceneTreeInit(void);
|
||||
#define nodeHas(id) ecsComponentDataHas(&NODE_COMPONENT, id)
|
||||
#define nodeGet(id) \
|
||||
((node_t*)ecsComponentDataGet(&NODE_COMPONENT, id))
|
||||
#define nodeAdd(id) \
|
||||
((node_t*)ecsComponentDataAdd(&NODE_COMPONENT, id))
|
||||
#define nodeRemove(id) ecsComponentDataRemove(&NODE_COMPONENT, id)
|
||||
|
||||
/**
|
||||
* Create a new scene item in the scene tree.
|
||||
@@ -32,7 +36,7 @@ void sceneTreeInit(void);
|
||||
*
|
||||
* @return The ID of the newly created scene item.
|
||||
*/
|
||||
ecsid_t sceneTreeCreate(void);
|
||||
ecsid_t nodeCreate(void);
|
||||
|
||||
/**
|
||||
* Get the parent of a given scene item.
|
||||
@@ -40,7 +44,7 @@ ecsid_t sceneTreeCreate(void);
|
||||
* @param id The ID of the scene item.
|
||||
* @return The ID of the parent scene item, or -1 if it has no parent.
|
||||
*/
|
||||
ecsid_t sceneTreeParentGet(const ecsid_t child);
|
||||
ecsid_t nodeParentGet(const ecsid_t child);
|
||||
|
||||
/**
|
||||
* Get the children of a given scene item. If children is NULL only the count
|
||||
@@ -50,7 +54,7 @@ ecsid_t sceneTreeParentGet(const ecsid_t child);
|
||||
* @param children Pointer to an array where the children IDs will be stored.
|
||||
* @return The number of children found.
|
||||
*/
|
||||
uint8_t sceneTreeChildGetAll(const ecsid_t id, ecsid_t *children);
|
||||
uint8_t nodeChildGetAll(const ecsid_t id, ecsid_t *children);
|
||||
|
||||
/**
|
||||
* Add a child to a parent in the scene tree.
|
||||
@@ -58,7 +62,7 @@ uint8_t sceneTreeChildGetAll(const ecsid_t id, ecsid_t *children);
|
||||
* @param parent The ID of the parent scene item.
|
||||
* @param child The ID of the child scene item to add.
|
||||
*/
|
||||
void sceneTreeChildAdd(const ecsid_t parent, const ecsid_t child);
|
||||
void nodeChildAdd(const ecsid_t parent, const ecsid_t child);
|
||||
|
||||
/**
|
||||
* Remove a child from a parent in the scene tree.
|
||||
@@ -66,14 +70,14 @@ void sceneTreeChildAdd(const ecsid_t parent, const ecsid_t child);
|
||||
* @param prnt The ID of the parent scene item.
|
||||
* @param child The ID of the child scene item to remove.
|
||||
*/
|
||||
void sceneTreeChildRemove(const ecsid_t prnt, const ecsid_t child);
|
||||
void nodeChildRemove(const ecsid_t prnt, const ecsid_t child);
|
||||
|
||||
/**
|
||||
* Remove all children from a parent in the scene tree.
|
||||
*
|
||||
* @param parent The ID of the parent scene item.
|
||||
*/
|
||||
void sceneTreeChildRemoveAll(const ecsid_t parent);
|
||||
void nodeChildRemoveAll(const ecsid_t parent);
|
||||
|
||||
/**
|
||||
* Returns true if the child is within the parent's children, recursively.
|
||||
@@ -82,7 +86,14 @@ void sceneTreeChildRemoveAll(const ecsid_t parent);
|
||||
* @param child The ID of the child scene item to check.
|
||||
* @return True if the child is in the parent's children, false otherwise.
|
||||
*/
|
||||
bool_t sceneTreeChildInTree(const ecsid_t parent, const ecsid_t child);
|
||||
bool_t nodeChildInTree(const ecsid_t parent, const ecsid_t child);
|
||||
|
||||
/**
|
||||
* Initialize the scene tree.
|
||||
*
|
||||
* This will initialize the ECS system and prepare the scene tree for use.
|
||||
*/
|
||||
void nodeInit(void);
|
||||
|
||||
/**
|
||||
* Callback for when an entity is added to the ECS.
|
||||
@@ -90,7 +101,7 @@ bool_t sceneTreeChildInTree(const ecsid_t parent, const ecsid_t child);
|
||||
*
|
||||
* @param id The ID of the entity being added.
|
||||
*/
|
||||
void sceneTreeEntityAdded(const ecsid_t id);
|
||||
void nodeEntityAdded(const ecsid_t id);
|
||||
|
||||
/**
|
||||
* Callback for when an entity is removed from the ECS.
|
||||
@@ -98,4 +109,4 @@ void sceneTreeEntityAdded(const ecsid_t id);
|
||||
*
|
||||
* @param id The ID of the entity being removed.
|
||||
*/
|
||||
void sceneTreeEntityRemoved(const ecsid_t id);
|
||||
void nodeEntityRemoved(const ecsid_t id);
|
||||
@@ -1,160 +0,0 @@
|
||||
// Copyright (c) 2025 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "scenetree.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
scenetreenode_t SCENE_TREE_DATA[ECS_ENTITY_COUNT_MAX] = { 0 };
|
||||
ecscomponent_t SCENE_TREE_COMPONENT = ecsComponentInit(
|
||||
SCENE_TREE_DATA,
|
||||
((ecscomponentcallbacks_t){
|
||||
.init = sceneTreeInit,
|
||||
.entityAdd = sceneTreeEntityAdded,
|
||||
.entityRemove = sceneTreeEntityRemoved
|
||||
})
|
||||
);
|
||||
|
||||
void sceneTreeInit(void) {
|
||||
// Default all items to have no parent
|
||||
for (ecsid_t i = 0; i < ECS_ENTITY_COUNT_MAX; i++) {
|
||||
SCENE_TREE_DATA[i].parent = -1;
|
||||
}
|
||||
}
|
||||
|
||||
ecsid_t sceneTreeParentGet(const ecsid_t child) {
|
||||
assertTrue(child >= 0 && child < ECS_ENTITY_COUNT_MAX, "Invalid child ID");
|
||||
if(!ecsComponentDataHas(&SCENE_TREE_COMPONENT, child)) return -1;
|
||||
return SCENE_TREE_DATA[child].parent;
|
||||
}
|
||||
|
||||
uint8_t sceneTreeChildGetAll(const ecsid_t id, ecsid_t *children) {
|
||||
if(!ecsComponentDataHas(&SCENE_TREE_COMPONENT, id)) return 0;
|
||||
if(children == NULL) return SCENE_TREE_DATA[id].childCount;
|
||||
|
||||
memoryCopy(
|
||||
children,
|
||||
SCENE_TREE_DATA[id].children,
|
||||
sizeof(ecsid_t) * SCENE_TREE_DATA[id].childCount
|
||||
);
|
||||
|
||||
return SCENE_TREE_DATA[id].childCount;
|
||||
}
|
||||
|
||||
void sceneTreeChildAdd(const ecsid_t parent, const ecsid_t child) {
|
||||
if(!ecsComponentDataHas(&SCENE_TREE_COMPONENT, parent)) {
|
||||
ecsComponentDataAdd(&SCENE_TREE_COMPONENT, parent);
|
||||
}
|
||||
if(!ecsComponentDataHas(&SCENE_TREE_COMPONENT, child)) {
|
||||
ecsComponentDataAdd(&SCENE_TREE_COMPONENT, child);
|
||||
}
|
||||
|
||||
scenetreenode_t *parentNode = &SCENE_TREE_DATA[parent];
|
||||
assertTrue(parentNode->childCount < SCENE_ITEM_CHILD_MAX, "Parent full.");
|
||||
|
||||
// Add child to parent's children array
|
||||
parentNode->children[parentNode->childCount] = child;
|
||||
parentNode->childCount++;
|
||||
|
||||
// Set child's parent
|
||||
SCENE_TREE_DATA[child].parent = parent;
|
||||
}
|
||||
|
||||
void sceneTreeChildRemove(
|
||||
const ecsid_t parent,
|
||||
const ecsid_t child
|
||||
) {
|
||||
assertTrue(
|
||||
ecsComponentDataHas(&SCENE_TREE_COMPONENT, parent),
|
||||
"SCENE TREE ECS lacks Parent."
|
||||
);
|
||||
assertTrue(
|
||||
ecsComponentDataHas(&SCENE_TREE_COMPONENT, child),
|
||||
"SCENE TREE ECS lacks Child."
|
||||
);
|
||||
|
||||
scenetreenode_t *childNode = &SCENE_TREE_DATA[child];
|
||||
scenetreenode_t *parentNode = &SCENE_TREE_DATA[parent];
|
||||
assertTrue(childNode->parent == parent, "Child does not belong to parent");
|
||||
assertTrue(parentNode->childCount > 0, "Parent has no children");
|
||||
|
||||
// Remove child from parent's children array
|
||||
for (uint8_t i = 0; i < parentNode->childCount; i++) {
|
||||
if (parentNode->children[i] == child) {
|
||||
// Shift remaining children down
|
||||
for (uint8_t j = i; j < parentNode->childCount - 1; j++) {
|
||||
parentNode->children[j] = parentNode->children[j + 1];
|
||||
}
|
||||
parentNode->childCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear child's parent
|
||||
childNode->parent = -1;
|
||||
|
||||
if(childNode->childCount == 0) {
|
||||
ecsComponentDataRemove(&SCENE_TREE_COMPONENT, child);
|
||||
}
|
||||
|
||||
if(parentNode->childCount == 0) {
|
||||
ecsComponentDataRemove(&SCENE_TREE_COMPONENT, parent);
|
||||
}
|
||||
}
|
||||
|
||||
void sceneTreeChildRemoveAll(const ecsid_t parent) {
|
||||
assertTrue(
|
||||
ecsComponentDataHas(&SCENE_TREE_COMPONENT, parent),
|
||||
"SCENE TREE ECS lacks Parent."
|
||||
);
|
||||
|
||||
scenetreenode_t *parentNode = &SCENE_TREE_DATA[parent];
|
||||
for(uint8_t i = 0; i < parentNode->childCount; i++) {
|
||||
ecsid_t child = parentNode->children[i];
|
||||
SCENE_TREE_DATA[child].parent = -1;
|
||||
|
||||
if(SCENE_TREE_DATA[child].childCount == 0) {
|
||||
ecsComponentDataRemove(&SCENE_TREE_COMPONENT, child);
|
||||
}
|
||||
}
|
||||
|
||||
ecsComponentDataRemove(&SCENE_TREE_COMPONENT, parent);
|
||||
}
|
||||
|
||||
bool_t sceneTreeChildInTree(
|
||||
const ecsid_t parent,
|
||||
const ecsid_t child
|
||||
) {
|
||||
assertTrue(
|
||||
ecsComponentDataHas(&SCENE_TREE_COMPONENT, parent),
|
||||
"SCENE TREE ECS lacks Parent."
|
||||
);
|
||||
assertTrue(
|
||||
ecsComponentDataHas(&SCENE_TREE_COMPONENT, child),
|
||||
"SCENE TREE ECS lacks Child."
|
||||
);
|
||||
|
||||
assertTrue(parent >= 0 && parent < ECS_ENTITY_COUNT_MAX, "Invalid parent ID");
|
||||
assertTrue(child >= 0 && child < ECS_ENTITY_COUNT_MAX, "Invalid child ID");
|
||||
assertTrue(parent != child, "Child cannot be a child of itself.");
|
||||
|
||||
scenetreenode_t *childNode = &SCENE_TREE_DATA[child];
|
||||
while(childNode) {
|
||||
if(childNode->parent == parent) return true;
|
||||
if(childNode->parent == -1) break; // No parent means we've reached the root
|
||||
childNode = &SCENE_TREE_DATA[childNode->parent];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void sceneTreeEntityAdded(const ecsid_t id) {
|
||||
SCENE_TREE_DATA[id].parent = -1; // Default parent to -1 (no parent)
|
||||
}
|
||||
|
||||
void sceneTreeEntityRemoved(const ecsid_t id) {
|
||||
if(SCENE_TREE_DATA[id].parent == -1) return;
|
||||
sceneTreeChildRemove(SCENE_TREE_DATA[id].parent, id);
|
||||
}
|
||||
@@ -6,16 +6,24 @@
|
||||
*/
|
||||
|
||||
#include "scenetest.h"
|
||||
#include "scene/scenetree.h"
|
||||
#include "scene/node.h"
|
||||
#include "display/camera.h"
|
||||
#include "display/display.h"
|
||||
|
||||
ecsid_t sceneTestAdd(void) {
|
||||
ecsid_t id = ecsEntityAdd();
|
||||
|
||||
// Initialize the entity with a camera component
|
||||
ecsid_t camera = ecsEntityAdd();
|
||||
sceneTreeChildAdd(id, camera);
|
||||
nodeChildAdd(id, camera);
|
||||
camera_t *camData = cameraAdd(camera);
|
||||
camData->type = CAMERA_TYPE_ORTHOGRAPHIC;
|
||||
camData->orthographic.left = 0.0f;
|
||||
camData->orthographic.right = 1.0f;
|
||||
camData->orthographic.top = 0.0f;
|
||||
camData->orthographic.bottom = 1.0f;
|
||||
camData->nearClip = -1.0f;
|
||||
camData->farClip = 1.0f;
|
||||
|
||||
// Optionally, you can set other properties or components here
|
||||
|
||||
|
||||
Reference in New Issue
Block a user