- C++ 100%
| interfaces | ||
| tests | ||
| .gitignore | ||
| LICENSE | ||
| project.cpp | ||
| README.md | ||
Crafter.Math
A C++23 math library for the Crafter engine, distributed as a set of C++ modules. Provides generic vector and matrix types alongside SIMD-specialized fixed-size vectors for float and _Float16, plus a small set of ray intersection routines.
The library is hardware-aware: it picks the widest SIMD path the target supports (SSE / AVX / AVX-512 on x86_64, RVV on RISC-V, SIMD128 on WebAssembly) and falls back to scalar code elsewhere.
Modules
import Crafter.Math; re-exports the following partitions:
| Partition | Contents |
|---|---|
:Basic |
ToRadian, plus the VectorF16 → VectorF32 alias on x86_64 without AVX512-FP16. |
:Vector |
Generic Vector<T, Len, Alignment> with .x/.y/.z/.w and .r/.g/.b/.a accessors, arithmetic, comparison, and conversion operators. |
:MatrixRowMajor |
MatrixRowMajor<T, ColumnSize, RowSize, Repeats> — row-major matrices with packed-batch support via Repeats. |
:VectorF32 |
VectorF32<Len, Packing> — SIMD-specialized 32-bit float vector with Load/Store, FMA, Cross, Dot, Length, Normalize, Sin/Cos, Shuffle, etc. |
:VectorF16 |
VectorF16<Len, Packing> — same surface as VectorF32 for _Float16 when the target supports it. |
:Intersection |
IntersectionTestRayTriangle, IntersectionTestRaySphere, IntersectionTestRayOrientedBox. |
:Common |
Internal SIMD type selection (__m128/256/512, __m128h/256h/512h, v128_t, or scalar array) used by the F16/F32 vectors. |
Len is the logical vector width (1–4 for most graphics use) and Packing is the number of vectors packed into one SIMD register — e.g. VectorF32<3, 4> holds four 3-vectors in a single 512-bit register, which is what the batched Dot, Length, and Normalize overloads operate on.
Example
import Crafter.Math;
using namespace Crafter;
// Generic 3-vector of floats.
Vector<float, 3> a(1.0f, 2.0f, 3.0f);
Vector<float, 3> b(4.0f, 5.0f, 6.0f);
auto c = a + b;
// SIMD-specialized 4-vector with one element of padding.
VectorF32<4, 1> p(1.0f);
VectorF32<4, 1> q(2.0f);
auto r = VectorF32<3, 1>::Cross(p, q);
// Ray vs. triangle.
float t = IntersectionTestRayTriangle<float>(
{0,0,0}, {1,0,0}, {0,1,0},
{0.25f, 0.25f, -1.0f}, {0, 0, 1});
Building
This project uses Crafter.Build. The build script in project.cpp declares the library as a static C++ module library and registers three test executables targeting different ISAs:
Vector-sapphirerapids— AVX-512 with FP16 (-march=sapphirerapids)Vector-x86-64-v4— AVX-512 baselineVector-x86-64-v3— AVX2 baselineVector-rv64gcv_zvl512b— RVV with VLEN≥512 (uses the 64-byte tier)Vector-rv64gcv_zvl256b— RVV with VLEN≥256 (32-byte tier)Vector-rv64gcv— RVA23 baseline ZVL128B (16-byte tier)
Build and run tests via your usual Crafter.Build entry point; build/ and bin/ are git-ignored.
Target support
- x86_64: SSE / AVX / AVX-512F selected per target; AVX512-FP16 is required for native
VectorF16(otherwise it aliasesVectorF32). F16C is used for fp16 ↔ fp32 conversion when available. - RISC-V: RVV 1.0 (the
Vextension, ratified Nov 2021, mandatory in the RVA23 profile). Storage is a 16/32/64-byte GNU vector picked at compile time from the guaranteed VLEN (__riscv_v_fixed_vlenfrom Clang's-mrvv-vector-bits=, else__riscv_v_min_vlenfrom the march'sZvl*suffix, else the ZVL128B baseline).VectorF16aliasesVectorF32until aZvfhpath lands. - WebAssembly:
wasm_simd128.h128-bit path; SIMD width is capped at 16 bytes. - Other targets: scalar fallback via
std::array<T, N>.
License
LGPL-3.0-only. See LICENSE.
Copyright © 2026 Catcrafts — catcrafts.net