From cdf5a5229c82aedc1b62ac35b8eeecbf8c5a394b Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 21 May 2026 12:52:23 -0500 Subject: [PATCH] Refactor cleaned a few things --- .../entity/component/display/entityposition.c | 85 ++++++++--- .../entity/component/display/entityposition.h | 144 +++++++++++++++--- .../component/display/entityrenderable.c | 138 +++-------------- .../component/display/entityrenderable.h | 134 ++-------------- src/dusk/entity/componentlist.h | 8 +- src/dusk/scene/initial/initialscene.c | 61 +++----- src/dusk/scene/initial/initialscene.h | 7 - src/dusk/scene/scene.c | 106 ++++++++----- src/dusk/scene/scene.h | 5 +- src/dusk/scene/scenelist.h | 4 +- 10 files changed, 316 insertions(+), 376 deletions(-) diff --git a/src/dusk/entity/component/display/entityposition.c b/src/dusk/entity/component/display/entityposition.c index 3c1c0c30..3813fb4b 100644 --- a/src/dusk/entity/component/display/entityposition.c +++ b/src/dusk/entity/component/display/entityposition.c @@ -7,9 +7,29 @@ #include "entity/entitymanager.h" -// Lazily recompute worldTransform from the parent chain. -static void entityPositionUpdateWorld(entityposition_t *pos) { - if(!pos->dirty) return; +// Decompose localTransform into the PRS cache. Only called when PRS_DIRTY. +static void entityPositionEnsurePRS(entityposition_t *pos) { + if(!(pos->flags & ENTITY_POSITION_FLAG_PRS_DIRTY)) return; + entityPositionDecompose(pos); + pos->flags &= ~ENTITY_POSITION_FLAG_PRS_DIRTY; +} + +// Rebuild localTransform from the PRS cache. Only called when LOCAL_DIRTY. +static void entityPositionEnsureLocal(entityposition_t *pos) { + if(!(pos->flags & ENTITY_POSITION_FLAG_LOCAL_DIRTY)) return; + glm_mat4_identity(pos->localTransform); + glm_translate(pos->localTransform, pos->position); + glm_rotate_x(pos->localTransform, pos->rotation[0], pos->localTransform); + glm_rotate_y(pos->localTransform, pos->rotation[1], pos->localTransform); + glm_rotate_z(pos->localTransform, pos->rotation[2], pos->localTransform); + glm_scale(pos->localTransform, pos->scale); + pos->flags &= ~ENTITY_POSITION_FLAG_LOCAL_DIRTY; +} + +// Recompute worldTransform from the parent chain. Only called when WORLD_DIRTY. +static void entityPositionEnsureWorld(entityposition_t *pos) { + entityPositionEnsureLocal(pos); + if(!(pos->flags & ENTITY_POSITION_FLAG_WORLD_DIRTY)) return; if(pos->parentEntityId == ENTITY_ID_INVALID) { glm_mat4_copy(pos->localTransform, pos->worldTransform); @@ -17,15 +37,16 @@ static void entityPositionUpdateWorld(entityposition_t *pos) { entityposition_t *parent = componentGetData( pos->parentEntityId, pos->parentComponentId, COMPONENT_TYPE_POSITION ); - entityPositionUpdateWorld(parent); + entityPositionEnsureWorld(parent); glm_mat4_mul(parent->worldTransform, pos->localTransform, pos->worldTransform); } - pos->dirty = false; + pos->flags &= ~ENTITY_POSITION_FLAG_WORLD_DIRTY; } void entityPositionMarkDirty(entityposition_t *pos) { - pos->dirty = true; + if(pos->flags & ENTITY_POSITION_FLAG_WORLD_DIRTY) return; + pos->flags |= ENTITY_POSITION_FLAG_WORLD_DIRTY; for(uint8_t i = 0; i < pos->childCount; i++) { entityposition_t *child = componentGetData( pos->childEntityIds[i], pos->childComponentIds[i], COMPONENT_TYPE_POSITION @@ -47,7 +68,7 @@ void entityPositionInit( glm_vec3_one(pos->scale); glm_mat4_identity(pos->localTransform); glm_mat4_identity(pos->worldTransform); - pos->dirty = false; + pos->flags = 0; pos->parentEntityId = ENTITY_ID_INVALID; pos->parentComponentId = COMPONENT_ID_INVALID; pos->childCount = 0; @@ -56,15 +77,17 @@ void entityPositionInit( void entityPositionLookAt( const entityid_t entityId, const componentid_t componentId, + vec3 eye, vec3 target, - vec3 up, - vec3 eye + vec3 up ) { entityposition_t *pos = componentGetData( entityId, componentId, COMPONENT_TYPE_POSITION ); glm_lookat(eye, target, up, pos->localTransform); - entityPositionDecompose(pos); + // localTransform is now authoritative; PRS cache is stale. + pos->flags = (pos->flags | ENTITY_POSITION_FLAG_PRS_DIRTY) + & ~ENTITY_POSITION_FLAG_LOCAL_DIRTY; entityPositionMarkDirty(pos); } @@ -76,7 +99,7 @@ void entityPositionGetTransform( entityposition_t *pos = componentGetData( entityId, componentId, COMPONENT_TYPE_POSITION ); - entityPositionUpdateWorld(pos); + entityPositionEnsureWorld(pos); glm_mat4_copy(pos->worldTransform, dest); } @@ -88,9 +111,22 @@ void entityPositionGetLocalTransform( entityposition_t *pos = componentGetData( entityId, componentId, COMPONENT_TYPE_POSITION ); + entityPositionEnsureLocal(pos); glm_mat4_copy(pos->localTransform, dest); } +void entityPositionGetLocalPosition( + const entityid_t entityId, + const componentid_t componentId, + vec3 dest +) { + entityposition_t *pos = componentGetData( + entityId, componentId, COMPONENT_TYPE_POSITION + ); + entityPositionEnsurePRS(pos); + glm_vec3_copy(pos->position, dest); +} + void entityPositionGetPosition( const entityid_t entityId, const componentid_t componentId, @@ -99,7 +135,10 @@ void entityPositionGetPosition( entityposition_t *pos = componentGetData( entityId, componentId, COMPONENT_TYPE_POSITION ); - glm_vec3_copy(pos->position, dest); + entityPositionEnsureWorld(pos); + dest[0] = pos->worldTransform[3][0]; + dest[1] = pos->worldTransform[3][1]; + dest[2] = pos->worldTransform[3][2]; } void entityPositionSetPosition( @@ -111,7 +150,9 @@ void entityPositionSetPosition( entityId, componentId, COMPONENT_TYPE_POSITION ); glm_vec3_copy(position, pos->position); - entityPositionRebuild(pos); + pos->flags = (pos->flags | ENTITY_POSITION_FLAG_LOCAL_DIRTY) + & ~ENTITY_POSITION_FLAG_PRS_DIRTY; + entityPositionMarkDirty(pos); } void entityPositionGetRotation( @@ -122,6 +163,7 @@ void entityPositionGetRotation( entityposition_t *pos = componentGetData( entityId, componentId, COMPONENT_TYPE_POSITION ); + entityPositionEnsurePRS(pos); glm_vec3_copy(pos->rotation, dest); } @@ -134,7 +176,9 @@ void entityPositionSetRotation( entityId, componentId, COMPONENT_TYPE_POSITION ); glm_vec3_copy(rotation, pos->rotation); - entityPositionRebuild(pos); + pos->flags = (pos->flags | ENTITY_POSITION_FLAG_LOCAL_DIRTY) + & ~ENTITY_POSITION_FLAG_PRS_DIRTY; + entityPositionMarkDirty(pos); } void entityPositionGetScale( @@ -145,6 +189,7 @@ void entityPositionGetScale( entityposition_t *pos = componentGetData( entityId, componentId, COMPONENT_TYPE_POSITION ); + entityPositionEnsurePRS(pos); glm_vec3_copy(pos->scale, dest); } @@ -157,7 +202,9 @@ void entityPositionSetScale( entityId, componentId, COMPONENT_TYPE_POSITION ); glm_vec3_copy(scale, pos->scale); - entityPositionRebuild(pos); + pos->flags = (pos->flags | ENTITY_POSITION_FLAG_LOCAL_DIRTY) + & ~ENTITY_POSITION_FLAG_PRS_DIRTY; + entityPositionMarkDirty(pos); } void entityPositionSetParent( @@ -218,12 +265,8 @@ entityposition_t *entityPositionGet( } void entityPositionRebuild(entityposition_t *pos) { - glm_mat4_identity(pos->localTransform); - glm_translate(pos->localTransform, pos->position); - glm_rotate_x(pos->localTransform, pos->rotation[0], pos->localTransform); - glm_rotate_y(pos->localTransform, pos->rotation[1], pos->localTransform); - glm_rotate_z(pos->localTransform, pos->rotation[2], pos->localTransform); - glm_scale(pos->localTransform, pos->scale); + pos->flags = (pos->flags | ENTITY_POSITION_FLAG_LOCAL_DIRTY) + & ~ENTITY_POSITION_FLAG_PRS_DIRTY; entityPositionMarkDirty(pos); } diff --git a/src/dusk/entity/component/display/entityposition.h b/src/dusk/entity/component/display/entityposition.h index 1513bfbb..99830d5b 100644 --- a/src/dusk/entity/component/display/entityposition.h +++ b/src/dusk/entity/component/display/entityposition.h @@ -8,24 +8,58 @@ #pragma once #include "entity/entitybase.h" +/** Maximum number of child position components this node can track. */ #define ENTITY_POSITION_CHILDREN_MAX 8 +/** + * PRS cache is stale. localTransform was written directly (e.g. lookAt) and + * position/rotation/scale need to be decomposed before they can be read. + */ +#define ENTITY_POSITION_FLAG_PRS_DIRTY (1 << 0) + +/** + * localTransform is stale. PRS was updated via a setter; the matrix needs to + * be rebuilt from position/rotation/scale before it can be used. + */ +#define ENTITY_POSITION_FLAG_LOCAL_DIRTY (1 << 1) + +/** + * worldTransform is stale. Either the local matrix changed or an ancestor + * moved; the full parent-chain multiply must be rerun before world data is read. + */ +#define ENTITY_POSITION_FLAG_WORLD_DIRTY (1 << 2) + typedef struct { + /** Local transform matrix, rebuilt lazily from position/rotation/scale. */ mat4 localTransform; + /** World transform matrix, recomputed lazily from the parent chain. */ mat4 worldTransform; + /** Cached local position (XYZ). May be stale when ENTITY_POSITION_FLAG_PRS_DIRTY is set. */ vec3 position; + /** Cached local euler rotation (XYZ, radians). May be stale when ENTITY_POSITION_FLAG_PRS_DIRTY is set. */ vec3 rotation; + /** Cached local scale (XYZ). May be stale when ENTITY_POSITION_FLAG_PRS_DIRTY is set. */ vec3 scale; - bool dirty; + /** Bitmask of ENTITY_POSITION_FLAG_* values describing which caches are stale. */ + uint8_t flags; + /** Entity ID of the parent node, or ENTITY_ID_INVALID if none. */ entityid_t parentEntityId; + /** Component ID of the parent position component, or COMPONENT_ID_INVALID if none. */ componentid_t parentComponentId; + /** Number of currently registered children. */ uint8_t childCount; + /** Entity IDs of child nodes. */ entityid_t childEntityIds[ENTITY_POSITION_CHILDREN_MAX]; + /** Component IDs of child position components. */ componentid_t childComponentIds[ENTITY_POSITION_CHILDREN_MAX]; } entityposition_t; /** - * Initialize the entity position component. + * Initializes the entity position component, setting identity transforms and + * zeroing all parent/child state. + * + * @param entityId The entity ID. + * @param componentId The component ID. */ void entityPositionInit( const entityid_t entityId, @@ -37,24 +71,24 @@ void entityPositionInit( * * @param entityId The entity ID. * @param componentId The component ID. - * @param target The target point to look at. - * @param up The up vector. - * @param eye The eye/camera position. + * @param eye The eye/camera position. + * @param target The target point to look at. + * @param up The up vector. */ void entityPositionLookAt( const entityid_t entityId, const componentid_t componentId, + vec3 eye, vec3 target, - vec3 up, - vec3 eye + vec3 up ); /** * Gets the world-space transform matrix, recomputing it lazily if dirty. * - * @param entityId The entity ID. + * @param entityId The entity ID. * @param componentId The component ID. - * @param dest Destination matrix. + * @param dest Destination matrix. */ void entityPositionGetTransform( const entityid_t entityId, @@ -65,9 +99,9 @@ void entityPositionGetTransform( /** * Gets the local transform matrix (does not include parent transforms). * - * @param entityId The entity ID. + * @param entityId The entity ID. * @param componentId The component ID. - * @param dest Destination matrix. + * @param dest Destination matrix. */ void entityPositionGetLocalTransform( const entityid_t entityId, @@ -76,7 +110,28 @@ void entityPositionGetLocalTransform( ); /** - * Gets the cached local position. + * Gets the cached local position (XYZ). Decomposes localTransform into PRS + * first if ENTITY_POSITION_FLAG_PRS_DIRTY is set; never triggers a matrix + * rebuild or world-transform update. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param dest Destination vector. + */ +void entityPositionGetLocalPosition( + const entityid_t entityId, + const componentid_t componentId, + vec3 dest +); + +/** + * Gets the world-space position. Rebuilds localTransform from PRS if + * ENTITY_POSITION_FLAG_LOCAL_DIRTY is set, then recomputes worldTransform + * from the parent chain if ENTITY_POSITION_FLAG_WORLD_DIRTY is set. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param dest Destination vector. */ void entityPositionGetPosition( const entityid_t entityId, @@ -85,7 +140,12 @@ void entityPositionGetPosition( ); /** - * Sets the local position and marks the world transform dirty. + * Sets the local position, updates the PRS cache immediately, and lazily + * flags localTransform and worldTransform (self + descendants) for rebuild. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param position The new local position. */ void entityPositionSetPosition( const entityid_t entityId, @@ -94,7 +154,12 @@ void entityPositionSetPosition( ); /** - * Gets the cached local euler rotation (XYZ, radians). + * Gets the cached local euler rotation (XYZ, radians). Decomposes + * localTransform into PRS first if ENTITY_POSITION_FLAG_PRS_DIRTY is set. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param dest Destination vector. */ void entityPositionGetRotation( const entityid_t entityId, @@ -103,7 +168,12 @@ void entityPositionGetRotation( ); /** - * Sets the local euler rotation (XYZ, radians) and marks the world transform dirty. + * Sets the local euler rotation (XYZ, radians), updates the PRS cache + * immediately, and lazily flags localTransform and worldTransform for rebuild. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param rotation The new local rotation. */ void entityPositionSetRotation( const entityid_t entityId, @@ -112,7 +182,12 @@ void entityPositionSetRotation( ); /** - * Gets the cached local scale. + * Gets the cached local scale. Decomposes localTransform into PRS first if + * ENTITY_POSITION_FLAG_PRS_DIRTY is set. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param dest Destination vector. */ void entityPositionGetScale( const entityid_t entityId, @@ -121,7 +196,12 @@ void entityPositionGetScale( ); /** - * Sets the local scale and marks the world transform dirty. + * Sets the local scale, updates the PRS cache immediately, and lazily flags + * localTransform and worldTransform for rebuild. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param scale The new local scale. */ void entityPositionSetScale( const entityid_t entityId, @@ -133,9 +213,9 @@ void entityPositionSetScale( * Sets the parent of this entity's position component. * Pass ENTITY_ID_INVALID / COMPONENT_ID_INVALID to detach from any parent. * - * @param entityId The child entity ID. - * @param componentId The child component ID. - * @param parentEntityId The parent entity ID. + * @param entityId The child entity ID. + * @param componentId The child component ID. + * @param parentEntityId The parent entity ID. * @param parentComponentId The parent component ID. */ void entityPositionSetParent( @@ -147,7 +227,13 @@ void entityPositionSetParent( /** * Returns a direct pointer to the entity position component data. - * After modifying localTransform directly, call entityPositionMarkDirty(). + * After modifying localTransform directly, call entityPositionMarkDirty() to + * set ENTITY_POSITION_FLAG_WORLD_DIRTY on self and descendants. After + * modifying PRS directly, call entityPositionRebuild() instead. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @return Pointer to the component data. */ entityposition_t *entityPositionGet( const entityid_t entityId, @@ -155,13 +241,21 @@ entityposition_t *entityPositionGet( ); /** - * Rebuilds the local transform matrix from the cached position/rotation/scale, - * then marks this node and all descendants dirty. + * Signals that the PRS cache was modified externally. Sets + * ENTITY_POSITION_FLAG_LOCAL_DIRTY so localTransform is rebuilt lazily on the + * next read, clears ENTITY_POSITION_FLAG_PRS_DIRTY, and propagates + * ENTITY_POSITION_FLAG_WORLD_DIRTY to self and all descendants. + * + * @param pos The position component whose PRS was modified. */ void entityPositionRebuild(entityposition_t *pos); /** - * Marks this node and all descendants as having a stale world transform. + * Sets ENTITY_POSITION_FLAG_WORLD_DIRTY on this node and all descendants, + * indicating that worldTransform must be recomputed before it is read. + * Call this after modifying localTransform directly. + * + * @param pos The position component to mark dirty. */ void entityPositionMarkDirty(entityposition_t *pos); @@ -180,5 +274,7 @@ void entityPositionDisposeDeep( /** * Decomposes the local transform matrix back into the position, rotation * (XYZ euler, radians), and scale cache fields. + * + * @param pos The position component to decompose. */ void entityPositionDecompose(entityposition_t *pos); diff --git a/src/dusk/entity/component/display/entityrenderable.c b/src/dusk/entity/component/display/entityrenderable.c index a93a04f8..3e2102b5 100644 --- a/src/dusk/entity/component/display/entityrenderable.c +++ b/src/dusk/entity/component/display/entityrenderable.c @@ -9,6 +9,13 @@ #include "entity/entitymanager.h" #include "display/shader/shaderunlit.h" #include "display/mesh/cube.h" +#include "display/spritebatch/spritebatch.h" + +errorret_t entityRenderableDrawDefault() { + errorChain(shaderSetColor(&SHADER_UNLIT, SHADER_UNLIT_COLOR, COLOR_WHITE)); + errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, NULL)); + return meshDraw(&CUBE_MESH_SIMPLE, 0, -1); +} void entityRenderableInit( const entityid_t entityId, @@ -17,133 +24,22 @@ void entityRenderableInit( entityrenderable_t *r = componentGetData( entityId, componentId, COMPONENT_TYPE_RENDERABLE ); - r->type = ENTITY_RENDERABLE_TYPE_MATERIAL; - r->mesh = &CUBE_MESH_SIMPLE; - r->shader = &SHADER_UNLIT; - r->material.unlit.color = COLOR_WHITE; -} - -entityrenderabletype_t entityRenderableGetType( - const entityid_t entityId, - const componentid_t componentId -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - return r->type; -} - -void entityRenderableSetType( - const entityid_t entityId, - const componentid_t componentId, - const entityrenderabletype_t type -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - r->type = type; -} - -mesh_t * entityRenderableGetMesh( - const entityid_t entityId, - const componentid_t componentId -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - return r->mesh; -} - -void entityRenderableSetMesh( - const entityid_t entityId, - const componentid_t componentId, - mesh_t *mesh -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - r->mesh = mesh; -} - -shader_t * entityRenderableGetShader( - const entityid_t entityId, - const componentid_t componentId -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - return r->shader; -} - -void entityRenderableSetShader( - const entityid_t entityId, - const componentid_t componentId, - shader_t *shader -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - r->shader = shader; -} - -shadermaterial_t * entityRenderableGetShaderMaterial( - const entityid_t entityId, - const componentid_t componentId -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - return &r->material; -} - -void entityRenderableSetColor( - const entityid_t entityId, - const componentid_t componentId, - const color_t color -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - r->material.unlit.color = color; -} - -void entityRenderableSpriteBatchAdd( - const entityid_t entityId, - const componentid_t componentId, - const spritebatchsprite_t *sprite -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - if(r->spritebatch.spriteCount >= ENTITY_RENDERABLE_SPRITEBATCH_SPRITES_MAX) return; - r->spritebatch.sprites[r->spritebatch.spriteCount++] = *sprite; -} - -void entityRenderableSpriteBatchClear( - const entityid_t entityId, - const componentid_t componentId -) { - entityrenderable_t *r = componentGetData( - entityId, componentId, COMPONENT_TYPE_RENDERABLE - ); - r->spritebatch.spriteCount = 0; + r->draw = entityRenderableDrawDefault; } void entityRenderableDispose( const entityid_t entityId, const componentid_t componentId ) { + +} + +errorret_t entityRenderableDraw( + const entityid_t entityId, + const componentid_t componentId +) { entityrenderable_t *r = componentGetData( entityId, componentId, COMPONENT_TYPE_RENDERABLE ); - if( - r->type == ENTITY_RENDERABLE_TYPE_CALLBACK && - r->userFree && - r->user - ) { - r->userFree(r->user); - r->user = NULL; - } - r->mesh = NULL; - r->shader = NULL; -} + return r->draw(); +} \ No newline at end of file diff --git a/src/dusk/entity/component/display/entityrenderable.h b/src/dusk/entity/component/display/entityrenderable.h index 7a1553c0..5213627e 100644 --- a/src/dusk/entity/component/display/entityrenderable.h +++ b/src/dusk/entity/component/display/entityrenderable.h @@ -11,48 +11,16 @@ #include "display/shader/shadermaterial.h" #include "display/spritebatch/spritebatch.h" -#define ENTITY_RENDERABLE_SPRITEBATCH_SPRITES_MAX 64 - -typedef enum { - ENTITY_RENDERABLE_TYPE_MATERIAL = 0, - ENTITY_RENDERABLE_TYPE_SPRITEBATCH, - ENTITY_RENDERABLE_TYPE_CALLBACK, -} entityrenderabletype_t; - -typedef errorret_t (*entityrenderablecallback_t)( - const entityid_t entityId, - const componentid_t componentId, - const mat4 view, - const mat4 proj, - const mat4 model, - void *user -); - typedef struct { - spritebatchsprite_t sprites[ENTITY_RENDERABLE_SPRITEBATCH_SPRITES_MAX]; - uint16_t spriteCount; -} entityrenderablespritebatch_t; - -typedef struct { - entityrenderabletype_t type; - shader_t *shader; - union { - struct { - mesh_t *mesh; - shadermaterial_t material; - }; - entityrenderablespritebatch_t spritebatch; - struct { - entityrenderablecallback_t callback; - void (*userFree)(void *user); - void *user; - }; - }; + errorret_t (*draw)(void); } entityrenderable_t; /** * Initializes the entity renderable component. Defaults to * ENTITY_RENDERABLE_TYPE_MATERIAL, the unlit shader, white color, no mesh. + * + * @param entityId The entity to initialize the component for. + * @param componentId The renderable component of the entity. */ void entityRenderableInit( const entityid_t entityId, @@ -61,6 +29,9 @@ void entityRenderableInit( /** * Disposes the entity renderable component, freeing any callback user data. + * + * @param entityId The entity to dispose the component for. + * @param componentId The renderable component of the entity. */ void entityRenderableDispose( const entityid_t entityId, @@ -68,90 +39,13 @@ void entityRenderableDispose( ); /** - * Gets the renderable type. + * Draws the entity using its renderable component data. + * + * @param entityId The entity to draw. + * @param componentId The renderable component of the entity. + * @return Any error state that happened. */ -entityrenderabletype_t entityRenderableGetType( +errorret_t entityRenderableDraw( const entityid_t entityId, const componentid_t componentId -); - -/** - * Sets the renderable type. - */ -void entityRenderableSetType( - const entityid_t entityId, - const componentid_t componentId, - const entityrenderabletype_t type -); - -/** - * Gets the mesh pointer (ENTITY_RENDERABLE_TYPE_MATERIAL only). - */ -mesh_t * entityRenderableGetMesh( - const entityid_t entityId, - const componentid_t componentId -); - -/** - * Sets the mesh pointer (ENTITY_RENDERABLE_TYPE_MATERIAL only). - */ -void entityRenderableSetMesh( - const entityid_t entityId, - const componentid_t componentId, - mesh_t *mesh -); - -/** - * Gets the shader pointer. - */ -shader_t * entityRenderableGetShader( - const entityid_t entityId, - const componentid_t componentId -); - -/** - * Sets the shader pointer. - */ -void entityRenderableSetShader( - const entityid_t entityId, - const componentid_t componentId, - shader_t *shader -); - -/** - * Gets a pointer to the shader material union - * (ENTITY_RENDERABLE_TYPE_MATERIAL only). - */ -shadermaterial_t * entityRenderableGetShaderMaterial( - const entityid_t entityId, - const componentid_t componentId -); - -/** - * Sets the unlit color (ENTITY_RENDERABLE_TYPE_MATERIAL only). - */ -void entityRenderableSetColor( - const entityid_t entityId, - const componentid_t componentId, - const color_t color -); - -/** - * Appends a sprite to the spritebatch renderable - * (ENTITY_RENDERABLE_TYPE_SPRITEBATCH only). - * Does nothing if the sprite buffer is full. - */ -void entityRenderableSpriteBatchAdd( - const entityid_t entityId, - const componentid_t componentId, - const spritebatchsprite_t *sprite -); - -/** - * Clears all buffered sprites from the spritebatch renderable - * (ENTITY_RENDERABLE_TYPE_SPRITEBATCH only). - */ -void entityRenderableSpriteBatchClear( - const entityid_t entityId, - const componentid_t componentId -); +); \ No newline at end of file diff --git a/src/dusk/entity/componentlist.h b/src/dusk/entity/componentlist.h index d3cf5fbd..4c7367c2 100644 --- a/src/dusk/entity/componentlist.h +++ b/src/dusk/entity/componentlist.h @@ -17,8 +17,8 @@ // Init function (optional) // Dispose function (optional) -X(POSITION, entityposition_t, position, entityPositionInit, NULL) -X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL) +X(POSITION, entityposition_t, position, entityPositionInit, NULL) +X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL) X(RENDERABLE, entityrenderable_t, renderable, entityRenderableInit, entityRenderableDispose) -X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose) -X(TRIGGER, entitytrigger_t, trigger, entityTriggerInit, NULL) +X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose) +X(TRIGGER, entitytrigger_t, trigger, entityTriggerInit, NULL) diff --git a/src/dusk/scene/initial/initialscene.c b/src/dusk/scene/initial/initialscene.c index 3a7ea5a3..cf712e47 100644 --- a/src/dusk/scene/initial/initialscene.c +++ b/src/dusk/scene/initial/initialscene.c @@ -9,57 +9,38 @@ #include "console/console.h" #include "display/spritebatch/spritebatch.h" #include "display/screen/screen.h" +#include "entity/entitymanager.h" #include "display/shader/shaderunlit.h" void initialSceneInit(void) { consolePrint("Initial scene initialized"); + + entityid_t camera = entityManagerAdd(); + componentid_t camPos = entityAddComponent(camera, COMPONENT_TYPE_POSITION); + componentid_t camCam = entityAddComponent(camera, COMPONENT_TYPE_CAMERA); + + // entitycamera_t *camData = (entitycamera_t*)entityGetComponent(camera, camCam); + + entityid_t cube = entityManagerAdd(); + // componentid_t cubePos = entityAddComponent(cube, COMPONENT_TYPE_POSITION); + componentid_t cubeDraw = entityAddComponent(cube, COMPONENT_TYPE_RENDERABLE); + // entityrenderable_t *cubeDrawData = ( + // (entityrenderable_t*)entityGetComponent(cube, cubeDraw) + // ); + + // Look at the cube. + vec3 eye, target, up; + glm_vec3_zero(target); + glm_vec3_copy((vec3){ 3.0f, 3.0f, 3.0f }, eye); + glm_vec3_copy((vec3){ 0.0f, 1.0f, 0.0f }, up); + entityPositionLookAt(camera, camPos, eye, target, up); } errorret_t initialSceneUpdate(void) { errorOk(); } -errorret_t initialSceneDraw(void) { - { - mat4 view, proj; - glm_perspective( - glm_rad(45.0f), - (float_t)SCREEN.width / (float_t)SCREEN.height, - 0.1f, - 100.0f, - proj - ); - shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj); - - glm_lookat( - (vec3){ 3.0f, 3.0f, 3.0f }, - (vec3){ 0.0f, 0.0f, 0.0f }, - (vec3){ 0.0f, 1.0f, 0.0f }, - view - ); - shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view); - } - - errorChain(displaySetState((displaystate_t){ - .flags = DISPLAY_STATE_FLAG_BLEND | DISPLAY_STATE_FLAG_DEPTH_TEST - })); - - // Draw entities - spriteBatchPushZ( - (vec3){ 0.0f, 0.0f, 0.0f }, - (vec3){ 32.0f, 32.0f, 0.0f }, - #if MESH_ENABLE_COLOR - COLOR_WHITE, - #endif - (vec2){ 0.0f, 0.0f }, - (vec2){ 1.0f, 1.0f } - ); - spriteBatchFlush(); - - errorOk(); -} - void initialSceneDispose(void) { } \ No newline at end of file diff --git a/src/dusk/scene/initial/initialscene.h b/src/dusk/scene/initial/initialscene.h index af29ae9b..371d25f6 100644 --- a/src/dusk/scene/initial/initialscene.h +++ b/src/dusk/scene/initial/initialscene.h @@ -24,13 +24,6 @@ void initialSceneInit(void); */ errorret_t initialSceneUpdate(void); -/** - * Initial scene drawer. - * - * @return Any error state that happened. - */ -errorret_t initialSceneDraw(void); - /** * Initial scene disposer. */ diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index 0473eca5..b5d46699 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -20,8 +20,8 @@ scenefuncs_t SCENE_FUNCTIONS[SCENE_TYPE_COUNT] = { { 0 }, - #define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \ - { initFunc, updateFunc, renderFunc, disposeFunc }, + #define X(structName, varName, varNameUpper, initFunc, updateFunc, disposeFunc) \ + { initFunc, updateFunc, disposeFunc }, #include "scene/scenelist.h" #undef X }; @@ -75,47 +75,85 @@ errorret_t sceneUpdate(void) { dusktimeepoch_t LAST; errorret_t sceneRender(void) { - mat4 model; - glm_mat4_identity(model); + mat4 proj, view, model, ident; + glm_mat4_identity(ident); errorChain(shaderBind(&SHADER_UNLIT)); - // Perform soft reset - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); - errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, NULL)); - errorChain(shaderSetColor(&SHADER_UNLIT, SHADER_UNLIT_COLOR, COLOR_WHITE)); - // Render scene. - if(SCENE.type != SCENE_TYPE_NULL && SCENE_FUNCTIONS[SCENE.type].render) { - errorChain(SCENE_FUNCTIONS[SCENE.type].render()); + entityid_t camera = entityCameraGetCurrent(); + entityid_t entities[ENTITY_COUNT_MAX]; + componentid_t components[ENTITY_COUNT_MAX]; + entityid_t entCount = componentGetEntitiesWithComponent( + COMPONENT_TYPE_RENDERABLE, + entities, components + ); + + // Anything to render? + if(camera != ENTITY_ID_INVALID && entCount > 0) { + componentid_t camPos = entityGetComponent(camera,COMPONENT_TYPE_POSITION); + componentid_t camCam = entityGetComponent(camera,COMPONENT_TYPE_CAMERA); + + // View + if(camPos == COMPONENT_ID_INVALID) { + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, ident)); + } else { + entityPositionGetTransform(camera, camPos, view); + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); + } + + // Projection + assertTrue( + camCam != COMPONENT_ID_INVALID, + "Current camera does not have a camera component?" + ); + entityCameraGetProjection(camera, camCam, proj); + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)); + + // For each ent. + for(entityid_t i = 0; i < entCount; i++) { + entityid_t entityId = entities[i]; + componentid_t renderableComp = components[i]; + + // Has position? + componentid_t posComp = entityGetComponent( + entityId, COMPONENT_TYPE_POSITION + ); + if(posComp == COMPONENT_ID_INVALID) { + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, ident)); + } else { + entityPositionGetTransform(entityId, posComp, model); + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); + } + + // Render. + errorChain(entityRenderableDraw(entityId, renderableComp)); + } } // UI Rendering - { - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, ident)); - mat4 view, proj; - glm_ortho( - 0.0f, SCREEN.width, - SCREEN.height, 0.0f, - 0.1f, 100.0f, - proj - ); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)); + glm_ortho( + 0.0f, SCREEN.width, + SCREEN.height, 0.0f, + 0.1f, 100.0f, + proj + ); + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)); - glm_lookat( - (vec3){ 0.0f, 0.0f, 1.0f }, - (vec3){ 0.0f, 0.0f, 0.0f }, - (vec3){ 0.0f, 1.0f, 0.0f }, - view - ); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); - - errorChain(displaySetState((displaystate_t){ - .flags = DISPLAY_STATE_FLAG_BLEND - })); - errorChain(uiRender()); - } + glm_lookat( + (vec3){ 0.0f, 0.0f, 1.0f }, + (vec3){ 0.0f, 0.0f, 0.0f }, + (vec3){ 0.0f, 1.0f, 0.0f }, + view + ); + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); + + errorChain(displaySetState((displaystate_t){ + .flags = DISPLAY_STATE_FLAG_BLEND + })); + errorChain(uiRender()); errorOk(); } diff --git a/src/dusk/scene/scene.h b/src/dusk/scene/scene.h index fb47233d..30261afc 100644 --- a/src/dusk/scene/scene.h +++ b/src/dusk/scene/scene.h @@ -13,7 +13,7 @@ typedef enum { SCENE_TYPE_NULL, - #define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \ + #define X(structName, varName, varNameUpper, initFunc, updateFunc, disposeFunc) \ SCENE_TYPE_##varNameUpper, #include "scene/scenelist.h" #undef X @@ -21,7 +21,7 @@ typedef enum { } scenetype_t; typedef union { - #define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \ + #define X(structName, varName, varNameUpper, initFunc, updateFunc, disposeFunc) \ structName varName; #include "scene/scenelist.h" #undef X @@ -30,7 +30,6 @@ typedef union { typedef struct { void (*init)(void); errorret_t (*update)(void); - errorret_t (*render)(void); void (*dispose)(void); } scenefuncs_t; diff --git a/src/dusk/scene/scenelist.h b/src/dusk/scene/scenelist.h index 5d47f3c9..e80ef912 100644 --- a/src/dusk/scene/scenelist.h +++ b/src/dusk/scene/scenelist.h @@ -6,8 +6,8 @@ */ #ifndef X - #define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \ + #define X(structName, varName, varNameUpper, initFunc, updateFunc, disposeFunc) \ ((void)) #endif -X(initialscene_t, initial, INITIAL, initialSceneInit, initialSceneUpdate, initialSceneDraw, initialSceneDispose) \ No newline at end of file +X(initialscene_t, initial, INITIAL, initialSceneInit, initialSceneUpdate, initialSceneDispose) \ No newline at end of file