// Copyright Epic Games, Inc. All Rights Reserved. #include "Speech2Face.h" #include "Speech2FaceInternal.h" #include "DataDefs.h" #if WITH_EDITOR FSpeech2Face::~FSpeech2Face() = default; TUniquePtr FSpeech2Face::Create() { FAudioDrivenAnimationModels DefaultModels; return FSpeech2Face::Create(DefaultModels); } TUniquePtr FSpeech2Face::Create(const FAudioDrivenAnimationModels& InModels) { TUniquePtr Pimpl = FSpeech2FaceInternal::Create(InModels); if (!Pimpl) { return nullptr; } return TUniquePtr(new FSpeech2Face(MoveTemp(Pimpl))); } void FSpeech2Face::SetMood(const EAudioDrivenAnimationMood& InMood) { Pimpl->SetMood(InMood); } void FSpeech2Face::SetMoodIntensity(const float InMoodIntensity) { Pimpl->SetMoodIntensity(InMoodIntensity); } FSpeech2Face::FSpeech2Face(TUniquePtr InPimpl) : Pimpl(MoveTemp(InPimpl)) { check(Pimpl); } bool FSpeech2Face::GenerateFaceAnimation(const FAudioParams& InAudioParams, float InOutputAnimationFps, bool bInGenerateBlinks, TFunction InShouldCancelCallback, TArray& OutAnimation, TArray& OutHeadAnimation) { return Pimpl->GenerateFaceAnimation(InAudioParams, InOutputAnimationFps, bInGenerateBlinks, InShouldCancelCallback, OutAnimation, OutHeadAnimation); } #endif //WITH_EDITOR namespace UE::MetaHuman { void ReplaceHeadGuiControlsWithRaw(TMap& OutControlMap) { for (const TPair& GuiToRaw : HeadControlsGuiToRawLookupTable) { float ControlValue; const bool bWasFound = OutControlMap.RemoveAndCopyValue(GuiToRaw.Key, ControlValue); if (bWasFound) { OutControlMap.Emplace(GuiToRaw.Value, ControlValue); } } } TSet GetMouthOnlyRawControls() { return MouthOnlyRawControls; } FTransform GetHeadPoseTransformFromRawControls(const TMap& InAnimationData) { const float* Rx = InAnimationData.Find(TEXT("mha_head_ik_ctrl.rx")); check(Rx); const float* Ry = InAnimationData.Find(TEXT("mha_head_ik_ctrl.ry")); check(Ry); const float* Rz = InAnimationData.Find(TEXT("mha_head_ik_ctrl.rz")); check(Rz); const float* Tx = InAnimationData.Find(TEXT("mha_head_ik_ctrl.tx")); check(Tx); const float* Ty = InAnimationData.Find(TEXT("mha_head_ik_ctrl.ty")); check(Ty); const float* Tz = InAnimationData.Find(TEXT("mha_head_ik_ctrl.tz")); check(Tz); if (Rx && Ry && Rz && Tx && Ty && Tz) { // We need to account for differences between the model and UE coordinate systems FRotator Rotator; Rotator.Roll = *Rx; Rotator.Pitch = *Ry * -1.0; Rotator.Yaw = *Rz * -1.0; FVector Translation; Translation.X = *Tx; Translation.Y = *Ty * -1.0; Translation.Z = *Tz; FTransform HeadPoseTransform = FTransform(Rotator, Translation); return HeadPoseTransform; } return FTransform::Identity; } } // namespace UE::MetaHuman