LifePlay-Revival/Docs/Migration/etat/CAM/CAM-B2p-SPEC.md
edujiro5972 8084622450 LifePlay UE 5.8 : état de développement au 2026-10-19
Tickets : REP1-T4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:57:42 +02:00

330 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CAM-B2p-SPEC : pendant le sexe, ZQSD pour la caméra et flèches pour le couple ; retour à la sortie (2026-10-14)
Demande de l'utilisateur, relayée par Big Boss : « il faut réattribuer les touches ZQSD au mouvement de la caméra car
c'est mon premier réflexe et les touches de directions au contrôle positionnement du couple dans l'espace. puis
restaurer les touches à la sortie ». SPEC en lecture seule ; aucune écriture sans GO. Elle absorbe le correctif de
`CAM-COMMUN6-DIAG.md` (option A) et l'analyse du KO Maj + souris (`CAM-COMMUN6-DIAG.md` § 6).
Sources relues le jour même (case C9a) : dumps de la VAL B2kmn (Room `…-011706`, PC `…-011816`, état Room
`3A451FDD`, PC `F45BE57A`) ; `Config/DefaultInput.ini` ; `LPKeyboard.ini` du build COMMUN-6 ;
`LPDirectControlSubsystem.cpp`, `LPOutdoorRoomSubsystem.cpp`, `LPKeyboardSubsystem.cpp`, `LPCameraModeSubsystem.cpp`.
## 1. État actuel (établi)
| Touche | Lecture | Hors sexe | Pendant le sexe |
|---|---|---|---|
| ZQSD | axes `MoveForward` (Z, W ; S) et `MoveRight` (Q, A ; D), `DefaultInput.ini:155-160`. Aucun Blueprint ne lit ces axes (aucun `InpAxisEvt_MoveForward/MoveRight` dans le PC). Ils ne sont lus qu'en C++, état brut des touches des mappages : marche de STG (`LPDirectControlSubsystem.cpp:162` `AxisValue`, `:1038`), `PlayerBusy` (`LPOutdoorRoomSubsystem.cpp:66-78`), `LPDebug` | marche (STG) | **rien** : la marche est coupée (`ScenePlaying`, `:759`) et `LPOutdoorRoom` sort tôt si `SexOn` (`:329`) |
| ← → | axe `LeftRight` → PC `InpAxisEvt_LeftRight` (PC:3098) → `Birdview.LeftRightBirdView` → Room `LeftRight` (`CustomEvent_4`) | caméra C2 (97) ou C3 | 97 faux (B2i) → `9` → `14` (`MoveObject`) : Maj → `27` → `ForEach SexPersons` → `SetActorLocation` (139) ; sans Maj → `281` `SceneCamera.SetActorLocation` (panoramique) |
| ↑ ↓ | axe `DownUp` → PC (PC:3044) → `Birdview.DownUpBirdview` → Room `DownUp` (`CustomEvent_8`) | caméra C2 (100) ou C3 | 100 faux → `8` → `17` (`MoveObject`) : Maj → `23` (couple) ; sans Maj → `45` (caméra) |
| Souris X | `CursorX` → PC `244` → `73` (**`MoveCamera`**, `InputAction_50` : bouton du milieu ou Alt, estimé `CAM-T3-CART.md`) → `101` (`SexOn`) → `75` (`SexCameraIndex` = 0) | C2, C1, vue d'ensemble | Scene : `CircleCamera` → `19` : Maj → rotation du couple ; sans Maj → rotation de `SceneCamera` + B2n. **POV : `75.else` → `136` → `204`, regard du POV ; Room n'est jamais appelée** |
| Maj | `InputKey_0/1` → `Room.StartMoveObject/StopMoveObject` (`MoveObject`) | constructeur | couple |
- Remappage : menu Clavier (`LPKeyboardSubsystem`, groupes « Movement » et « Camera »), écrit dans
`Saved/Config/Windows/LPKeyboard.ini`. Le C++ qui lit les axes par leur nom suit donc ce remappage. AZERTY :
Z et Q sont mappés directement. W et A le sont aussi (QWERTY), donc A fait aussi un pas à gauche en AZERTY.
- Vue en mode Scene : `CamRoom`, sauf au départ de C3 (`CAM-COMMUN6-DIAG.md` § 2).
## 2. Conception proposée
Principe : **ne changer aucun mappage**. Le comportement est porté par `GI.SexOn`, relu à chaque image. Le retour
à la sortie est donc automatique, quel que soit le chemin (Endsex, menu, changement de lieu) : dès que `SexOn`
redevient faux, ZQSD rend la marche (STG) et les flèches rendent la caméra. Le même interrupteur coupe déjà la marche
de STG. On ne crée ni ne restaure aucun état, donc aucun risque de rester bloqué dans le mauvais jeu de touches.
### Essai J8 (COMMUN-6, relayé par Big Boss le 2026-10-14)
L'utilisateur juge l'orbite B2n en mode Scene difficile à contrôler (« la souris ne réagit pas bien »). C'est le
défaut du DIAG § 2 : la vue est `CamRoom` (Q8), et la souris tourne `SceneCamera`, hors de la vue. Ce que la souris
déplace à l'écran est un effet de bord du suivi de `CamRoom`, pas l'orbite. Exigence retenue pour B2p : **en mode
Scene, la vue et la cible de la souris et de ZQSD sont la même caméra**. C'est ce que fait P1 (vue = `SceneCamera`),
qui porte aussi B2n (souris) et P3 (ZQSD). Big Boss demande cette correction ; elle vaut décision de revenir sur Q8
pendant le sexe, à confirmer par l'utilisateur au GO de B2p.
### Molette en mode Scene (« pas de zoom », essai COMMUN-6, relayé par Big Boss)
Voie lue dans les dumps (établi) :
- PC : `InputAxisEvent_7` (`ScrollDownUp`) → `47` (valeur ≠ 0 ET `CallFunction_59`, non lu) → `22` (`downup`) →
`159` (`SexOn`) vrai → `69` (`Room.bHidden`) faux → `990` `Birdview.ScrollDownUp(downup)` ;
- Room : `ScrollDownUp` (`CustomEvent_55`) → `98` (`AND_62` = vue `CamRoom` ET `NOT SexOn`, B2i) faux pendant le
sexe → `10` (Builder OU Sexe OU Space) → `12` (`MoveObject`, Maj) :
- sans Maj : `125` `SceneCamera.SetActorLocation` (zoom d'origine, sur `SceneCamera`) ;
- avec Maj : `24` (voie couple).
Cause : la même que le § 2 du DIAG. La molette rapproche ou éloigne `SceneCamera`, qui n'est pas en vue (la vue est
`CamRoom`). B2i a fermé la voie C2 (98) pendant le sexe. **P1 suffit à rendre le zoom visible**, sans nœud de plus.
- **P3 bis** (C++, avec P3, environ 15 lignes de plus), si le zoom d'origine (125) ne vise pas le couple ou n'a pas
de bornes : en mode Scene, la valeur de molette (`ScrollDownUp`, lue comme les axes ZQSD) rapproche ou éloigne
`SceneCamera` du pivot P, avec les mêmes bornes que Z/S (80 à 800 cm). Pour ne pas cumuler deux zooms, P3 bis ne
s'active que si l'essai de P1 montre que 125 ne convient pas. C'est à décider après l'essai : la fiche B2p-C le
prévoit, désactivé par une constante.
### P1 (Room, MCP) : la vue Scene est `SceneCamera` (absorbe C6D, option A, revient sur Q8 pendant le sexe)
- E1 : `ApplyRoomCamera` : Branche S1 (`VariableGet_258.SexOn`) entre `CustomEvent_43.then` et `77` ; S1.then →
`394` ; S1.else → `77`.
- E2 : `UpdateRoomCam` : Branche S2 (`258.SexOn`) entre `CustomEvent_45.then` et `91` ; S2.then → `394` ;
S2.else → `91`.
- E3 : `303.then` → `441` (arrêt de la minuterie).
- 2 nœuds, 9 liens. Sans P1, ZQSD n'aurait rien de visible à déplacer (la vue serait `CamRoom`, qui suit la tête).
### P2 (Room, MCP) : flèches = couple, sans Maj, pendant le sexe
- Nouveau `BooleanOR` (A ← `VariableGet_62.MoveObject`, B ← `VariableGet_85.SexOn`) → `14.Condition` et
`17.Condition`. Pendant le sexe, les flèches prennent toujours la voie « couple » d'origine (139, 23). Hors sexe,
rien ne change.
- 1 nœud, 4 liens. Maj + flèches fait la même chose que les flèches seules.
- La rotation du couple reste Maj + souris, avec le bouton `MoveCamera` (inchangé). Option R, non proposée pour
l'alpha : Maj + ← → = rotation. Il faudrait un tri Maj/sans Maj dans `14.then`, soit environ 4 nœuds de plus.
### P3 (C++, `LPCameraModeSubsystem`, fichier CAM) : ZQSD = caméra pendant le sexe
Dans le ticker existant. Conditions : `SexOn` vrai, menu Clavier fermé (`ULPKeyboardSubsystem::IsMenuOpen`), PC et
vue valides. Les axes `MoveForward` et `MoveRight` sont lus comme `AxisValue` de STG (copie locale, mappages suivis).
- **Mode Scene** (vue = `Room.SceneCamera`) :
- pivot P = moyenne des positions de `GI.SexPersons`. Tableau vide : rien ;
- Q / D : orbite en lacet autour de P, à 90°/s. La caméra tourne du même angle, comme l'orbite B2n : le cadrage
est gardé ;
- Z / S : avance ou recul vers P, à 200 cm/s, distance bornée entre 80 et 800 cm. Pas de balayage de collision
(comme B2n) ; l'évitement des murs viendrait avec B2l.
- **POV** (vue = `SexPersons[i]`) : Q / D = lacet et Z / S = tangage, à 90°/s, sur le composant `FirstPersonSM` de
la personne en vue. C'est le composant que la souris tourne en POV (PC `204` et `316`, self ←
`SexPersons[309]`). Lacet : `AddWorldRotation(0, lacet, 0)`. Tangage : autour de l'axe droit du composant (pas de
l'axe Y du monde comme 316), borné à ±80°.
- **Autre vue** (`CamRoom` si P1 n'est pas posé, ou vue d'ensemble) : rien.
- Témoin (pour le KO Maj + souris) : au plus une ligne par seconde pendant le sexe, tant qu'une touche
ZQSD/flèche/Maj est tenue : `Sexe : touches Z=%d Q=%d S=%d D=%d fleches=%+.0f/%+.0f Maj=%d MoveObject=%d
MoveCamera=%d ; vue %s ; index POV %d ; couple a (%.0f, %.0f, %.0f)`.
- Environ 120 lignes ; `.h` : 2 membres (dernier temps de témoin, vitesse). Aucune lecture `Accessed None` possible
(réflexion avec contrôle de nullité, comme les témoins existants).
### P5 (Room, MCP) : remise de l'orientation de C1 à chaque passage de la minuterie (KO plafond, DIAG § 7)
**Sorti de B2p le 2026-10-14 (priorité de l'utilisateur) : traité par `CAM-B2s-FICHE.md`, avec P6.** Le volume de
B2p dans Room redevient P1 + P2 : 3 nœuds, 13 liens.
- Après `512` (B2k, `83.then`) : `512.then` → nouveau `K2_SetWorldRotation` (self ← `VariableGet_265.FirstPersonSM`,
`NewRotation` ← nouveau `MakeRotator` (Pitch 0, Roll 0, Yaw ← `CallFunction_514.Yaw`)), `bSweep` et `bTeleport`
faux. 514 = `BreakRotator(524 = GetControlRotation(PC))`, qui existe déjà.
- La vue C1 est horizontale, dans la direction de contrôle, quelle que soit la pose de la tête (fin de scène,
assis, couché). Assis, la souris tourne aussi la vue (lacet de contrôle par B2h).
- 2 nœuds, 4 liens. Hors C1 et pendant le sexe : non atteint (`81`, `82`, `83`). Le tangage en C1 à la souris
n'est pas traité.
### P4 (facultatif) : aide dans le menu des contrôles
Une ligne « Pendant le sexe : ZQSD = caméra, flèches = couple, Maj + souris = rotation » dans le menu Clavier.
`LPKeyboardSubsystem` n'est pas un fichier CAM : c'est à son propriétaire de décider. Ce n'est pas nécessaire pour
l'alpha.
### Ce qui ne bouge pas
- PC, GI, Person, `LPDirectControlSubsystem` (STG) : aucun changement.
- La marche reste coupée pendant le sexe (`:759`), donc ZQSD ne fait pas marcher le joueur.
- La souris reste comme aujourd'hui : orbite B2n en Scene (une fois P1 posé), regard B2m en POV, Maj + souris
(+ `MoveCamera`) pour la rotation du couple.
## 3. Fichiers et volume
| Fichier | Partie | Nœuds / lignes | Agent |
|---|---|---|---|
| `Content/BPs/Room.uasset` | P1 + P2 + P5 | 5 nœuds, 17 liens, environ 50 appels MCP | lp-mcp-bp, puis lp-validator (V5, V6) |
| `Source/LifePlay/LPCameraModeSubsystem.cpp` / `.h` | P3 | environ 120 lignes | lp-impl, compilation par `Build.ps1` |
Barème : a1 b1 c1 d1 e1 f1 = 6 → N3. S = C3 1 (deux voies, MCP et C++) + f 1 (vitesses à régler à l'essai) = 2,
moins de 3. On fait **deux fiches sous cette SPEC** : B2p-R (Room) et B2p-C (C++), parce que les agents et les
validations diffèrent. Case C9a.
## 4. Estimation
- Fiches B2p-R et B2p-C : 30 min.
- Écriture de P3 (lp-impl) et VAL statique : 1 h, sans jeton UE.
- Un seul passage UE :
- compilation C++ (`Build.ps1`) : environ 10 min ;
- éditeur MCP pour Room (P1, P2, P5) : environ 55 min ;
- VAL V5 et V6 : environ 15 min.
- Total : environ 2 h 40 de travail, dont environ 1 h 20 sous jeton UE.
## 5. Risques
- Le cadrage de `SceneCamera` en début de scène n'a pas été revu depuis la migration (celui de `pickPreset`) : à
voir en V7.
- ZQSD et l'orbite B2n déplacent la même caméra autour du même pivot : c'est compatible.
- Sans collision, la caméra peut traverser un mur en reculant (S) ; la borne de 800 cm limite le cas.
- Si `SexOn` restait vrai après une sortie anormale, ZQSD resterait sur la caméra. C'est le même interrupteur que la
marche de STG, donc le risque n'est pas nouveau. Au journal COMMUN-6, la marche reprend à 05:19:02.
- Les flèches déplacent le couple dans les directions d'origine de Maj + flèches (139, 23). Leur repère n'a pas été
revu (caméra ou monde) : à voir en V7.
- P1 revient sur la décision Q8 : **c'est à l'utilisateur de décider**. Sans P1, P3 en mode Scene n'a pas d'effet
visible (sauf départ en C3).
## 6. Essais (V7)
| N° | Action | Attendu |
|---|---|---|
| CAM-41 | Scène lancée depuis C1, puis depuis C2, puis depuis C3. | Vue de scène dès l'entrée. |
| CAM-42 | En Scene : Q, D, Z, S. | Orbite autour du couple ; avance et recul, bornés. |
| CAM-43 | En POV : Q, D, Z, S. | Le regard tourne et monte ou descend ; aucune marche. |
| CAM-44 | Flèches, sans Maj, en Scene et en POV. | Le couple se déplace ; la caméra ne bouge pas. |
| CAM-45 | Maj + souris (avec le bouton du milieu ou Alt), en Scene. | Le couple tourne. |
| CAM-46 | Sortie par Endsex, puis par le menu, puis par un changement de lieu. | ZQSD = marche, flèches = caméra C1/C2/C3 comme avant ; mode de caméra d'avant la scène. |
| CAM-47 | Remapper ZQSD dans le menu Clavier, puis refaire CAM-42. | Les touches remappées pilotent la caméra. |
| CAM-48 | Témoin : pendant le sexe, tenir Maj et bouger la souris. | Lignes « Sexe : touches … » au journal (`MoveObject`, `MoveCamera`, vue). |
| CAM-49 (P5) | Scène lancée depuis C1, fin de scène, retour en C1 ; puis s'asseoir (cinéma, bar), passer en C1 assis, se lever et marcher. | Vue C1 horizontale, jamais vers le plafond ni le sol ; la souris tourne la vue, même assis. |
| CAM-54 (P1, molette) | En scène de sexe, mode Scene (dès l'entrée et après POV → Scene) : molette avant et arrière, sans Maj. | La caméra en vue se rapproche ou s'éloigne du couple. Noter si elle vise mal ou passe à travers le couple (P3 bis). |
| CAM-55 (P1, J8) | Mode Scene : souris (avec le bouton de `MoveCamera`), puis Q et D. | La caméra en vue tourne autour du couple, sans à-coup ; la souris et ZQSD agissent sur la même caméra. |
## 7. Complément B2p-D : glisser-déposer du couple, rotation, modes, curseur (2026-10-14, demande de l'utilisateur relayée par Big Boss)
Demande : pendant le sexe, il n'y a que deux modes, POV (un par participant) et Scene. On doit pouvoir cliquer
(bouton gauche) sur le couple pour le sélectionner, puis le glisser à la souris pour le poser où l'on veut, en
complément des flèches. La souris ne fait plus tourner le couple.
### 7.1 Constat sur la rotation à la souris (établi par le témoin « Sexe : touches », journal COMMUN-7, 07:36-07:38)
- La scène est partie de **C2** (`CamC1On=0`, `CamC3On=0`) : ce n'est donc pas le cas J9 (départ en C1). La vue
Scene est `CameraActor_2147480653` (`CamRoom`, Q8 encore en place).
- Maj arrive bien à Room : `Maj=1 MoveObject=1` sur toutes les lignes de 07:37:47 à 07:38:23.
- Maj + flèches déplacent bien le couple : sa position passe de (-3131513, -14967009) à (-3131639, -14967327).
- Maj + molette le montent ou le descendent : Z passe de 42 à 46, 60, 81, puis 140, et revient à 82.
- **La rotation à la souris demande en plus `MoveCamera`**, c'est-à-dire un bouton de souris tenu. Chaîne du PC :
- un bouton (`InputKey_10` ou `_14`) appelle `StartMoveCamera` ;
- sans ce bouton, `73.else` est pris, et Room n'est jamais appelée.
- Au journal, `MoveCamera=1` n'apparaît que 3 fois en 37 s de Maj tenu (07:38:09, :11, :22). L'utilisateur a donc
surtout bougé la souris **sans bouton**. Dans ce cas, aucune rotation n'est possible, et c'était déjà le cas dans
le jeu d'origine.
- **B2p-C n'y est pour rien** : il ne lit ni n'écrit la souris, `MoveObject` ou `MoveCamera`, et n'agit que sur ZQSD
(et la molette, désactivée).
- Le témoin ne donne pas le lacet du couple. On ne peut donc pas prouver que la rotation se fait quand le bouton est
tenu. B2p-D ajoute le lacet au témoin.
### 7.2 Modes pendant le sexe (établi, dump du PC)
La touche C fait le cycle suivant :
- `IfThenElse_44` (`SexCameraIndex` inférieur au nombre de `SexPersons`) vrai : POV de `SexPersons[index]`
(`55`), puis incrément de l'index ;
- sinon : `POVOn` = faux, index = 0, `353` (`ChargenCameras[0]`), puis `140` (`ApplyRoomCamera`), c'est-à-dire le
mode Scene.
Il n'y a donc que **POV × n + Scene**, sans autre mode. Avec B2p-R, la vue de Scene devient toujours `SceneCamera`
(aujourd'hui : `CamRoom` hors C3). Rien à changer pour les modes.
### 7.3 Glisser-déposer (C++, `LPCameraModeSubsystem`, partie D1)
Dans le ticker par image (`TickSexCamera`), seulement si `SexOn` est vrai, en mode Scene (la vue n'est pas l'une
des `SexPersons`) et sans menu à l'écran.
- **Sélection** (front montant du bouton gauche, lu dans `PlayerInput`) :
- pour chaque personne du couple, projection à l'écran (`ProjectWorldLocationToScreen`) du bassin (`pelvis`) et
de la tête (`head`) ;
- le couple est sélectionné si le curseur (`GetMousePosition`) est à moins de 120 px de l'un de ces points ou du
segment qui les joint ;
- on ne fait **pas de tracé de collision**, parce que les `SexPersons` sont en `NoCollision` pendant le sexe
(relevé LPDebug `coll=NoCollision`) ;
- un clic sur un widget de l'interface est absorbé par l'UI (mode `GameAndUI`) et n'arrive pas au `PlayerInput` :
il ne sélectionne rien.
- **Glisser** (bouton tenu) :
- le rayon du curseur (`DeprojectMousePositionToWorld`) coupe le plan horizontal à la hauteur actuelle du couple
(son Z ne change pas : la hauteur reste réglée par Maj + molette) ;
- le décalage entre ce point et le pivot est gardé depuis la sélection ;
- toutes les `SexPersons` sont déplacées du même vecteur XY (`SetActorLocation`, sans balayage, comme les flèches
d'origine).
- **Garde « dans la pièce »** : le pivot est borné aux limites XY du sol de Room (composant `Room.Box`), moins une
marge de 30 cm. Les cloisons intérieures ne sont pas testées (limite connue, comme les flèches).
- **Relâcher** : la pose est faite, la sélection est levée, et une ligne
`Sexe : couple pose a (x, y, z), lacet %.0f` est écrite.
- **Pas d'orbite pendant le glisser** : le même clic lance aussi `StartMoveCamera` (PC), donc la souris ferait aussi
tourner la caméra. Tant que la sélection dure, D1 remet `PC.MoveCamera` à faux à chaque image (réflexion, variable
d'exécution du PC, aucun asset touché). Hors sélection, rien ne change : un clic à côté du couple garde l'orbite à
la souris.
### 7.4 Rotation (partie D2, proposée)
- **Molette pendant le glisser** (bouton gauche tenu sur le couple) : ±15° de lacet par cran, autour du pivot.
Recommandé.
- Conflit à neutraliser : la molette passe aussi à Room, qui rapproche `SceneCamera` (nœud 125, sans Maj).
- Pendant la sélection, D1 garde donc la position et la rotation de la caméra en vue prises au clic, et les remet
à chaque image. Cela neutralise ce zoom et toute orbite parasite, en plus de la remise de `MoveCamera`.
- La caméra reste immobile tant que le couple est tenu.
- La rotation d'origine (Maj + bouton tenu + souris) est gardée sans changement.
- Non retenu : des touches dédiées (A/E en AZERTY sont déjà mappées : A = pas à gauche, E = interagir).
### 7.5 Flèches
P2 de B2p-R (les flèches déplacent le couple sans Maj) reste le complément au clavier. Rien de plus.
### 7.6 Curseur en mode Scene
- Le jeu est en mode d'entrée `GameAndUI` (curseur du jeu, widget `Cursor`). Le curseur est donc normalement
visible en mode Scene. L'orbite à la souris d'origine se fait par glisser avec un bouton (`MoveCamera`), et ZQSD
et la molette ne dépendent pas du curseur.
- **À vérifier en V7** : `GetMousePosition` doit rendre une position en mode Scene. Si le curseur est capturé (pas
de position), D1 ne sélectionne rien, sans autre effet, et une ligne au journal le dit une fois par scène. Le
correctif éventuel (`SetShowMouseCursor`, mode d'entrée) serait un ajout séparé, car il touche au comportement
global du PC.
### 7.7 Fichiers, volume, estimation
| Partie | Fichier | Volume | Jeton UE |
|---|---|---|---|
| D1 + D2 + témoin du lacet | `LPCameraModeSubsystem.cpp` / `.h` | environ 150 lignes | non (écriture) ; compilation au build suivant |
- Room, PC, GI et Person : aucun changement d'asset.
- Écriture : environ 1 h 30. VAL statique (lp-validator) : 20 min. Compilation : environ 10 min, sous jeton UE, avec
le build suivant.
- Barème : a1 b1 c1 d1 e1 f1 = 6 → N3 ; S = C3 1 + f 1 (seuils de sélection et de rotation à régler à l'essai) = 2 :
une fiche (B2p-D). Case C9a.
### 7.8 Risques
- Clic sur le couple qui ouvre aussi une interaction de Room (`SelectUnderCursor`, PC 145) : à voir en V7. Si c'est
le cas, D1 n'agit qu'à partir d'un déplacement de 5 px. Un clic bref reste alors un clic, et la sélection
commence au glisser.
- Couple posé contre un meuble ou dans le lit d'à côté : pas de collision. C'est la même limite que les flèches.
- Écriture de `PC.MoveCamera` pendant la sélection : variable d'exécution, remise par le jeu au prochain clic.
C'est sans effet hors sélection.
- La sélection par projection peut prendre le couple même quand on clique juste à côté (120 px) : seuil à régler.
### 7.9 Ordre recommandé
- **B2p-R passe tel quel**, sans attendre B2p-D. B2p-D est en C++ seul, sans asset, et ne dépend pas de B2p-R : il
marche dans toute vue de Scene. Il est plus juste avec `SceneCamera`, parce que ZQSD et la molette agissent alors
sur la même vue.
- B2p-D s'écrit ensuite, sans jeton, et sera compilé avec le build suivant (COMMUN-8).
### 7.10 Essais
| N° | Action | Attendu |
|---|---|---|
| CAM-58 | Mode Scene : clic gauche maintenu sur un corps du couple, glisser, relâcher. | Le couple suit le curseur au sol (à sa hauteur), puis se pose ; la caméra ne tourne pas pendant le glisser ; ligne « Sexe : couple pose ». |
| CAM-59 | Pendant le glisser : molette. | Le couple tourne de 15° par cran. |
| CAM-60 | Glisser vers un mur. | Le couple s'arrête à 30 cm du bord du sol. |
| CAM-61 | Clic gauche à côté du couple, puis glisser. | Orbite de la caméra comme avant (pas de sélection). |
| CAM-62 | C pendant la scène. | POV de chaque participant, puis Scene ; rien d'autre. |
### 7.11 Précisions de l'utilisateur (relayées par Big Boss), qui remplacent 7.3 (hauteur) et 7.4 (rotation)
**a) Remettre le couple sur le lit : hauteur de la surface sous le curseur.** « il y a des moments où on ne peut
plus replacer les personnages sur le lit correctement ».
- À la sélection, un tracé vertical part du pivot vers le bas (canal Visibility, collision complexe ; couple, `Wall`
et `CamRoom` ignorés). Il donne la surface sous le couple, Zs0 (lit, sol). On garde l'écart dz = Z du pivot − Zs0.
C'est le même principe que la mesure M1d de STG (`under=…fnt_bed02`, `lowestMinusUnder`).
- Pendant le glisser :
- le rayon du curseur est tracé dans la scène, avec les mêmes acteurs ignorés ; il touche la surface visée
(dessus du lit ou sol) en H ;
- nouveau pivot XY = H.XY + décalage de prise (gardé depuis la sélection), borné au sol de Room ;
- un tracé vertical à ce nouveau XY donne Zs ; nouveau Z du pivot = Zs + dz.
On pose ainsi le couple sur le lit, ou on l'en retire, en gardant son rapport à la surface. La racine qui monte de
88 cm à 05:14 (COMMUN-6) vient de l'animation : dz, pris à la sélection, la conserve.
- Si le rayon du curseur ne touche rien (vers le ciel ou hors de la pièce), le couple ne bouge pas à cette image.
- Maj + molette (réglage fin de la hauteur, voie d'origine) reste disponible.
- À accorder avec STG au moment de l'écriture : réutiliser sa fonction de surface sous le couple si elle est
exposée. Sinon, le tracé ci-dessus est autonome et ne touche pas son fichier.
**b) Clic droit = rotation, clic gauche = glisser-déposer.**
- Clic droit sur le couple (même sélection par projection que le clic gauche), maintenu, avec un mouvement
horizontal : lacet du couple autour du pivot, 0,3° par pixel. La caméra est figée pendant ce temps (même
neutralisation qu'en 7.4).
- Clic droit ailleurs que sur le couple : comportement actuel inchangé.
- Ce que fait aujourd'hui le clic droit pendant le sexe (dump du PC) :
- les boutons de souris (`InputKey_10` et `_14`, relus avec `GetInputKeyTimeDown(RightMouseButton /
LeftMouseButton)`) lancent `StartMoveCamera`. Glisser avec un bouton fait donc tourner la caméra (orbite) ou,
avec Maj, le couple ;
- l'action `ManualAnimating` (clic droit, Ctrl) règle `Manual`. Pendant le sexe, `Manual` et la souris règlent la
vitesse d'animation (`247` et `246` → `AnimatingSpeed`, quand `MoveCamera` est faux). Mais le nœud qui met
`Manual` à vrai (`IfThenElse_39`) n'a plus d'entrée d'exécution dans le dump : cette voie est **morte** ;
- non vérifié : un menu contextuel au clic droit porté par un widget de scène (hors PC). À voir en V7 (CAM-59).
Conclusion : la rotation au clic droit **sur le couple** ne prend la place que de l'orbite au clic droit sur le
couple. L'orbite reste au clic droit ou gauche à côté du couple, et avec ZQSD.
- La rotation d'origine (Maj + bouton + souris) reste. La molette pendant la sélection (7.4) n'est plus nécessaire :
elle est retirée de D2.
**c) Retour des affectations à la sortie** : il est automatique. Tout passe par `SexOn`, relu à chaque image, et
aucun mappage n'est modifié. Si un bouton est tenu au moment où `SexOn` devient faux, la sélection est levée sans
pose supplémentaire et la caméra n'est plus figée.
**Volume revu** : environ 200 lignes de C++ (B2p-D), 2 h d'écriture, 20 min de VAL statique ; compilation avec
COMMUN-8. Aucun asset touché.
**Essais revus**
| N° | Action | Attendu |
|---|---|---|
| CAM-58 | Clic gauche maintenu sur le couple, glisser du sol vers le lit, puis du lit vers le sol. | Le couple suit le curseur et se pose sur le dessus du lit (puis au sol) à la bonne hauteur ; caméra immobile pendant le glisser. |
| CAM-59 | Clic droit maintenu sur le couple, souris à gauche puis à droite. | Le couple tourne sur place ; caméra immobile. |
| CAM-60 | Glisser vers un mur. | Arrêt à 30 cm du bord du sol. |
| CAM-61 | Clic gauche ou droit à côté du couple, glisser. | Orbite de la caméra comme avant. |
| CAM-62 | C pendant la scène. | POV de chaque participant, puis Scene. |
| CAM-63 | Finir la scène en tenant un bouton. | Retour normal en C1, C2 ou C3 ; aucun mouvement de couple après la sortie. |