Any mathematical space, one library.

Geometry libraries hardcode their space: CGAL's kernels, Eigen's linear algebra, GLM's vectors all assume flat Euclidean R^N wired into every type. Need geodesics on a sphere, distances in hyperbolic space, mesh operations on some other manifold? That's a different, specialized library each time — or a parallel hand-written stack duplicating the one you already have.

Spatium doesn't hardcode a space. It has a concept hierarchy — Set → TopologicalSpace → MetricSpace → NormedSpace → InnerProductSpace → Manifold → RiemannianManifold → Surface — and any type satisfying a concept's requirements gets the whole library for free:

struct FlatTorus { /* distance(), exp_map(), log_map(), project()... */ };

static_assert(spatium::RiemannianManifold<FlatTorus>);

// Mesh<FlatTorus>, subdivision, geodesics, morphisms — all work automatically.One exception to "all work automatically", stated here rather than left to

be discovered: spatial acceleration is still flat. spatial/'s BVH

bounds with axis-aligned boxes, so ray casting and nearest-neighbour

queries are accelerated in Euclidean space and unaccelerated off it. The

operations still give correct answers on any space; they just walk

everything. A ball tree over geodesic balls is the fix and is an open item

in the roadmap, not an oversight.

C++23, in large part header-only — three deliberate exceptions exist where real complexity made that the wrong tradeoff, not an oversight: the Vulkan viewer needs genuine C linkage, the periodic-table data backs a single compiled translation unit, and the physics/mechanics research track plus optional CUDA/ipc-toolkit integrations sit outside the header-only spine on purpose. See Architecture for the honest breakdown, not a marketing gloss.

- Kerr black hole — full 4-coordinate geodesic integration, GPU-rendered (CUDA) at 1920x1080 (video)

- A donut, declaratively — built entirely from torus()/offset()/scatter(), see the getting-started guide (build-up video)

The donut is also where the scene DSL's argument is easiest to check. A scene is described as spaces rather than as meshes, and the description stays a small inspectable graph: 34 nodes describing 2,021,984 objects. Geometry that would be 64,654,768 vertices if every object carried its own copy is stored as 39,272 — about 1646x — and the frame renders in under a gigabyte. That is not a trick in the renderer; it is what having described the scene as spaces buys.

More in gallery/.

- Space hierarchy as concepts — Set, TopologicalSpace, MetricSpace, NormedSpace, InnerProductSpace, Manifold, RiemannianManifold, Surface

- Concrete spaces — Euclidean<N>, Sphere<N>, Hyperbolic<N>, ParametricSurface, ImplicitSurface

- Geometric primitives & operations — Line/Ray/Segment/Hyperplane/Triangle/Polygon/Circle/Disk/Box/Simplex; intersection (Moller-Trumbore, slab method, analytical ray-quadric), distance, boolean ops, clipping

- Mesh & geodesics — Mesh<Surface>, subdivision with surface projection, LOD chains, geodesic distance (Dijkstra + heat method), geodesic Voronoi, discrete exterior calculus

- Morphisms — typed maps between spaces with pipe composition: point | scale | shift | project

- Declarative scene DSL (io::build) —torus()/offset()/scatter()/compose()build a flat, inspectableTrace, not a tree of opaque closures; analytic until the last mile (offset surfaces and area-weighted placement are real function composition, no mesh anywhere until something actually needs triangles). Getting-started tutorial:docs/getting-started-dsl.md, runnable inexamples/donut_demo.cpp

- Arbitrary precision — Boost.Multiprecision (Real50, Real100, any digit count), same generic algorithms; optional, -DSPATIUM_BOOST=ON

- Physics & relativity research track — geometric-mechanics integrators (symplectic, Lie-group, variational), metric-agnostic geodesic integration (Schwarzschild/Kerr), and RSC — a trained dispatcher that picks which method/precision to use per problem, not hand-tuned; see Roadmap

- N-dimensional, zero-cost — templated on dimension and scalar type, concepts checked at compile time, no virtual dispatch

#include <spatium/spatium.hpp>

#include <print>

using namespace spatium;

using namespace spatium::geometry;

int main() {

// Geometry — clean factory syntax

auto t = tri(Vec3{0, 0, 0}, Vec3{1, 0, 0}, Vec3{0, 1, 0});

std::println("area = {:.4f}, normal = {}", t.area(), t.normal());

// Intersection via pipe

auto r = *ray(Vec3{0.25, 0.25, 5}, Vec3{0, 0, -1});

if (auto hit = r | t)

std::println("hit at {}", *hit);

// Morphism pipeline

auto scale = morph<E3, E3>([](const Vec3& p) { return p * 2.0; });

auto proj = morph<E3, E2>([](const Vec3& p) -> Vec2 { return {p[0], p[1]}; });

auto result = pt<E3>(Vec3{1, 2, 3}) | scale | proj;

std::println("{}", result); // P(2, 4)

// Sphere geodesics

S2 sphere;

auto north = pt<S2>(Vec3{0, 0, 1});

auto east = pt<S2>(Vec3{1, 0, 0});

auto tangent = north.log(east, sphere);

auto midpoint = north.exp(tangent, 0.5, sphere);

std::println("geodesic midpoint: {}", midpoint);

// Mesh subdivision

auto mesh = mesh::icosahedron(sphere);

auto refined = mesh::subdivide(mesh, sphere, 3);

std::println("{}", refined); // Mesh{V=642 F=1280 E≈1920}

}Requires C++23 (GCC 15+ or Clang 19+), CMake 3.28+, Catch2 v3 for tests.

