187 lines
17 KiB
Markdown
187 lines
17 KiB
Markdown
|
|
Fiche STM1-SPEC-03 — Niveau N2 — Modèle prévu opus medium | utilisé claude-opus-5-5 — Agent session « Medium · STM1 » (pas de sous-agent) — Skills sk-protocol, lp-ue-compat
|
|||
|
|
|
|||
|
|
# STM1-SPEC-03 : SPEC exécutable du pilote Londres, option O-B (eau par maillage) (2026-10-20)
|
|||
|
|
|
|||
|
|
Ordre : Big Boss (`local_104ff22d`). Décisions de l'utilisateur sur STM1-SPEC-02, citées par Big Boss : « un pilote sur Londres d'abord » ;
|
|||
|
|
« l'accord pour télécharger des extraits OSM : approuvé » ; « eau visible aussi en mode classique oui » ; « appouve O-B ».
|
|||
|
|
Consignes : annoncer la source exacte, la taille et la licence de chaque extrait **avant** tout téléchargement ; téléchargement dans un
|
|||
|
|
dossier neuf hors dépôt ; fichiers jamais exécutés, lus par un outil séparé ; **pas d'IMPL ni de copie UE sans GO**. Rien n'a été téléchargé ni modifié par cette fiche.
|
|||
|
|
|
|||
|
|
## 0. Annonce des extraits (à relayer à l'utilisateur avant téléchargement)
|
|||
|
|
|
|||
|
|
| # | Extrait | Source exacte | Taille | Licence |
|
|||
|
|
|---|---|---|---|---|
|
|||
|
|
| D1 | **Eau** de la boîte de Londres : `natural=water`, `water=*`, `waterway=riverbank`, `landuse=reservoir/basin`, voies **et relations**, avec géométrie | API Overpass publique, `POST https://overpass-api.de/api/interpreter`, requête Q1 (§ 2.1), sortie XML `out geom` | **estimée 2 à 10 Mo** (plafond imposé dans la requête : `[maxsize:52428800]`, 50 Mo) ; taille réelle notée au téléchargement | données © OpenStreetMap contributors, **ODbL 1.0** (https://www.openstreetmap.org/copyright) ; usage de l'API selon la politique des instances publiques (https://wiki.openstreetmap.org/wiki/Overpass_API, usage raisonnable, deux requêtes) |
|
|||
|
|
| D2 | **Bâtiments nommés** de la même boîte (`way["building"]["name"]`), avec géométrie, pour le recalage | même API, requête Q2 (§ 2.1) | **estimée 15 à 60 Mo** (plafond `[maxsize:209715200]`, 200 Mo) | idem, ODbL 1.0 |
|
|||
|
|
| (écarté) | extrait complet Grand Londres Geofabrik | `https://download.geofabrik.de/europe/united-kingdom/england/greater-london-latest.osm.pbf` | 123 Mo (page Geofabrik : « File size: 123 MB », données jusqu'au 2026-10-18T20:25:06Z) | ODbL 1.0 |
|
|||
|
|
|
|||
|
|
L'extrait Geofabrik n'est **pas proposé** : format PBF, illisible par le lecteur XML du plugin (`OSMFile.cpp`) ; il faudrait installer un outil
|
|||
|
|
tiers (osmium). Les deux requêtes Overpass donnent du XML directement lisible.
|
|||
|
|
|
|||
|
|
**Dossier de téléchargement** (neuf, hors dépôt) : `D:\Game\LifePlay_Data\OSM\STM1-PILOTE-20261020\` (`q1-eau.osm.xml`, `q2-batiments.osm.xml`,
|
|||
|
|
plus les deux requêtes en `.txt` et un `LISEZMOI.txt` : source, date, taille, MD5, licence). Téléchargement par `curl --data-urlencode` dans une commande à part.
|
|||
|
|
Les fichiers ne sont **jamais exécutés** : seul le commandlet du § 3 les lit, comme du XML.
|
|||
|
|
|
|||
|
|
## 1. Données établies (lecture, sans copie UE)
|
|||
|
|
|
|||
|
|
- Projection des cartes : sinusoïdale, relative à l'origine `(RelLat, RelLon)` du `.osm` d'origine (moyenne des nœuds), en centimètres :
|
|||
|
|
`x = (Lon − RelLon) · cos(Lat) · k`, `y = −(Lat − RelLat) · k`, avec `k = 40 075 036 / 360 × 100` cm par degré
|
|||
|
|
(`Plugins/StreetMap/Source/StreetMapImporting/StreetMapFactory.cpp:8-9, 53-80`). L'origine n'est **pas** stockée (STM1-SPEC-02 § 1).
|
|||
|
|
- `UStreetMap` CentralLondon : 49 425 bâtiments, dont **12 092 nommés**, et 0 eau (CSV U8-T7b) ; `BoundsMin/BoundsMax` disponibles (`StreetMap.h:173-177`).
|
|||
|
|
- Maillage `Static/CentralLondon` : 11 232 × 8 090 m, hauteur 310 m (`L7h_meshes_55.csv`), une section, `StreetMapMasked`.
|
|||
|
|
- Triangulation avec trous : `UE::Geometry::TConstrainedDelaunay2<double>` (`Add(TPolygon2, bIsHole)`, `EFillRule`, `Triangulate()`, sortie `Triangles`) ou
|
|||
|
|
`ConstrainedDelaunayTriangulate(TGeneralPolygon2)` : `Engine/Plugins/Runtime/GeometryProcessing/Source/GeometryAlgorithms/Public/ConstrainedDelaunay2.h:25-166`.
|
|||
|
|
Plugin `GeometryProcessing` monté dans l'éditeur (`Saved/Logs/LifePlay.log` : « Mounting Engine plugin GeometryProcessing ») mais **absent** de `LifePlay.uproject`.
|
|||
|
|
- Création de maillage : `UStaticMesh::BuildFromMeshDescriptions` (`StaticMesh.h:1891`).
|
|||
|
|
- Cuisson : `+DirectoriesToAlwaysCook=(Path="/Game")` (`Config/DefaultGame.ini:51`) : un asset sous `/Game/Heavy/StreetMap/Water/` est cuit sans réglage de plus.
|
|||
|
|
- `LifePlayEditorTools.Build.cs` a `MeshDescription` et `StreetMapRuntime`, mais **pas** `XmlParser` ni `GeometryAlgorithms` ni `StaticMeshDescription`.
|
|||
|
|
|
|||
|
|
## 2. Étapes du pilote
|
|||
|
|
|
|||
|
|
### 2.1 Données (D1, D2), après accord relayé par Big Boss
|
|||
|
|
|
|||
|
|
Boîte englobante généreuse, l'origine étant inconnue (la carte fait 11,2 × 8,1 km autour du centre de Londres) : **sud 51,44 ; ouest −0,25 ; nord 51,58 ; est 0,05**
|
|||
|
|
(≈ 15,5 × 20,9 km). Le recalage (§ 2.2) ne garde que ce qui tombe dans les bornes de la carte.
|
|||
|
|
|
|||
|
|
Q1 (eau) :
|
|||
|
|
```
|
|||
|
|
[out:xml][timeout:180][maxsize:52428800][bbox:51.44,-0.25,51.58,0.05];
|
|||
|
|
( way["natural"="water"]; relation["natural"="water"];
|
|||
|
|
way["water"]; relation["water"];
|
|||
|
|
way["waterway"="riverbank"]; relation["waterway"="riverbank"];
|
|||
|
|
way["landuse"~"^(reservoir|basin)$"]; relation["landuse"~"^(reservoir|basin)$"]; );
|
|||
|
|
out geom;
|
|||
|
|
```
|
|||
|
|
Q2 (bâtiments nommés) :
|
|||
|
|
```
|
|||
|
|
[out:xml][timeout:300][maxsize:209715200][bbox:51.44,-0.25,51.58,0.05];
|
|||
|
|
way["building"]["name"];
|
|||
|
|
out tags geom;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2.2 Recalage (seuil 2 m)
|
|||
|
|
|
|||
|
|
1. Apparier par nom exact, sans tenir compte de la casse : les bâtiments nommés de l'`UStreetMap` (`Name`, `BuildingPoints`) contre ceux de D2. On écarte les noms ambigus (plus d'une occurrence d'un côté ou de l'autre).
|
|||
|
|
2. Pour chaque paire : centroïde de l'asset `(x, y)` (moyenne des points) et centroïde OSM `(Lat, Lon)` (moyenne des nœuds) ;
|
|||
|
|
`RelLat_i = Lat + y / k` ; `RelLon_i = Lon − x / (k · cos Lat)`.
|
|||
|
|
3. Origine = **médiane** des `RelLat_i` et des `RelLon_i`. Résidu de chaque paire = distance entre `(x, y)` et la projection de `(Lat, Lon)` avec l'origine retenue.
|
|||
|
|
4. **Critères d'acceptation** (version initiale) : au moins 500 paires ; résidu médian **≤ 2 m (200 cm)** ; au moins 80 % des paires sous 5 m. Sinon : arrêt, rapport, aucun asset écrit.
|
|||
|
|
**Changement (décision de Big Boss, 2026-10-20, après le DryRun R1 : 4 523 paires, médiane 129 cm, 79,2 % sous 5 m)** :
|
|||
|
|
- **estimation** en deux passes : origine de passe 1 sur toutes les paires ; rejet des paires au-delà de médiane + 3 × MAD ; origine de passe 2 sur les paires retenues ; nombre d'écartées noté ;
|
|||
|
|
- **critères** : au moins 500 paires **retenues** ; résidu médian (paires retenues) ≤ 2 m ; **taux de paires retenues ≥ 70 %** des paires appariées.
|
|||
|
|
Motif cité : appliquer « ≥ 80 % sous 5 m » aux seules paires retenues après rejet le rendrait vrai par construction (critère circulaire).
|
|||
|
|
Rapportés pour information : la part sous 5 m sur **toutes** les paires avec l'origine corrigée, et le déplacement de l'origine entre les deux passes (cm).
|
|||
|
|
Le juge final reste l'essai visuel du pilote (eau sur les quais).
|
|||
|
|
Les centres de boîte remplacent les centroïdes : l'extrait D2 ne contient que les `<bounds>` (STM1-B2-FIN § 2-6).
|
|||
|
|
5. Contrôle croisé : les bornes du maillage `Static/CentralLondon` doivent recouvrir celles de l'`UStreetMap` (écart d'au plus 1 m). Cela vérifie que le maillage partage le repère des données. Sinon : arrêt.
|
|||
|
|
|
|||
|
|
### 2.3 Polygones et triangulation
|
|||
|
|
|
|||
|
|
- Q1 `out geom` : une voie fermée = un polygone ; une relation = assemblage des membres `outer` et `inner` (chaînage par extrémités communes ; anneaux non fermés : arrêt du polygone, compté dans le rapport).
|
|||
|
|
- Projection avec l'origine du § 2.2, puis découpe à la boîte de la carte (`BoundsMin/BoundsMax` + 50 m).
|
|||
|
|
- Triangulation : `TConstrainedDelaunay2<double>`, extérieurs `bIsHole=false`, intérieurs `bIsHole=true`, `FillRule = Positive` après orientation (extérieurs dans le sens trigonométrique), `Triangulate()`.
|
|||
|
|
- Rapport : nombre de polygones, de trous, de triangles et de sommets ; aire totale d'eau en km². Attendu indicatif pour la Tamise dans la carte : plusieurs km².
|
|||
|
|
|
|||
|
|
### 2.4 Commandlet `ULPBuildCityWaterCommandlet` (`Source/LifePlayEditorTools`, neuf)
|
|||
|
|
|
|||
|
|
- Ligne : `-run=LPBuildCityWater -City=CentralLondon -Water=<q1> -Buildings=<q2> [-DryRun] [-Report=<chemin .md sous etat\REL\STM1\>]`.
|
|||
|
|
- Lecture XML par `FXmlFile` (module `XmlParser`), recalage (§ 2.2), triangulation (§ 2.3).
|
|||
|
|
- Création du `StaticMesh` `/Game/Heavy/StreetMap/Water/CentralLondon` par `FMeshDescription` et `BuildFromMeshDescriptions` :
|
|||
|
|
- une section, matériau `M_LP_Water` ;
|
|||
|
|
- normales vers le haut, UV en mètres ;
|
|||
|
|
- sans collision, sans lightmap (`bGenerateLightmapUVs = false`) ;
|
|||
|
|
- Z = 0 dans le repère de la carte.
|
|||
|
|
- `-DryRun` : rapport seul, aucun asset. Sans `-DryRun` : instantané `Tools\Snapshot.ps1` d'abord (nouveau dossier : instantané vide, noté), puis sauvegarde du paquet.
|
|||
|
|
- `Build.cs` : ajouter `XmlParser`, `GeometryAlgorithms`, `GeometryCore`, `StaticMeshDescription` aux dépendances privées.
|
|||
|
|
- `LifePlay.uproject` : **non touché** dans l'option G1 recommandée (§ 5 bis). L'ajout du plugin `GeometryProcessing` (G2) demanderait une décision de l'utilisateur.
|
|||
|
|
|
|||
|
|
### 2.5 Matériau `M_LP_Water` (neuf, `/Game/Heavy/StreetMap/Water/M_LP_Water`)
|
|||
|
|
|
|||
|
|
Opaque, **deux faces** (`TwoSided`, pour ne pas dépendre de l'enroulement des triangles), `MSM_DefaultLit`, couleur de base (0,03 ; 0,18 ; 0,32), rugosité 0,15, spéculaire 0,5. Pas de normale animée au pilote (option ensuite).
|
|||
|
|
Créé par MCP (`MaterialTools.create_material` et `connect_to_output`) sous instantané, ou à la main. Aucun matériau existant touché.
|
|||
|
|
|
|||
|
|
### 2.6 Sous-système de pose `ULPCityWaterSubsystem` (`Source/LifePlay`, neuf, **présent aussi en Shipping**)
|
|||
|
|
|
|||
|
|
- `UGameInstanceSubsystem` ; ticker de 0,25 s, même détection que la trace : maillage de `GI.StreetMapStatic.StaticMeshComponent` (lecture par réflexion, aucun appel ni écriture dans le GI).
|
|||
|
|
- Au changement de maillage :
|
|||
|
|
- déduire le nom de la ville du maillage (`/Game/Heavy/StreetMap/Static/<Ville>`) ;
|
|||
|
|
- charger `/Game/Heavy/StreetMap/Water/<Ville>` s'il existe (sinon, rien) ;
|
|||
|
|
- créer ou réutiliser **un** `UStaticMeshComponent` attaché à la racine de `StreetMap_Static`, sans collision, sans ombre.
|
|||
|
|
- **Hauteur Z** : au-dessus du sol pavé (`Plane` de `MapMarkers`, lu par réflexion) de **+2 cm**. Repli si le plan n'est pas trouvé : le Z mesuré au pilote, écrit en constante.
|
|||
|
|
- **Visible aussi en mode classique** (décision de l'utilisateur) : aucune dépendance à `ClassicMap`.
|
|||
|
|
- Ville sans eau : composant masqué.
|
|||
|
|
- Ligne de journal `LogLifePlay` à chaque pose : ville, asset, Z. La trace `[LPCity]` reste inchangée.
|
|||
|
|
|
|||
|
|
### 2.7 Lecture préalable (PIE, lecture seule, avec jeton)
|
|||
|
|
|
|||
|
|
Avant l'IMPL du § 2.6 : en PIE, relever la transformation du `Plane` de `MapMarkers` (Z monde, échelle) et celle de `StreetMap_Static` après `MoveCity`.
|
|||
|
|
Elle n'a pas pu être lue hors PIE (CART-04 § 5). Si la PIE est refusée, on prend le repli constant et on règle le Z à l'essai.
|
|||
|
|
|
|||
|
|
## 3. Ordre et jetons
|
|||
|
|
|
|||
|
|
| Étape | Fiche | Copie UE | Écrit |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| 1 | téléchargement D1, D2 (après accord relayé) | non | dossier hors dépôt seulement |
|
|||
|
|
| 2 | IMPL commandlet + `Build.cs` + `uproject` (§ 2.4) | non (code) | sources sous instantané, CHG |
|
|||
|
|
| 3 | BUILD éditeur (lp-builder) | **oui** | — |
|
|||
|
|
| 4 | commandlet `-DryRun` : rapport de recalage (critères § 2.2) | **oui** | rapport seul |
|
|||
|
|
| 5 | matériau `M_LP_Water` et commandlet réel | **oui** | 2 assets sous `Content/Heavy/StreetMap/Water/` (hors git, instantané) |
|
|||
|
|
| 6 | lecture PIE (§ 2.7) | **oui** | — |
|
|||
|
|
| 7 | IMPL sous-système (§ 2.6), BUILD, VAL distincte | oui (build) | sources, CHG |
|
|||
|
|
| 8 | essai utilisateur (build Development) : vue de la Tamise, modes par défaut et classique ; captures | — | — |
|
|||
|
|
|
|||
|
|
## 4. Critères d'acceptation du pilote
|
|||
|
|
|
|||
|
|
| # | Critère | Preuve |
|
|||
|
|
|---|---|---|
|
|||
|
|
| P1 | recalage : au moins 500 paires, résidu médian ≤ 2 m, au moins 80 % sous 5 m | rapport du commandlet |
|
|||
|
|
| P2 | maillage d'eau créé, triangles > 0, aire ≥ 1 km², sans collision | rapport, lecture MCP |
|
|||
|
|
| P3 | en jeu, mode par défaut : la Tamise apparaît bleue, alignée sur les quais (écart visuel < 5 m) ; pas de scintillement avec le pavé | captures de l'utilisateur |
|
|||
|
|
| P4 | en mode classique : eau visible aussi | capture |
|
|||
|
|
| P5 | autres villes inchangées (pas d'asset d'eau = rien), `000Dummy` sans eau | essai sur une autre ville, journal |
|
|||
|
|
| P6 | aucun asset existant modifié (GI, MapMarkers, StreetMap_*, matériaux, 280 cartes) | `CopieEtat` (MD5) |
|
|||
|
|
| P7 | crédits : ligne ODbL avec source exacte (Overpass, date, requête) prête pour la DOC | brouillon de crédits |
|
|||
|
|
|
|||
|
|
## 5. Risques et parades
|
|||
|
|
|
|||
|
|
- **Recalage raté** : les données de 2020 ne correspondent plus (noms changés) → critères P1, arrêt avant tout asset.
|
|||
|
|
- **Relations incomplètes** (membres coupés par la boîte) : la boîte est large, et les anneaux non fermés sont comptés et ignorés.
|
|||
|
|
- **Scintillement** avec le `Plane` : 2 cm, réglable ; `TranslucencySortPriority` sans objet (opaque).
|
|||
|
|
- **Eau recouvrant des pontons ou des ponts** (bâtiments dans le fleuve, CART-03 § 3) : attendu ; les bâtiments, plus hauts, restent au-dessus.
|
|||
|
|
- **Charge sur l'API Overpass** : deux requêtes seulement, une seule fois.
|
|||
|
|
- **Licence** : attribution ODbL ; les crédits du projet sont à compléter (règle « source exacte »).
|
|||
|
|
|
|||
|
|
## 5 bis. Téléchargement fait (étape 1, 2026-10-20) et point GeometryProcessing
|
|||
|
|
|
|||
|
|
Accord de l'utilisateur cité par Big Boss : « Oui, STM1 peut télécharger D1 et D2 depuis overpass-api.de dans D:\Game\LifePlay_Data\OSM\STM1-PILOTE-20261020\. »
|
|||
|
|
|
|||
|
|
| Fichier | HTTP | Taille | Annonce | Erreur Overpass | MD5 | Contenu |
|
|||
|
|
|---|---|---|---|---|---|---|
|
|||
|
|
| `q1-eau.osm.xml` (2026-10-20T08:04:13Z, `osm_base` 08:03:42Z) | 200 | 2 308 011 o | 2 à 10 Mo (plafond 50) : **conforme** | 0 `<remark>` | `4e9722b9db2539fc023cf830bf403538` | 713 voies, 88 relations ; `water=river` 78 (dont 4 relations multipolygones sans nom), `pond` 259, `basin` 56, `canal` 54, `lake` 24, `lock` 21, `reservoir` 8 ; `waterway=dock` 30 |
|
|||
|
|
| `q2-batiments.osm.xml` (2026-10-20T08:04:59Z) | 200 | 15 484 375 o | 15 à 60 Mo (plafond 200) : **conforme** | 0 `<remark>` | `d441164aef0677f711a2e788cda5db16` | 29 246 bâtiments nommés |
|
|||
|
|
|
|||
|
|
Dossier : `D:\Game\LifePlay_Data\OSM\STM1-PILOTE-20261020\`, avec `q1-eau.txt`, `q2-batiments.txt` et `LISEZMOI.txt` (URL, requête, date, taille, MD5, licence). Deux requêtes, une fois chacune. Aucun fichier exécuté.
|
|||
|
|
Restent aussi `d1-date.txt` et `d2-date.txt` (une ligne de date chacun, repris dans le LISEZMOI) : leur retrait a été refusé par la permission, sans autre tentative.
|
|||
|
|
|
|||
|
|
**GeometryProcessing et `LifePlay.uproject` (local, non commité par décision de l'utilisateur)**
|
|||
|
|
|
|||
|
|
Constat : `GeometryProcessing.uplugin` ne déclare pas `EnabledByDefault`. Le plugin est monté parce que des plugins actifs en dépendent : `ChaosVD`,
|
|||
|
|
`Dataflow`, `MeshLODToolset`, `ChaosClothAssetEditorCore`, … (`grep -rl '"GeometryProcessing"'` sur les `.uplugin` du moteur ; journal : « Mounting Engine plugin GeometryProcessing »).
|
|||
|
|
|
|||
|
|
| Option | Principe | Pour | Contre |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **G1 (recommandée)** | dépendance de module seulement : `GeometryAlgorithms`, `GeometryCore` dans `LifePlayEditorTools.Build.cs` (éditeur seulement) ; `LifePlay.uproject` non touché | aucune modification du `.uproject` local ; le module est déjà présent dans la cible éditeur par dépendance transitive (estimé) | fragile si l'un de ces plugins est désactivé un jour ; à **prouver au BUILD** (une erreur UBT « module introuvable » ferait passer à G2 ou G3) |
|
|||
|
|
| G2 | ajouter `{"Name": "GeometryProcessing", "Enabled": true, "TargetAllowList": ["Editor"]}` au `.uproject` | explicite et robuste | le `.uproject` est local : **décision de l'utilisateur** requise, ligne à reporter à chaque copie |
|
|||
|
|
| G3 | se passer de GeometryProcessing : triangulation par oreilles de `GeometryCore` (`CompGeom/PolygonTriangulation.h`, `Polygon2.h`), avec les trous raccordés à la main | seulement `GeometryCore` (module du moteur, sans plugin) | plus de code, et plus fragile sur les relations complexes (îles, docks) |
|
|||
|
|
|
|||
|
|
Seul le commandlet (éditeur) triangule ; le sous-système de jeu (§ 2.6) ne dépend d'aucun module de géométrie. La copie 5.8 n'est donc pas concernée en Shipping.
|
|||
|
|
|
|||
|
|
## 6. Incertitudes, écarts, fichiers
|
|||
|
|
|
|||
|
|
- Non vérifié : tailles réelles de D1 et D2 (estimées) ; Z et échelle du `Plane` (§ 2.7) ; repère commun maillage `Static` et `UStreetMap` (contrôle § 2.2.5) ; disponibilité de `TConstrainedDelaunay2` hors éditeur (seul le commandlet en a besoin : éditeur seulement).
|
|||
|
|
- Fichiers écrits : `D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\STM1\STM1-SPEC-03.md` (A) ; `STM1-TACHES.md` (M).
|
|||
|
|
|
|||
|
|
Tours : ≈ 6 / 40 (déclaré ; `FicheStats.py` fait foi).
|
|||
|
|
|
|||
|
|
Suite : Big Boss doit relayer l'annonce du § 0 à l'utilisateur ; après son accord, téléchargement D1 et D2 (étape 1, sans copie UE), puis GO de l'IMPL du commandlet. État : SPEC prête, rien téléchargé.
|