Sun, 06 Oct 2024 20:49:43 +0200
revert introduction of high level ucx trees and stick to the low level API
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * Copyright 2023 Mike Becker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef ASCENSION_SCENE_H #define ASCENSION_SCENE_H #include "datatypes.h" #include "transform.h" #include "camera.h" #include "texture.h" #include <cx/list.h> typedef struct AscSceneNode AscSceneNode; typedef void(*asc_scene_free_func)(AscSceneNode*); typedef void(*asc_scene_update_func)(AscSceneNode*); enum AscRenderGroup { ASC_RENDER_GROUP_SPRITE_OPAQUE, ASC_RENDER_GROUP_SPRITE_BLEND, ASC_RENDER_GROUP_COUNT }; struct AscSceneNode { AscSceneNode *parent; AscSceneNode *prev; AscSceneNode *next; AscSceneNode *children; AscSceneNode *last_child; CxList *behaviors; asc_scene_free_func free_func; asc_scene_update_func update_func; unsigned depth; // TODO: do we really need this bullshit? asc_vec3f position; asc_vec3f rotation; asc_vec3f scale; asc_transform transform; asc_transform world_transform; enum AscRenderGroup render_group; /** * Custom flags for this node. * The #ASC_SCENE_NODE_FLAGS_MASK bits are reserved for general flags. */ uint32_t flags; }; typedef struct AscSprite { AscSceneNode data; AscTexture tex; } AscSprite; /** * The reserved bits for general flags. */ #define ASC_SCENE_NODE_FLAGS_MASK 0xFF000000 /** * Set when a graphics update is needed in this frame. */ #define ASC_SCENE_NODE_UPDATE_GRAPHICS 0x01000000 /** * Set when a graphics updated happened last frame. */ #define ASC_SCENE_NODE_GRAPHICS_UPDATED 0x10000000 /** * Set when a transform update is needed in this frame. */ #define ASC_SCENE_NODE_UPDATE_TRANSFORM 0x02000000 /** * Set when a transform update happened last frame. */ #define ASC_SCENE_NODE_TRANSFORM_UPDATED 0x20000000 /** * Set when the node is not supposed to be shown on screen. */ #define ASC_SCENE_NODE_HIDDEN 0x80000000 /** * Draws the scene with the specified root node. * * @param root the root node of the scene graph * @param viewport the window viewport the scene shall be drawn to * @param camera the camera to obtain the view and projection matrix from */ __attribute__((__nonnull__)) void asc_scene_draw(AscSceneNode *root, asc_recti viewport, AscCamera *camera); /** * Creates an empty node that may serve as a container for other nodes. * * The free_func of this node will be a simple free(). * * @return the new node */ AscSceneNode *asc_scene_node_empty(void); /** * Unlinks the node from its parent and frees the entire subtree. * * The free_func of this node and all child nodes is called, starting * with the leaf nodes and terminating with \p node. * * @param node the node to unlink */ void asc_scene_node_free(AscSceneNode *node); /** * Links a node to a (new) parent. * * @param parent the (new) parent * @param node the node to link */ __attribute__((__nonnull__)) void asc_scene_node_link( AscSceneNode *restrict parent, AscSceneNode *restrict node ); /** * Unlinks a node from its parent. * * This might be useful to temporarily remove a subtree from a scene. * To permanently remove the node use asc_scene_node_free(). * * @param node the node to unlink */ __attribute__((__nonnull__)) void asc_scene_node_unlink(AscSceneNode *node); /** * Adds a behavior function to the node. * * A behavior function MUST NOT be added more than once to the same node. * This will not be checked. * * @param node the node * @param behavior the behavior function */ __attribute__((__nonnull__)) void asc_scene_add_behavior( AscSceneNode *node, asc_scene_update_func behavior ); /** * Removes a behavior function from the node. * * If the behavior function is not attached to this node, this function * does nothing. * * @param node the node * @param behavior the behavior function */ __attribute__((__nonnull__)) void asc_scene_remove_behavior( AscSceneNode *node, asc_scene_update_func behavior ); __attribute__((__nonnull__)) void asc_node_update(AscSceneNode *node); __attribute__((__nonnull__)) void asc_node_update_transform(AscSceneNode *node); __attribute__((__nonnull__)) static inline void asc_set_position(AscSceneNode *node, float x, float y, float z) { node->position.x = x; node->position.y = y; node->position.z = z; asc_node_update_transform(node); } __attribute__((__nonnull__)) static inline void asc_set_position2d(AscSceneNode *node, int x, int y) { node->position.x = (float)x; node->position.y = (float)y; node->position.z = 0.f; asc_node_update_transform(node); } __attribute__((__nonnull__)) static inline asc_vec2i asc_get_position2d(AscSceneNode *node) { return (asc_vec2i) {(int) node->position.x, (int) node->position.y}; } __attribute__((__nonnull__)) static inline void asc_set_scale(AscSceneNode *node, float width, float height, float depth) { node->scale.width = width; node->scale.height = height; node->scale.depth = depth; asc_node_update_transform(node); } __attribute__((__nonnull__)) static inline void asc_set_scale2d(AscSceneNode *node, int width, int height) { node->scale.width = (float)width; node->scale.height = (float)height; node->scale.depth = 1.f; asc_node_update_transform(node); } __attribute__((__nonnull__)) static inline asc_vec2i asc_get_scale2d(AscSceneNode *node) { return (asc_vec2i) {(int) node->scale.width, (int) node->scale.height}; } #endif // ASCENSION_SCENE_H