// Build+run: g++ -std=c++17 -I../include test_convex.cpp -o test_convex && ./test_convex
// CPU-oracle test for TerrainEdit::CONVEX.
// Proves a 6-plane cube classifies (solid/air sign) identically to add_box,
// across add/subtract and solid/air base density, inside + outside the shape.
#include "dc_edit.h"
#include <cstdio>
#include <cmath>
#include <vector>
static int sgn(float v) { return v > 0.f ? 1 : (v < 0.f ? -1 : 0); }
int main() {
// Unit cube [-1,1]^3 as 6 outward half-spaces (inside = n·p <= d).
std::vector<ConvexPlane> cube = {
{ 1, 0, 0, 1}, {-1, 0, 0, 1},
{ 0, 1, 0, 1}, { 0,-1, 0, 1},
{ 0, 0, 1, 1}, { 0, 0,-1, 1},
};
int checks = 0, mism = 0;
for (float strength : { 1.0f, -1.0f }) {
for (float base : { -50.0f, 50.0f }) {
DCEditList boxL, cvxL;
boxL.add_box(0, 0, 0, 1, 1, 1, strength);
cvxL.add_convex(0, 0, 0, cube, strength);
auto bE = boxL.snapshot();
auto cE = cvxL.snapshot();
for (float x = -2.f; x <= 2.f; x += 0.25f)
for (float y = -2.f; y <= 2.f; y += 0.25f)
for (float z = -2.f; z <= 2.f; z += 0.25f) {
float rb = DCEditList::apply(bE, x, y, z, base);
float rc = DCEditList::apply(cE, x, y, z, base);
++checks;
if (sgn(rb) != sgn(rc)) {
if (mism < 12)
printf("MISMATCH @(%.2f,%.2f,%.2f) s=%+.0f base=%+.0f box=%.3f cvx=%.3f\n",
x, y, z, strength, base, rb, rc);
++mism;
}
}
}
}
// Face flatness: on the +x face (x=1) the convex SDF term is ~0 → add from air
// base yields ~0 (the exact zero-crossing).
DCEditList c2; c2.add_convex(0, 0, 0, cube, 1.f);
float face = DCEditList::apply(c2.snapshot(), 1.f, 0.f, 0.f, -50.f);
printf("checks=%d sign-mismatches=%d +x-face add value (expect ~0)=%.4f\n",
checks, mism, face);
return mism == 0 ? 0 : 1;
}