# 3JHV — 3jsheightmapviewer

A new, standalone project for consolidating selected features from
`../terrain-heightmap-viewer/` into one coherent heightmap exploration engine.

## Current status

Core milestones 1–6 are complete, including real-GPU acceptance reported by the
user on 2026-09-29.
The viewer provides versioned settings, validated world import and terrain rendering at the exact exported resolution. Three original
GPL terrain textures are bundled locally. Walking/freecam, a minimap and a
navigation HUD are available, together with scenery, vegetation, layer controls
and minimap overlays. The catalogue bundles the verified demo house; other model
IDs use visible proxy/procedural fallbacks pending asset provenance checks.
The original viewer remains unchanged. See [Acceptance and handoff](docs/ACCEPTANCE.md)
for repeatable checks, deployment, known limitations and the recorded user acceptance.

The first implementation pass is described in
[Core migration plan](CORE_MIGRATION_PLAN.md). It includes core scenery and
vegetation. The [Shadow integration plan](SHADOW_INTEGRATION_PLAN.md) covers
milestones 7–11. The [terrain lighting foundation](docs/TERRAIN_LIGHTING.md) and
[shadow resources with safe replacement](docs/SHADOW_RESOURCES.md), and
[live updates and shadow stability](docs/LIVE_SHADOWS.md) (milestones 7–9)
are implemented. Milestone 10 adds public lighting and shadow controls; the
bundled configuration now starts in Sunlit mode with shadows on. Older schema-1
configurations that omit these settings retain Original/off.
The [panoramic sky and fog controls](docs/SKY.md) are now integrated, including
background rotation and independent horizon fog colour. The bundled configuration
enables the panorama; older configurations keep the original flat background.

## Install and run

Use Node.js 18, 20 or 22+ and npm 9+:

```sh
cd 3JHV
npm ci
npm run dev
```

Open the loopback URL printed by Vite. **Import scenery-editor ZIP bundle** accepts
the editor's viewer-bundle v2 ZIP in one selection; you can also drop the ZIP into
the import area. It loads the final terrain, scenery, optional generated vegetation
and asset catalogue. The editor's ZIP contains asset references, not GLB models or
textures; those resolve against this viewer's installed local assets.

**Import compiled-world folder** accepts the complete output directory from
`../terrain_world_compiler/`. The viewer's own adapter loads terrain-world v1/v2 JSON,
including source maps, transition strips, corner joins, shared normals, scenery
and local or normalized water. V2 normalization covers submerged connectors
at one common sea level. Choose the folder containing `world.json`;
keep its subfolders intact. See [Compiled worlds](docs/COMPILED_WORLDS.md).

Alternatively, select or drop a heightmap PNG and its
terrain metadata JSON together, optionally including generated vegetation and
runtime scenery v2/v3 or legacy county features v3. The viewer reports the
validated world dimensions, grid and scenery counts, and renders terrain and
water, scenery and vegetation. Invalid imports or failed rebuilds leave the
current world intact. Click the terrain to capture the mouse: WASD move, Shift sprints, Space jumps, F toggles
freecam, R respawns and Escape releases the mouse. Click land on the minimap to
teleport. **Frame terrain** enables orbit inspection; **Explore** resumes your
position. M toggles the minimap and H hides/shows the surrounding panels.
Switch between **Natural** textures and the **Topographic** diagnostic palette.
Natural now combines the grass tile with deterministic two-scale vertex colours
and woodland/pasture/rough-grazing tints. Saturation, colour strength, patch sizes
and palette are configured under `groundTint` in `public/config/viewer.json`;
`inlandColour` sets the green base outside land-use regions. Reload to apply
edits. See [Ground tint](docs/GROUND_TINT.md).
Fog can be turned off.
Natural also draws deterministic grass within 100 metres of the player, fading
between 80 and 100 metres. **Grass ground cover** toggles it independently;
orbit inspection follows the orbit target. Grass avoids water, steep slopes,
roads, building footprints and source-visible land-use polygons. See
[Grass ground cover](docs/GRASS.md).
The planned [source-local grass update](SOURCE_LOCAL_GRASS_PLAN.md) preserves
each source map's arrangement inside compiled worlds, gives connectors their own
placements and keeps runtime generation compatible with future terrain streaming.

