Skip to main content

Crate roxlap_core

Crate roxlap_core 

Source
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’s tile_* validation poses.
gline
gline per-scanline frustum setup — port of the projection math at the top of voxlap5.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 helpers genperp (voxlap5.c:9546), mat0 (voxlap5.c:9568), and setlimb (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 opticast entry 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 (grouscan for gline, the 4.7-scalar / 4.9-SSE rasterizers for hrend / 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 Rasterizer implementation — port of voxlaptest’s 4.7.5 scalar hrendzsse / vrendzsse fallbacks (voxlap5.c:1947 / :2003 post-4.8.4 line numbers). Writes one u32 ARGB pixel + one f32 z-buffer entry per screen position from radar entries the (still-stubbed) gline will produce in R4.3.
sky
Sky-texture resource for the textured-sky startsky path.
sprite
KV6 sprite type + the draw_sprite dispatcher.
world_lighting
Voxlap’s world-voxel lighting bake (updatelighting, voxlap5.c:10539).
world_query
Per-voxel world queries against a .vxl column-slab world.

Structs§

Camera
Camera state. All vectors are in voxel-world units (1 unit = 1 voxel); the basis is right-handed with down aligned to +z (i.e. z grows downward into the map, matching voxlap’s coordinate system).
Engine
Voxel engine state.
LightSrc
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 reads r2 not r, matching voxlap’s vx5.lightsrc[i].r2-keyed range check.

Constants§

DEFAULT_KV6COL
Voxlap’s vx5.kv6col default — mid-grey, equal R/G/B so the sprite update_reflects nolighta optimisation kicks in.