Charge le plugin via AdditionalPluginDirectories, conserve ShowCouple et les commandlets anim côté jeu, et documente les lots S0–S8 (CHG-212 à CHG-220). Co-authored-by: Cursor <cursoragent@cursor.com>
271 lines
19 KiB
Markdown
271 lines
19 KiB
Markdown
# S2-CART — Cartographie d'extraction du module `LPAnimMeasure`
|
||
|
||
- **Date :** 2026-10-06
|
||
- **Fiche :** S2-T1 | **Agent :** A-CART | **Rôle :** Cartographie (lecture seule, aucun code modifié)
|
||
- **Modèle prévu :** `claude-sonnet-5-5-high` (M2)
|
||
- **Références :** `S1/S1-SPEC.md`, `S1/S1-CART.md`
|
||
|
||
---
|
||
|
||
## 1. Décision principale : `LPAnimRedirect`
|
||
|
||
`LPAnimRedirect.cpp` appelle `FLPSandboxConfig::Get().QuaterniusUALRoot` (seule dépendance, ligne 23 de `ClipPath`). `LPPoseOrchestrator.cpp` appelle `LPAnimRedirect::ClipPath` 8 fois (l. 223, 233, 237, 255, 262, 303, 345, 404). `LPDirectControlSubsystem.cpp` (runtime jeu, module `LifePlay`) appelle `IsGameTarget()` (l. 880) et `ClipPath()` (l. 960).
|
||
|
||
Garder Redirect dans `LifePlay` n'est **pas possible** : `LPPoseOrchestrator` va dans `LPAnimMeasure`, qui ne peut pas dépendre de `LifePlay` (cycle `LifePlay` → `LPAnimMeasure` → `LifePlay`).
|
||
|
||
### Choix retenu : **(b) Redirect déménage dans `LPAnimMeasure`, racine UAL injectée**
|
||
|
||
- `LPAnimRedirect` ne dépend plus de `LPSandboxConfig` (le `#include "LPSandboxConfig.h"` disparaît du `.cpp`).
|
||
- Ajout d'un point d'injection dans `LPAnimRedirect.h` :
|
||
- `LPANIMMEASURE_API void SetUALRoot(const FString& Root);`
|
||
- `LPANIMMEASURE_API const FString& GetUALRoot();`
|
||
- Valeur par défaut interne : `TEXT("/Game/Quaternius/UAL")` (identique au défaut de `FLPSandboxConfig::QuaterniusUALRoot`, donc comportement inchangé sans ini).
|
||
- `LPANIMMEASURE_API` ajouté à `IsGameTarget()` et `ClipPath()`.
|
||
- **Câblage côté `LifePlay`** (propriétaire de `LPSandboxConfig`, qui reste dans `LifePlay` pour S3) :
|
||
`LifePlay.cpp` passe de `FDefaultGameModuleImpl` à une classe `FLifePlayModule : FDefaultGameModuleImpl` dont `StartupModule()` appelle `LPAnimRedirect::SetUALRoot(FLPSandboxConfig::Get().QuaterniusUALRoot)`. Le singleton lit `Config/LPSandbox.ini` ; l'ini est donc pris en compte pour tous les consommateurs (sandbox, `LPDirectControlSubsystem`, commandlets), sans exiger que la sandbox soit lancée d'abord.
|
||
Alternative plus légère, moins sûre : appeler `SetUALRoot` au début de `ALPPairSandboxCharacter::BeginPlay`. À éviter : `LPDirectControlSubsystem` et les commandlets s'exécuteraient avec la valeur par défaut seulement.
|
||
- **Couplage à documenter** : le contrat `S1-SPEC.md` (clé `Sandbox.Roots/QuaterniusUALRoot`) reste valide, mais sa consommation passe par `SetUALRoot` au lieu d'un appel direct. `S1-CART.md` doit mettre à jour la ligne `LPAnimRedirect.cpp:23` (consommateur indirect).
|
||
- Pourquoi (b) plutôt que laisser Redirect hors module : `LPPoseOrchestrator` (dans `LPAnimMeasure`) en dépend directement, donc l'un des deux doit bouger ou être injecté. Déplacer Redirect + une seule fonction d'injection est le plus petit changement (2 fichiers, 1 setter).
|
||
- Alternative écartée (c) : injecter un resolver `TFunction<FString(const FString&)>` dans l'Orchestrator. Plus invasif (signatures `Run`/`Restore`/`SampleAt`), et `IsGameTarget()` devrait rester séparé.
|
||
|
||
---
|
||
|
||
## 2. Liste exhaustive des fichiers à déplacer
|
||
|
||
Source : `Source/LifePlay/` → destination : `Source/LPAnimMeasure/` (structure plate comme `LifePlay`, pas de `Public/`/`Private/`).
|
||
|
||
| # | Fichier | Destination |
|
||
|---|---|---|
|
||
| 1 | `LPPoseMeasure.h` | `Source/LPAnimMeasure/LPPoseMeasure.h` |
|
||
| 2 | `LPPoseMeasure.cpp` | `Source/LPAnimMeasure/LPPoseMeasure.cpp` |
|
||
| 3 | `LPSkeletonProfile.h` | `Source/LPAnimMeasure/LPSkeletonProfile.h` |
|
||
| 4 | `LPSkeletonProfile.cpp` | `Source/LPAnimMeasure/LPSkeletonProfile.cpp` |
|
||
| 5 | `LPPoseOrchestrator.h` | `Source/LPAnimMeasure/LPPoseOrchestrator.h` |
|
||
| 6 | `LPPoseOrchestrator.cpp` | `Source/LPAnimMeasure/LPPoseOrchestrator.cpp` |
|
||
| 7 | `LPAnimRedirect.h` | `Source/LPAnimMeasure/LPAnimRedirect.h` |
|
||
| 8 | `LPAnimRedirect.cpp` | `Source/LPAnimMeasure/LPAnimRedirect.cpp` |
|
||
|
||
Nouveaux fichiers du module :
|
||
|
||
| Fichier | Contenu |
|
||
|---|---|
|
||
| `Source/LPAnimMeasure/LPAnimMeasure.Build.cs` | règles du module (section 5) |
|
||
| `Source/LPAnimMeasure/LPAnimMeasure.h` | `LPANIMMEASURE_API DECLARE_LOG_CATEGORY_EXTERN(LogLPAnimMeasure, Log, All);` |
|
||
| `Source/LPAnimMeasure/LPAnimMeasure.cpp` | `IMPLEMENT_MODULE(FDefaultModuleImpl, LPAnimMeasure)` + `DEFINE_LOG_CATEGORY(LogLPAnimMeasure)` |
|
||
|
||
**Ne bougent PAS** : `LPSandboxConfig.h/.cpp` (reste dans `LifePlay`, S3), `LPPairSandbox.*`, `LPDirectControlSubsystem.*`, `LifePlay.h/.cpp`.
|
||
|
||
---
|
||
|
||
## 3. Dépendances sortantes de chaque fichier déplacé
|
||
|
||
| Fichier | `#include` projet (hors Engine) | Autres dépendances à traiter |
|
||
|---|---|---|
|
||
| `LPPoseMeasure.h` | `CoreMinimal.h` | 6 symboles `LIFEPLAY_API` → `LPANIMMEASURE_API` ; commentaire l.~74 (« LifePlayEditorTools ») |
|
||
| `LPPoseMeasure.cpp` | `LPPoseMeasure.h`, `LPSkeletonProfile.h`, **`LifePlay.h`** (l. 6) | 12 `UE_LOG(LogLifePlay…)` (l. 298, 862, 878…) ; Engine : `Animation/AnimSequence.h`, `Animation/Skeleton.h`, `Misc/FileHelper.h` |
|
||
| `LPSkeletonProfile.h` | `CoreMinimal.h` | `FLPSkeletonProfile` et 2 fonctions `LIFEPLAY_API` → `LPANIMMEASURE_API` |
|
||
| `LPSkeletonProfile.cpp` | `LPSkeletonProfile.h`, **`LifePlay.h`** (l. 5) | 4 `UE_LOG(LogLifePlay…)` ; Engine : `Dom/JsonObject.h`, `Serialization/Json*`, `HAL/FileManager.h`, `Misc/Paths.h` ; lit `Tools/anim/profiles/*.json` via `FPaths::ProjectDir()` (aucun changement) |
|
||
| `LPPoseOrchestrator.h` | `LPPoseMeasure.h` | aucune API exportée aujourd'hui (voir §4) |
|
||
| `LPPoseOrchestrator.cpp` | `LPPoseOrchestrator.h`, `LPAnimRedirect.h`, **`LifePlay.h`** (l. 5) | 4 `UE_LOG(LogLifePlay…)` ; Engine : `Animation/AnimSequence.h`, `HAL/FileManager.h`, `Misc/FileHelper.h`, `Misc/Paths.h` |
|
||
| `LPAnimRedirect.h` | `CoreMinimal.h` | ajouter `LPANIMMEASURE_API` + `SetUALRoot/GetUALRoot` |
|
||
| `LPAnimRedirect.cpp` | `LPAnimRedirect.h`, **`LPSandboxConfig.h`** (l. 2, à supprimer) | `GConfig` (`Misc/ConfigCacheIni.h`), `FPaths` |
|
||
|
||
### Couplages à casser (sinon cycle de modules)
|
||
|
||
1. **`LifePlay.h` / `LogLifePlay`** : 3 `.cpp` (20 appels `UE_LOG` au total : Measure 12, Orchestrator 4, SkeletonProfile 4) incluent `LifePlay.h`. `LPAnimMeasure` ne peut pas dépendre de `LifePlay`. Solution : catégorie propre `LogLPAnimMeasure` (`LPAnimMeasure.h/.cpp`), remplacement mécanique `LogLifePlay` → `LogLPAnimMeasure` et `#include "LifePlay.h"` → `#include "LPAnimMeasure.h"`.
|
||
- **Effet de bord** : `Tools/LogStats.ps1` ligne 51 compte les lignes `LogLifePlay` (statistique de session). Les lignes `POSET`/`PROFIL` migrent vers `LogLPAnimMeasure` ; ajouter une entrée `LogLPAnimMeasure` dans ce script (ou accepter la baisse du compteur). Aucune occurrence de `LogLifePlay` dans `Source/LifePlayEditorTools`.
|
||
2. **`LPSandboxConfig.h`** dans `LPAnimRedirect.cpp` : voir §1.
|
||
3. Aucune autre référence à des types `ALP*`/`ULP*`/`FLPSandbox*`/`FLPPair*`/`GEngine`/`UWorld` dans `LPPoseMeasure.cpp`, `LPSkeletonProfile.cpp`, `LPPoseOrchestrator.cpp` (vérifié par grep, 0 occurrence) : l'extraction est propre hors les deux points ci-dessus.
|
||
|
||
---
|
||
|
||
## 4. Consommateurs : `#include` et usages (hors fichiers déplacés)
|
||
|
||
### 4.1. `Source/LifePlay`
|
||
|
||
| Consommateur | `#include` | Symboles utilisés | Action |
|
||
|---|---|---|---|
|
||
| `LPPairSandbox.cpp` l. 5-7 | `LPAnimRedirect.h`, `LPPoseMeasure.h`, `LPPoseOrchestrator.h` | `LPAnimRedirect::ClipPath` (l. 1923, 1929, 2011, 3089, 3111) ; `LPPoseMeasure::Sample/Compare/KeyBones/LogReport/TFitReport/TransferPose/WriteRetargetPose/TPoses/TFitResult` (l. 1419-1520, 1923-1932) ; `LPPoseOrchestrator::Run/Restore/SampleAt` (l. 1450-1451) | includes inchangés (include path public du module), mais **exports à ajouter** (§4.3) |
|
||
| `LPPairSandbox.cpp` l. 8 | `LPSandboxConfig.h` | — | inchangé (reste dans `LifePlay`) |
|
||
| `LPDirectControlSubsystem.cpp` l. 10 | `LPAnimRedirect.h` | `IsGameTarget()` l. 880, `ClipPath()` l. 960 | include inchangé ; dépendance `LifePlay` → `LPAnimMeasure` en `Build.cs` |
|
||
| `LifePlay.cpp` | (nouveau) `LPAnimRedirect.h`, `LPSandboxConfig.h` | `SetUALRoot` dans `StartupModule` | à créer |
|
||
|
||
### 4.2. `Source/LifePlayEditorTools`
|
||
|
||
| Consommateur | `#include` | Symboles utilisés (tous déjà exportés) |
|
||
|---|---|---|
|
||
| `LPAnimTwistCommandlet.cpp` l. 10-11 | `LPPoseMeasure.h`, `LPSkeletonProfile.h` | `LPSkeletonProfile::Find` (l. 59), `LPPoseMeasure::Sample`, `TPoses` (l. 265-295) |
|
||
| `LPAnimEvalCommandlet.cpp` l. 9-10 | `LPPoseMeasure.h`, `LPSkeletonProfile.h` | `LPSkeletonProfile::Find` (l. 86, 171), `Sample`, `TransferPose`, `Compare`, `TPoses`, `WriteRetargetPose`, `TFitResult` |
|
||
| `LPAnimCatalogCommandlet.cpp` l. 8 | `LPPoseMeasure.h` | `RoleBone` (l. 31), `Sample` (l. 144) |
|
||
| `LPAnimChecks.h` l. 15 | `LPPoseMeasure.h` | `FLPPose` (type en signature publique) ; `LPAnimChecks.cpp` : `RoleBone` (l. 26), `Sample` (l. 270) |
|
||
| `LPAnimTwistCommandlet.h` l. 7 | — (commentaire) | mention `LPPoseMeasure::TransferPose` |
|
||
|
||
`LifePlayEditorTools` n'inclut ni `LPPoseOrchestrator.h`, ni `LPAnimRedirect.h`, ni `LPSandboxConfig.h`.
|
||
`LPAnimEvalCommandlet` a son propre `ClipPath(ClipDir, ...)` (fonction locale) et n'utilise pas `LPAnimRedirect`.
|
||
|
||
### 4.3. Exports requis (la frontière de module les rend obligatoires)
|
||
|
||
Aujourd'hui exportés par `LIFEPLAY_API` (→ `LPANIMMEASURE_API`) : `LPPoseMeasure::{Sample, TPoses, TFitResult, TransferPose, WriteRetargetPose, Compare, RoleBone}`, `FLPSkeletonProfile` (struct), `LPSkeletonProfile::{Find, Identify}`.
|
||
|
||
**À ajouter** (utilisés aujourd'hui par `LPPairSandbox.cpp` qui reste dans `LifePlay`, donc cross-module après extraction) :
|
||
|
||
| Symbole | Utilisé par |
|
||
|---|---|
|
||
| `LPPoseMeasure::KeyBones` | `LPPairSandbox.cpp` l. 1419 |
|
||
| `LPPoseMeasure::LogReport` | `LPPairSandbox.cpp` l. 1477, 1483, 1493 |
|
||
| `LPPoseMeasure::TFitReport` | `LPPairSandbox.cpp` l. 1520 |
|
||
| `LPPoseOrchestrator::Run` | `LPPairSandbox.cpp` l. 1451 |
|
||
| `LPPoseOrchestrator::Restore` | `LPPairSandbox.cpp` l. 1451 |
|
||
| `LPPoseOrchestrator::SampleAt` | `LPPairSandbox.cpp` l. 1450 |
|
||
| `LPAnimRedirect::IsGameTarget`, `ClipPath`, `SetUALRoot`, `GetUALRoot` | `LPPairSandbox.cpp`, `LPDirectControlSubsystem.cpp`, `LifePlay.cpp` |
|
||
|
||
Restent internes (non exportés, usage intra-module uniquement) : `LPPoseMeasure::{AlignToReference, ScorePose, SyncSample, FormatPassage, FormatKept, FormatSnapshot}` et `LPSkeletonProfile::All`.
|
||
Les structs de données (`FLPPose`, `FLPPoseMeasureReport`, `FLPPoseScore`, `FLPJointScore`, `FLPTFitSegment`, `FLPTFitAdjust`, `FLPTFitResult`, `FLPOrchestratorRound`, `FLPTPoseAdjust`) sont des structs sans UCLASS/USTRUCT ; elles n'ont besoin d'aucun export (types header-only, membres `TArray`/`FString` inline). `FLPSkeletonProfile` conserve son `API` car elle a des méthodes `.cpp` (`Bone`, `Chain`).
|
||
|
||
---
|
||
|
||
## 5. Frontière de module proposée
|
||
|
||
### 5.1. `Source/LPAnimMeasure/LPAnimMeasure.Build.cs`
|
||
|
||
```csharp
|
||
using UnrealBuildTool;
|
||
|
||
public class LPAnimMeasure : ModuleRules
|
||
{
|
||
public LPAnimMeasure(ReadOnlyTargetRules Target) : base(Target)
|
||
{
|
||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||
|
||
// Structure plate (comme LifePlay) : exposer le dossier du module aux dependants.
|
||
PublicIncludePaths.Add(ModuleDirectory);
|
||
|
||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine" });
|
||
|
||
// LPSkeletonProfile : lecture des profils Tools/anim/profiles/*.json
|
||
PrivateDependencyModuleNames.Add("Json");
|
||
}
|
||
}
|
||
```
|
||
|
||
Justification des dépendances (vérifiées par les `#include` Engine des 8 fichiers) :
|
||
- `Core`, `CoreUObject`, `Engine` : `UAnimSequence`, `USkeleton`, `FTransform`, `GConfig`, `FPaths`, `IFileManager`, `FFileHelper`. `Engine` public car `FLPPose` n'expose que des types Core (`FName`, `FTransform`, `FQuat`, `FString`), mais les en-têtes sont consommés par des modules qui ont déjà `Engine` ; le garder public est inoffensif.
|
||
- `Json` (+ `JsonUtilities` non requis) : `Dom/JsonObject.h`, `Serialization/JsonReader.h`, `JsonSerializer.h` dans `LPSkeletonProfile.cpp`.
|
||
- **Aucune** dépendance vers `LifePlay` ni `LifePlayEditorTools`.
|
||
- `Json` reste aussi dans `LifePlay.Build.cs` : il est ajouté en AP1 pour `LPSkeletonProfile` ; une fois le fichier déplacé, vérifier qu'aucun autre fichier de `LifePlay` n'utilise `Json` avant de le retirer (non traité ici, laisser en l'état est sans risque).
|
||
|
||
### 5.2. Export API
|
||
|
||
`LPANIMMEASURE_API` (généré par UBT pour le module `LPAnimMeasure`) remplace `LIFEPLAY_API` dans les 4 headers déplacés (pas de `LIFEPLAY_API` résiduel dans `LPPoseMeasure.h`, `LPSkeletonProfile.h`, `LPAnimRedirect.h`, `LPPoseOrchestrator.h`).
|
||
|
||
### 5.3. `Source/LPAnimMeasure/LPAnimMeasure.cpp`
|
||
|
||
```cpp
|
||
#include "LPAnimMeasure.h"
|
||
#include "Modules/ModuleManager.h"
|
||
|
||
IMPLEMENT_MODULE(FDefaultModuleImpl, LPAnimMeasure);
|
||
DEFINE_LOG_CATEGORY(LogLPAnimMeasure);
|
||
```
|
||
|
||
(`IMPLEMENT_PRIMARY_GAME_MODULE` reste uniquement dans `LifePlay.cpp`.)
|
||
|
||
### 5.4. `LifePlay.Build.cs`
|
||
|
||
Ajouter :
|
||
|
||
```csharp
|
||
PublicDependencyModuleNames.Add("LPAnimMeasure");
|
||
```
|
||
|
||
Public (et non Private) car `LifePlayEditorTools` dépend de `LifePlay` publiquement et les headers `LPPoseMeasure.h` etc. sont inclus par ses commandlets ; une dépendance explicite dans `LifePlayEditorTools.Build.cs` est quand même ajoutée (5.5) pour ne pas dépendre de la transitivité. `PublicIncludePaths.Add(ModuleDirectory)` de `LifePlay` n'est plus nécessaire pour ces 4 headers mais reste requis pour `LPAssetRegistryHelpers.h` et autres.
|
||
|
||
### 5.5. `LifePlayEditorTools.Build.cs`
|
||
|
||
Ajouter dans `PublicDependencyModuleNames` (à côté de `"LifePlay"`) : `"LPAnimMeasure"` — public car `LPAnimChecks.h` expose `FLPPose` dans sa signature.
|
||
|
||
### 5.6. `LifePlay.uproject` — entrée `Modules`
|
||
|
||
Insérer **avant** `LifePlay` (même phase de chargement `Default`, ordre explicite) :
|
||
|
||
```json
|
||
{
|
||
"Name": "LPAnimMeasure",
|
||
"Type": "Runtime",
|
||
"LoadingPhase": "Default"
|
||
}
|
||
```
|
||
|
||
`Type: Runtime` car `LifePlay` (module runtime du jeu packagé) en dépend (`LPDirectControlSubsystem` utilise `LPAnimRedirect`). Les dépendances ne sont pas déclarées dans le `.uproject` (c'est `Build.cs` qui gère ; `AdditionalDependencies` n'est pas requis).
|
||
|
||
### 5.7. Targets
|
||
|
||
- `Source/LifePlay.Target.cs` : `ExtraModuleNames` → `{ "LifePlay", "LPAnimMeasure" }`.
|
||
- `Source/LifePlayEditor.Target.cs` : `ExtraModuleNames` → `{ "LifePlay", "LPAnimMeasure", "LifePlayEditorTools" }`.
|
||
|
||
---
|
||
|
||
## 6. Graphe de dépendances
|
||
|
||
### Avant
|
||
|
||
```
|
||
LifePlayEditorTools ──► LifePlay
|
||
├─ LPPoseMeasure ──► LPSkeletonProfile
|
||
├─ LPPoseOrchestrator ──► LPPoseMeasure, LPAnimRedirect
|
||
├─ LPAnimRedirect ──► LPSandboxConfig
|
||
├─ LPPairSandbox ──► Redirect, Measure, Orchestrator, SandboxConfig
|
||
└─ LPDirectControlSubsystem ──► LPAnimRedirect
|
||
```
|
||
|
||
### Après
|
||
|
||
```
|
||
┌────────────────────────────────────────────┐
|
||
LifePlayEditorTools ──┤ ▼
|
||
│ │ LPAnimMeasure (Runtime, nouveau)
|
||
▼ │ ├─ LPPoseMeasure ──► LPSkeletonProfile
|
||
LifePlay ────────┘ ├─ LPPoseOrchestrator ──► LPPoseMeasure
|
||
│ │ └─► LPAnimRedirect
|
||
├─ LPSandboxConfig (reste, S3) ├─ LPAnimRedirect (UALRoot injectee)
|
||
├─ LPPairSandbox ───► LPAnimMeasure (Redirect, Measure, Orchestrator) + LPSandboxConfig
|
||
├─ LPDirectControlSubsystem ───► LPAnimMeasure (Redirect)
|
||
└─ LifePlay.cpp StartupModule ─► LPAnimRedirect::SetUALRoot(FLPSandboxConfig::Get().QuaterniusUALRoot)
|
||
```
|
||
|
||
Sens des flèches module :
|
||
|
||
| De | Vers | Type |
|
||
|---|---|---|
|
||
| `LifePlay` | `LPAnimMeasure` | Public |
|
||
| `LifePlayEditorTools` | `LifePlay` | Public (existant) |
|
||
| `LifePlayEditorTools` | `LPAnimMeasure` | Public (nouveau) |
|
||
| `LPAnimMeasure` | `LifePlay` | **aucune** (acyclique) |
|
||
| `LPAnimMeasure` | `LifePlayEditorTools` | **aucune** |
|
||
|
||
Couplage résiduel documenté : `LPAnimRedirect` ne lit plus `LPSandboxConfig` ; le flux va dans le sens `LifePlay` (config) → `LPAnimMeasure` (setter). Ordre de chargement : `LPAnimMeasure` avant `LifePlay` (garanti par la dépendance `Build.cs` et par l'ordre dans `.uproject`).
|
||
|
||
---
|
||
|
||
## 7. Risques et points de vigilance
|
||
|
||
| # | Risque | Mitigation |
|
||
|---|---|---|
|
||
| R1 | `LogLifePlay` → `LogLPAnimMeasure` : la catégorie change dans les logs `POSET`/`PROFIL` et le compteur `Tools/LogStats.ps1:51` | ajouter `LogLPAnimMeasure` au script |
|
||
| R2 | `SetUALRoot` non appelé avant premier `ClipPath` (commandlet sans module `LifePlay` initialisé) | `LifePlay` est toujours chargé (module primaire) avant les commandlets de `LifePlayEditorTools` ; défaut interne identique au défaut de la config |
|
||
| R3 | Symbole non exporté oublié → erreur de lien `LNK2019` dans `LPPairSandbox.cpp` | liste §4.3 (8 symboles existants à exporter + 2 nouveaux) |
|
||
| R4 | `LifePlayEditorTools` en `bUseUnity = false` : aucune modification | — |
|
||
| R5 | `LPAnimMeasure` en compilation unity : aucun namespace anonyme avec noms identiques entre les 3 `.cpp` ne doit entrer en collision (ces fichiers étaient déjà dans l'unity de `LifePlay`) | si collision, ajouter `bUseUnity = false` au `Build.cs` |
|
||
| R6 | Les `.uasset` ne référencent pas ces classes C++ (aucune `UCLASS`/`USTRUCT` dans les 8 fichiers) : pas de redirecteur de classe `CoreRedirects` à écrire | — |
|
||
| R7 | `Tools/RetargetQuaternius.py` cite `LPPoseMeasure::WriteRetargetPose`/`LPSkeletonProfile::Identify` uniquement en commentaires | aucune action |
|
||
|
||
---
|
||
|
||
## 8. Ordre d'exécution suggéré (pour S2-T2)
|
||
|
||
1. Créer `Source/LPAnimMeasure/` + `LPAnimMeasure.Build.cs`, `LPAnimMeasure.h/.cpp`.
|
||
2. `git mv` des 8 fichiers (conserve l'historique).
|
||
3. Remplacer `LIFEPLAY_API` → `LPANIMMEASURE_API`, `LifePlay.h` → `LPAnimMeasure.h`, `LogLifePlay` → `LogLPAnimMeasure` dans les fichiers déplacés ; ajouter les exports manquants (<28>4.3) ; retirer l'include de `LPSandboxConfig.h` dans `LPAnimRedirect.cpp` et ajouter `SetUALRoot/GetUALRoot`.
|
||
4. `LifePlay.cpp` : `FLifePlayModule::StartupModule` → `SetUALRoot(...)`.
|
||
5. Mettre à jour `LifePlay.Build.cs`, `LifePlayEditorTools.Build.cs`, `LifePlay.uproject`, les deux `*.Target.cs`.
|
||
6. Regénérer le projet (`GenerateProjectFiles`) et compiler Editor + Game ; lancer la validation (commandlets `LPAnimEval`, `LPAnimCatalog`, `LPAnimTwist`) pour contrôler l'absence de régression.
|