Phase 5: region select + client-side glTF export
Adds the Region Export API (GET /api/export/:serverId/:dimension/ :x1/:z1/:x2/:z2, chunk-coordinate range, capped at 64 chunks server- side) streaming raw chunkSections rows for a footprint, plus a fully client-side pipeline that turns that into a downloadable glTF (.glb): a JS port of the Rust worker's greedy mesher (voxel-mesh.js, mirrored test-for-test against worker/src/mesh.rs) and block-color palette (block-colors.js, mirrored against worker/src/palette.rs), a base64 section decoder, mesh merging with per-section world offsets, and a hand-rolled minimal GLB writer (gltf-export.js) — hand-rolled rather than Babylon's GLTF2Export since this project's Babylon usage never meshes client-side (only renders pre-built buffers) and a live Scene/Engine isn't needed or unit-testable. The whole mesh+export pipeline runs inside a Web Worker (export-worker.js) so a multi-chunk export doesn't block the UI thread. The map UI gets a drag-to-select region tool (chunk-snapped, live rectangle preview, cap enforced client-side too) and an Export glTF button. Built test-first per the project's TDD workflow; the exported .glb was independently validated with @gltf-transform/cli against real seeded terrain data (correct triangle count, vertex count, and bounding box for the selected area). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015tKdPZt78zbPUZMXWzKEKt
This commit is contained in:
@@ -43,6 +43,20 @@ html(lang="en")
|
||||
button.px-2.py-1.bg-neutral-700.rounded.text-xs(x-on:click="cancelMarkerForm") Cancel
|
||||
p.text-xs.text-amber-400(x-show="markerStatus" x-text="markerStatus")
|
||||
aside.w-80.flex.flex-col.border-l.border-neutral-700.bg-neutral-800(x-show="server")
|
||||
div.border-b.border-neutral-700.p-2.space-y-2
|
||||
div.flex.items-center.justify-between
|
||||
h2.text-sm.font-semibold Region export
|
||||
button.px-2.py-1.rounded.text-xs(
|
||||
x-bind:class="selectingRegion ? 'bg-amber-600' : 'bg-neutral-700'"
|
||||
x-on:click="toggleSelectingRegion"
|
||||
x-text="selectingRegion ? 'drag on map…' : '+ select region'")
|
||||
p.text-xs.text-neutral-400(x-show="regionStatus" x-text="regionStatus")
|
||||
div.flex.gap-1(x-show="regionBounds")
|
||||
button.flex-1.px-2.py-1.bg-emerald-700.rounded.text-xs(
|
||||
x-bind:disabled="exporting" x-on:click="exportRegion"
|
||||
x-text="exporting ? 'exporting…' : 'Export glTF'")
|
||||
button.px-2.py-1.bg-neutral-700.rounded.text-xs(x-on:click="cancelRegionSelection") Cancel
|
||||
|
||||
div.border-b.border-neutral-700.p-2.space-y-2(style="max-height: 40%; overflow-y: auto;")
|
||||
div.flex.items-center.justify-between
|
||||
h2.text-sm.font-semibold Markers
|
||||
|
||||
Reference in New Issue
Block a user