- ra3.map: capture the object RoadType; ra3.models pairs the map's
Start/End road objects and drapes a flat textured ribbon along each
segment (tessellated to the relief).
- Ground decals (roads/sidewalks) get a per-vertex screen-space depth
offset (scene::vertex.bias) applied in the object shader and the
software rasteriser, so they no longer z-fight or clip into the
terrain at top-down angles.
- Tactical view aligned with retail (SAGE LookAtTranslator): middle-drag
orbits yaw/pitch, a middle click resets angle/pitch/zoom, arrow keys
pan, wheel zooms within the retail zoom range; WASD pan removed and
left-drag no longer rotates.
- ui_event gains middle/right/released buttons; Vulkan + SDL map them.
- docs: roads, depth bias and camera controls.
Read the buildings and props a map places from its compiled art (the
uncompressed worldbuilder stream + embedded DDS textures):
- ra3.models: BAB asset-stream parser (lazy slices), W3DMesh + D3DHierarchy
decode, DDS (DXT1/3/5 + uncompressed) decode, per-mesh bone remap and
bind-pose single-joint skinning, flattened to one world-space triangle soup.
- ra3.map: parse the ObjectsList chunk into (type, x, y, z, angle).
- ra3.terrain: render3d rasterises the scene over the raymarched terrain with
a z-buffer; gpu_terrain carries the scene for the GPU backends.
- ra3.vulkan: second pipeline + depth attachment, terrain.frag writes
gl_FragDepth, and a small depth bias keeps ground decals from z-fighting.
- objects.fx shaders (compiled to SPIR-V), embedded like scene/terrain.
Only opaque parts are drawn: FX-light billboards (DefaultW3D.fx / BasicW3D.fx)
and damage-fill shells (BuildingsGenericDamageFill.fx) are skipped, since the
latter paint the wrecked interior (e.g. orange CBBuilding_Wood) over the shell.
Ground-decal meshes with no diffuse role and the Road templates themselves are
still not drawn.