]> git.lizzy.rs Git - shadowclad.git/blobdiff - src/engine/scene.c
Add minimal, wonky scene tree system
[shadowclad.git] / src / engine / scene.c
diff --git a/src/engine/scene.c b/src/engine/scene.c
new file mode 100644 (file)
index 0000000..e1a4cee
--- /dev/null
@@ -0,0 +1,63 @@
+#include <stdlib.h>
+
+#include "engine/logger.h"
+
+#include "scene.h"
+
+Scene* currentScene = NULL;
+
+static Transform identity = { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = 0.0f,
+                              .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = 0.0f,
+                              .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = 0.0f,
+                              .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f };
+
+void multiply(Transform* transform, Transform by) {
+       GLfloat* a = (GLfloat*) &by;
+       GLfloat* b = (GLfloat*) transform;
+
+       for (size_t row = 0; row < 4; ++row) {
+               for (size_t col = 0; col < 4; ++col) {
+                       b[(row * 4) + col] =
+                               a[(row * 4) + 0] * b[(0 * 4) + col]
+                               + a[(row * 4) + 1] * b[(1 * 4) + col]
+                               + a[(row * 4) + 2] * b[(2 * 4) + col]
+                               + a[(row * 4) + 3] * b[(3 * 4) + col];
+               }
+       }
+}
+
+void translate(Transform* transform, Vector3D vec) {
+       multiply(transform, (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = vec.x,
+                                      .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = vec.y,
+                                      .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = vec.z,
+                                      .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f });
+}
+
+Scene* newScene() {
+       Scene* scene = malloc(sizeof(Scene));
+       *scene = (Scene) { .parent = NULL,
+                          .numChildren = 0u,
+                          .children = NULL,
+                          .transform = identity,
+                          .solid = NULL };
+       return scene;
+}
+
+void insertChildScene(Scene* scene, Scene* newChild) {
+       if (!scene || !newChild) {
+               return;
+       }
+       if (newChild->parent) {
+               logError(
+                       "Cannot insert scene 0x%p as child of 0x%p, because it is already child of 0x%p",
+                       newChild,
+                       scene,
+                       newChild->parent);
+               return;
+       }
+
+       scene->children = realloc(scene->children, ++(scene->numChildren) * sizeof(Scene*));
+       scene->children[scene->numChildren - 1] = newChild;
+
+       newChild->parent = scene;
+}