raycast fin

This commit is contained in:
2025-10-05 16:05:57 +01:00
parent c8dfcd857e
commit 628a6c5ade
4 changed files with 64 additions and 39 deletions

View File

@@ -12,5 +12,6 @@ struct AABB
function bool AABB_Collide(AABB a, AABB b); function bool AABB_Collide(AABB a, AABB b);
function bool AABB_Point(AABB a, V2f v); function bool AABB_Point(AABB a, V2f v);
function bool AABB_Slab(V2f origin, V2f point, AABB a);
#endif // LD_GAME_AABB_H_ #endif // LD_GAME_AABB_H_

View File

@@ -1,5 +1,5 @@
#include "game/aabb.h" #include "game/aabb.h"
#include "core/types.h" #include <math.h>
bool AABB_Collide(AABB a, AABB b) bool AABB_Collide(AABB a, AABB b)
{ {
@@ -19,17 +19,18 @@ bool AABB_Slab(V2f origin, V2f point, AABB a)
{ {
V2f start = a.pos; V2f start = a.pos;
V2f finish = {a.pos.x + a.size.x, a.pos.y + a.size.y}; V2f finish = {a.pos.x + a.size.x, a.pos.y + a.size.y};
V2f direction = {origin.x - point.x, origin.y - point.y}; V2f invdirection = {1 / (origin.x - point.x), 1 / (origin.y - point.y)};
// x // x
F32 tLow = (start.x - origin.x) / direction.x; F32 tLow = (start.x - origin.x) * invdirection.x;
F32 tHigh = (finish.x - origin.x) / direction.x; F32 tHigh = (finish.x - origin.x) * invdirection.x;
F32 tMin = min(tLow, tHigh); F32 tMin = min(tLow, tHigh);
F32 tMax = max(tLow, tHigh); F32 tMax = max(tLow, tHigh);
// y // y
tLow = (start.x - origin.x) / direction.x; tLow = (start.y - origin.y) * invdirection.y;
tHigh = (finish.x - origin.x) / direction.x; tHigh = (finish.y - origin.y) * invdirection.y;
tMin = max(tMin, min(tLow, tHigh)); tMin = max(tMin, min(tLow, tHigh));
tMax = min(tMax, max(tLow, tHigh)); tMax = min(tMax, max(tLow, tHigh));
return tMax >= max(0.0, tMin);
return tMax >= tMin;
} }

View File

@@ -6,7 +6,8 @@
#define MAX_UNFINISHED 128 #define MAX_UNFINISHED 128
typedef struct navSearchNodeState navSearchNodeState; typedef struct navSearchNodeState navSearchNodeState;
struct navSearchNodeState{ struct navSearchNodeState
{
bool visited; bool visited;
U64 distance; U64 distance;
U32 shortest; U32 shortest;
@@ -14,37 +15,45 @@ struct navSearchNodeState{
}; };
typedef struct navSearchState navSearchState; typedef struct navSearchState navSearchState;
struct navSearchState{ struct navSearchState
{
navSearchNodeState nodeStates[NAV_MAX_NODES]; navSearchNodeState nodeStates[NAV_MAX_NODES];
}; };
navSearchState initState(U32 start, U32 meshSize) { navSearchState initState(U32 start, U32 meshSize)
navSearchState state = {}; {
for(U32 i = 0; i < meshSize; i++) { navSearchState state;
state.nodeStates[i].visited = false; for (U32 i = 0; i < meshSize; i++)
{
state.nodeStates[i].visited = false;
state.nodeStates[i].addedToUnvisited = false; state.nodeStates[i].addedToUnvisited = false;
state.nodeStates[i].distance = U64_MAX; state.nodeStates[i].distance = U64_MAX;
state.nodeStates[i].shortest = 0; state.nodeStates[i].shortest = 0;
} }
state.nodeStates[start].distance = 0; state.nodeStates[start].distance = 0;
return state; return state;
} }
U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchState state, U32 *offset) { U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchState state, U32 *offset)
U32 lowest = U32_MAX; {
U32 lowest = U32_MAX;
U32 lowestI = U32_MAX; U32 lowestI = U32_MAX;
bool startFound = false; bool startFound = false;
for(U32 i = *offset; i < unfinishedCount; i++) { for (U32 i = *offset; i < unfinishedCount; i++)
{
navSearchNodeState checkNode = state.nodeStates[unfinishedIndexes[i]]; navSearchNodeState checkNode = state.nodeStates[unfinishedIndexes[i]];
if(checkNode.visited) { if (checkNode.visited)
if(!startFound) { {
if (!startFound)
{
*offset = i; *offset = i;
} }
continue; continue;
} }
startFound = true; startFound = true;
if (lowest > checkNode.distance) { if (lowest > checkNode.distance)
lowest = cast(U32) checkNode.distance; {
lowest = cast(U32) checkNode.distance;
lowestI = unfinishedIndexes[i]; lowestI = unfinishedIndexes[i];
} }
} }
@@ -52,7 +61,8 @@ U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchSta
} }
// Generate a path to follow between the start and end node. // Generate a path to follow between the start and end node.
NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) { NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end)
{
navSearchState state = initState(start, mesh->nodeCount); navSearchState state = initState(start, mesh->nodeCount);
U32 unfinishedCount = 1; U32 unfinishedCount = 1;
U32 unfinishedIndexes[NAV_MAX_NODES] = {start}; U32 unfinishedIndexes[NAV_MAX_NODES] = {start};
@@ -63,19 +73,26 @@ NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) {
U32 unfinishedOffset = 0; U32 unfinishedOffset = 0;
U32 lowestNodeIndex = start; U32 lowestNodeIndex = start;
bool found = false; bool found = false;
while(!found) { while (!found)
for(int connectionI = 0 ; connectionI < mesh->nodes[lowestNodeIndex].connectionCount; connectionI++) { {
NavConnection *connection = &mesh->nodes[lowestNodeIndex].connections[connectionI]; for (int connectionI = 0; connectionI < mesh->nodes[lowestNodeIndex].connectionCount; connectionI++)
navSearchNodeState *testNode = &state.nodeStates[connection->NodeIndex]; {
if(testNode->visited) {continue;} NavConnection *connection = &mesh->nodes[lowestNodeIndex].connections[connectionI];
U32 distance = cast(U32) (state.nodeStates[lowestNodeIndex].distance + connection->Cost); navSearchNodeState *testNode = &state.nodeStates[connection->NodeIndex];
distance += cast(U32) (mesh->nodes[end].pos.x - mesh->nodes[connection->NodeIndex].pos.x); if (testNode->visited)
distance += cast(U32) (mesh->nodes[end].pos.y - mesh->nodes[connection->NodeIndex].pos.y); {
if(testNode->distance > distance) { continue;
}
U32 distance = cast(U32)(state.nodeStates[lowestNodeIndex].distance + connection->Cost);
distance += cast(U32)(mesh->nodes[end].pos.x - mesh->nodes[connection->NodeIndex].pos.x);
distance += cast(U32)(mesh->nodes[end].pos.y - mesh->nodes[connection->NodeIndex].pos.y);
if (testNode->distance > distance)
{
testNode->distance = distance; testNode->distance = distance;
testNode->shortest = lowestNodeIndex; testNode->shortest = lowestNodeIndex;
} }
if(!testNode->addedToUnvisited) { if (!testNode->addedToUnvisited)
{
unfinishedIndexes[unfinishedCount] = connection->NodeIndex; unfinishedIndexes[unfinishedCount] = connection->NodeIndex;
unfinishedCount++; unfinishedCount++;
testNode->addedToUnvisited = true; testNode->addedToUnvisited = true;
@@ -83,13 +100,15 @@ NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) {
} }
state.nodeStates[lowestNodeIndex].visited = true; state.nodeStates[lowestNodeIndex].visited = true;
lowestNodeIndex = getLowestState(unfinishedIndexes, unfinishedCount, state, &unfinishedOffset); lowestNodeIndex = getLowestState(unfinishedIndexes, unfinishedCount, state, &unfinishedOffset);
if(lowestNodeIndex == end) { if (lowestNodeIndex == end)
{
found = true; found = true;
} }
} }
NavPath res_path = {0}; NavPath res_path = {0};
U32 index = end; U32 index = end;
while(index!=start) { while (index != start)
{
res_path.indexes[res_path.nodeCount] = index; res_path.indexes[res_path.nodeCount] = index;
res_path.nodeCount++; res_path.nodeCount++;
index = state.nodeStates[index].shortest; index = state.nodeStates[index].shortest;

View File

@@ -3,16 +3,20 @@
#include "../player.h" #include "../player.h"
#include <SDL3/SDL_events.h> #include <SDL3/SDL_events.h>
void UpdateWorld(F32 delta, World *world) { void UpdateWorld(F32 delta, World *world)
{
UpdateNPCs(delta, world); UpdateNPCs(delta, world);
} }
void UpdateNPCs(F32 delta, World *world) { void UpdateNPCs(F32 delta, World *world)
for(U32 i = 0; i < world->npcCount; i++) { {
for (U32 i = 0; i < world->npcCount; i++)
{
updateNPC(delta, &world->npcs[i], world); updateNPC(delta, &world->npcs[i], world);
} }
} }
void ProcessEvents(SDL_Event *event, World *world) { void ProcessEvents(SDL_Event *event, World *world)
{
PlayerUpdate(event, &world->player); PlayerUpdate(event, &world->player);
} }