Better unit test for the collision system.

This commit is contained in:
Zed A. Shaw 2024-10-26 18:13:06 -04:00
parent ec1ed23c52
commit c19cd707d1
3 changed files with 115 additions and 59 deletions

View file

@ -1,4 +1,7 @@
#include "collider.hpp"
#include <fmt/core.h>
using namespace fmt;
using DinkyECS::Entity;
@ -19,8 +22,20 @@ bool SpatialHashTable::occupied(Point at) const {
return table.contains(at);
}
inline void find_neighbor(const PointEntityMap &table, FoundList &result, Point at) {
auto it = table.find(at);
/*
* Avoid doing work by using the dy,dx and confirming that
* at.x or at.y is > 0. If either is 0 then there can't be
* a neighbor since that's out of bounds.
*/
inline void find_neighbor(const PointEntityMap &table, FoundList &result, Point at, int dy, int dx) {
// don't bother checking for cells out of bounds
if((dx < 0 && at.x <= 0) || (dy < 0 && at.y <= 0)) {
return;
}
Point cell = {at.x + dx, at.y + dy};
auto it = table.find(cell);
if (it != table.end()) {
result.insert(result.end(), it->second);
}
@ -31,16 +46,16 @@ std::tuple<bool, FoundList> SpatialHashTable::neighbors(Point cell, bool diag) c
// just unroll the loop since we only check four directions
// this also solves the problem that it was detecting that the cell was automatically included as a "neighbor" but it's not
find_neighbor(table, result, {cell.x, cell.y+1}); // north
find_neighbor(table, result, {cell.x, cell.y-1}); // south
find_neighbor(table, result, {cell.x+1, cell.y}); // east
find_neighbor(table, result, {cell.x-1, cell.y}); // west
find_neighbor(table, result, {cell.x+1, cell.y-1}); // south east
find_neighbor(table, result, cell, 0, 1); // north
find_neighbor(table, result, cell, 0, -1); // south
find_neighbor(table, result, cell, 1, 0); // east
find_neighbor(table, result, cell, -1, 0); // west
if(diag) {
find_neighbor(table, result, {cell.x-1, cell.y-1}); // south west
find_neighbor(table, result, {cell.x+1, cell.y+1}); // north east
find_neighbor(table, result, {cell.x-1, cell.y+1}); // north west
find_neighbor(table, result, cell, 1, -1); // south east
find_neighbor(table, result, cell, -1, -1); // south west
find_neighbor(table, result, cell, 1, 1); // north east
find_neighbor(table, result, cell, -1, 1); // north west
}
return std::tuple(!result.empty(), result);