Expand description
roxlap engine core.
A pure-Rust port of Ken Silverman’s Voxlap voxel engine. See
PORTING-RUST.md at the workspace root for the substage roadmap.
Stage R3 lands the public Engine / Camera surface with a
sky-fill stub renderer. R4 replaces the stub with the full
opticast + grouscan algorithm.
§World handedness and the horizontal mirror
roxlap’s world is z-down: x = east, y = north, z points
down into the map. Physically the triple (east, north, up) is
left-handed, so a faithfully-projected view is horizontally
mirrored relative to a real camera at the same heading — the
viewer’s geometric right lands on screen-left. This is Voxlap’s
native convention; it is baked into the projection, the frustum
cull, the scan loops, and every bit-exact oracle golden, and is
reproduced deliberately. It is not a bug.
The camera basis the engine actually renders with is
right-handed in the (right, down, forward) sense
(right × down = +forward). Build it with
Camera::from_yaw_pitch, Camera::orbit, or
Camera::look_at — never by rotating Camera::default, whose
placeholder basis is left-handed and will make the sprite cull
reject every sprite.
§I want an un-mirrored world
Do not “fix” the mirror by negating right in the basis. That
flips the chirality to right × down = -forward; the world still
renders, but the sprite frustum cull then rejects every sprite
(and you diverge from the oracle goldens). The mirror is in the
projection, not the basis.
Handle it on the consumer side instead — pick one and stay consistent:
- mirror a single world axis in your scene → world mapping (e.g. negate world-x when you place content), or
- negate your yaw input so headings sweep the opposite way.
Either re-establishes the chirality your project expects without touching the engine. (A true engine-side de-mirror would mean negating screen-x in both the grid raycaster and the sprite rasteriser while preserving the cull’s normal winding — a large, golden-breaking change that diverges from Voxlap, and is out of scope here.)
Re-exports§
pub use grid_view::ChunkGrid;pub use grid_view::GridView;pub use opticast::opticast;pub use opticast::OpticastOutcome;pub use opticast::OpticastSettings;pub use world_lighting::apply_lighting_with_cache;pub use world_lighting::update_lighting;pub use world_lighting::update_lighting_chunk;pub use world_lighting::EstNormCache;
Modules§
- camera_
math - Per-frame camera-derived state — port of voxlaptest’s
setcamera(voxlap5.c:2246). - drawtile
- Voxlap’s 2D textured-quad blit primitive —
drawtile(voxlap5.c:6954). Used for HUD overlays, weapon sprites, and the oracle’stile_*validation poses. - gline
glineper-scanline frustum setup — port of the projection math at the top ofvoxlap5.c:gline(lines 1146..1175).- grid_
view - Per-frame voxel-world borrow shape.
- kfa_
draw - KFA (animated kv6) sprite renderer — voxlap’s
kfadraw(voxlap5.c:9759) plus the bone-transform helpersgenperp(voxlap5.c:9546),mat0(voxlap5.c:9568), andsetlimb(voxlap5.c:9643). - meltsphere
- Sphere-region voxel extraction (
meltsphere) and its support tables. - opticast
- Per-frame orchestrator — wires the R4.1 builders into a single
opticastentry point. - opticast_
prelude - Per-frame opticast prelude — the integer / fixed-point state cache
voxlap derives at the top of
opticast(voxlap5.c:2284..2303) before the column-scan loops run. - rasterizer
- Rasterizer trait + per-frame scan scratch — the callback surface
the four-quadrant scan loops dispatch into. R4.3 will provide the
real implementation (
grouscanforgline, the 4.7-scalar / 4.9-SSE rasterizers forhrend/vrend); test code can plug a recording stub here and exercise the scan loops without any actual world data. - ray_
aabb - S1.1 — ray ↔ axis-aligned bounding box clip helper.
- scalar_
rasterizer - Scalar
Rasterizerimplementation — port of voxlaptest’s 4.7.5 scalarhrendzsse/vrendzssefallbacks (voxlap5.c:1947/:2003post-4.8.4 line numbers). Writes oneu32ARGB pixel + onef32z-buffer entry per screen position from radar entries the (still-stubbed)glinewill produce in R4.3. - sky
- Sky-texture resource for the textured-sky
startskypath. - sprite
- KV6 sprite type + the
draw_spritedispatcher. - world_
lighting - Voxlap’s world-voxel lighting bake (
updatelighting, voxlap5.c:10539). - world_
query - Per-voxel world queries against a
.vxlcolumn-slab world.
Structs§
- Camera
- Camera state. All vectors are in voxel-world units (1 unit = 1
voxel); the basis is right-handed with
downaligned to +z (i.e. z grows downward into the map, matching voxlap’s coordinate system). - Engine
- Voxel engine state.
- Light
Src - One point light source for sprite (and, eventually, world) lighting.
Mirror of voxlap’s
lightsrc_t(voxlap5.h): position, squared reach radius, and intensity scale. The lighting math readsr2notr, matching voxlap’svx5.lightsrc[i].r2-keyed range check.
Constants§
- DEFAULT_
KV6COL - Voxlap’s
vx5.kv6coldefault — mid-grey, equal R/G/B so the spriteupdate_reflectsnolighta optimisation kicks in.