]> git.lizzy.rs Git - shadowclad.git/blob - src/engine/scene.c
Separate tranform code into geometry
[shadowclad.git] / src / engine / scene.c
1 #include <stdlib.h>
2
3 #include "engine/logger.h"
4
5 #include "geometry.h"
6 #include "scene.h"
7
8 Scene* currentScene = NULL;
9
10
11
12 Scene* newScene() {
13         Scene* scene = malloc(sizeof(Scene));
14         *scene = (Scene) { .parent = NULL,
15                            .numChildren = 0u,
16                            .children = NULL,
17                            .transform = identity(),
18                            .solid = NULL };
19         return scene;
20 }
21
22 void insertChildScene(Scene* scene, Scene* newChild) {
23         if (!scene || !newChild) {
24                 return;
25         }
26         if (newChild->parent) {
27                 logError(
28                         "Cannot insert scene 0x%p as child of 0x%p, because it is already child of 0x%p",
29                         newChild,
30                         scene,
31                         newChild->parent);
32                 return;
33         }
34
35         scene->children = realloc(scene->children, ++(scene->numChildren) * sizeof(Scene*));
36         scene->children[scene->numChildren - 1] = newChild;
37
38         newChild->parent = scene;
39 }
40
41 void reparentScene(Scene* scene, Scene* newParent) {
42         if (!scene) {
43                 return;
44         }
45
46         if (scene->parent) {
47                 Scene* parent = scene->parent;
48                 size_t indexInParent = parent->numChildren;
49                 for (size_t i = 0; i < parent->numChildren; ++i) {
50                         if (parent->children[i] == scene) {
51                                 indexInParent = i;
52                                 break;
53                         }
54                 }
55                 // This includes the hopefully impossible case where parent->numChildren == 0
56                 if (indexInParent == parent->numChildren) {
57                         logError("Scene %p not found in children of parent %p", scene, parent);
58                 }
59                 else {
60                         for (size_t i = indexInParent; i < parent->numChildren - 1; ++i) {
61                                 parent->children[i] = parent->children[i + 1];
62                         }
63                         parent->children = realloc(parent->children, --(parent->numChildren) * sizeof(Scene*));
64                 }
65         }
66
67         scene->parent = NULL;
68
69         insertChildScene(newParent, scene);
70 }