# With Nix (recommended)

nix develop

cmake --preset default

cmake --build --preset default

ctest --preset default

# Without Nix

cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug

ninja -C buildCMakePresets.json has presets beyond default for common configurations — release (Eigen, for RSC training-heavy work), modules (the C++23 modules build path), noeigen, vulkan-dev, cuda, and two benchmark-harness presets. cmake --list-presets shows all of them.

* Defaults to ON only when Spatium is the top-level CMake project (built

standalone, as above). Pulled in via add_subdirectory() or FetchContent

from another project, these four default to OFF instead, so a downstream

consumer gets just Spatium::sdk without forcing a Vulkan/Catch2/example

build it never asked for -- see "Using in Your Project" below.

include(FetchContent)

FetchContent_Declare(spatium

GIT_REPOSITORY https://github.com/Vaniell0/spatium.git

GIT_TAG v1.0.0

)

FetchContent_MakeAvailable(spatium)

target_link_libraries(your_target PRIVATE Spatium::sdk)This pulls in only the header-only Spatium::sdk interface target -- the

Vulkan viewer, examples, tests, and RSC tools all default OFF when Spatium

isn't the top-level CMake project, so nothing beyond Spatium::sdk and its

one required dependency (Boost headers, for Real50/Real100) gets built.

See examples/external-consumer/ for a

complete, independently-buildable project using exactly this snippet.

find_package(Spatium REQUIRED)

target_link_libraries(your_target PRIVATE Spatium::sdk)Any struct with the right methods satisfies the concepts automatically:

struct FlatTorus {

using ScalarType = double;

using PointType = Vec<double, 2>;

using TangentVector = Vec<double, 2>;

static constexpr std::size_t dimension = 2;

static constexpr bool is_complete = true;

bool contains(const PointType& p) const { /* ... */ }

ScalarType distance(const PointType& a, const PointType& b) const { /* ... */ }

PointType exp_map(const PointType& p, const TangentVector& v, ScalarType t) const { /* ... */ }

TangentVector log_map(const PointType& p, const PointType& q) const { /* ... */ }

ScalarType metric_at(const PointType& p, const TangentVector& u, const TangentVector& v) const { /* ... */ }

PointType project(const PointType& p) const { /* ... */ }

TangentVector normal(const PointType& p) const { /* ... */ }

};

static_assert(spatium::RiemannianManifold<FlatTorus>);

static_assert(spatium::Surface<FlatTorus>);

// Mesh<FlatTorus>, subdivision, morphisms — all work automatically.#include <spatium/core/precision.hpp>

using namespace spatium;

// 50-digit precision

Euclidean<3, Real50> space;

Vec<Real50, 3> a{Real50{0}, Real50{0}, Real50{0}};

Vec<Real50, 3> b{Real50{3}, Real50{4}, Real50{0}};

auto d = space.distance(a, b); // 5.000...000 (50 digits)- Architecture — concept hierarchy, design decisions, the real dependency graph

- Conventions — namespace/subdivision/error-handling rules, and the known violations being fixed

- API Reference — all types, methods, concepts

- Quick Start Guide — getting started

- Getting Started: The Declarative Scene DSL — zero-barrier-to-entry, build a donut in three declarative steps

- Extending Spatium — defining custom spaces and primitives

- Roadmap — what's done, what's planned, project history

- Concept-Driven Physics — how physics/mechanics/fits the concept hierarchy

include/spatium/

core/ concepts, error, verify, precision

algebra/ Vec, Matrix, Quaternion, Complex, Dual (autodiff), calculus,

ODE solvers, linear solve, polynomial solvers, Eigen interop

algebra/groups/ SO3, SE3

spaces/ Euclidean, Sphere, Hyperbolic, ParametricSurface, ImplicitSurface

geometry/ primitives, intersection, distance, boolean ops, ray_surface (Quadric)

mesh/ Mesh, subdivision, LOD, topology, geodesic, voronoi, DEC

spatial/ BVH (SAH build, ray_cast, nearest, query_box)

discrete/ FiniteSet, GeometricSet

render/ supersample_pixel(), camera, write_image, parallel_for_rows

io/ Table, SVG, OBJ, STL

physics/ periodic-table element data (the one compiled TU)

physics/atomic/ atom/orbital models, Bohr model, SVG rendering

physics/mechanics/ integrators, symplectic/Lie-group/variational structure, contact

physics/relativity/ Schwarzschild/Kerr geodesic integration, accretion disks

viewer/ Vulkan app (multi-mesh, point clouds, ImGui)

point.hpp, morphism.hpp, spatium.hpp

rsc/ RSC — trained dispatcher on top of Spatium (7 domains, see docs/ROADMAP.md)

tests/, examples/, benchmarks/

nix run .#primitives # unified primitives + BVH raycast, interactive Vulkan

nix run .#tumbling # Dzhanibekov-effect rigid-body tumble (LGVI), frame sequenceMore demos exist in examples/ — analytical ray tracing, a Schwarzschild/Kerr GR raytracer, an Ellis wormhole flythrough, and others; cmake --list-presets and nix flake show list every buildable target.

Apache License 2.0 — see LICENSE. Contributing guide: CONTRIBUTING.md.

Project history: docs/ROADMAP.md.