Files
VoxelForge/Standalone/Tools/webviewer
Fr0zkaandClaude Opus 5.5 95cf8de107 tools: web viewer shows the owner's world; collapsible phone menu (W2)
export_world.py exports the owner four-strate world (LOD0-2 around each arrival + one FI
passage view) through the headless mesh exporter and converts to GLB (16-45 MB, 0.6-1.7M
triangles each); GLBs are git-ignored and regenerated by the script. Menu collapses to a
button (collapsed by default on phones), smaller phone controls, loading progress and errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-10-29 00:10:28 +01:00
..

VoxelForge local web viewer

This folder contains a Python standard-library server, a .vfmesh to GLB converter, and a Three.js page for viewing exported VoxelForge worlds. The converter accepts VFMSH001 and VFMSH002 files, preserves vertex normals and tile/triangle counts, and writes metre-scale GLB geometry. It rotates VoxelForge's Z-up coordinates to glTF's Y-up coordinates.

Three.js and its GLTF loader are loaded from jsDelivr at the pinned version 0.160.0, so the browser needs internet access the first time it loads the page. Python and the viewer server need no package installs.

Convert existing meshes

From this directory, convert one or more existing exports:

python3 convert.py \
  ../../../Saved/Linux/l32/capture-sw-far-v20-settled-surface.vfmesh \
  ../../../Saved/Linux/l32/fi-floor-v20-lod4-focus.vfmesh \
  ../../../Saved/Linux/linux23/capture-fi-mouth.vfmesh

The GLBs go into meshes/ by default. To use another output folder, add --out-dir /path/to/glbs. The converter reads the source mesh directly and does not regenerate a world.

Refresh the owner world previews

From the repository root, run:

python3 Standalone/Tools/webviewer/export_world.py

This uses the existing Saved/Linux/l101/bin/VoxelForgeCoreHeadless-l101-clang exporter to regenerate LOD0–2 arrival views for SW, FI, TN, and VS, plus a FI passage view. It applies the CPU affinity and memory limits used by the capture runners, writes the GLBs into Standalone/Tools/webviewer/meshes/, and keeps per-view logs and a size/count summary in Saved/Linux/w2/. To use another compatible headless binary, pass --headless-binary /path/to/VoxelForgeCoreHeadless-*.

Start and view

cd Standalone/Tools/webviewer
python3 server.py

Open http://127.0.0.1:8000/ in a WebGL-capable browser on the same machine. The server binds to 127.0.0.1 by default. To serve GLBs from a different local folder:

python3 server.py --mesh-dir /path/to/glbs --port 8000

For a phone connected over Tailscale, bind to the viewer machine's Tailscale address with --host <tailscale-ip> and open http://<tailscale-ip>:8000/ on the phone. Keep the browser online so it can load the pinned Three.js modules from jsDelivr.

On Windows with Python 3, run py -3 server.py --mesh-dir .\meshes from this folder and open http://127.0.0.1:8000/ on that Windows machine.

Controls

  • Click the world to capture the mouse, then use W/A/S/D and mouse movement to fly and look. Space rises; C or Ctrl descends. Esc releases the mouse.
  • On touch screens, drag the left pad to move and the right pad to look. Touch pads can show or hide the pads; this also makes them available in headset browsers that do not report a coarse pointer.
  • Adjust flight speed with the slider. Toggle wireframe or normal-colour shading in the panel.
  • Choose mesh A and an optional mesh B. Click Show B or press B to switch between them. Fit view frames the active mesh.
  • The overlay shows the active mesh's triangles and tiles and the camera position in metres.

The viewer uses normal-based lighting and distance fog. It applies a simple viewer material; VFMSH002 resource material IDs are read and skipped by the converter.