mirror of
https://github.com/recastnavigation/recastnavigation.git
synced 2026-06-08 08:13:49 +00:00
Added unit tests file to match RecastRasterization.cpp. Moved rcAddSpan tests there.
Also added a bunch of new tests that should cover most cases. The test that checks invalid spans is currently failing
This commit is contained in:
@@ -22,6 +22,7 @@ target_sources(Tests PRIVATE
|
||||
Recast/Tests_Alloc.cpp
|
||||
Recast/Tests_Recast.cpp
|
||||
Recast/Tests_RecastFilter.cpp
|
||||
Recast/Tests_RecastRasterization.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(Tests PRIVATE Recast Detour DetourCrowd)
|
||||
|
||||
@@ -511,94 +511,6 @@ TEST_CASE("rcClearUnwalkableTriangles", "[recast]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rcAddSpan", "[recast]")
|
||||
{
|
||||
rcContext ctx(false);
|
||||
|
||||
float verts[] = {
|
||||
1, 2, 3,
|
||||
0, 2, 6
|
||||
};
|
||||
float bmin[3];
|
||||
float bmax[3];
|
||||
rcCalcBounds(verts, 2, bmin, bmax);
|
||||
|
||||
float cellSize = 1.5f;
|
||||
float cellHeight = 2;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
rcCalcGridSize(bmin, bmax, cellSize, &width, &height);
|
||||
|
||||
rcHeightfield hf;
|
||||
REQUIRE(rcCreateHeightfield(&ctx, hf, width, height, bmin, bmax, cellSize, cellHeight));
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
unsigned short smin = 0;
|
||||
unsigned short smax = 1;
|
||||
unsigned char area = 42;
|
||||
int flagMergeThr = 1;
|
||||
|
||||
SECTION("Add a span to an empty heightfield.")
|
||||
{
|
||||
bool result = rcAddSpan(&ctx, hf, x, y, smin, smax, area, flagMergeThr);
|
||||
REQUIRE(result);
|
||||
REQUIRE(hf.spans[0] != 0);
|
||||
REQUIRE(hf.spans[0]->smin == smin);
|
||||
REQUIRE(hf.spans[0]->smax == smax);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
}
|
||||
|
||||
SECTION("Add a span that gets merged with an existing span.")
|
||||
{
|
||||
bool result = rcAddSpan(&ctx, hf, x, y, smin, smax, area, flagMergeThr);
|
||||
REQUIRE(result);
|
||||
REQUIRE(hf.spans[0] != 0);
|
||||
REQUIRE(hf.spans[0]->smin == smin);
|
||||
REQUIRE(hf.spans[0]->smax == smax);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
|
||||
smin = 1;
|
||||
smax = 2;
|
||||
result = rcAddSpan(&ctx, hf, x, y, smin, smax, area, flagMergeThr);
|
||||
REQUIRE(result);
|
||||
REQUIRE(hf.spans[0] != 0);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 2);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
}
|
||||
|
||||
SECTION("Add a span that merges with two spans above and below.")
|
||||
{
|
||||
smin = 0;
|
||||
smax = 1;
|
||||
REQUIRE(rcAddSpan(&ctx, hf, x, y, smin, smax, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != 0);
|
||||
REQUIRE(hf.spans[0]->smin == smin);
|
||||
REQUIRE(hf.spans[0]->smax == smax);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == 0);
|
||||
|
||||
smin = 2;
|
||||
smax = 3;
|
||||
REQUIRE(rcAddSpan(&ctx, hf, x, y, smin, smax, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0]->next != 0);
|
||||
REQUIRE(hf.spans[0]->next->smin == smin);
|
||||
REQUIRE(hf.spans[0]->next->smax == smax);
|
||||
REQUIRE(hf.spans[0]->next->area == area);
|
||||
|
||||
smin = 1;
|
||||
smax = 2;
|
||||
REQUIRE(rcAddSpan(&ctx, hf, x, y, smin, smax, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != 0);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 3);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rcRasterizeTriangle", "[recast]")
|
||||
{
|
||||
|
||||
195
Tests/Recast/Tests_RecastRasterization.cpp
Normal file
195
Tests/Recast/Tests_RecastRasterization.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
#include "Recast.h"
|
||||
#include "catch2/catch_amalgamated.hpp"
|
||||
|
||||
TEST_CASE("rcAddSpan", "[recast][rasterization]")
|
||||
{
|
||||
rcContext ctx(false);
|
||||
|
||||
constexpr int xSize = 4;
|
||||
constexpr int ySize = 10;
|
||||
constexpr int zSize = 4;
|
||||
|
||||
constexpr float cellSize = 1.0f;
|
||||
constexpr float cellHeight = 2.0f;
|
||||
|
||||
constexpr float minBounds[3] {0.0f, 0.0f, 0.0f};
|
||||
constexpr float maxBounds[3] {cellSize * xSize, cellHeight * ySize, cellSize * zSize};
|
||||
|
||||
rcHeightfield hf;
|
||||
REQUIRE(rcCreateHeightfield(&ctx, hf, xSize, zSize, minBounds, maxBounds, cellSize, cellHeight));
|
||||
|
||||
constexpr unsigned char area = 42;
|
||||
constexpr int flagMergeThr = 1;
|
||||
|
||||
SECTION("Add a span to an empty heightfield.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 1, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 1);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Adding invalid or zero-size spans does nothing.")
|
||||
{
|
||||
// min == max
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 0, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] == nullptr);
|
||||
|
||||
// min > maxs
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 1, 0, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Two spans that are not touching are not merged.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 1, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 1);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 2, 3, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->next != nullptr);
|
||||
REQUIRE(hf.spans[0]->next->smin == 2);
|
||||
REQUIRE(hf.spans[0]->next->smax == 3);
|
||||
REQUIRE(hf.spans[0]->next->area == area);
|
||||
REQUIRE(hf.spans[0]->next->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Two spans with different area ids within the flag merge threshold are merged and the highest area ID is used.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 1, 42, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 1);
|
||||
REQUIRE(hf.spans[0]->area == 42);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 1, 2, 24, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 2);
|
||||
REQUIRE(hf.spans[0]->area == 42); // Higher area ID takes precedent
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Two spans with different area ids outside the flag merge threshold are merged and the area ID of the last span added is used.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 1, 42, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 1);
|
||||
REQUIRE(hf.spans[0]->area == 42);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 1, 8, 24, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 8);
|
||||
REQUIRE(hf.spans[0]->area == 24); // Area ID of the last-added span takes precedent
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Add a span that gets merged with an existing span.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 1, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 1);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 1, 2, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 2);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Add a span that merges with two spans above and below.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 1, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 1);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 2, 3, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0]->next != nullptr);
|
||||
REQUIRE(hf.spans[0]->next->smin == 2);
|
||||
REQUIRE(hf.spans[0]->next->smax == 3);
|
||||
REQUIRE(hf.spans[0]->next->area == area);
|
||||
REQUIRE(hf.spans[0]->next->next == nullptr);
|
||||
|
||||
// After adding the third span, they should all get merged into a single span.
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 1, 2, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 3);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Spans are insertion-sorted in ascending order of Y value.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 2, 3, area, flagMergeThr));
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 1, area, flagMergeThr));
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 6, 7, area, flagMergeThr));
|
||||
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 1);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next != nullptr);
|
||||
|
||||
REQUIRE(hf.spans[0]->next->smin == 2);
|
||||
REQUIRE(hf.spans[0]->next->smax == 3);
|
||||
REQUIRE(hf.spans[0]->next->area == area);
|
||||
REQUIRE(hf.spans[0]->next->next != nullptr);
|
||||
|
||||
REQUIRE(hf.spans[0]->next->next->smin == 6);
|
||||
REQUIRE(hf.spans[0]->next->next->smax == 7);
|
||||
REQUIRE(hf.spans[0]->next->next->area == area);
|
||||
REQUIRE(hf.spans[0]->next->next->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Adding a span inside another span merges them.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 8, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 8);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 2, 3, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 8);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Overlapping spans are merged.")
|
||||
{
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 0, 4, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 4);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
|
||||
REQUIRE(rcAddSpan(&ctx, hf, 0, 0, 2, 6, area, flagMergeThr));
|
||||
REQUIRE(hf.spans[0] != nullptr);
|
||||
REQUIRE(hf.spans[0]->smin == 0);
|
||||
REQUIRE(hf.spans[0]->smax == 6);
|
||||
REQUIRE(hf.spans[0]->area == area);
|
||||
REQUIRE(hf.spans[0]->next == nullptr);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user