djeada 1232c50a4e apply format 1 month ago
..
README.md 1232c50a4e apply format 1 month ago
hannibal_path.py 8d27d9c68f Hannibal path (#827) 2 months ago
map_bounds.json 7cb69244c1 Fix shoulder curvature by modifying main torso body geometry 2 months ago
pipeline.py 1232c50a4e apply format 1 month ago
provinces.py 8d27d9c68f Hannibal path (#827) 2 months ago
requirements.txt 1232c50a4e apply format 1 month ago

README.md

Campaign Map Preprocessing (offline)

Single-shot pipeline to prep the West Mediterranean campaign map. It locks coordinates, fetches base coast/land data, and emits UV-space assets the QML/OpenGL widget can consume.

What it does

  • Loads fixed bounds from map_bounds.json (equirectangular projection, normalized UV).
  • Downloads Natural Earth 10m land + rivers (public domain) into tools/map_pipeline/build.
  • Clips to bounds, projects/normalizes, writes assets/campaign_map/land_uv.geojson.
  • Triangulates land polygons → assets/campaign_map/land_mesh.bin (float32 u,v pairs) and land_mesh.obj.
  • Extracts coastline/rivers polylines → assets/campaign_map/coastlines_uv.json, rivers_uv.json, and OBJ line exports.
  • Renders preview PNG → assets/campaign_map/campaign_preview.png.
  • Renders base textures → assets/campaign_map/campaign_base_color.png and campaign_water.png.
  • Downloads ETOPO2022 (60s bedrock) and generates a terrain heightmap → assets/campaign_map/terrain_height.png + terrain_height.json.

Dependencies

  • Python 3
  • fiona, shapely, pillow, mapbox_earcut, numpy, rasterio (install via pip install -r requirements.txt)

Run (does everything)

./tools/map_pipeline/pipeline.py

Outputs land/rivers UV, mesh binaries, OBJs, preview PNG, and base textures to assets/campaign_map/.

Provinces (rough draft)

Generate a gameplay-focused provinces.json with hand-authored boundaries (requires shapely + mapbox_earcut):

./tools/map_pipeline/provinces.py

This writes assets/campaign_map/provinces.json (triangulated UVs + colors).

Hannibal's Campaign Path

Generate progressive path lines for Hannibal's 8-mission campaign:

./tools/map_pipeline/hannibal_path.py

This script uses hardcoded city lon/lat coordinates from provinces.py and converts them to UV space using map_bounds.json. It generates assets/campaign_map/hannibal_path.json containing 8 progressive path lines, one for each campaign mission:

  • Mission 0: Crossing the Rhône (New Carthage → Massalia)
  • Mission 1: Battle of Ticino (+ Mediolanum)
  • Mission 2: Battle of Trebia (consolidates in Cisalpine Gaul)
  • Mission 3: Battle of Trasimene (+ Veii through Etruria)
  • Mission 4: Battle of Cannae (+ Capua in Southern Italy)
  • Mission 5: Campania Campaign (maintains Capua position)
  • Mission 6: Crossing the Alps (flashback - path through mountains)
  • Mission 7: Battle of Zama (final - + Syracuse → Carthage)

Each successive path builds upon the previous one, with the last path being the longest and covering all previous waypoints.

Coastline-Aware Features:

  • Routes follow the North African coast westward before crossing at Gibraltar
  • Coastal segments along Spanish, French, and Italian coasts use smooth curves
  • Each segment is classified as 'coastal', 'land', or 'open_sea'
  • Open-sea crossings only occur at Gibraltar (Africa→Spain) and Sicily→Carthage
  • Intermediate waypoints create natural, organic appearance along shores
  • The C++ renderer uses a three-pass system (dark border, gold highlight, red core)
  • Line widths: 10px border, 6.5px highlight, 3.5px core for high visibility
  • Historical map styling with gold/amber tones for authenticity

Validation System: The script includes comprehensive validation that ensures:

  • Path Continuity: All segments are continuous with no gaps (max 0.25 UV distance between waypoints)
  • Sea Crossing Validation: Only authorized sea crossings are allowed (Gibraltar and Sicily-Carthage)
  • Rendering Simulation: Simulates C++ GL_LINE_STRIP rendering to verify paths will display correctly
  • Exit on Error: Script exits with error code 1 if any validation fails, ensuring only valid paths are generated

The validation output shows for each mission:

  • Total waypoints and segments
  • Authorized sea crossings detected
  • Path length and average segment size
  • Confirmation that path will render as continuous GL_LINE_STRIP in C++

Note: This script does NOT require provinces.json - it calculates UV coordinates directly from lon/lat. If you need to generate provinces.json for the full campaign map visualization, run provinces.py after running the full pipeline.