# Fortress architecture v3.1 — level masonry

`fortress-architecture.mjs` is original procedural Three.js geometry for El Morro, San Cristóbal, its mapped outer works, and the Garita del Diablo platform. It uses no downloaded 3D model. It leaves all large fort areas and courtyards uncovered.

## Integration

```js
import {buildFortressArchitecture, FORTRESS_WAY_IDS} from './fortress-architecture.mjs';
const fortresses = buildFortressArchitecture({
  THREE, xy, height, materials,
  data, // assets/geography.json
  osm   // assets/geography-osm.json; needed for 260863192
});
scene.add(fortresses.group);
```

The builder does not fetch, alter terrain, modify data, or attach the group itself. `xy(lon,lat)` accepts a Vector2, `{x,z}`, or `[x,z]` result. `height(x,z)` must return metres above the same vertical datum as the terrain. The caller supplies Three.js, so the module does not create a second library instance.

Optional `options.courtyards`, `options.garitas`, and `options.cannons` can each be false. `materials.stone` and `materials.stoneNormal` are existing texture objects, or provide `materials.fortressStone` as a material. Textures remain caller-owned. `dispose()` detaches the group and disposes only module-created geometry/materials.

- Replace the legacy fort wall/parapet renderer only for exported `FORTRESS_WAY_IDS`: 561634537, 142863669, 260863192, 561590374, 509326337, 509326338, 203648928. Retain fort metadata, travel exclusions, and anchors as needed. No broad roof geometry should be restored for those footprints.
- Remove the prior overlapping El Morro and San Cristóbal garitas. Keep distinct city-wall garitas outside these forts.
- Keep the ordinary city-wall renderer, except way **308896766 segments 31, 32, 33**, zero-based `path[i] → path[i+1]`. Those three segments exactly coincide with the San Cristóbal north boundary (about 193 metres) and otherwise double-draw it. The other city-wall ways have no segment midpoints within 3 metres of these fort boundaries.
- San Cristóbal's shared internal boundary between 142863669 and 260863192 is suppressed by geometric adjacency, not rendered as a new curtain wall.

## Collision records

`colliders` contains one record for every rendered exterior masonry run:

```js
{ax, az, bx, bz, bottomA, bottomB, topA, topB, thickness, nx, nz, sourceId}
```

These are metre coordinates. The axis follows the centre of the narrow wall; `thickness` is **full width**, not half-width. `nx,nz` points outward from the fort polygon. Linearly interpolate bottom and top with the nearest segment parameter `t`. `topA/topB` include the real cap top, including the local leveling applied by the builder. Collision records are not automatically activated: the caller can spatially index them and apply only the thin exterior walls.

No records are returned for courtyard recesses, cannon, garitas, gate-frame pillars, or the interior of any fort polygon. Both entrance gaps are omitted. Measured against the current records, the El Morro portal centre has at least 3.26 m clearance to exterior collision edges and the San Cristóbal approach has 4.14 m. El Morro's decorative arch itself has an approximately 4.2 m wide clear opening. This avoids a solid area obstruction across either fort.

## What is mapped and what is interpreted

1. **Mapped footprint boundaries:** exact supplied OSM longitude/latitude coordinates, resampled at <=1.7 m spacing. These are community map outlines, not a certified engineering survey. Top and base values come from the supplied terrain sampler, rather than OSM height/level tags. Shared internal boundaries are removed. Narrow exterior faces and coping have width, not a whole-area flat roof.
2. **Masonry top treatment (v3.1):** every raw OSM edge is a level architectural run. Long edges may split when a smoothed measured crest profile changes persistently by over 3.5 m, with approximately 10 m minimum spans. Every resulting run uses a constant upper-envelope crest, rounded up to 0.5 m; the parapet is 0.92 m above that level and has a 0.14 m cap. Profile sampling still uses the measured surface at 0, 1.8 and 3.5 m inward (the inward crest estimate is limited to 5.5 m above the edge). The output never interpolates a wavy or sloping top between DEM samples. Closed end faces form the vertical steps at terrace changes, corners and openings. This is an explicit architectural interpretation of measured terrain evidence, not a surveyed historic parapet elevation or confirmed terrace-break location.
3. **Wall feet (v3.1):** each section has one constant foundation elevation, 2 m below the minimum sampled terrain along both faces and 3 m outward. Both wall faces extend fully to that footing; ends are closed. The original grassy/sloped terrain remains exposed between masonry sections. The terrain can still occlude the bottom part of a wall with an irregular contact line because the existing DEM cannot represent a vertical historic escarp; that contact is not a gap in the masonry foundation.
4. **Courtyard facades:** narrow facade lines traced manually from the supplied USACE/NOAA aerial, to approximately a few metres. They only draw where terrain evidence indicates a retaining-height change. Arched recesses use original interpreted architectural dimensions and only appear where the terrain leaves enough clearance. They are not tunnels or a surveyed room layout. No courtyard roof is created.
5. **Garitas:** five original low-poly round sentry boxes with a real doorway gap, molded base, cornice, dome, finial and dark observation slits. Locations correspond to small mapped/aerial projections. Exact modern dimensions and sub-metre positions were not surveyed. The Devil's Sentry Box is represented separately from its much larger OSM platform polygon.
6. **Artillery:** five original interpreted sample cannon on documented battery areas. These do not assert the current inventory, precise artifact positions, or a historically complete armament arrangement.
7. **Entrance:** El Morro bridge crossing is placed at the corresponding boundary on the supplied aerial, rather than treating the official entrance GPS as the wall point. The portal dimensions are interpreted. San Cristóbal uses an open approach gap; a speculative portal was not added there.

