Files
GR-raytracing/src/spacetime_minkowski.c
T
wyj f7380cbf75 Feat: Rework ray termination into escaped/dark/unresolved/incomplete
Replace the position capture cutoff with a camera-relative dark threshold
shared by every backend, and carry explicit outcome/reason provenance
through the ray, RayPool, adaptive mesh, lens-map and replay paths.

- eval/eval_slab return SpacetimePointStatus; remove SPACETIME_RAY_CAPTURED
  and the Schwarzschild capture radius; decouple observer construction from
  ray position.
- RayEndpoint stores RayOutcome/RayReason plus the last trusted state;
  budget exhaustion is retryable UNRESOLVED, data/integration failures are
  INCOMPLETE.
- Normal dark terminal is L - L0 >= --dark-threshold (default 8), with L0
  taken at the camera event and kept distinct from the worldtube entry
  energy; photon energy and frequency ratio are never reset.
- Implement E/D/U triangle decisions with merged budget retries, persistent
  probe witnesses promoted in place by vertex identity, conformity settling,
  and approximate-black boundary provenance with achieved-scale statistics.
- Add RayPool continuation state and per-ray step budgets.
- Bump lens-map to v2 with explicit end/outcome/reason, approx_black,
  threshold/retry/geometry provenance and per-frame retry counts; reject v1.
- Gate production output on incomplete/error results, overridable with
  --allow-incomplete.
- Update AGENTS.md, the design document and usage docs; add the termination
  oracle and regression coverage.

make -B -j4 BUILD_TYPE=Debug test passes with bit-identical reference HDRs.
2026-10-05 06:22:47 -04:00

100 lines
3.1 KiB
C

#include "spacetime.h"
#include <stdlib.h>
typedef struct {
double escape_radius;
} MinkowskiContext;
static SpacetimePointStatus minkowski_eval(const SpacetimeSource *source,
double t, const double x[3],
MetricData *metric) {
(void)source;
(void)t;
(void)x;
*metric = (MetricData){
.alpha = 1.0,
.gamma = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}};
return SPACETIME_POINT_OK;
}
static SpacetimeRayStatus minkowski_classify(const SpacetimeSource *source,
double t, const double x[3]) {
const MinkowskiContext *context = source->context;
const double radius_squared = x[0] * x[0] + x[1] * x[1] + x[2] * x[2];
(void)t;
return radius_squared >= context->escape_radius * context->escape_radius
? SPACETIME_RAY_ESCAPED
: SPACETIME_RAY_ACTIVE;
}
static void minkowski_destroy(SpacetimeSource *source) {
free(source->context);
source->context = NULL;
source->ops = NULL;
}
static size_t minkowski_asymptotic_end_count(const SpacetimeSource *source) {
(void)source;
return 1;
}
static int minkowski_asymptotic_end(const SpacetimeSource *source,
size_t index, SpacetimeAsymptoticEnd *out) {
(void)source;
if (index != 0)
return -1;
*out = (SpacetimeAsymptoticEnd){
.end_id = 0,
.exterior_kind = ASYMPTOTIC_EXTERIOR_MINKOWSKI,
.mass = 0.0,
.frame_origin = {0.0, 0.0, 0.0},
.frame_axes = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}};
return 0;
}
static int minkowski_escape_worldtube_sample(
const SpacetimeSource *source, SpacetimeEndId end_id, double t,
SpacetimeEscapeWorldtubeSample *out) {
const MinkowskiContext *context = source->context;
if (end_id != 0)
return -1;
*out = (SpacetimeEscapeWorldtubeSample){.center = {0.0, 0.0, 0.0},
.velocity = {0.0, 0.0, 0.0},
.radius = context->escape_radius,
.radius_rate = 0.0,
.velocity_constant = 1,
.valid = 1};
(void)t;
return 0;
}
static const SpacetimeOps minkowski_ops = {
.eval = minkowski_eval,
.classify = minkowski_classify,
.asymptotic_end_count = minkowski_asymptotic_end_count,
.asymptotic_end = minkowski_asymptotic_end,
.escape_worldtube_sample = minkowski_escape_worldtube_sample,
.destroy = minkowski_destroy,
};
int spacetime_create_minkowski(SpacetimeSource *source, double escape_radius) {
if (source == NULL || escape_radius <= 0.0)
return -1;
MinkowskiContext *context = malloc(sizeof *context);
if (context == NULL)
return -1;
context->escape_radius = escape_radius;
source->ops = &minkowski_ops;
source->context = context;
if (spacetime_source_finalize(source)) {
minkowski_destroy(source);
return -1;
}
return 0;
}
int spacetime_create_default(SpacetimeSource *source) {
return spacetime_create_minkowski(source, 1024.0);
}