OverviewFilesCommitsIssuesDocsReleasesPeers

dc-terrain / libdc / test / test_convex.cpp

51 lines · cpp ref:
// 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;
}