**Lighting** switches between Original and Sunlit;
**Shadows** toggles occlusion while keeping Sunlit slope lighting. Topographic
suspends these effects and retains your preferences. Lighting changes preserve
your camera and loaded terrain. **Sky & fog** controls the panorama, its rotation
and the independent fog colour. See [World import](docs/IMPORT_CONTRACT.md) for supported
files, [Exploration](docs/EXPLORATION.md) for controls and collision limits, and
[Terrain rendering](docs/TERRAIN_RENDERING.md) for the appearance contract.
See [Scenery rendering](docs/SCENERY_RENDERING.md) for layers, fallbacks and
[asset provenance](docs/SCENERY_ASSETS.md).

Dependencies install locally; runtime requires no CDN or network assets.
Initial installation needs npm registry access or a populated npm cache.

```sh
npm test
npm run build
npm run preview
```

For optional headless acceptance, run `npm run test:browser` after building.
It uses the shared Playwright installation and automatically starts/stops
loopback servers. See [Acceptance](docs/ACCEPTANCE.md) for setup and coverage.

Production files are in `dist/` and support hosting in a subdirectory. Edit
`public/config/viewer.json` and reload to change development settings. See
[Configuration](docs/CONFIGURATION.md) for defaults and validation, and
[Migration ledger](docs/MIGRATION_LEDGER.md) for source state, licences,
selected files, tests and deferred assets.

## Direction

- Preserve the late-1990s/early-2000s visual target and walking-simulator focus.
- One application with explicit configuration, rather than separate experimental
  entry points for each rendering feature.
- Keep terrain data, rendering, movement, asset loading and optional gameplay
  separated internally. Consolidation does not mean one monolithic subsystem.
- Preserve metre-based coordinates, existing export compatibility, offline
  operation and npm-based dependency management.
- Migrate working features deliberately, including their relevant tests and
  documentation. Do not copy dependency directories or generated builds.
- Make 3JHV independent: no permanent runtime imports from the old project.

## Core migration sequence

The [Core migration plan](CORE_MIGRATION_PLAN.md) defines the implementation
phases and their acceptance criteria:

1. **Standalone shell:** source inventory, local dependencies and configuration.
2. **World import:** heightmap/metadata decoding, coordinates and scenery contracts.
3. **Terrain rendering:** exact exported grid, retained textures, coastal blending
   and resource lifecycle. Normal rendering has no elevation-driven ground
   colouring or texture fade; elevation colouring is exclusive to Topographic.
4. **Exploration:** walking/freecam, minimap, HUD and controls.
5. **Scenery:** shared catalogue, buildings, roads, hedgerows and vegetation,
   including vegetation-specific alpha cutouts and clear asset ownership.
6. **Acceptance:** independent build, validation and handoff.

Resource use remains uncapped by application policy for now: no configured
grid or memory budgets and no automatic reduction of terrain resolution.
Actual platform limits still apply; report detectable allocation failures clearly.

Core retains base lighting and configurable fog. Sunlit lighting, local shadows
and panoramic sky are available. Other optional
systems, including distance tools, objectives, vehicles and rigid-body physics,
will be evaluated individually after core acceptance.

Terrain deformation remains a future experiment; it is not a prerequisite for
this migration and should not force the initial viewer into a volumetric design.

## Migration acceptance

For each feature, record its source, retained behaviour, discarded experiments,
configuration and verification steps. Compare the same existing world in both
applications. Do not silently regenerate source worlds or alter imported assets.

Asset redistribution rights must be checked individually before copying them;
do not assume every externally supplied image or GLB shares the code's licence.
Preserve licence notices and attribution when code and assets are migrated.
