Refactor cleaned a few things
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
);
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
+72
-34
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
X(initialscene_t, initial, INITIAL, initialSceneInit, initialSceneUpdate, initialSceneDispose)
|
||||
Reference in New Issue
Block a user