200 lines
17 KiB
Markdown
200 lines
17 KiB
Markdown
|
|
# Fiche STG-B2q-DIAG — Niveau N3 — Modèle prévu claude-opus-5-5 | utilisé claude-opus-5-5 — Agent orchestrateur STG (session principale) — Skills lp-lot, sk-protocol
|
|||
|
|
|
|||
|
|
# STG-B2q-DIAG : personnages assis éliminés par le rendu (2026-10-14)
|
|||
|
|
|
|||
|
|
Fiche B2q, confiée à STG par Big Boss (CAM est pris par B2p ; le sujet touche le maillage des Person). DIAG en lecture seule, sans UE et
|
|||
|
|
sans écriture hors de ce livrable. Lot STG, registre `STG-TACHES.md`.
|
|||
|
|
|
|||
|
|
Faits donnés par Big Boss :
|
|||
|
|
- COMMUN-6, 05:28-05:32, au bar : la PNJ d'en face, puis le joueur assis, disparaissent selon l'angle de C2. `hidden=0`, et aucune ligne
|
|||
|
|
T-occ : le rayon caméra → tête était libre.
|
|||
|
|
- COMMUN-7, 07:48, au café (« Having a meal ») : « Bridget a disparu ». Le joueur est assis `fnt_new048`, place `_67`
|
|||
|
|
(journal : `OccupyingFnt _67` dès 07:47:45, `currentAnimation=fnt_new048-f-0-sit`, `meshZ=-80.4`) ; la capture montre une chaise vide.
|
|||
|
|
|
|||
|
|
Point de départ : hypothèse de CAM (`etat\CAM\CAM-COMMUN6-DIAG.md` § 8), reprise et vérifiée ci-dessous.
|
|||
|
|
|
|||
|
|
## 1. Sources
|
|||
|
|
|
|||
|
|
| Repère | Fichier |
|
|||
|
|
|---|---|
|
|||
|
|
| E1 | moteur UE 5.8, `Engine\Source\Runtime\Engine\Private\Components\SkeletalMeshComponent.cpp` l. 3417-3495 (`USkeletalMeshComponent::CalcBounds`) |
|
|||
|
|
| E2 | idem, `SkinnedMeshComponent.cpp` l. 2169-2175 (`CalcBounds`) et l. 2225-2300 (`CalcMeshBound`) |
|
|||
|
|
| P | `etat\portage55\L6f\L6f_dump_Person.txt` : graphes de Person (`UserConstructionScript` l. 1-12, `NewProxy` l. 1851-1955) |
|
|||
|
|
| C | `etat\CAM\CAM-T4_LPDumpComponents_20261011-004910.txt` : composants SCS de Person (`PenisSM`, `HairSM`, `DirtyTalkSM`, parents `CharacterMesh0`) |
|
|||
|
|
| A | `Content\BPs\Person.uasset` : table des noms (`grep -c -a`) |
|
|||
|
|
| I | `Config\DefaultEngine.ini` l. 30 |
|
|||
|
|
| J | journal en cours de COMMUN-7 (café) |
|
|||
|
|
|
|||
|
|
## 2. Ce qui est établi
|
|||
|
|
|
|||
|
|
### 2.1 Comment UE 5.8 calcule les bornes de rendu d'un SkeletalMesh (E1, E2)
|
|||
|
|
|
|||
|
|
`USkeletalMeshComponent::CalcBounds` appelle `CalcMeshBound(RootBoneTranslation, bHasValidBodies, …)`. Dans `CalcMeshBound`, les cas sont
|
|||
|
|
examinés dans cet ordre :
|
|||
|
|
1. composant invisible, ou `bComponentUseFixedSkelBounds` : bornes de l'asset ;
|
|||
|
|
2. composant leader en bornes fixes : bornes de l'asset du leader ;
|
|||
|
|
3. leader avec `bUseBoundsFromLeaderPoseComponent` : bornes du leader ;
|
|||
|
|
4. **asset physique avec corps** : AABB des corps, qui **suivent les os**, donc la pose ;
|
|||
|
|
5. leader avec asset physique : idem, sur les corps du leader ;
|
|||
|
|
6. **sinon, bornes importées de l'asset** (pose de référence, debout), **décalées de la seule translation de l'os racine** ;
|
|||
|
|
|
|||
|
|
puis `BoxExtent *= BoundsScale`, autour du **même centre**.
|
|||
|
|
|
|||
|
|
Sans asset physique, les bornes **ne suivent donc pas la pose** : seul le déplacement de l'os racine les déplace.
|
|||
|
|
|
|||
|
|
### 2.2 Les maillages des Person
|
|||
|
|
|
|||
|
|
- **Pas d'asset physique** sur `bridget_gp` ni `michael` (CAM § 8 : aucun import `PhysicsAsset`). Les corps tombent dans le cas 6.
|
|||
|
|
- Composants (C) :
|
|||
|
|
- le corps est `CharacterMesh0`, hérité de `ACharacter` ;
|
|||
|
|
- `PenisSM` et `HairSM` lui sont attachés. `UserConstructionScript` leur donne le corps comme **leader pose** (P l. 1-12) ;
|
|||
|
|
- `DirtyTalkSM` est un widget.
|
|||
|
|
- **Vêtements, cheveux et accessoires** ajoutés par `Person::NewProxy` (P l. 1851-1955) : sur chaque nouveau composant, `SetBoundsScale(3.0)`,
|
|||
|
|
`SetCastShadow(false)`, `SetRenderCustomDepth(true)`, **`bUseAttachParentBound = true`**, puis `SetLeaderPoseComponent(Mesh)`. Ces
|
|||
|
|
composants prennent donc **les bornes du corps**, et leur `BoundsScale 3` est sans effet (les bornes du parent sont reprises telles
|
|||
|
|
quelles). Conséquence : quand le corps est éliminé, **tout disparaît avec lui** (vêtements, cheveux). C'est bien « la chaise vide ».
|
|||
|
|
- Corps (`CharacterMesh0`) : aucun graphe de Person ne règle ses bornes. La table des noms (A) ne contient ni
|
|||
|
|
`bComponentUseFixedSkelBounds`, ni `bUseBoundsFromLeaderPoseComponent`, ni `bIncludeComponentLocationIntoBounds`. Ses 3 occurrences de
|
|||
|
|
`BoundsScale` s'expliquent par `SetBoundsScale` / `NewBoundsScale`, ses 2 de `bUseAttachParentBound` par le nœud de `NewProxy`. Une
|
|||
|
|
valeur de `BoundsScale` stockée sur le gabarit du corps n'est pas exclue sans lecture MCP. **Estimé : 1 (défaut)**.
|
|||
|
|
- `r.AllowOcclusionQueries=True` (I) : les requêtes d'occlusion sont actives.
|
|||
|
|
- Aucun C++ du projet ne touche aux bornes ni au culling (`grep` de `BoundsScale`, `bUseAttachParentBound` et `LeaderPose` dans `Source/` :
|
|||
|
|
0).
|
|||
|
|
|
|||
|
|
### 2.3 Les poses assises
|
|||
|
|
|
|||
|
|
- Assis, le corps joue l'animation de meuble dans l'Anim BP (`anim=bp:Daily_F_C currentAnimation=fnt_new048-f-0-sit`), et le composant
|
|||
|
|
est relevé (`meshZ` -80,4 au lieu de -90). Les bornes restent celles de la pose debout, autour de la racine.
|
|||
|
|
- Ce DIAG n'établit pas de combien le corps s'écarte de la racine dans ces animations. Le journal ne relève ni les os en XY ni les bornes.
|
|||
|
|
Les relevés M1d (COMMUN-6) ne donnent que des hauteurs, en scène de couple.
|
|||
|
|
|
|||
|
|
## 3. Cause (estimée, forte)
|
|||
|
|
|
|||
|
|
Le corps assis est éliminé parce que ses bornes, **celles de la pose debout autour de la racine**, ne contiennent plus le corps. Les
|
|||
|
|
animations de meuble déplacent le bassin et non la racine. Deux mécanismes sont possibles, selon l'angle :
|
|||
|
|
- **occlusion** : les bornes sont derrière la table, le comptoir ou le dossier, alors que le corps dépasse et est visible. La requête
|
|||
|
|
d'occlusion les juge cachées et élimine le maillage entier, vêtements compris. C'est le plus probable au bar et au café (tables), en C2
|
|||
|
|
qui tourne autour ;
|
|||
|
|
- **frustum** : les bornes sont hors du champ alors que le corps y est.
|
|||
|
|
|
|||
|
|
`hidden=0` et l'absence de T-occ sont compatibles avec les deux. Trancher entre eux, et mesurer l'écart, demande le témoin du § 5.
|
|||
|
|
|
|||
|
|
À exclure, peu probable :
|
|||
|
|
- la distance d'affichage (`MaxDrawDistance` / `CullDistance`) : le joueur assis est proche ;
|
|||
|
|
- le `LOD` : un maillage n'est pas éliminé par le LOD ;
|
|||
|
|
- `VisibilityBasedAnimTickOption` : il arrête l'animation, pas l'affichage.
|
|||
|
|
|
|||
|
|
**Observation annexe (hors B2q)** : l'assiette et le sandwich qui flottent près de l'épaule de la PNJ au café sont un accessoire de place
|
|||
|
|
mal attaché. Mineur ; à noter pour plus tard.
|
|||
|
|
|
|||
|
|
## 4. Correctif proposé (C++ sans asset ; rien n'est écrit sans GO)
|
|||
|
|
|
|||
|
|
| Id | Geste | Coût d'écriture | Coût de rendu | Risque |
|
|||
|
|
|---|---|---|---|---|
|
|||
|
|
| **B2q-a (recommandé)** | **BoundsScale adaptatif du corps.** Toutes les 0,5 s, pour chaque `Person_C` visible de la pièce, on calcule l'écart entre le bassin (`hip`, sinon `pelvis`, sinon l'os 0) et le centre des bornes du corps, puis le facteur `S = max(1, (écart + rayon des bornes) / rayon des bornes)`, borné à 4. On ne l'applique qu'en cas de changement de plus de 10 % : `SetBoundsScale(S)`, `UpdateBounds()`, `MarkRenderStateDirty()`. Une ligne de journal par changement. Debout, `S` = 1 : pas de surcoût. Assis, couché ou en meuble, `S` couvre le corps déplacé. Les vêtements suivent (`bUseAttachParentBound`). | ≈ 50 lignes C++ (DirectControl ou Debug, fichier STG), N3, VAL, 1 build | seulement pour les personnages assis : leurs bornes sont jusqu'à 4 fois plus grandes, donc ils sont un peu plus souvent dessinés hors champ ou cachés (ombres comprises). Faible pour une dizaine de corps ; à mesurer au bar (`stat unit` avant/après) | faible : les bornes de rendu ne servent ni aux collisions ni aux tracés |
|
|||
|
|
| B2q-b (repli, plus simple) | `BoundsScale = 3` fixe sur le corps de toutes les Person (balayage toutes les 2 s, comme le propose CAM) | ≈ 30 lignes | constant, sur tous les personnages, même debout | faible ; il peut ne pas suffire si l'écart dépasse ≈ 1,2 m |
|
|||
|
|
| B2q-c | Asset physique pour `bridget_gp` et `michael` : des bornes exactes qui suivent les os | 2 gros assets dans l'éditeur, hors alpha | nul | les corps entrent dans les tracés Visibility (sondes C2, T-occ) |
|
|||
|
|
| B2q-d | `r.AllowOcclusionQueries=False` | 1 ligne de config | global (tout le jeu) | ne règle pas le cas frustum ; non recommandé |
|
|||
|
|
|
|||
|
|
`bIncludeComponentLocationIntoBounds` (suggéré par Big Boss) n'ajoute à la boîte que le point d'origine du composant (E2 l. 2173-2175, E1
|
|||
|
|
l. 3472-3487). Cela ne couvre pas un corps déplacé : **non retenu**.
|
|||
|
|
|
|||
|
|
## 5. Témoin proposé (T-cull, à mettre dans le même build ; recommandé même avec B2q-a)
|
|||
|
|
|
|||
|
|
Dans `LPDebugSubsystem` (relevé des personnes, actif avec `-LPPersonsLog`), toutes les 0,5 s, pour chaque `Person_C` non cachée à moins de
|
|||
|
|
15 m de la caméra :
|
|||
|
|
- **une ligne de mesure par changement de pose de meuble** (`currentAnimation` ou `OccupyingFnt`) :
|
|||
|
|
`T-cull mesure <Person> anim=<fnt…> bassin a %.0f cm du centre des bornes (dans=%d) ; bornes %.0f x %.0f x %.0f ; BoundsScale %.2f ; physAsset=%d` ;
|
|||
|
|
- **une ligne d'alerte** si le bassin est à l'écran (`ProjectWorldLocationToScreen` dans le viewport) et que le corps n'a pas été rendu
|
|||
|
|
depuis 0,2 s (`WasRecentlyRendered(0.2f)` faux) :
|
|||
|
|
`T-cull : <Person> non rendue, bassin a l'ecran, a %.0f cm du centre des bornes (dans=%d), occlusion=%d`.
|
|||
|
|
|
|||
|
|
Ces lignes chiffrent l'écart réel des poses assises et tranchent entre occlusion et frustum (`dans=0` avec le centre des bornes hors du
|
|||
|
|
champ : frustum). Elles diront aussi si B2q-a suffit. Coût : ≈ 35 lignes, 1 build ; journal seulement.
|
|||
|
|
|
|||
|
|
## 5b. Complément (Big Boss, café, 07:48-07:49)
|
|||
|
|
|
|||
|
|
L'utilisateur rapporte : « les deux ont disparu ». Les deux personnages assis à la même table (le joueur et la PNJ) disparaissent **en même
|
|||
|
|
temps**, sous un même angle de C2. Cela va dans le sens du § 3 : deux corps assis à la même table ont chacun leurs bornes debout centrées
|
|||
|
|
sur leur racine, et les deux boîtes passent ensemble derrière le même plateau ou hors du champ au même angle. Une cause propre à un
|
|||
|
|
personnage (vêtement, animation, `hidden`) est moins probable. Le mécanisme **occlusion par la table** reste le plus probable ; le témoin
|
|||
|
|
T-cull le tranchera (`dans=0` et `occlusion=1` attendus pour les deux à la même heure).
|
|||
|
|
|
|||
|
|
## 6. Estimation et ordre proposé
|
|||
|
|
|
|||
|
|
1. T-cull et B2q-a dans le même build (COMMUN-8 ou suivant), avec une VAL statique : ≈ 85 lignes, N3, 1 build.
|
|||
|
|
2. Essai :
|
|||
|
|
- le bar (C2 autour de la PNJ d'en face, puis du joueur assis) ;
|
|||
|
|
- le café, assis à `fnt_new048` ;
|
|||
|
|
- un personnage couché ;
|
|||
|
|
- `stat unit` avant et après, au bar.
|
|||
|
|
3. Si une disparition persiste avec une ligne `T-cull` à `dans=1`, la cause n'est pas les bornes : ouvrir une fiche Ombres/occlusion.
|
|||
|
|
|
|||
|
|
## 7. Fichiers à commiter
|
|||
|
|
|
|||
|
|
`Docs/Migration/etat/ST/STG/STG-B2q-DIAG.md`.
|
|||
|
|
|
|||
|
|
Tours : 14
|
|||
|
|
|
|||
|
|
## 8. Complément après l'essai COMMUN-8 : B2q-a insuffisant au café (2026-10-14)
|
|||
|
|
|
|||
|
|
Demande de Big Boss : l'utilisateur dit « manque l'homme » (café, vers 09:09) ; l'homme assis est invisible, son téléphone flotte. DIAG en
|
|||
|
|
lecture seule, sans UE.
|
|||
|
|
|
|||
|
|
### 8.1 Ce que dit le journal (établi)
|
|||
|
|
|
|||
|
|
Source : `D:\Game\LifePlay_Build_5.8_COMMUN-8_Development\Windows\LifePlay\Saved\Logs\LifePlay.log` (10 128 lignes à la lecture).
|
|||
|
|
|
|||
|
|
- **Bar, chambre (B2q-a a suffi)** : bassin à 13-123 cm du centre des bornes selon le meuble (`fnt_chair06` : 123 cm, une autre place :
|
|||
|
|
47 cm) ; S monte à 1,5-4 et l'écart est couvert.
|
|||
|
|
- **Café (`cafe___vin01`, chargé à 09:07:11, places `fnt_new048` `_59`, `_60`, `_66`, `_67`)** : bassin à **290 cm** (hommes, anim.
|
|||
|
|
`fnt_new048-m-0-sit`) et **297 cm** (femmes, `-f-0-sit`) du centre des bornes. Les mesures sont identiques pour les quatre personnes de
|
|||
|
|
même sexe, au cm près. S plafonne à 4, et les alertes `T-cull : … non rendue … dans=0, centre a l'ecran=0` sont fréquentes :
|
|||
|
|
`PlayerCharacter` 86, `Person_C_2147481930` 34, `…906` 2, `…954` 1.
|
|||
|
|
- Les capsules (`LPDebug persons`) sont **sur les places** : `PlayerCharacter` en (-3131768, -14967061) sur `_59`, `…930` sur `_60`, la
|
|||
|
|
chaise sous chacun (`visibleComp` = la place, -41,1). Le téléphone flotte « à sa place » sur la capture. **Le corps est donc à la place,
|
|||
|
|
et c'est le centre des bornes qui est à ≈ 3 m.**
|
|||
|
|
- **Fait nouveau, qui corrige le § 2.2 du DIAG** : à la première vue de chaque personne, la ligne `B2q-a` part de **`BoundsScale 3.00`**
|
|||
|
|
(5 lignes `3.00 -> …`, dont 3 `3.00 -> 1.00`). Le corps a déjà **BoundsScale 3** dans le jeu d'origine : c'est le réglage du gabarit ou
|
|||
|
|
d'un Blueprint (le même 3 que `NewProxy`). L'estimation « 1 (défaut) » du § 2.2 était fausse. **B2q-a ramène les personnes debout à 1** :
|
|||
|
|
c'est une baisse par rapport à l'origine (risque R3 de la VAL réalisé). Elle est sans dommage visible debout, puisque le bassin est à
|
|||
|
|
13-16 cm du centre, mais il faut la corriger.
|
|||
|
|
|
|||
|
|
### 8.2 Pourquoi le centre des bornes est à 3 m (estimé, fort)
|
|||
|
|
|
|||
|
|
Sans asset physique, les bornes sont celles de l'asset, **décalées de `RootBoneTranslation`**, la translation de l'os racine dans la pose
|
|||
|
|
courante (§ 2.1 ; moteur `SkeletalMeshComponent.cpp` l. 3449-3470). La capsule et le corps sont sur la place, et les bornes sont à 290 ou
|
|||
|
|
297 cm, avec une valeur **fixe par animation** (hommes 290, femmes 297, sur 4 places différentes). Lecture : **l'animation de meuble
|
|||
|
|
`fnt_new048-*-0-sit` déplace l'os racine d'≈ 3 m, et l'os du bassin compense en sens inverse.** Le corps reste sur la place, mais UE
|
|||
|
|
croit que le maillage a suivi la racine. C'est la même cause que pour les écarts plus petits (`fnt_chair06` : 123 cm). L'amplitude dépend
|
|||
|
|
de l'animation, sans doute de la façon dont elle a été créée ou convertie : racine au pivot du groupe de meubles.
|
|||
|
|
Non établi : la position de l'os racine n'est pas au journal. Le témoin du § 8.4 l'écrira.
|
|||
|
|
|
|||
|
|
Plafond nécessaire avec B2q-a : le facteur s'applique de façon uniforme aux trois axes. Un écart de 290 cm le long de l'axe mince des bornes
|
|||
|
|
(demi-étendue 13 cm, épaisseur du corps en pose de référence) demande `S ≈ (290 + 13) / 13 ≈ 23`, soit des bornes de ≈ 6 × 29 × 41 m.
|
|||
|
|
À ce niveau, la personne n'est plus jamais éliminée : la culling est de fait coupée pour elle.
|
|||
|
|
|
|||
|
|
### 8.3 Correctif proposé B2q-b (rien n'est écrit sans GO)
|
|||
|
|
|
|||
|
|
| Id | Geste | Coût d'écriture | Coût de rendu | Risque |
|
|||
|
|
|---|---|---|---|---|
|
|||
|
|
| **B2q-b1 (recommandé pour l'alpha)** | Dans `FitPersonBounds` : (1) **plancher = l'échelle d'origine** de chaque personne, relevée à la première vue (3 dans le jeu d'origine) : plus jamais en dessous, ce qui corrige la baisse de B2q-a ; (2) **plafond porté à 25** ; le facteur est calculé comme aujourd'hui, au besoin réel par axe. | ≈ 15 lignes, N3, VAL, 1 build | seulement pour les personnes dont la pose sort des bornes (au café, toutes les assises) : elles ne sont plus jamais éliminées (frustum ni occlusion), ombres comprises. Au café, 4 à 6 corps Daz (≈ 50-100 k triangles chacun) toujours dessinés. Estimé faible à modéré ; à mesurer par les lignes `LPDebug hitch` au café (COMMUN-8 contre le build suivant) | faible : aucun effet sur collisions ni tracés ; journal inchangé (une ligne par changement de plus de 10 %) |
|
|||
|
|
| B2q-b2 (après l'alpha, juste) | Recentrer les bornes sur le bassin : réécrire `RootBoneTranslation` du corps avec la position du bassin (en espace composant) après l'évaluation de l'animation et avant le calcul des bornes ; les bornes suivent alors le corps à S = 3 | ≈ 30 lignes, mais l'ordre des ticks (animation, puis bornes, puis notre ticker) n'est pas établi sans essai ; N4 | nul | moyen : `RootBoneTranslation` est recalculé à chaque évaluation ; l'écriture peut être écrasée ou arriver trop tard (une image de retard) |
|
|||
|
|
| B2q-b3 (après l'alpha) | Asset physique minimal créé en mémoire (un corps sphérique sur l'os du bassin, `PhysicsAssetOverride`), collision du corps mise à `NoCollision` : les bornes suivent les os (cas 4 du § 2.1) | ≈ 40 lignes, N4 | nul | élevé sans essai : création des corps physiques, entrée dans les tracés Visibility si la collision n'est pas coupée à temps, chemin `bHasValidBodies` à vérifier |
|
|||
|
|
| B2q-b4 | Corriger les animations de meuble (racine au siège) | assets, hors alpha | nul | conversion de toutes les `fnt_*` |
|
|||
|
|
|
|||
|
|
Recommandation : **B2q-b1 pour l'alpha** (simple, sûr, coût borné aux seules personnes assises loin de leur racine), plus le témoin du
|
|||
|
|
§ 8.4. B2q-b2 sera étudié après l'alpha si le coût mesuré gêne.
|
|||
|
|
|
|||
|
|
### 8.4 Témoin complété (même build, ≈ 5 lignes)
|
|||
|
|
|
|||
|
|
La ligne `T-cull mesure` donnera aussi la distance de l'**os racine** (os 0) au bassin et au composant :
|
|||
|
|
`… racine a %.0f cm du bassin, a %.0f cm du composant`. Une racine à ≈ 3 m du bassin et du composant établit le § 8.2.
|
|||
|
|
|
|||
|
|
### 8.5 Cas d'essai à ajouter (build suivant)
|
|||
|
|
|
|||
|
|
- **Café** : assis au comptoir ou à une table `fnt_new048`, avec les PNJ assis ; tourner C2 tout autour. Plus aucune disparition, plus
|
|||
|
|
aucune alerte `T-cull … non rendue` ; `B2q-a : … BoundsScale 3.00 -> 2x.xx` et `racine a ≈ 290-300 cm du bassin`.
|
|||
|
|
- **Debout** : aucune ligne `B2q-a … -> 1.00` (plancher à l'échelle d'origine).
|
|||
|
|
- **Coût** : lignes `LPDebug hitch` au café, comparées à COMMUN-8.
|