17 KiB
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.osmd'origine (moyenne des nœuds), en centimètres :x = (Lon − RelLon) · cos(Lat) · k,y = −(Lat − RelLat) · k, aveck = 40 075 036 / 360 × 100cm par degré (Plugins/StreetMap/Source/StreetMapImporting/StreetMapFactory.cpp:8-9, 53-80). L'origine n'est pas stockée (STM1-SPEC-02 § 1). UStreetMapCentralLondon : 49 425 bâtiments, dont 12 092 nommés, et 0 eau (CSV U8-T7b) ;BoundsMin/BoundsMaxdisponibles (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(), sortieTriangles) ouConstrainedDelaunayTriangulate(TGeneralPolygon2):Engine/Plugins/Runtime/GeometryProcessing/Source/GeometryAlgorithms/Public/ConstrainedDelaunay2.h:25-166. PluginGeometryProcessingmonté dans l'éditeur (Saved/Logs/LifePlay.log: « Mounting Engine plugin GeometryProcessing ») mais absent deLifePlay.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.csaMeshDescriptionetStreetMapRuntime, mais pasXmlParserniGeometryAlgorithmsniStaticMeshDescription.
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)
- 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). - 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). - Origine = médiane des
RelLat_iet desRelLon_i. Résidu de chaque paire = distance entre(x, y)et la projection de(Lat, Lon)avec l'origine retenue. - 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).
- Contrôle croisé : les bornes du maillage
Static/CentralLondondoivent 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 membresouteretinner(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érieursbIsHole=false, intérieursbIsHole=true,FillRule = Positiveaprè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(moduleXmlParser), recalage (§ 2.2), triangulation (§ 2.3). - Création du
StaticMesh/Game/Heavy/StreetMap/Water/CentralLondonparFMeshDescriptionetBuildFromMeshDescriptions:- 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.
- une section, matériau
-DryRun: rapport seul, aucun asset. Sans-DryRun: instantanéTools\Snapshot.ps1d'abord (nouveau dossier : instantané vide, noté), puis sauvegarde du paquet.Build.cs: ajouterXmlParser,GeometryAlgorithms,GeometryCore,StaticMeshDescriptionaux dépendances privées.LifePlay.uproject: non touché dans l'option G1 recommandée (§ 5 bis). L'ajout du pluginGeometryProcessing(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 deGI.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
UStaticMeshComponentattaché à la racine deStreetMap_Static, sans collision, sans ombre.
- déduire le nom de la ville du maillage (
- Hauteur Z : au-dessus du sol pavé (
PlanedeMapMarkers, 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 ;TranslucencySortPrioritysans 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 maillageStaticetUStreetMap(contrôle § 2.2.5) ; disponibilité deTConstrainedDelaunay2hors é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é.