diff --git a/data/blackboard.art b/data/blackboard.art index f09515e..63526b6 100644 Binary files a/data/blackboard.art and b/data/blackboard.art differ diff --git a/src/Asteroid.c b/src/Asteroid.c index d22a54b..04f9e23 100644 --- a/src/Asteroid.c +++ b/src/Asteroid.c @@ -183,6 +183,8 @@ v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations, result[i] = V2(((math_cosf(iterationAngle * i) + 1) * asteroidRadius), ((math_sinf(iterationAngle * i) + 1) * asteroidRadius)); + ASSERT(result[i].x >= 0 && result[i].y >= 0); + #if 1 f32 displacementDist = 0.50f * asteroidRadius; i32 vertexDisplacement = @@ -284,8 +286,9 @@ b32 checkEdgeProjectionOverlap(v2 *vertexList, i32 listSize, return result; } -b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, - f32 dt, f32 ddPSpeed) +INTERNAL b32 moveEntity(World *world, MemoryArena_ *transientArena, + Entity *entity, i32 entityIndex, v2 ddP, f32 dt, + f32 ddPSpeed) { ASSERT(ABS(ddP.x) <= 1.0f && ABS(ddP.y) <= 1.0f); /* @@ -295,7 +298,7 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, newPos = (a*t^2)/2 + oldVelocity*t + oldPos */ - ddP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeed); + ddP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeed); v2 oldDp = entity->dP; v2 resistance = v2_scale(oldDp, 2.0f); ddP = v2_sub(ddP, resistance); @@ -313,59 +316,59 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, // TODO(doyle): Collision for rects, (need to create vertex list for it) #if 1 - if (entity->renderMode == rendermode_polygon && entity->collides) + for (i32 i = entityIndex + 1; i < world->entityIndex; i++) { - for (i32 i = entityIndex + 1; i < state->entityIndex; i++) + Entity *checkEntity = &world->entityList[i]; + ASSERT(checkEntity->id != entity->id); + + if (world->collisionTable[entity->type][checkEntity->type]) { - Entity *checkEntity = &state->entityList[i]; - ASSERT(checkEntity->id != entity->id); + ASSERT(entity->vertexPoints); + ASSERT(checkEntity->vertexPoints); - if (checkEntity->renderMode == rendermode_polygon && - checkEntity->collides) + /* Create entity edge lists */ + v2 *entityVertexListOffsetToP = entity_generateUpdatedVertexList( + transientArena, entity); + + v2 *checkEntityVertexListOffsetToP = + entity_generateUpdatedVertexList(transientArena, + checkEntity); + + v2 *entityEdgeList = createNormalEdgeList(transientArena, + entityVertexListOffsetToP, + entity->numVertexPoints); + + v2 *checkEntityEdgeList = createNormalEdgeList( + transientArena, checkEntityVertexListOffsetToP, + checkEntity->numVertexPoints); + + /* Combine both edge lists into one */ + i32 totalNumEdges = + checkEntity->numVertexPoints + entity->numVertexPoints; + v2 *edgeList = + memory_pushBytes(transientArena, totalNumEdges * sizeof(v2)); + for (i32 i = 0; i < entity->numVertexPoints; i++) { - /* Create entity edge lists */ - v2 *entityVertexListOffsetToP = - entity_createVertexList(&state->transientArena, entity); - - v2 *checkEntityVertexListOffsetToP = entity_createVertexList( - &state->transientArena, checkEntity); - - v2 *entityEdgeList = createNormalEdgeList( - &state->transientArena, entityVertexListOffsetToP, - entity->numVertexPoints); - - v2 *checkEntityEdgeList = createNormalEdgeList( - &state->transientArena, checkEntityVertexListOffsetToP, - checkEntity->numVertexPoints); - - /* Combine both edge lists into one */ - i32 totalNumEdges = - checkEntity->numVertexPoints + entity->numVertexPoints; - v2 *edgeList = memory_pushBytes(&state->transientArena, - totalNumEdges * sizeof(v2)); - for (i32 i = 0; i < entity->numVertexPoints; i++) - { - edgeList[i] = entityEdgeList[i]; - } - - for (i32 i = 0; i < checkEntity->numVertexPoints; i++) - { - edgeList[i + entity->numVertexPoints] = - checkEntityEdgeList[i]; - } - - if (checkEdgeProjectionOverlap( - entityVertexListOffsetToP, entity->numVertexPoints, - checkEntityVertexListOffsetToP, - checkEntity->numVertexPoints, edgeList, totalNumEdges)) - { - willCollide = TRUE; - } + edgeList[i] = entityEdgeList[i]; } - if (willCollide) { - break; + for (i32 i = 0; i < checkEntity->numVertexPoints; i++) + { + edgeList[i + entity->numVertexPoints] = checkEntityEdgeList[i]; } + + if (checkEdgeProjectionOverlap( + entityVertexListOffsetToP, entity->numVertexPoints, + checkEntityVertexListOffsetToP, + checkEntity->numVertexPoints, edgeList, totalNumEdges)) + { + willCollide = TRUE; + } + } + + if (willCollide) + { + break; } } #endif @@ -389,68 +392,106 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, return willCollide; } -INTERNAL void addAsteroid(GameState *state, v2 windowSize) +INTERNAL void addAsteroid(World *world, v2 windowSize) { - Entity *asteroid = &state->entityList[state->entityIndex]; - asteroid->id = state->entityIndex++; + Entity *asteroid = &world->entityList[world->entityIndex++]; + asteroid->id = world->entityIdCounter++; i32 randValue = rand(); i32 randX = (randValue % (i32)windowSize.w); i32 randY = (randValue % (i32)windowSize.h); asteroid->pos = V2i(randX, randY); - asteroid->size = V2(75.0f, 75.0f); + asteroid->size = V2(100.0f, 100.0f); asteroid->hitbox = asteroid->size; - asteroid->offset = V2(asteroid->size.w * -0.5f, 0); - asteroid->scale = 1; - asteroid->rotation = 45; + asteroid->offset = v2_scale(asteroid->size, -0.5f); asteroid->type = entitytype_asteroid; asteroid->direction = direction_null; asteroid->renderMode = rendermode_polygon; asteroid->numVertexPoints = 10; asteroid->vertexPoints = createAsteroidVertexList( - &state->persistentArena, asteroid->numVertexPoints, - (i32)(asteroid->size.x * 0.5f)); + &world->entityArena, asteroid->numVertexPoints, + (i32)(asteroid->size.w * 0.5f)); - asteroid->tex = NULL; - asteroid->collides = TRUE; + asteroid->color = V4(0.0f, 0.5f, 0.5f, 1.0f); +} + +INTERNAL void addBullet(World *world, Entity *shooter) +{ + Entity *bullet = &world->entityList[world->entityIndex++]; + bullet->id = world->entityIdCounter++; + + bullet->offset = v2_scale(bullet->size, -0.5f); + bullet->pos = v2_add(shooter->pos, bullet->offset); + bullet->hitbox = bullet->size; + bullet->size = V2(2.0f, 20.0f); + bullet->rotation = shooter->rotation; + bullet->renderMode = rendermode_quad; + + // TODO(doyle): Figure out how to free this memory on entity delete. A free list? + bullet->vertexPoints = + memory_pushBytes(&world->entityArena, sizeof(v2) * 4); + bullet->vertexPoints[0] = V2(0, bullet->size.h); + bullet->vertexPoints[1] = V2(0, 0); + bullet->vertexPoints[2] = V2(bullet->size.w, 0); + bullet->vertexPoints[3] = bullet->size; + + bullet->numVertexPoints = 4; + + bullet->type = entitytype_bullet; + bullet->color = V4(1.0f, 1.0f, 0, 1.0f); +} + +INTERNAL void setCollisionRule(World *world, enum EntityType a, + enum EntityType b, b32 rule) +{ + ASSERT(a <= entitytype_count); + ASSERT(b <= entitytype_count); + world->collisionTable[a][b] = rule; + world->collisionTable[b][a] = rule; } void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, v2 windowSize, f32 dt) { + MemoryIndex globalTransientArenaSize = + (MemoryIndex)((f32)memory->transientSize * 0.5f); memory_arenaInit(&state->transientArena, memory->transient, - memory->transientSize); + globalTransientArenaSize); + World *world = &state->world; if (!state->init) { srand((u32)time(NULL)); - memory_arenaInit(&state->persistentArena, memory->persistent, - memory->persistentSize); initAssetManager(state); initRenderer(state, windowSize); - state->pixelsPerMeter = 70.0f; + world->pixelsPerMeter = 70.0f; + + MemoryIndex entityArenaSize = + (MemoryIndex)((f32)memory->transientSize * 0.5f); + + u8 *arenaBase = state->transientArena.base + state->transientArena.size; + memory_arenaInit(&world->entityArena, arenaBase, entityArenaSize); { // Init asteroid entities i32 numAsteroids = 15; for (i32 i = 0; i < numAsteroids; i++) - addAsteroid(state, windowSize); + addAsteroid(world, windowSize); } -#if 1 { // Init ship entity - Entity *ship = &state->entityList[state->entityIndex]; - ship->id = state->entityIndex++; + Entity *ship = &world->entityList[world->entityIndex++]; + ship->id = world->entityIdCounter++; ship->pos = V2(100, 100); ship->size = V2(25.0f, 50.0f); ship->hitbox = ship->size; - ship->offset = v2_scale(ship->size, 0.5f); + ship->offset = v2_scale(ship->size, -0.5f); ship->numVertexPoints = 3; ship->vertexPoints = memory_pushBytes( - &state->persistentArena, sizeof(v2) * ship->numVertexPoints); + &world->entityArena, sizeof(v2) * ship->numVertexPoints); v2 triangleBaseP = V2(0, 0); v2 triangleTopP = V2(ship->size.w * 0.5f, ship->size.h); @@ -464,19 +505,21 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, ship->type = entitytype_ship; ship->direction = direction_null; ship->renderMode = rendermode_polygon; - ship->tex = NULL; - ship->collides = TRUE; - + ship->color = V4(1.0f, 0.5f, 0.5f, 1.0f); } -#endif + { // Global Collision Rules + setCollisionRule(world, entitytype_ship, entitytype_asteroid, TRUE); + setCollisionRule(world, entitytype_bullet, entitytype_asteroid, + TRUE); + } + + world->camera.min = V2(0, 0); + world->camera.max = state->renderer.size; + world->worldSize = windowSize; - state->camera.min = V2(0, 0); - state->camera.max = state->renderer.size; state->init = TRUE; - state->worldSize = windowSize; - debug_init(&state->persistentArena, windowSize, state->assetManager.font); } @@ -509,26 +552,26 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, if (getKeyStatus(&state->input.keys[keycode_left_square_bracket], readkeytype_repeat, 0.2f, dt)) { - addAsteroid(state, windowSize); + addAsteroid(world, windowSize); } - for (i32 i = 0; i < state->entityIndex; i++) + for (i32 i = 0; i < world->entityIndex; i++) { - Entity *entity = &state->entityList[i]; + Entity *entity = &world->entityList[i]; ASSERT(entity->type != entitytype_invalid); v2 pivotPoint = {0}; // Loop entity around world - if (entity->pos.y >= state->worldSize.h) + if (entity->pos.y >= world->worldSize.h) entity->pos.y = 0; else if (entity->pos.y < 0) - entity->pos.y = state->worldSize.h; + entity->pos.y = world->worldSize.h; - if (entity->pos.x >= state->worldSize.w) + if (entity->pos.x >= world->worldSize.w) entity->pos.x = 0; else if (entity->pos.x < 0) - entity->pos.x = state->worldSize.w; + entity->pos.x = world->worldSize.w; f32 ddPSpeedInMs = 0; v2 ddP = {0}; @@ -560,6 +603,12 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, entity->rotation -= (rotationsPerSecond) * dt; } + if (getKeyStatus(&state->input.keys[keycode_space], + readkeytype_delayedRepeat, 0.0f, dt)) + { + addBullet(world, entity); + } + if (ddP.x > 0.0f && ddP.y > 0.0f) { // NOTE(doyle): Cheese it and pre-compute the vector for @@ -572,6 +621,11 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2"); DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2"); DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32"); + + renderer_rect(&state->renderer, world->camera, entity->pos, + V2(5, 5), V2(0, 0), + DEGREES_TO_RADIANS(entity->rotation), NULL, + V4(1.0f, 1.0f, 1.0f, 1.0f), renderflag_no_texture); } else if (entity->type == entitytype_asteroid) { @@ -648,26 +702,43 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, f32 dirOffset = ((randValue % 10) + 1) / 100.0f; v2_scale(ddP, dirOffset); - // NOTE(doyle): Make asteroids start and move at constant speed + // NOTE(doyle): Make asteroids start and move at constant speed by + // ensuring that dP is "refreshed" with non-decaying acceleration ddPSpeedInMs = 1; - entity->dP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs); + entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs); entity->rotation += (60 * dt); #endif } + else if (entity->type == entitytype_bullet) + { + ddPSpeedInMs = 5; + Radians rotation = DEGREES_TO_RADIANS((entity->rotation + 90.0f)); + ddP = V2(math_cosf(rotation), math_sinf(rotation)); + entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs); + } - b32 willCollide = moveEntity(state, entity, i, ddP, dt, ddPSpeedInMs); - v4 entityColor = V4(1.0f, 1.0f, 1.0f, 1.0f); -#if 1 + b32 willCollide = moveEntity(world, &state->transientArena, entity, i, + ddP, dt, ddPSpeedInMs); + v4 collideColor = {0}; if (willCollide) { - entityColor = V4(1.0f, 1.0f, 0, 1.0f); + collideColor = V4(1.0f, 0, 0, 0.5f); + } + + if (entity->type == entitytype_bullet) + { + if (!math_pointInRect(world->camera, entity->pos)) + { + world->entityList[i] = world->entityList[--world->entityIndex]; + i--; + continue; + } } -#endif RenderFlags flags = renderflag_wireframe | renderflag_no_texture; - renderer_entity(&state->renderer, &state->transientArena, state->camera, + renderer_entity(&state->renderer, &state->transientArena, world->camera, entity, V2(0, 0), 0, - entityColor, flags); + collideColor, flags); } #if 1 diff --git a/src/Debug.c b/src/Debug.c index b961d11..f1e34fc 100644 --- a/src/Debug.c +++ b/src/Debug.c @@ -273,19 +273,27 @@ void debug_drawUi(GameState *state, f32 dt) updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt); renderConsole(&state->renderer, &state->transientArena); - MemoryArena_ *transient = &state->transientArena; - i32 transientSizeInKbs = transient->size / 1024; - i32 transientUsedInKbs = transient->used / 1024; - v2 transientUsage = V2i(transientUsedInKbs, transientSizeInKbs); - DEBUG_PUSH_VAR("Transient Size: %.0f", transient->size, "f32"); - DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2"); + { // Print Memory Arena Info + DEBUG_PUSH_STRING("== MEMORY ARENAS =="); + MemoryArena_ *transient = &state->transientArena; + i32 transientSizeInKbs = transient->size / 1024; + i32 transientUsedInKbs = transient->used / 1024; + v2 transientUsage = V2i(transientUsedInKbs, transientSizeInKbs); + DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2"); - MemoryArena_ *persistent = &state->persistentArena; - i32 persistentSizeInKbs = persistent->size / 1024; - i32 persistentUsedInKbs = persistent->used / 1024; - v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs); - DEBUG_PUSH_VAR("Permanent Size: %.0f", persistent->size, "f32"); - DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2"); + MemoryArena_ *persistent = &state->persistentArena; + i32 persistentSizeInKbs = persistent->size / 1024; + i32 persistentUsedInKbs = persistent->used / 1024; + v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs); + DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2"); + + MemoryArena_ *entityArena = &state->world.entityArena; + i32 entitySizeInKbs = entityArena->size / 1024; + i32 entityUsedInKbs = entityArena->used / 1024; + v2 entityUsage = V2i(entityUsedInKbs, entitySizeInKbs); + DEBUG_PUSH_VAR("Entity Usage: %.0f/%.0f", entityUsage, "v2"); + DEBUG_PUSH_STRING("== =="); + } DEBUG_PUSH_VAR("Num Vertex: %d", GLOBAL_debug.callCount[debugcount_numVertex], "i32"); diff --git a/src/Entity.c b/src/Entity.c index 6555c06..982ff99 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -89,8 +89,12 @@ void entity_addAnim(AssetManager *const assetManager, Entity *const entity, DEBUG_LOG("No more free entity animation slots"); } -v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity) +v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena, + Entity *entity) { + ASSERT(entity->vertexPoints); + ASSERT(entity->numVertexPoints >= 3); + v2 *result = memory_pushBytes(transientArena, entity->numVertexPoints * sizeof(v2)); @@ -98,9 +102,10 @@ v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity) { result[i] = v2_add(entity->vertexPoints[i], entity->offset); result[i] = v2_add(result[i], entity->pos); + } - math_applyRotationToVertexes(result[0], entity->offset, + math_applyRotationToVertexes(entity->pos, V2(0 ,0), DEGREES_TO_RADIANS(entity->rotation), result, entity->numVertexPoints); diff --git a/src/Renderer.c b/src/Renderer.c index 48a8694..259d935 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -574,11 +574,15 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, renderTex.texRect = texRect; } + // TODO(doyle): Proper blending + v4 renderColor = color; + if (v4_equals(color, V4(0, 0, 0, 0))) renderColor = entity->color; + if (entity->renderMode == rendermode_quad) { renderer_rect(renderer, camera, entity->pos, entity->size, v2_add(entity->offset, pivotPoint), totalRotation, - &renderTex, color, flags); + &renderTex, entity->color, flags); } else if (entity->renderMode == rendermode_polygon) { @@ -586,12 +590,12 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, ASSERT(entity->vertexPoints); v2 *offsetVertexPoints = - entity_createVertexList(transientArena, entity); + entity_generateUpdatedVertexList(transientArena, entity); renderer_polygon(renderer, camera, offsetVertexPoints, entity->numVertexPoints, v2_add(entity->offset, pivotPoint), totalRotation, - &renderTex, color, flags); + &renderTex, renderColor, flags); } else { diff --git a/src/dengine.c b/src/dengine.c index 62e41c3..35d1f25 100644 --- a/src/dengine.c +++ b/src/dengine.c @@ -172,8 +172,13 @@ i32 main(void) memory.transientSize = transientSize; memory.transient = PLATFORM_MEM_ALLOC_(NULL, transientSize, u8); - GameState gameState = {0}; - glfwSetWindowUserPointer(window, CAST(void *)(&gameState)); + MemoryArena_ gameArena = {0}; + memory_arenaInit(&gameArena, memory.persistent, memory.persistentSize); + + GameState *gameState = MEMORY_PUSH_STRUCT(&gameArena, GameState); + gameState->persistentArena = gameArena; + + glfwSetWindowUserPointer(window, CAST(void *)(gameState)); /* ******************* @@ -203,7 +208,7 @@ i32 main(void) glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - asteroid_gameUpdateAndRender(&gameState, &memory, windowSize, + asteroid_gameUpdateAndRender(gameState, &memory, windowSize, secondsElapsed); GL_CHECK_ERROR(); @@ -233,7 +238,7 @@ i32 main(void) char textBuffer[256]; snprintf(textBuffer, ARRAY_COUNT(textBuffer), "Dengine | %f ms/f | %f fps | Entity Count: %d", - msPerFrame, framesPerSecond, gameState.entityIndex); + msPerFrame, framesPerSecond, gameState->world.entityIndex); glfwSetWindowTitle(window, textBuffer); titleUpdateFrequencyInSeconds = 0.5f; diff --git a/src/include/Dengine/Asteroid.h b/src/include/Dengine/Asteroid.h index 401efa2..e9a27bb 100644 --- a/src/include/Dengine/Asteroid.h +++ b/src/include/Dengine/Asteroid.h @@ -8,23 +8,35 @@ #include "Dengine/Platform.h" #include "Dengine/Renderer.h" +typedef struct World +{ + MemoryArena_ entityArena; + + v2 *entityVertexListCache[entitytype_count]; + Entity entityList[1024]; + i32 entityIndex; + + u32 entityIdCounter; + + f32 pixelsPerMeter; + v2 worldSize; + Rect camera; + + // TODO(doyle): Ensure we change this if it gets too big + b32 collisionTable[entitytype_count][entitytype_count]; +} World; + typedef struct GameState { b32 init; - Entity entityList[1024]; - i32 entityIndex; - f32 pixelsPerMeter; - - v2 worldSize; - - Rect camera; - + World world; AssetManager assetManager; KeyInput input; MemoryArena_ transientArena; MemoryArena_ persistentArena; + Renderer renderer; } GameState; diff --git a/src/include/Dengine/Entity.h b/src/include/Dengine/Entity.h index 4d08392..09ce33d 100644 --- a/src/include/Dengine/Entity.h +++ b/src/include/Dengine/Entity.h @@ -28,6 +28,7 @@ enum EntityType entitytype_invalid, entitytype_ship, entitytype_asteroid, + entitytype_bullet, entitytype_count, }; @@ -42,10 +43,7 @@ typedef struct EntityAnim typedef struct Entity { - i32 id; - - i32 childIds[8]; - i32 numChilds; + u32 id; v2 pos; v2 dP; @@ -53,11 +51,11 @@ typedef struct Entity v2 hitbox; v2 size; - // NOTE(doyle): Offset from origin point to the entity's considered "center" - // point, all operations work from this point, i.e. rotation, movement, - // collision detection - // If this is a polygon, the offset should be from the 1st vertex point - // specified + /* + NOTE(doyle): Offset is the vector to shift the polygons "origin" to the + world origin. In our case this should strictly be negative as we have + a requirement that all vertex points must be strictly positive. + */ v2 offset; enum RenderMode renderMode; @@ -70,17 +68,11 @@ typedef struct Entity enum EntityType type; enum Direction direction; + v4 color; Texture *tex; b32 flipX; b32 flipY; - // TODO(doyle): Two collision flags, we want certain entities to collide - // with certain types of entities only (i.e. projectile from hero to enemy, - // only collides with enemy). Having two flags is redundant, but! it does - // allow for early-exit in collision check if the entity doesn't collide at - // all - b32 collides; - EntityAnim animList[16]; i32 animListIndex; @@ -95,5 +87,6 @@ void entity_updateAnim(Entity *const entity, const f32 dt); void entity_addAnim(AssetManager *const assetManager, Entity *const entity, const char *const animName); -v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity); +v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena, + Entity *entity); #endif diff --git a/src/include/Dengine/Math.h b/src/include/Dengine/Math.h index 48e195c..e41d635 100644 --- a/src/include/Dengine/Math.h +++ b/src/include/Dengine/Math.h @@ -410,5 +410,23 @@ INTERNAL inline void math_applyRotationToVertexes(v2 pos, v2 pivotPoint, vertexList[i] = newP; } } +INTERNAL inline f32 math_lerp(f32 a, f32 t, f32 b) +{ + /* + Linear blend between two values. We having a starting point "a", and + the distance to "b" is defined as (b - a). Then we can say + + a + t(b - a) + + As our linear blend fn. We start from "a" and choosing a t from 0->1 + will vary the value of (b - a) towards b. If we expand this, this + becomes + + a + (t * b) - (a * t) == (1 - t)a + t*b + */ + f32 result = ((1 - t) * a) + (t * b); + + return result; +} #endif