The existing single-height DEM still gives the underlying surface some rounded edges. This module provides vertical masonry, human-scale details, and open access over that surface; it is not a complete measured reconstruction of the six-level/three-level interiors. It does not fabricate underground tunnels, stacked occupied rooms, or interior traversal.

## Primary reference evidence

- [NPS: Castillo San Felipe del Morro](https://www.nps.gov/saju/learn/historyculture/el-morro.htm) describes the six-level ocean-facing fort and thick masonry construction. Used for overall architectural character, not as a dimensioned mesh source.
- [NPS: Castillo San Cristóbal](https://www.nps.gov/saju/learn/historyculture/san-cristobal.htm) describes its three levels, irregular triangular bastions, dry moat, artillery ramps, and the eleven casemates bordering the main plaza. Used for architectural vocabulary; the model's conditional recess count is not a claim to reproduce those eleven rooms.
- [NPS: visitor directions](https://www.nps.gov/saju/planyourvisit/directions.htm) supplies the official approach coordinates. El Morro's boundary opening is approximately 44 m from its GPS approach point; its position is inferred from the bridge visible in the aerial.
- [Library of Congress, HABS PR-93: San Carlos Ravelin](https://www.loc.gov/resource/hhh.pr0116.sheet/?sp=1) is primary evidence for the non-classical configuration of the San Cristóbal outer works and the orientation of its north and south ramparts. Catalogue information was consulted. The drawing raster requests were unavailable (HTTP 403), so no measurement in this module is attributed to those sheets.
- The supplied terrain manifest identifies USGS 3DEP PR_PuertoRicoUSVI_D24, acquired 2023–2025; the supplied aerial identifies USACE/NOAA 2009–2010. This module consumes the host sampler/texture; it does not redistribute a new terrain or imagery asset.

## Data licensing and attribution

The polygon and wall data are from the supplied OpenStreetMap snapshot (2026-09-27). Preserve **© OpenStreetMap contributors**, the [ODbL/copyright link](https://www.openstreetmap.org/copyright), and the project's existing terrain/imagery/texture credits. Original mesh construction and interpreted small details were created for this task. No third-party fortress mesh was copied or downloaded.

## Verification

`validate-fortresses.mjs` builds against the recovered site's actual geometry and height grids and validates finite vertices, sensible vertical bounds, shared-edge suppression, gate clearance, collider bounds, disposal, and a maximum of four combined draw calls. Result: **49,070 triangles, four draw calls, 188 level masonry sections, 1,650 exterior collision segments, about 2,646 m of narrow wall, five garitas, five cannon, 16 conditional facade recesses**. All coordinates are finite. Validation additionally asserts `topA === topB` and `bottomA === bottomB` for every exterior collider. Courtyard cornices also use constant levels with stepped section transitions.

Local visual checks covered El Morro oblique, El Morro's entrance, and San Cristóbal oblique. No browser warnings/errors were emitted. The QA preview intentionally omitted the host's lighthouse, city buildings, player and sky effects; it is only a geometry check. `morro-qa.png`, `morro-entry-qa.png`, and `cristobal-qa.png` record those views. These preview/reference files are work aids; only the `.mjs` module and this source note need integration.

## v3.1 visual correction

The revision removes the prior per-vertex draping fallback entirely, adds full-depth back/end faces and section-level embedded footings, and applies the same horizontal-cornice rule to the narrow courtyard facades. The OSM horizontal boundaries, gate clearances, open court areas, module API and 1,650 collision segments are preserved. No terrain mesh was flattened, no broad roof/terrace slab was introduced, and no plan-area collision was added. `morro-level-entry-qa.png` records the corrected view from the official El Morro approach at player eye height, facing north.
