# CAM-B2b : amendement de la SPEC après les essais de B2 (brouillon, 2026-10-13) Brouillon de la session CAM, à reporter dans `CAM-SPEC.md` (§ (a) B2, § (e) C2, § (f), § 7 V5) après l'accord de Big Boss. Copie d'avant prévue : `D:\Game\LifePlay_Backup_5.5\CAM\SPEC-avant-B2b\CAM-SPEC.md`. Aucun asset touché par ce document. ## 1. Entrées - Essais de B2 (utilisateur, relayés par Big Boss, 2026-10-13) : - « quand on est près d'un mur la camera est trop proche » ; - « J'ai perdu la capacité de me déplacer ou de déplacer la caméra » ; - « les 2 caméra dans les scène de sexe sont toujours oprationnelles » (point 7 conforme). - Exigence de l'utilisateur (relayée par Big Boss) : « la caméra doit toujours être placée dans la pièce et jamais dehors sinon le mur fait obstruction quand on change de vue ». - Diagnostic : `CAM-B2-journal.txt`, section « Essais utilisateur ». ## 2. Faits relus (lecture seule) | Fait | Preuve | |---|---| | Room sait déjà définir son volume : `isPointInsideRoom(Point)` = `IsPointInBox(Point, O, E)`. Origine `O` = (Room.X, Room.Y, Room.Z + H/2). Étendue `E` = (`Wall2.X − sol.X`, `Wall4.Y − sol.Y`, H/2), avec H = `WallT.Z − sol.Z` et sol = `StaticMeshComponent`. Boîte alignée sur les axes du monde | dump `CAM-B2-VAL_LPDumpFunction_20261013-132919.txt:4051-4162` | | En extérieur, l'échelle Z de la racine vaut 0,01 : `WallT` descend à ≈ 20 cm du sol, donc la hauteur de la boîte vaut ≈ 20 cm. Les positions X/Y des murs ne changent pas (seul Z est mis à l'échelle) | `LPOutdoorRoomSubsystem.cpp:13-16, 55` ; journal des essais l. 1269 « Piece exterieure (echelle Z 0.010) » | | La ruelle de la capture est une pièce extérieure | même ligne 1269 | | Les murs `Wall1-4` ne bloquent le canal Camera que par estimation (réponses par défaut, R5) ; le plafond `WallT` ignore Camera | SPEC R5 (RCOMP:17-19, copie 5.5) | | Les flèches, la molette et la souris de pièce déplacent `SceneCamera` = `ChargenCameras[0]` (`ScrollDownUp`, `LeftRight`, `DownUp`, `CircleCamera`, `RotateCamera`, sous `BuilderOn OR SexOn OR SpaceOn`) | CAM-T2 § 3 ; ROOM:1326-1340, 394-700 | | La marche ZQSD (`Walk`) ne dépend pas de la cible de vue ; elle est bloquée par un menu de `MenuClasses` ou par `GI.CurrentScene` non vide | `LPDirectControlSubsystem.cpp:51-55, 606, 840-895` | ## 3. Règle de confinement (nouvelle, s'applique à toute vue de pièce posée par CAM) **Volume de la pièce** = boîte de `isPointInsideRoom`, réduite d'une marge `m` = 30 cm (rayon de balayage 20 + 10) : - X dans [O.X − |E.X| + m, O.X + |E.X| − m] ; même règle pour Y avec E.Y ; - **intérieur** (échelle Z ≥ 0,05) : Z dans [sol.Z + 50, `WallT`.Z − 25] ; - **extérieur** (échelle Z < 0,05) : Z ≥ sol.Z + 50, sans borne haute (pas de plafond). En extérieur, « dans la pièce » veut donc dire : dans l'emprise au sol de Room (positions de `Wall2` / `Wall4`) et du côté du personnage par rapport aux façades. Les façades de la rue ne sont pas des murs de Room ; c'est le balayage (canal Camera) qui les traite. Que cette emprise coïncide avec l'espace de la ruelle entre les façades reste **estimé** : à mesurer à l'essai (point (f) ajouté ci-dessous). Une boîte reste vide si la pièce est plus étroite que 2 m. Dans ce cas, la borne retenue est le centre O sur cet axe. ## 4. Modifications de C2 (remplacent B2-3 et B2-6 pour la partie position) - **B2b-1 Cible confinée** (`ComputeC2Target`) : `Desired` → **Clamp** dans le volume (§ 3) → balayage de la tête vers la cible bornée (rayon **20**, au lieu de 12). En cas d'impact : `Location + Normal × 20`, puis Clamp → `C2Target`. - **B2b-2 Repli vers l'intérieur et vers le haut** : si `Distance(C2Target, tête) < 80`, on recalcule un second point `Desired2` = tête + (0, 0, 100) − F × 60. Ce point est borné (Clamp), balayé de la tête vers lui, puis borné à nouveau. Il devient `C2Target`. La vue plonge alors sur le personnage au lieu de coller au mur. La hauteur plafond − 25 reste respectée à l'intérieur. - **B2b-3 Trajectoire protégée** (`UpdateRoomCam`, poursuite) : après `VInterpTo`, on balaie de la tête vers `Next` (rayon 20) ; en cas d'impact, `Next` := `Location + Normal × 20`, puis Clamp. Le lissage ne passe donc jamais derrière un mur ni hors de la boîte, même pendant un demi-tour du personnage. - **B2b-4 Commutation sans lissage** : `PlaceC2` pose déjà la caméra sans lissage avant `SetViewTargetWithBlend`. Le point posé est désormais celui de B2b-1 / B2b-2, donc dans le volume. `CamRoom` naît à la position du personnage (B2-2), ce qui est sans effet puisque `PlaceC2` la replace avant la bascule de vue. Vérification : V5 relit l'ordre `PlaceC2` → `SetViewTargetWithBlend` (466). ## 5. Contrôle des autres vues (exigence « jamais dehors ») | Vue | Position | Dans la pièce ? | |---|---|---| | Entrée en pièce, touche C vers C2 | `PlaceC2` (B2b-1, B2b-2) | oui, par construction | | C2 pendant la poursuite | B2b-3 | oui, par construction | | C1 | yeux du personnage | oui | | **C3 provisoire (jusqu'à B3)** | `ChargenCameras[0]` = ancienne caméra de pièce, placée par l'ancienne logique | **non garanti** : c'est l'ancienne vue, qui peut se trouver derrière un mur. C'est vraisemblablement le « mur qui fait obstruction quand on change de vue » (estimé) | | C3 de B3, intérieur | (O.X, O.Y, plafond − 5) | oui, si B3 prend la boîte du § 3 et non `GetActorBounds` (le mobilier peut élargir les bornes de l'acteur) | | C3 de B3, extérieur | `O + s·(E.A − 50)·Â`, Z = sol + 380 | oui en XY si la boîte du § 3 est utilisée ; Z libre dehors | Amendement de B3, à reporter : remplacer `GetActorBounds(Room)` par la boîte du § 3 (B3-1, § (e) C3), avec la même marge. ## 6. Pilotage de la caméra en C2 (choix de l'utilisateur en attente) - **Option 1 (recommandée)** : en C2, `LeftRight` / `CircleCamera` (flèches gauche/droite, souris X) font varier un décalage de lacet `C2Yaw`. `DownUp` / `RotateCamera` (flèches haut/bas, souris Y) font varier un décalage de hauteur `C2Pitch`, borné. La molette (`ScrollDownUp`) fait varier la distance `C2Dist`, entre 100 et 300 cm (175 au départ). `Desired` tourne avec `C2Yaw` autour du personnage. Le confinement du § 3 et le repli s'appliquent ensuite, sans changement. Relais : en tête des 5 événements de déplacement de Room, une branche « vue = `CamRoom` » vrai → réglage de C2 ; faux → chaîne actuelle (déplacement de `SceneCamera`). - **Option 2** : en C2, le premier appui sur une commande de caméra rend la vue manuelle (`SceneCamera`, comme avant B2), puis la touche C reprend le cycle. C'est plus simple, mais la poursuite est perdue jusqu'au prochain C. ## 7. Marche du personnage Hors périmètre de cet amendement tant que le test qui tranche n'est pas fait : C3 (ancienne vue) puis ZQSD, dans le build B2. Si le personnage marche en C3 et pas en C2, la cause est CAM et une section 7 sera écrite. Sinon, la cause est hors CAM et se signale au lot concerné (B-SOL, menu ou scène restés actifs). ## 8. Critères ajoutés - V5 (dump de Room) : `SphereTraceSingle` 3 (cible, repli, trajectoire) ; `FClamp` ou `Clamp` ≥ 3 ; `Vector_Distance` ≥ 1 ; `VInterpTo` 1 ; `RInterpTo` 1 ; `SetViewTargetWithBlend` 3 ; ordre 465 → 466 inchangé. - Essais (§ (f)) : - dos à un mur, coin de pièce, couloir étroit : la caméra reste dans la pièce et se relève au lieu de coller au mur ; - demi-tour rapide : aucune image derrière un mur ; - C1 → C2 : la première image est déjà dans la pièce ; - ruelle extérieure : la caméra reste entre les façades (mesure de l'emprise, § 3) ; - option 1 : flèches, souris et molette font tourner et éloigner C2. ## 9. Coût estimé (copie UE) | Partie | Nœuds | MCP | Contrôles et build | |---|---|---|---| | B2b-1 à B2b-4 (confinement, repli, trajectoire) | ≈ 40 | ≈ 45 min | V5, V6 ≈ 5 min ; V7 ≈ 5 min | | Option 1 (pilotage) | ≈ 30 | ≈ 35 min | dans le même build | | Option 2 (pilotage) | ≈ 10 | ≈ 15 min | dans le même build | Total avec l'option 1 : ≈ 1 h 30 de copie UE, puis un nouvel essai.