diff --git a/src/Asteroid.c b/src/Asteroid.c index 620b8f1..36b2b5f 100644 --- a/src/Asteroid.c +++ b/src/Asteroid.c @@ -177,8 +177,11 @@ v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations, for (i32 i = 0; i < iterations; i++) { i32 randValue = rand(); - result[i] = V2(math_cosf(iterationAngle * i) * asteroidRadius, - math_sinf(iterationAngle * i) * asteroidRadius); + + // NOTE(doyle): Sin/cos generate values from +-1, we want to create + // vertices that start from 0, 0 (i.e. strictly positive) + result[i] = V2(((math_cosf(iterationAngle * i) + 1) * asteroidRadius), + ((math_sinf(iterationAngle * i) + 1) * asteroidRadius)); #if 1 f32 displacementDist = 0.50f * asteroidRadius; @@ -239,6 +242,27 @@ v2 *createEntityEdgeList(MemoryArena_ *transientArena, Entity *entity) return result; } +v2 calculateProjectionRangeForEdge(Entity *entity, v2 edgeNormal) +{ + v2 result = {0}; + result.max = v2_dot(entity->vertexPoints[0], edgeNormal); + result.max = result.min; + + for (i32 vertexIndex = 0; vertexIndex < entity->numVertexPoints; + vertexIndex++) + { + f32 dist = + v2_dot(entity->vertexPoints[vertexIndex], edgeNormal); + + if (dist < result.min) + result.min = dist; + else if (dist > result.max) + result.max = dist; + } + + return result; +} + b32 checkEntityProjectionOverlap(Entity *entity, Entity *checkEntity, v2 *entityEdges) { @@ -246,39 +270,10 @@ b32 checkEntityProjectionOverlap(Entity *entity, Entity *checkEntity, for (i32 edgeIndex = 0; edgeIndex < entity->numVertexPoints && result; edgeIndex++) { - v2 entityProjectionRange = {0}; - entityProjectionRange.max = - v2_dot(entity->vertexPoints[0], entityEdges[0]); - entityProjectionRange.max = entityProjectionRange.min; - - for (i32 vertexIndex = 0; vertexIndex < entity->numVertexPoints; - vertexIndex++) - { - f32 dist = v2_dot(entity->vertexPoints[vertexIndex], - entityEdges[edgeIndex]); - - if (dist < entityProjectionRange.min) - entityProjectionRange.min = dist; - else if (dist > entityProjectionRange.max) - entityProjectionRange.max = dist; - } - - v2 checkEntityProjectionRange = {0}; - checkEntityProjectionRange.min = - v2_dot(entity->vertexPoints[0], entityEdges[0]); - checkEntityProjectionRange.max = checkEntityProjectionRange.min; - - for (i32 vertexIndex = 0; vertexIndex < checkEntity->numVertexPoints; - vertexIndex++) - { - f32 dist = v2_dot(checkEntity->vertexPoints[vertexIndex], - entityEdges[edgeIndex]); - - if (dist < checkEntityProjectionRange.min) - checkEntityProjectionRange.min = dist; - else if (dist > checkEntityProjectionRange.max) - checkEntityProjectionRange.max = dist; - } + v2 entityProjectionRange = + calculateProjectionRangeForEdge(entity, entityEdges[edgeIndex]); + v2 checkEntityProjectionRange = calculateProjectionRangeForEdge( + checkEntity, entityEdges[edgeIndex]); if (!v2_intervalsOverlap(entityProjectionRange, checkEntityProjectionRange)) @@ -337,13 +332,15 @@ void moveEntity(GameState *state, Entity *entity, v2 ddP, f32 dt, f32 ddPSpeed) // Convert inplace the vector normal of the edges for (i32 i = 0; i < numEntityEdges; i++) { - entityEdges[i] = V2(entityEdges[i].y, -entityEdges[i].x); + entityEdges[i] = v2_perpendicular(entityEdges[i]); + entityEdges[i] = v2_add(entityEdges[i], entity->pos); } for (i32 i = 0; i < numCheckEntityEdges; i++) { + checkEntityEdges[i] = v2_perpendicular(checkEntityEdges[i]); checkEntityEdges[i] = - V2(entityEdges[i].y, -entityEdges[i].x); + v2_add(checkEntityEdges[i], checkEntity->pos); } if ((checkEntityProjectionOverlap(entity, checkEntity, @@ -355,7 +352,9 @@ void moveEntity(GameState *state, Entity *entity, v2 ddP, f32 dt, f32 ddPSpeed) } } - if (willCollide) break; + if (willCollide) { + break; + } } } #endif @@ -397,15 +396,13 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, ship->vertexPoints = memory_pushBytes( &state->persistentArena, sizeof(v2) * ship->numVertexPoints); - Basis shipBasis = getDefaultBasis(ship); - v2 triangleTopPoint = V2(shipBasis.pos.x + (ship->size.w * 0.5f), - shipBasis.pos.y + ship->size.h); - v2 triangleRightSide = - V2(shipBasis.pos.x + ship->size.w, shipBasis.pos.y); + v2 triangleBaseP = V2(0, 0); + v2 triangleTopP = V2(ship->size.w * 0.5f, ship->size.h); + v2 triangleRightP = V2(ship->size.w, triangleBaseP.y); - ship->vertexPoints[0] = shipBasis.pos; - ship->vertexPoints[1] = triangleRightSide; - ship->vertexPoints[2] = triangleTopPoint; + ship->vertexPoints[0] = triangleBaseP; + ship->vertexPoints[1] = triangleRightP; + ship->vertexPoints[2] = triangleTopP; ship->scale = 1; ship->type = entitytype_ship; @@ -414,7 +411,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, ship->tex = NULL; ship->collides = TRUE; - i32 numAsteroids = 10; + i32 numAsteroids = 8; for (i32 i = 0; i < numAsteroids; i++) { Entity *asteroid = &state->entityList[state->entityIndex]; @@ -427,13 +424,13 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, asteroid->size = V2(100.0f, 100.0f); asteroid->hitbox = asteroid->size; - asteroid->offset = v2_scale(asteroid->size, 0.5f); + asteroid->offset = V2(asteroid->size.w * -0.5f, 0); asteroid->scale = 1; asteroid->type = entitytype_asteroid; asteroid->direction = direction_null; asteroid->renderMode = rendermode_polygon; - asteroid->numVertexPoints = 16; + asteroid->numVertexPoints = 8; asteroid->vertexPoints = createAsteroidVertexList( &state->persistentArena, asteroid->numVertexPoints, (i32)(asteroid->size.x * 0.5f)); @@ -535,8 +532,6 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, } ddPSpeedInMs = 25; - pivotPoint = v2_scale(entity->size, 0.5f); - 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"); @@ -617,39 +612,20 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, // NOTE(doyle): Make asteroids start and move at constant speed ddPSpeedInMs = 2; - entity->dP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs); + entity->dP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs); + entity->rotation += (randValue % 20) * dt; } moveEntity(state, entity, ddP, dt, ddPSpeedInMs); RenderFlags flags = renderflag_wireframe | renderflag_no_texture; renderer_entity(&state->renderer, &state->transientArena, state->camera, - entity, pivotPoint, 0, V4(0.4f, 0.8f, 1.0f, 1.0f), - flags); - - Basis entityBasis = getDefaultBasis(entity); - renderer_rect(&state->renderer, state->camera, entityBasis.pos, - V2(4, 4), entityBasis.pivotPoint, - DEGREES_TO_RADIANS(entity->rotation), NULL, - V4(1.0f, 0, 0, 1.0f), flags); + entity, V2(0, 0), 0, + V4(0.4f, 0.8f, 1.0f, 1.0f), flags); } -#if 1 - TrianglePoints triangle = {0}; - triangle.points[0] = V2(100, 200); - triangle.points[1] = V2(200, 100); - triangle.points[2] = V2(100, 300); - - LOCAL_PERSIST Degrees rotation = 0.0f; - rotation += (60.0f) * dt; - - RenderFlags flags = renderflag_wireframe | renderflag_no_texture; - renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), - rotation, NULL, V4(1, 1, 1, 1), flags); - debug_drawUi(state, dt); debug_clearCounter(); -#endif renderer_renderGroups(&state->renderer); } diff --git a/src/Entity.c b/src/Entity.c index 58ede6b..4a77d1e 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -86,53 +86,3 @@ void entity_addAnim(AssetManager *const assetManager, Entity *const entity, DEBUG_LOG("No more free entity animation slots"); } - -Basis getBasis(Entity *entity, enum RectBaseline baseline) -{ - ASSERT(baseline < rectbaseline_count); - - v2 basis = v2_sub(entity->pos, entity->offset); - v2 pivotPoint = v2_scale(entity->size, 0.5f); - v2 size = entity->size; - switch (baseline) - { - case rectbaseline_top: - basis.y += (size.h); - basis.x += (size.w * 0.5f); - break; - case rectbaseline_topLeft: - basis.y += (size.h); - break; - case rectbaseline_topRight: - basis.y += (size.h); - basis.x += (size.w); - break; - case rectbaseline_bottom: - basis.x += (size.w * 0.5f); - break; - case rectbaseline_bottomRight: - basis.x += (size.w); - break; - case rectbaseline_left: - basis.y += (size.h * 0.5f); - break; - case rectbaseline_right: - basis.x += (size.w); - basis.y += (size.h * 0.5f); - break; - - case rectbaseline_bottomLeft: - break; - default: - DEBUG_LOG( - "getPosRelativeToRect() warning: baseline enum not recognised"); - break; - } - - Basis result = {0}; - result.pos = basis; - result.pivotPoint = pivotPoint; - - return result; -} - diff --git a/src/Renderer.c b/src/Renderer.c index 45daf61..8da2815 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -13,11 +13,6 @@ typedef struct RenderQuad Vertex vertex[4]; } RenderQuad_; -typedef struct RenderTriangle -{ - Vertex vertex[3]; -} RenderTriangle_; - // NOTE(doyle): A vertex batch is the batch of vertexes comprised to make one // shape INTERNAL void beginVertexBatch(Renderer *renderer) @@ -317,30 +312,6 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, return result; } -INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer, - TrianglePoints triangle, - v2 pivotPoint, Radians rotate, - RenderTex renderTex) -{ - /* Convert texture coordinates to normalised texture coordinates */ - v4 texRectNdc = getTexRectNormaliseDeviceCoords(renderTex); - - RenderTriangle_ result = {0}; - result.vertex[0].pos = triangle.points[0]; - result.vertex[0].texCoord = V2(texRectNdc.x, texRectNdc.w); - - result.vertex[1].pos = triangle.points[1]; - result.vertex[1].texCoord = V2(texRectNdc.x, texRectNdc.y); - - result.vertex[2].pos = triangle.points[2]; - result.vertex[2].texCoord = V2(texRectNdc.z, texRectNdc.w); - - applyRotationToVertexes(triangle.points[0], pivotPoint, rotate, - result.vertex, ARRAY_COUNT(result.vertex)); - - return result; -} - INTERNAL inline RenderQuad_ createDefaultTexQuad(Renderer *renderer, RenderTex *renderTex) { @@ -447,31 +418,21 @@ void renderer_polygon(Renderer *const renderer, Rect camera, { ASSERT((i + 1) < numPoints); - RenderTriangle_ tri = {0}; - tri.vertex[0].pos = triangulationBaseP; - tri.vertex[1].pos = polygonPoints[i]; - tri.vertex[2].pos = polygonPoints[i + 1]; + Vertex triangle[3] = {0}; + triangle[0].pos = triangulationBaseP; + triangle[1].pos = polygonPoints[i]; + triangle[2].pos = polygonPoints[i + 1]; applyRotationToVertexes(triangulationBaseP, pivotPoint, rotate, - tri.vertex, 3); - addVertexToRenderGroup_(renderer, renderTex->tex, color, tri.vertex, - ARRAY_COUNT(tri.vertex), rendermode_polygon, + triangle, ARRAY_COUNT(triangle)); + addVertexToRenderGroup_(renderer, renderTex->tex, color, triangle, + ARRAY_COUNT(triangle), rendermode_polygon, flags); triangulationIndex++; } endVertexBatch(renderer); } -void renderer_triangle(Renderer *const renderer, Rect camera, - TrianglePoints triangle, v2 pivotPoint, Degrees rotate, - RenderTex *renderTex, v4 color, RenderFlags flags) -{ - Radians totalRotation = DEGREES_TO_RADIANS(rotate); - renderer_polygon(renderer, camera, triangle.points, - ARRAY_COUNT(triangle.points), pivotPoint, totalRotation, - renderTex, color, flags); -} - void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, Font *const font, const char *const string, v2 pos, v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags) @@ -573,21 +534,6 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, totalRotation, &renderTex, color, flags); } - else if (entity->renderMode == rendermode_triangle) - { - Basis entityBasis = getDefaultBasis(entity); - v2 triangleTopPoint = V2(entityBasis.pos.x + (entity->size.w * 0.5f), - entityBasis.pos.y + entity->size.h); - v2 triangleRightSide = - V2(entityBasis.pos.x + entity->size.w, entityBasis.pos.y); - - v2 entityPolygonPoints[] = {entityBasis.pos, triangleRightSide, - triangleTopPoint}; - - renderer_polygon(renderer, camera, entityPolygonPoints, - ARRAY_COUNT(entityPolygonPoints), pivotPoint, - totalRotation, &renderTex, color, flags); - } else if (entity->renderMode == rendermode_polygon) { ASSERT(entity->numVertexPoints >= 3); @@ -595,14 +541,17 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, v2 *offsetVertexPoints = memory_pushBytes( transientArena, entity->numVertexPoints * sizeof(v2)); + for (i32 i = 0; i < entity->numVertexPoints; i++) { offsetVertexPoints[i] = - v2_add(entity->vertexPoints[i], entity->pos); + v2_add(entity->vertexPoints[i], entity->offset); + offsetVertexPoints[i] = v2_add(offsetVertexPoints[i], entity->pos); } renderer_polygon(renderer, camera, offsetVertexPoints, - entity->numVertexPoints, pivotPoint, totalRotation, + entity->numVertexPoints, + v2_add(entity->offset, pivotPoint), totalRotation, &renderTex, color, flags); } else diff --git a/src/include/Dengine/Entity.h b/src/include/Dengine/Entity.h index 346333f..44252cf 100644 --- a/src/include/Dengine/Entity.h +++ b/src/include/Dengine/Entity.h @@ -22,27 +22,6 @@ enum Direction direction_num, }; -typedef struct Basis -{ - v2 pos; - v2 pivotPoint; -} Basis; - -enum RectBaseline -{ - rectbaseline_top, - rectbaseline_topLeft, - rectbaseline_topRight, - rectbaseline_bottom, - rectbaseline_bottomRight, - rectbaseline_bottomLeft, - rectbaseline_left, - rectbaseline_right, - rectbaseline_center, - rectbaseline_count, - -}; - enum EntityType { entitytype_invalid, @@ -72,6 +51,12 @@ 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 v2 offset; enum RenderMode renderMode; @@ -110,13 +95,4 @@ void entity_setActiveAnim(Entity *const entity, const char *const animName); void entity_updateAnim(Entity *const entity, const f32 dt); void entity_addAnim(AssetManager *const assetManager, Entity *const entity, const char *const animName); - -Basis getBasis(Entity *entity, enum RectBaseline baseline); -inline Basis getDefaultBasis(Entity *entity) -{ - Basis result = getBasis(entity, rectbaseline_bottomLeft); - return result; -} - - #endif diff --git a/src/include/Dengine/Math.h b/src/include/Dengine/Math.h index a3df7dd..5307a88 100644 --- a/src/include/Dengine/Math.h +++ b/src/include/Dengine/Math.h @@ -203,6 +203,11 @@ INTERNAL inline b32 v2_intervalsOverlap(const v2 a, const v2 b) return result; } +INTERNAL inline v2 v2_perpendicular(const v2 a) { + v2 result = {a.y, -a.x}; + return result; +} + INTERNAL inline v3 v3_cross(const v3 a, const v3 b) { /* diff --git a/src/include/Dengine/Renderer.h b/src/include/Dengine/Renderer.h index 264e7c6..fa342b2 100644 --- a/src/include/Dengine/Renderer.h +++ b/src/include/Dengine/Renderer.h @@ -25,10 +25,6 @@ typedef struct RenderTex v4 texRect; } RenderTex; -typedef struct TrianglePoints { - v2 points[3]; -} TrianglePoints; - typedef u32 RenderFlags; enum RenderFlag { renderflag_wireframe = 0x1, @@ -41,7 +37,6 @@ enum RenderFlag { enum RenderMode { rendermode_quad, - rendermode_triangle, rendermode_polygon, rendermode_count, rendermode_invalid, @@ -111,10 +106,6 @@ inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size, renderTex, color, flags); } -void renderer_triangle(Renderer *const renderer, Rect camera, - TrianglePoints triangle, v2 pivotPoint, Radians rotate, - RenderTex *renderTex, v4 color, RenderFlags flags); - void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, Font *const font, const char *const string, v2 pos, v2 pivotPoint, Radians rotate, v4 color,