diff --git a/Unreal/PS_AI_Agent/Content/MetaHumans/Animations/BodyBP.uasset b/Unreal/PS_AI_Agent/Content/MetaHumans/Animations/BodyBP.uasset new file mode 100644 index 0000000..c99bf00 Binary files /dev/null and b/Unreal/PS_AI_Agent/Content/MetaHumans/Animations/BodyBP.uasset differ diff --git a/Unreal/PS_AI_Agent/Content/MetaHumans/Animations/target.uasset b/Unreal/PS_AI_Agent/Content/MetaHumans/Animations/target.uasset new file mode 100644 index 0000000..6203785 Binary files /dev/null and b/Unreal/PS_AI_Agent/Content/MetaHumans/Animations/target.uasset differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsPostureComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsPostureComponent.cpp index b7fefda..939068e 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsPostureComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Agent_ElevenLabs/Source/PS_AI_Agent_ElevenLabs/Private/ElevenLabsPostureComponent.cpp @@ -17,6 +17,14 @@ static const FName EyeLookDownRight(TEXT("eyeLookDownRight")); static const FName EyeLookInRight(TEXT("eyeLookInRight")); static const FName EyeLookOutRight(TEXT("eyeLookOutRight")); +// ── ARKit full eye range (degrees) ────────────────────────────────────────── +// These represent the physical range of eye motion that maps to ARKit curve +// value 0→1. MaxEyeHorizontal/Vertical control the CASCADE threshold (when +// the head kicks in), but the visual eye deflection is always normalized by +// these fixed constants so the eye curves look correct at any threshold. +static constexpr float ARKitEyeRangeHorizontal = 30.0f; +static constexpr float ARKitEyeRangeVertical = 20.0f; + // ───────────────────────────────────────────────────────────────────────────── // Construction // ───────────────────────────────────────────────────────────────────────────── @@ -72,17 +80,19 @@ void UElevenLabsPostureComponent::UpdateEyeCurves(float EyeYaw, float EyePitch) CurrentEyeCurves.Reset(); // Horizontal: positive yaw = looking right + // Normalized by the fixed ARKit physical range, NOT MaxEyeHorizontal + // (which only controls the cascade threshold). if (EyeYaw > 0.0f) { // Looking right: left eye looks outward, right eye looks inward (nasal) - const float Value = FMath::Clamp(EyeYaw / MaxEyeHorizontal, 0.0f, 1.0f); + const float Value = FMath::Clamp(EyeYaw / ARKitEyeRangeHorizontal, 0.0f, 1.0f); CurrentEyeCurves.Add(EyeLookOutLeft, Value); CurrentEyeCurves.Add(EyeLookInRight, Value); } else if (EyeYaw < 0.0f) { // Looking left: left eye looks inward (nasal), right eye looks outward - const float Value = FMath::Clamp(-EyeYaw / MaxEyeHorizontal, 0.0f, 1.0f); + const float Value = FMath::Clamp(-EyeYaw / ARKitEyeRangeHorizontal, 0.0f, 1.0f); CurrentEyeCurves.Add(EyeLookInLeft, Value); CurrentEyeCurves.Add(EyeLookOutRight, Value); } @@ -90,13 +100,13 @@ void UElevenLabsPostureComponent::UpdateEyeCurves(float EyeYaw, float EyePitch) // Vertical: positive pitch = looking up if (EyePitch > 0.0f) { - const float Value = FMath::Clamp(EyePitch / MaxEyeVertical, 0.0f, 1.0f); + const float Value = FMath::Clamp(EyePitch / ARKitEyeRangeVertical, 0.0f, 1.0f); CurrentEyeCurves.Add(EyeLookUpLeft, Value); CurrentEyeCurves.Add(EyeLookUpRight, Value); } else if (EyePitch < 0.0f) { - const float Value = FMath::Clamp(-EyePitch / MaxEyeVertical, 0.0f, 1.0f); + const float Value = FMath::Clamp(-EyePitch / ARKitEyeRangeVertical, 0.0f, 1.0f); CurrentEyeCurves.Add(EyeLookDownLeft, Value); CurrentEyeCurves.Add(EyeLookDownRight, Value); } @@ -197,19 +207,29 @@ void UElevenLabsPostureComponent::TickComponent( TargetHeadYaw = 0.0f; } - // ── 6. HEAD: realign when eyes overflow (check against TARGET) ───── + // ── 6. HEAD: realign when eyes overflow (check against body TARGET) ── + // + // Head overflow is checked relative to where the BODY IS GOING + // (TargetBodyWorldYaw), not where it currently is. This prevents + // the head from overcompensating during body interpolation — + // otherwise the head turns to track while body catches up, then + // snaps back when body arrives (two-step animation artifact). - const float EyeDeltaYaw = DeltaYaw - TargetHeadYaw; + const float HeadDeltaYaw = FMath::FindDeltaAngleDegrees( + TargetBodyWorldYaw + MeshForwardYawOffset, TargetWorldYaw); + + const float EyeDeltaYaw = HeadDeltaYaw - TargetHeadYaw; if (FMath::Abs(EyeDeltaYaw) > MaxEyeHorizontal) { - TargetHeadYaw = FMath::Clamp(DeltaYaw, -MaxHeadYaw, MaxHeadYaw); + TargetHeadYaw = FMath::Clamp(HeadDeltaYaw, -MaxHeadYaw, MaxHeadYaw); } // Head smoothly interpolates toward its persistent target CurrentHeadYaw = FMath::FInterpTo(CurrentHeadYaw, TargetHeadYaw, DeltaTime, HeadInterpSpeed); - // Eyes = remaining gap (naturally decreases as head catches up) + // Eyes = remaining gap (during transients, eyes may sit at MaxEye while + // the head catches up — ARKit normalization keeps visual deflection small) CurrentEyeYaw = FMath::Clamp(DeltaYaw - CurrentHeadYaw, -MaxEyeHorizontal, MaxEyeHorizontal); // ── 5. PITCH: relative cascade (Eyes → Head, no body pitch) ──────── diff --git a/build Lancelot.bat b/build Lancelot.bat new file mode 100644 index 0000000..e26b11d --- /dev/null +++ b/build Lancelot.bat @@ -0,0 +1,35 @@ +@echo off +chcp 65001 >nul +title Build PS_AI_Agent + +echo ============================================================ +echo PS_AI_Agent - Compilation plugin ElevenLabs (UE 5.5) +echo ============================================================ +echo. +echo ATTENTION : Ferme l'Unreal Editor avant de continuer ! +echo (Les DLL seraient verrouillees et la compilation echouerait) +echo. +pause + +echo. +echo Compilation en cours... +echo (Seuls les .cpp modifies sont recompiles, ~16s) +echo. + +powershell.exe -Command "& 'C:\Program Files\Epic Games\UE_5.5\Engine\Build\BatchFiles\RunUAT.bat' BuildEditor -project='E:\ASTERION\GIT\PS_AI_Agent\Unreal\PS_AI_Agent\PS_AI_Agent.uproject' -notools -noP4 2>&1" + +echo. +if %ERRORLEVEL% == 0 ( + echo ============================================================ + echo SUCCES - Compilation terminee sans erreur. + echo Tu peux relancer l'Unreal Editor. + echo ============================================================ +) else ( + echo ============================================================ + echo ECHEC - Erreur de compilation (code %ERRORLEVEL%) + echo Consulte le log ci-dessus pour le detail. + echo ============================================================ +) + +echo. +pause