src/scene.c

Mon, 04 Mar 2024 21:16:46 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 04 Mar 2024 21:16:46 +0100
changeset 32
86468a71dd73
parent 31
8324037e0148
child 33
e7ddb52facd3
permissions
-rw-r--r--

add transformation matrix

universe@21 1 /*
universe@21 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@21 3 * Copyright 2023 Mike Becker. All rights reserved.
universe@21 4 *
universe@21 5 * Redistribution and use in source and binary forms, with or without
universe@21 6 * modification, are permitted provided that the following conditions are met:
universe@21 7 *
universe@21 8 * 1. Redistributions of source code must retain the above copyright
universe@21 9 * notice, this list of conditions and the following disclaimer.
universe@21 10 *
universe@21 11 * 2. Redistributions in binary form must reproduce the above copyright
universe@21 12 * notice, this list of conditions and the following disclaimer in the
universe@21 13 * documentation and/or other materials provided with the distribution.
universe@21 14 *
universe@21 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@21 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@21 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@21 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@21 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@21 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@21 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@21 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@21 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@21 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@21 25 * POSSIBILITY OF SUCH DAMAGE.
universe@21 26 */
universe@21 27
universe@21 28 #include "ascension/scene.h"
universe@21 29 #include "ascension/error.h"
universe@21 30
universe@29 31 #include <cx/tree.h>
universe@29 32
universe@21 33 #include <assert.h>
universe@21 34
universe@30 35 #define node_layout_ \
universe@29 36 offsetof(AscSceneNode, parent), offsetof(AscSceneNode, children), \
universe@29 37 offsetof(AscSceneNode, prev), offsetof(AscSceneNode, next)
universe@30 38 #define child_list_off_ \
universe@30 39 offsetof(AscSceneNode, children), offsetof(AscSceneNode, next)
universe@29 40
universe@21 41 void asc_scene_init(AscScene *scene) {
universe@21 42 if (scene->root != NULL) {
universe@21 43 asc_error("Scene is already initialized.");
universe@21 44 return;
universe@21 45 }
universe@29 46 scene->root = asc_scene_node_empty();
universe@21 47 }
universe@21 48
universe@21 49 void asc_scene_destroy(AscScene *scene) {
universe@21 50 asc_scene_node_free(scene->root);
universe@21 51 }
universe@21 52
universe@29 53 void asc_scene_add(AscScene *scene, AscSceneNode *node) {
universe@29 54 asc_scene_node_link(scene->root, node);
universe@32 55 asc_node_update(node);
universe@29 56 }
universe@29 57
universe@30 58 void asc_scene_draw(AscScene const *scene) {
universe@30 59 CxTreeIterator iter = cx_tree_iterator(scene->root, false, child_list_off_);
universe@32 60
universe@32 61 // skip the root node deliberately, we know it's just the container
universe@32 62 cxIteratorNext(iter);
universe@32 63
universe@32 64 // draw the children
universe@30 65 cx_foreach(AscSceneNode*, node, iter) {
universe@32 66 if (node->need_update && node->update_func != NULL) {
universe@32 67 node->need_update = false;
universe@32 68 asc_transform_copy(node->transform, node->parent->transform);
universe@32 69 node->update_func(node);
universe@32 70 }
universe@32 71 // TODO: don't visit the tree for drawing, visit the render groups
universe@30 72 if (node->draw_func != NULL) {
universe@30 73 node->draw_func(node);
universe@30 74 }
universe@29 75 }
universe@29 76 }
universe@29 77
universe@29 78 AscSceneNode *asc_scene_node_empty(void) {
universe@27 79 AscSceneNode *node = calloc(1, sizeof(AscSceneNode));
universe@21 80 assert(node != NULL);
universe@29 81 node->free_func = (asc_scene_free_func) free;
universe@32 82 asc_transform_identity(node->transform);
universe@21 83 return node;
universe@21 84 }
universe@21 85
universe@21 86 void asc_scene_node_free(AscSceneNode *node) {
universe@21 87 if (node == NULL) return;
universe@27 88
universe@27 89 // remove this node from its parent
universe@27 90 asc_scene_node_unlink(node);
universe@27 91
universe@31 92 // free the entire subtree
universe@31 93 CxTreeIterator iter = cx_tree_iterator(node, true, child_list_off_);
universe@31 94 cx_foreach(AscSceneNode*, child, iter) {
universe@31 95 if (!iter.exiting) continue;
universe@31 96 if (child->free_func != NULL) {
universe@31 97 child->free_func(child);
universe@31 98 } else {
universe@31 99 free(child);
universe@31 100 }
universe@21 101 }
universe@21 102 }
universe@21 103
universe@29 104 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) {
universe@30 105 cx_tree_link(parent, node, node_layout_);
universe@29 106 }
universe@29 107
universe@21 108 void asc_scene_node_unlink(AscSceneNode *node) {
universe@30 109 cx_tree_unlink(node, node_layout_);
universe@21 110 }

mercurial