Projekt for SPIE - Avatar for safety briefing / managment event
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1377 lines
44 KiB

// Georgy Treshchev 2025.
#include "BlendRealisticMetaHumanLipSyncAnimNode.h"
#include "RuntimeMetaHumanLipSyncModule.h"
#include "Animation/AnimInstanceProxy.h"
#include "Misc/EngineVersionComparison.h"
namespace RuntimeLipSync_GuiToRawControlsUtils
{
constexpr int32 NumGuiControls = 174;
constexpr int32 NumRawControls = 251;
using GuiControlsArray = TArray<float, TFixedAllocator<NumGuiControls>>;
using RawControlsArray = TArray<float, TFixedAllocator<NumRawControls>>;
struct GuiToRawControlInfo
{
int32 InputIndex; // gui control
int32 OutputIndex; // raw control
float From;
float To;
float Slope;
float Cut;
};
const TSet<FString> EyesCurveNames = {
"CTRL_expressions_eyeBlinkL",
"CTRL_expressions_eyeBlinkR",
"CTRL_expressions_eyeLidPressL",
"CTRL_expressions_eyeLidPressR",
"CTRL_expressions_eyeWidenL",
"CTRL_expressions_eyeWidenR",
"CTRL_expressions_eyeSquintInnerL",
"CTRL_expressions_eyeSquintInnerR",
"CTRL_expressions_eyeCheekRaiseL",
"CTRL_expressions_eyeCheekRaiseR",
"CTRL_expressions_eyeFaceScrunchL",
"CTRL_expressions_eyeFaceScrunchR",
"CTRL_expressions_eyeUpperLidUpL",
"CTRL_expressions_eyeUpperLidUpR",
"CTRL_expressions_eyeRelaxL",
"CTRL_expressions_eyeRelaxR",
"CTRL_expressions_eyeLowerLidUpL",
"CTRL_expressions_eyeLowerLidUpR",
"CTRL_expressions_eyeLowerLidDownL",
"CTRL_expressions_eyeLowerLidDownR",
"CTRL_expressions_eyeLookUpL",
"CTRL_expressions_eyeLookUpR",
"CTRL_expressions_eyeLookDownL",
"CTRL_expressions_eyeLookDownR",
"CTRL_expressions_eyeLookLeftL",
"CTRL_expressions_eyeLookLeftR",
"CTRL_expressions_eyeLookRightL",
"CTRL_expressions_eyeLookRightR"
};
const TArray<FString> DefaultGuiNames = {
"CTRL_L_brow_down.ty",
"CTRL_R_brow_down.ty",
"CTRL_L_brow_lateral.ty",
"CTRL_R_brow_lateral.ty",
"CTRL_L_brow_raiseIn.ty",
"CTRL_R_brow_raiseIn.ty",
"CTRL_L_brow_raiseOut.ty",
"CTRL_R_brow_raiseOut.ty",
"CTRL_L_ear_up.ty",
"CTRL_R_ear_up.ty",
"CTRL_L_eye_blink.ty",
"CTRL_R_eye_blink.ty",
"CTRL_L_eye_lidPress.ty",
"CTRL_R_eye_lidPress.ty",
"CTRL_L_eye_squintInner.ty",
"CTRL_R_eye_squintInner.ty",
"CTRL_L_eye_cheekRaise.ty",
"CTRL_R_eye_cheekRaise.ty",
"CTRL_L_eye_faceScrunch.ty",
"CTRL_R_eye_faceScrunch.ty",
"CTRL_L_eye_eyelidU.ty",
"CTRL_R_eye_eyelidU.ty",
"CTRL_L_eye_eyelidD.ty",
"CTRL_R_eye_eyelidD.ty",
"CTRL_L_eye.ty",
"CTRL_R_eye.ty",
"CTRL_L_eye.tx",
"CTRL_R_eye.tx",
"CTRL_L_eye_pupil.ty",
"CTRL_R_eye_pupil.ty",
"CTRL_C_eye_parallelLook.ty",
"CTRL_L_eyelashes_tweakerIn.ty",
"CTRL_R_eyelashes_tweakerIn.ty",
"CTRL_L_eyelashes_tweakerOut.ty",
"CTRL_R_eyelashes_tweakerOut.ty",
"CTRL_L_nose.ty",
"CTRL_R_nose.ty",
"CTRL_L_nose.tx",
"CTRL_R_nose.tx",
"CTRL_L_nose_wrinkleUpper.ty",
"CTRL_R_nose_wrinkleUpper.ty",
"CTRL_L_nose_nasolabialDeepen.ty",
"CTRL_R_nose_nasolabialDeepen.ty",
"CTRL_L_mouth_suckBlow.ty",
"CTRL_R_mouth_suckBlow.ty",
"CTRL_L_mouth_lipsBlow.ty",
"CTRL_R_mouth_lipsBlow.ty",
"CTRL_C_mouth.ty",
"CTRL_C_mouth.tx",
"CTRL_L_mouth_upperLipRaise.ty",
"CTRL_R_mouth_upperLipRaise.ty",
"CTRL_L_mouth_lowerLipDepress.ty",
"CTRL_R_mouth_lowerLipDepress.ty",
"CTRL_L_mouth_cornerPull.ty",
"CTRL_R_mouth_cornerPull.ty",
"CTRL_L_mouth_stretch.ty",
"CTRL_R_mouth_stretch.ty",
"CTRL_L_mouth_stretchLipsClose.ty",
"CTRL_R_mouth_stretchLipsClose.ty",
"CTRL_L_mouth_dimple.ty",
"CTRL_R_mouth_dimple.ty",
"CTRL_L_mouth_cornerDepress.ty",
"CTRL_R_mouth_cornerDepress.ty",
"CTRL_L_mouth_pressU.ty",
"CTRL_R_mouth_pressU.ty",
"CTRL_L_mouth_pressD.ty",
"CTRL_R_mouth_pressD.ty",
"CTRL_L_mouth_purseU.ty",
"CTRL_R_mouth_purseU.ty",
"CTRL_L_mouth_purseD.ty",
"CTRL_R_mouth_purseD.ty",
"CTRL_L_mouth_towardsU.ty",
"CTRL_R_mouth_towardsU.ty",
"CTRL_L_mouth_towardsD.ty",
"CTRL_R_mouth_towardsD.ty",
"CTRL_L_mouth_funnelU.ty",
"CTRL_R_mouth_funnelU.ty",
"CTRL_L_mouth_funnelD.ty",
"CTRL_R_mouth_funnelD.ty",
"CTRL_L_mouth_lipsTogetherU.ty",
"CTRL_R_mouth_lipsTogetherU.ty",
"CTRL_L_mouth_lipsTogetherD.ty",
"CTRL_R_mouth_lipsTogetherD.ty",
"CTRL_L_mouth_lipBiteU.ty",
"CTRL_R_mouth_lipBiteU.ty",
"CTRL_L_mouth_lipBiteD.ty",
"CTRL_R_mouth_lipBiteD.ty",
"CTRL_L_mouth_tightenU.ty",
"CTRL_R_mouth_tightenU.ty",
"CTRL_L_mouth_tightenD.ty",
"CTRL_R_mouth_tightenD.ty",
"CTRL_L_mouth_lipsPressU.ty",
"CTRL_R_mouth_lipsPressU.ty",
"CTRL_L_mouth_sharpCornerPull.ty",
"CTRL_R_mouth_sharpCornerPull.ty",
"CTRL_C_mouth_stickyU.ty",
"CTRL_L_mouth_stickyInnerU.ty",
"CTRL_R_mouth_stickyInnerU.ty",
"CTRL_L_mouth_stickyOuterU.ty",
"CTRL_R_mouth_stickyOuterU.ty",
"CTRL_C_mouth_stickyD.ty",
"CTRL_L_mouth_stickyInnerD.ty",
"CTRL_R_mouth_stickyInnerD.ty",
"CTRL_L_mouth_stickyOuterD.ty",
"CTRL_R_mouth_stickyOuterD.ty",
"CTRL_L_mouth_lipSticky.ty",
"CTRL_R_mouth_lipSticky.ty",
"CTRL_L_mouth_pushPullU.ty",
"CTRL_R_mouth_pushPullU.ty",
"CTRL_L_mouth_pushPullD.ty",
"CTRL_R_mouth_pushPullD.ty",
"CTRL_L_mouth_thicknessU.ty",
"CTRL_R_mouth_thicknessU.ty",
"CTRL_L_mouth_thicknessD.ty",
"CTRL_R_mouth_thicknessD.ty",
"CTRL_L_mouth_thicknessInwardU.ty",
"CTRL_R_mouth_thicknessInwardU.ty",
"CTRL_L_mouth_thicknessInwardD.ty",
"CTRL_R_mouth_thicknessInwardD.ty",
"CTRL_L_mouth_cornerSharpnessU.ty",
"CTRL_R_mouth_cornerSharpnessU.ty",
"CTRL_L_mouth_cornerSharpnessD.ty",
"CTRL_R_mouth_cornerSharpnessD.ty",
"CTRL_L_mouth_lipsTowardsTeethU.ty",
"CTRL_R_mouth_lipsTowardsTeethU.ty",
"CTRL_L_mouth_lipsTowardsTeethD.ty",
"CTRL_R_mouth_lipsTowardsTeethD.ty",
"CTRL_C_mouth_lipShiftU.ty",
"CTRL_C_mouth_lipShiftD.ty",
"CTRL_L_mouth_lipsRollU.ty",
"CTRL_R_mouth_lipsRollU.ty",
"CTRL_L_mouth_lipsRollD.ty",
"CTRL_R_mouth_lipsRollD.ty",
"CTRL_L_mouth_corner.ty",
"CTRL_L_mouth_corner.tx",
"CTRL_R_mouth_corner.ty",
"CTRL_R_mouth_corner.tx",
"CTRL_C_tongue_inOut.ty",
"CTRL_C_tongue_move.ty",
"CTRL_C_tongue_move.tx",
"CTRL_C_tongue_press.ty",
"CTRL_C_tongue_wideNarrow.ty",
"CTRL_C_tongue_bendTwist.ty",
"CTRL_C_tongue_bendTwist.tx",
"CTRL_C_tongue_roll.ty",
"CTRL_C_tongue_tipMove.ty",
"CTRL_C_tongue_tipMove.tx",
"CTRL_C_tongue_thickThin.ty",
"CTRL_C_jaw.ty",
"CTRL_C_jaw.tx",
"CTRL_C_jaw_fwdBack.ty",
"CTRL_L_jaw_clench.ty",
"CTRL_R_jaw_clench.ty",
"CTRL_L_jaw_ChinRaiseU.ty",
"CTRL_R_jaw_ChinRaiseU.ty",
"CTRL_L_jaw_ChinRaiseD.ty",
"CTRL_R_jaw_ChinRaiseD.ty",
"CTRL_L_jaw_chinCompress.ty",
"CTRL_R_jaw_chinCompress.ty",
"CTRL_C_jaw_openExtreme.ty",
"CTRL_L_neck_stretch.ty",
"CTRL_R_neck_stretch.ty",
"CTRL_C_neck_swallow.ty",
"CTRL_L_neck_mastoidContract.ty",
"CTRL_R_neck_mastoidContract.ty",
"CTRL_neck_throatUpDown.ty",
"CTRL_neck_digastricUpDown.ty",
"CTRL_neck_throatExhaleInhale.ty",
"CTRL_C_teethU.ty",
"CTRL_C_teethU.tx",
"CTRL_C_teeth_fwdBackU.ty",
"CTRL_C_teethD.ty",
"CTRL_C_teethD.tx",
"CTRL_C_teeth_fwdBackD.ty",
};
const TArray<FString> DefaultRawControlNames = {
"CTRL_expressions_browDownL",
"CTRL_expressions_browDownR",
"CTRL_expressions_browLateralL",
"CTRL_expressions_browLateralR",
"CTRL_expressions_browRaiseInL",
"CTRL_expressions_browRaiseInR",
"CTRL_expressions_browRaiseOuterL",
"CTRL_expressions_browRaiseOuterR",
"CTRL_expressions_earUpL",
"CTRL_expressions_earUpR",
"CTRL_expressions_eyeBlinkL",
"CTRL_expressions_eyeBlinkR",
"CTRL_expressions_eyeLidPressL",
"CTRL_expressions_eyeLidPressR",
"CTRL_expressions_eyeWidenL",
"CTRL_expressions_eyeWidenR",
"CTRL_expressions_eyeSquintInnerL",
"CTRL_expressions_eyeSquintInnerR",
"CTRL_expressions_eyeCheekRaiseL",
"CTRL_expressions_eyeCheekRaiseR",
"CTRL_expressions_eyeFaceScrunchL",
"CTRL_expressions_eyeFaceScrunchR",
"CTRL_expressions_eyeUpperLidUpL",
"CTRL_expressions_eyeUpperLidUpR",
"CTRL_expressions_eyeRelaxL",
"CTRL_expressions_eyeRelaxR",
"CTRL_expressions_eyeLowerLidUpL",
"CTRL_expressions_eyeLowerLidUpR",
"CTRL_expressions_eyeLowerLidDownL",
"CTRL_expressions_eyeLowerLidDownR",
"CTRL_expressions_eyeLookUpL",
"CTRL_expressions_eyeLookUpR",
"CTRL_expressions_eyeLookDownL",
"CTRL_expressions_eyeLookDownR",
"CTRL_expressions_eyeLookLeftL",
"CTRL_expressions_eyeLookLeftR",
"CTRL_expressions_eyeLookRightL",
"CTRL_expressions_eyeLookRightR",
"CTRL_expressions_eyePupilWideL",
"CTRL_expressions_eyePupilWideR",
"CTRL_expressions_eyePupilNarrowL",
"CTRL_expressions_eyePupilNarrowR",
"CTRL_expressions_eyeParallelLookDirection",
"CTRL_expressions_eyelashesUpINL",
"CTRL_expressions_eyelashesUpINR",
"CTRL_expressions_eyelashesUpOUTL",
"CTRL_expressions_eyelashesUpOUTR",
"CTRL_expressions_eyelashesDownINL",
"CTRL_expressions_eyelashesDownINR",
"CTRL_expressions_eyelashesDownOUTL",
"CTRL_expressions_eyelashesDownOUTR",
"CTRL_expressions_noseWrinkleL",
"CTRL_expressions_noseWrinkleR",
"CTRL_expressions_noseWrinkleUpperL",
"CTRL_expressions_noseWrinkleUpperR",
"CTRL_expressions_noseNostrilDepressL",
"CTRL_expressions_noseNostrilDepressR",
"CTRL_expressions_noseNostrilDilateL",
"CTRL_expressions_noseNostrilDilateR",
"CTRL_expressions_noseNostrilCompressL",
"CTRL_expressions_noseNostrilCompressR",
"CTRL_expressions_noseNasolabialDeepenL",
"CTRL_expressions_noseNasolabialDeepenR",
"CTRL_expressions_mouthCheekSuckL",
"CTRL_expressions_mouthCheekSuckR",
"CTRL_expressions_mouthCheekBlowL",
"CTRL_expressions_mouthCheekBlowR",
"CTRL_expressions_mouthLipsBlowL",
"CTRL_expressions_mouthLipsBlowR",
"CTRL_expressions_mouthLeft",
"CTRL_expressions_mouthRight",
"CTRL_expressions_mouthUp",
"CTRL_expressions_mouthDown",
"CTRL_expressions_mouthUpperLipRaiseL",
"CTRL_expressions_mouthUpperLipRaiseR",
"CTRL_expressions_mouthLowerLipDepressL",
"CTRL_expressions_mouthLowerLipDepressR",
"CTRL_expressions_mouthCornerPullL",
"CTRL_expressions_mouthCornerPullR",
"CTRL_expressions_mouthStretchL",
"CTRL_expressions_mouthStretchR",
"CTRL_expressions_mouthStretchLipsCloseL",
"CTRL_expressions_mouthStretchLipsCloseR",
"CTRL_expressions_mouthDimpleL",
"CTRL_expressions_mouthDimpleR",
"CTRL_expressions_mouthCornerDepressL",
"CTRL_expressions_mouthCornerDepressR",
"CTRL_expressions_mouthPressUL",
"CTRL_expressions_mouthPressUR",
"CTRL_expressions_mouthPressDL",
"CTRL_expressions_mouthPressDR",
"CTRL_expressions_mouthLipsPurseUL",
"CTRL_expressions_mouthLipsPurseUR",
"CTRL_expressions_mouthLipsPurseDL",
"CTRL_expressions_mouthLipsPurseDR",
"CTRL_expressions_mouthLipsTowardsUL",
"CTRL_expressions_mouthLipsTowardsUR",
"CTRL_expressions_mouthLipsTowardsDL",
"CTRL_expressions_mouthLipsTowardsDR",
"CTRL_expressions_mouthFunnelUL",
"CTRL_expressions_mouthFunnelUR",
"CTRL_expressions_mouthFunnelDL",
"CTRL_expressions_mouthFunnelDR",
"CTRL_expressions_mouthLipsTogetherUL",
"CTRL_expressions_mouthLipsTogetherUR",
"CTRL_expressions_mouthLipsTogetherDL",
"CTRL_expressions_mouthLipsTogetherDR",
"CTRL_expressions_mouthUpperLipBiteL",
"CTRL_expressions_mouthUpperLipBiteR",
"CTRL_expressions_mouthLowerLipBiteL",
"CTRL_expressions_mouthLowerLipBiteR",
"CTRL_expressions_mouthLipsTightenUL",
"CTRL_expressions_mouthLipsTightenUR",
"CTRL_expressions_mouthLipsTightenDL",
"CTRL_expressions_mouthLipsTightenDR",
"CTRL_expressions_mouthLipsPressL",
"CTRL_expressions_mouthLipsPressR",
"CTRL_expressions_mouthSharpCornerPullL",
"CTRL_expressions_mouthSharpCornerPullR",
"CTRL_expressions_mouthStickyUC",
"CTRL_expressions_mouthStickyUINL",
"CTRL_expressions_mouthStickyUINR",
"CTRL_expressions_mouthStickyUOUTL",
"CTRL_expressions_mouthStickyUOUTR",
"CTRL_expressions_mouthStickyDC",
"CTRL_expressions_mouthStickyDINL",
"CTRL_expressions_mouthStickyDINR",
"CTRL_expressions_mouthStickyDOUTL",
"CTRL_expressions_mouthStickyDOUTR",
"CTRL_expressions_mouthLipsStickyLPh1",
"CTRL_expressions_mouthLipsStickyLPh2",
"CTRL_expressions_mouthLipsStickyLPh3",
"CTRL_expressions_mouthLipsStickyRPh1",
"CTRL_expressions_mouthLipsStickyRPh2",
"CTRL_expressions_mouthLipsStickyRPh3",
"CTRL_expressions_mouthLipsPushUL",
"CTRL_expressions_mouthLipsPushUR",
"CTRL_expressions_mouthLipsPushDL",
"CTRL_expressions_mouthLipsPushDR",
"CTRL_expressions_mouthLipsPullUL",
"CTRL_expressions_mouthLipsPullUR",
"CTRL_expressions_mouthLipsPullDL",
"CTRL_expressions_mouthLipsPullDR",
"CTRL_expressions_mouthLipsThinUL",
"CTRL_expressions_mouthLipsThinUR",
"CTRL_expressions_mouthLipsThinDL",
"CTRL_expressions_mouthLipsThinDR",
"CTRL_expressions_mouthLipsThickUL",
"CTRL_expressions_mouthLipsThickUR",
"CTRL_expressions_mouthLipsThickDL",
"CTRL_expressions_mouthLipsThickDR",
"CTRL_expressions_mouthLipsThinInwardUL",
"CTRL_expressions_mouthLipsThinInwardUR",
"CTRL_expressions_mouthLipsThinInwardDL",
"CTRL_expressions_mouthLipsThinInwardDR",
"CTRL_expressions_mouthLipsThickInwardUL",
"CTRL_expressions_mouthLipsThickInwardUR",
"CTRL_expressions_mouthLipsThickInwardDL",
"CTRL_expressions_mouthLipsThickInwardDR",
"CTRL_expressions_mouthCornerSharpenUL",
"CTRL_expressions_mouthCornerSharpenUR",
"CTRL_expressions_mouthCornerSharpenDL",
"CTRL_expressions_mouthCornerSharpenDR",
"CTRL_expressions_mouthCornerRounderUL",
"CTRL_expressions_mouthCornerRounderUR",
"CTRL_expressions_mouthCornerRounderDL",
"CTRL_expressions_mouthCornerRounderDR",
"CTRL_expressions_mouthUpperLipTowardsTeethL",
"CTRL_expressions_mouthUpperLipTowardsTeethR",
"CTRL_expressions_mouthLowerLipTowardsTeethL",
"CTRL_expressions_mouthLowerLipTowardsTeethR",
"CTRL_expressions_mouthUpperLipShiftLeft",
"CTRL_expressions_mouthUpperLipShiftRight",
"CTRL_expressions_mouthLowerLipShiftLeft",
"CTRL_expressions_mouthLowerLipShiftRight",
"CTRL_expressions_mouthUpperLipRollInL",
"CTRL_expressions_mouthUpperLipRollInR",
"CTRL_expressions_mouthUpperLipRollOutL",
"CTRL_expressions_mouthUpperLipRollOutR",
"CTRL_expressions_mouthLowerLipRollInL",
"CTRL_expressions_mouthLowerLipRollInR",
"CTRL_expressions_mouthLowerLipRollOutL",
"CTRL_expressions_mouthLowerLipRollOutR",
"CTRL_expressions_mouthCornerUpL",
"CTRL_expressions_mouthCornerUpR",
"CTRL_expressions_mouthCornerDownL",
"CTRL_expressions_mouthCornerDownR",
"CTRL_expressions_mouthCornerWideL",
"CTRL_expressions_mouthCornerWideR",
"CTRL_expressions_mouthCornerNarrowL",
"CTRL_expressions_mouthCornerNarrowR",
"CTRL_expressions_jawOpen",
"CTRL_expressions_jawLeft",
"CTRL_expressions_jawRight",
"CTRL_expressions_jawFwd",
"CTRL_expressions_jawBack",
"CTRL_expressions_jawClenchL",
"CTRL_expressions_jawClenchR",
"CTRL_expressions_jawChinRaiseDL",
"CTRL_expressions_jawChinRaiseDR",
"CTRL_expressions_jawChinRaiseUL",
"CTRL_expressions_jawChinRaiseUR",
"CTRL_expressions_jawChinCompressL",
"CTRL_expressions_jawChinCompressR",
"CTRL_expressions_jawOpenExtreme",
"CTRL_expressions_neckStretchL",
"CTRL_expressions_neckStretchR",
"CTRL_expressions_neckSwallowPh1",
"CTRL_expressions_neckSwallowPh2",
"CTRL_expressions_neckSwallowPh3",
"CTRL_expressions_neckSwallowPh4",
"CTRL_expressions_neckMastoidContractL",
"CTRL_expressions_neckMastoidContractR",
"CTRL_expressions_neckThroatDown",
"CTRL_expressions_neckThroatUp",
"CTRL_expressions_neckDigastricDown",
"CTRL_expressions_neckDigastricUp",
"CTRL_expressions_neckThroatExhale",
"CTRL_expressions_neckThroatInhale",
"CTRL_expressions_teethUpU",
"CTRL_expressions_teethUpD",
"CTRL_expressions_teethDownU",
"CTRL_expressions_teethDownD",
"CTRL_expressions_teethLeftU",
"CTRL_expressions_teethLeftD",
"CTRL_expressions_teethRightU",
"CTRL_expressions_teethRightD",
"CTRL_expressions_teethFwdU",
"CTRL_expressions_teethFwdD",
"CTRL_expressions_teethBackU",
"CTRL_expressions_teethBackD",
"CTRL_expressions_tongueUp",
"CTRL_expressions_tongueDown",
"CTRL_expressions_tongueLeft",
"CTRL_expressions_tongueRight",
"CTRL_expressions_tongueOut",
"CTRL_expressions_tongueIn",
"CTRL_expressions_tongueBendUp",
"CTRL_expressions_tongueBendDown",
"CTRL_expressions_tongueTwistLeft",
"CTRL_expressions_tongueTwistRight",
"CTRL_expressions_tongueTipUp",
"CTRL_expressions_tongueTipDown",
"CTRL_expressions_tongueTipLeft",
"CTRL_expressions_tongueTipRight",
"CTRL_expressions_tongueWide",
"CTRL_expressions_tongueNarrow",
"CTRL_expressions_tonguePress",
"CTRL_expressions_tongueRoll",
"CTRL_expressions_tongueThick",
"CTRL_expressions_tongueThin"
};
const TArray<GuiToRawControlInfo> GuiToRawMappings = {
{0, 0, 0.000000, 1.000000, 1.000000, 0.000000},
{1, 1, 0.000000, 1.000000, 1.000000, 0.000000},
{2, 2, 0.000000, 1.000000, 1.000000, 0.000000},
{3, 3, 0.000000, 1.000000, 1.000000, 0.000000},
{4, 4, 0.000000, 1.000000, 1.000000, 0.000000},
{5, 5, 0.000000, 1.000000, 1.000000, 0.000000},
{6, 6, 0.000000, 1.000000, 1.000000, 0.000000},
{7, 7, 0.000000, 1.000000, 1.000000, 0.000000},
{8, 8, 0.000000, 1.000000, 1.000000, 0.000000},
{9, 9, 0.000000, 1.000000, 1.000000, 0.000000},
{10, 10, 0.000000, 1.000000, 1.000000, 0.000000},
{11, 11, 0.000000, 1.000000, 1.000000, 0.000000},
{10, 14, -1.000000, 0.000000, -1.000000, 0.000000},
{11, 15, -1.000000, 0.000000, -1.000000, 0.000000},
{12, 12, 0.000000, 1.000000, 1.000000, 0.000000},
{13, 13, 0.000000, 1.000000, 1.000000, 0.000000},
{14, 16, 0.000000, 1.000000, 1.000000, 0.000000},
{15, 17, 0.000000, 1.000000, 1.000000, 0.000000},
{16, 18, 0.000000, 1.000000, 1.000000, 0.000000},
{17, 19, 0.000000, 1.000000, 1.000000, 0.000000},
{18, 20, 0.000000, 1.000000, 1.000000, 0.000000},
{19, 21, 0.000000, 1.000000, 1.000000, 0.000000},
{20, 22, -1.000000, 0.000000, -1.000000, 0.000000},
{21, 23, -1.000000, 0.000000, -1.000000, 0.000000},
{20, 24, 0.000000, 1.000000, 1.000000, 0.000000},
{21, 25, 0.000000, 1.000000, 1.000000, 0.000000},
{22, 28, -1.000000, 0.000000, -1.000000, 0.000000},
{23, 29, -1.000000, 0.000000, -1.000000, 0.000000},
{22, 26, 0.000000, 1.000000, 1.000000, 0.000000},
{23, 27, 0.000000, 1.000000, 1.000000, 0.000000},
{24, 30, 0.000000, 1.000000, 1.000000, 0.000000},
{25, 31, 0.000000, 1.000000, 1.000000, 0.000000},
{24, 32, -1.000000, 0.000000, -1.000000, 0.000000},
{25, 33, -1.000000, 0.000000, -1.000000, 0.000000},
{26, 34, 0.000000, 1.000000, 1.000000, 0.000000},
{27, 35, 0.000000, 1.000000, 1.000000, 0.000000},
{26, 36, -1.000000, 0.000000, -1.000000, 0.000000},
{27, 37, -1.000000, 0.000000, -1.000000, 0.000000},
{28, 38, 0.000000, 1.000000, 1.000000, 0.000000},
{29, 39, 0.000000, 1.000000, 1.000000, 0.000000},
{28, 40, -1.000000, 0.000000, -1.000000, 0.000000},
{29, 41, -1.000000, 0.000000, -1.000000, 0.000000},
{30, 42, 0.000000, 1.000000, 1.000000, 0.000000},
{31, 47, 0.000000, 1.000000, 1.000000, 0.000000},
{32, 48, 0.000000, 1.000000, 1.000000, 0.000000},
{33, 49, 0.000000, 1.000000, 1.000000, 0.000000},
{34, 50, 0.000000, 1.000000, 1.000000, 0.000000},
{31, 43, -1.000000, 0.000000, -1.000000, 0.000000},
{32, 44, -1.000000, 0.000000, -1.000000, 0.000000},
{33, 45, -1.000000, 0.000000, -1.000000, 0.000000},
{34, 46, -1.000000, 0.000000, -1.000000, 0.000000},
{35, 51, 0.000000, 1.000000, 1.000000, 0.000000},
{36, 52, 0.000000, 1.000000, 1.000000, 0.000000},
{35, 55, -1.000000, 0.000000, -1.000000, 0.000000},
{36, 56, -1.000000, 0.000000, -1.000000, 0.000000},
{37, 57, 0.000000, 1.000000, 1.000000, 0.000000},
{38, 58, 0.000000, 1.000000, 1.000000, 0.000000},
{37, 59, -1.000000, 0.000000, -1.000000, 0.000000},
{38, 60, -1.000000, 0.000000, -1.000000, 0.000000},
{39, 53, 0.000000, 1.000000, 1.000000, 0.000000},
{40, 54, 0.000000, 1.000000, 1.000000, 0.000000},
{41, 61, 0.000000, 1.000000, 1.000000, 0.000000},
{42, 62, 0.000000, 1.000000, 1.000000, 0.000000},
{43, 65, 0.000000, 1.000000, 1.000000, 0.000000},
{44, 66, 0.000000, 1.000000, 1.000000, 0.000000},
{43, 63, -1.000000, 0.000000, -1.000000, 0.000000},
{44, 64, -1.000000, 0.000000, -1.000000, 0.000000},
{45, 67, 0.000000, 1.000000, 1.000000, 0.000000},
{46, 68, 0.000000, 1.000000, 1.000000, 0.000000},
{47, 71, 0.000000, 1.000000, 1.000000, 0.000000},
{47, 72, -1.000000, 0.000000, -1.000000, 0.000000},
{48, 69, 0.000000, 1.000000, 1.000000, 0.000000},
{48, 70, -1.000000, 0.000000, -1.000000, 0.000000},
{49, 73, 0.000000, 1.000000, 1.000000, 0.000000},
{50, 74, 0.000000, 1.000000, 1.000000, 0.000000},
{51, 75, 0.000000, 1.000000, 1.000000, 0.000000},
{52, 76, 0.000000, 1.000000, 1.000000, 0.000000},
{53, 77, 0.000000, 1.000000, 1.000000, 0.000000},
{54, 78, 0.000000, 1.000000, 1.000000, 0.000000},
{55, 79, 0.000000, 1.000000, 1.000000, 0.000000},
{56, 80, 0.000000, 1.000000, 1.000000, 0.000000},
{57, 81, 0.000000, 1.000000, 1.000000, 0.000000},
{58, 82, 0.000000, 1.000000, 1.000000, 0.000000},
{59, 83, 0.000000, 1.000000, 1.000000, 0.000000},
{60, 84, 0.000000, 1.000000, 1.000000, 0.000000},
{61, 85, 0.000000, 1.000000, 1.000000, 0.000000},
{62, 86, 0.000000, 1.000000, 1.000000, 0.000000},
{63, 87, 0.000000, 1.000000, 1.000000, 0.000000},
{64, 88, 0.000000, 1.000000, 1.000000, 0.000000},
{65, 89, 0.000000, 1.000000, 1.000000, 0.000000},
{66, 90, 0.000000, 1.000000, 1.000000, 0.000000},
{67, 91, 0.000000, 1.000000, 1.000000, 0.000000},
{68, 92, 0.000000, 1.000000, 1.000000, 0.000000},
{69, 93, 0.000000, 1.000000, 1.000000, 0.000000},
{70, 94, 0.000000, 1.000000, 1.000000, 0.000000},
{71, 95, 0.000000, 1.000000, 1.000000, 0.000000},
{72, 96, 0.000000, 1.000000, 1.000000, 0.000000},
{73, 97, 0.000000, 1.000000, 1.000000, 0.000000},
{74, 98, 0.000000, 1.000000, 1.000000, 0.000000},
{75, 99, 0.000000, 1.000000, 1.000000, 0.000000},
{76, 100, 0.000000, 1.000000, 1.000000, 0.000000},
{77, 101, 0.000000, 1.000000, 1.000000, 0.000000},
{78, 102, 0.000000, 1.000000, 1.000000, 0.000000},
{79, 103, 0.000000, 1.000000, 1.000000, 0.000000},
{80, 104, 0.000000, 1.000000, 1.000000, 0.000000},
{81, 105, 0.000000, 1.000000, 1.000000, 0.000000},
{82, 106, 0.000000, 1.000000, 1.000000, 0.000000},
{83, 107, 0.000000, 1.000000, 1.000000, 0.000000},
{84, 108, 0.000000, 1.000000, 1.000000, 0.000000},
{85, 109, 0.000000, 1.000000, 1.000000, 0.000000},
{86, 110, 0.000000, 1.000000, 1.000000, 0.000000},
{87, 111, 0.000000, 1.000000, 1.000000, 0.000000},
{88, 112, 0.000000, 1.000000, 1.000000, 0.000000},
{89, 113, 0.000000, 1.000000, 1.000000, 0.000000},
{90, 114, 0.000000, 1.000000, 1.000000, 0.000000},
{91, 115, 0.000000, 1.000000, 1.000000, 0.000000},
{92, 116, 0.000000, 1.000000, 1.000000, 0.000000},
{93, 117, 0.000000, 1.000000, 1.000000, 0.000000},
{94, 118, 0.000000, 1.000000, 1.000000, 0.000000},
{95, 119, 0.000000, 1.000000, 1.000000, 0.000000},
{96, 120, 0.000000, 1.000000, 1.000000, 0.000000},
{97, 121, 0.000000, 1.000000, 1.000000, 0.000000},
{98, 122, 0.000000, 1.000000, 1.000000, 0.000000},
{99, 123, 0.000000, 1.000000, 1.000000, 0.000000},
{100, 124, 0.000000, 1.000000, 1.000000, 0.000000},
{101, 125, 0.000000, 1.000000, 1.000000, 0.000000},
{102, 126, 0.000000, 1.000000, 1.000000, 0.000000},
{103, 127, 0.000000, 1.000000, 1.000000, 0.000000},
{104, 128, 0.000000, 1.000000, 1.000000, 0.000000},
{105, 129, 0.000000, 0.330000, 3.030303, 0.000000},
{105, 129, 0.330000, 0.660000, -3.030303, 2.000000},
{105, 130, 0.330000, 0.660000, 3.030303, -1.000000},
{105, 130, 0.660000, 1.000000, -2.941176, 2.941176},
{105, 131, 0.660000, 1.000000, 2.941176, -1.941176},
{106, 132, 0.000000, 0.330000, 3.030303, 0.000000},
{106, 132, 0.330000, 0.660000, -3.030303, 2.000000},
{106, 133, 0.330000, 0.660000, 3.030303, -1.000000},
{106, 133, 0.660000, 1.000000, -2.941176, 2.941176},
{106, 134, 0.660000, 1.000000, 2.941176, -1.941176},
{107, 135, 0.000000, 1.000000, 1.000000, 0.000000},
{108, 136, 0.000000, 1.000000, 1.000000, 0.000000},
{109, 137, 0.000000, 1.000000, 1.000000, 0.000000},
{110, 138, 0.000000, 1.000000, 1.000000, 0.000000},
{107, 139, -1.000000, 0.000000, -1.000000, 0.000000},
{108, 140, -1.000000, 0.000000, -1.000000, 0.000000},
{109, 141, -1.000000, 0.000000, -1.000000, 0.000000},
{110, 142, -1.000000, 0.000000, -1.000000, 0.000000},
{111, 143, 0.000000, 1.000000, 1.000000, 0.000000},
{112, 144, 0.000000, 1.000000, 1.000000, 0.000000},
{113, 145, 0.000000, 1.000000, 1.000000, 0.000000},
{114, 146, 0.000000, 1.000000, 1.000000, 0.000000},
{111, 147, -1.000000, 0.000000, -1.000000, 0.000000},
{112, 148, -1.000000, 0.000000, -1.000000, 0.000000},
{113, 149, -1.000000, 0.000000, -1.000000, 0.000000},
{114, 150, -1.000000, 0.000000, -1.000000, 0.000000},
{115, 151, 0.000000, 1.000000, 1.000000, 0.000000},
{116, 152, 0.000000, 1.000000, 1.000000, 0.000000},
{117, 153, 0.000000, 1.000000, 1.000000, 0.000000},
{118, 154, 0.000000, 1.000000, 1.000000, 0.000000},
{115, 155, -1.000000, 0.000000, -1.000000, 0.000000},
{116, 156, -1.000000, 0.000000, -1.000000, 0.000000},
{117, 157, -1.000000, 0.000000, -1.000000, 0.000000},
{118, 158, -1.000000, 0.000000, -1.000000, 0.000000},
{119, 159, 0.000000, 1.000000, 1.000000, 0.000000},
{120, 160, 0.000000, 1.000000, 1.000000, 0.000000},
{121, 161, 0.000000, 1.000000, 1.000000, 0.000000},
{122, 162, 0.000000, 1.000000, 1.000000, 0.000000},
{119, 163, -1.000000, 0.000000, -1.000000, 0.000000},
{120, 164, -1.000000, 0.000000, -1.000000, 0.000000},
{121, 165, -1.000000, 0.000000, -1.000000, 0.000000},
{122, 166, -1.000000, 0.000000, -1.000000, 0.000000},
{123, 167, 0.000000, 1.000000, 1.000000, 0.000000},
{124, 168, 0.000000, 1.000000, 1.000000, 0.000000},
{125, 169, 0.000000, 1.000000, 1.000000, 0.000000},
{126, 170, 0.000000, 1.000000, 1.000000, 0.000000},
{127, 171, 0.000000, 1.000000, 1.000000, 0.000000},
{127, 172, -1.000000, 0.000000, -1.000000, 0.000000},
{128, 173, 0.000000, 1.000000, 1.000000, 0.000000},
{128, 174, -1.000000, 0.000000, -1.000000, 0.000000},
{129, 175, 0.000000, 1.000000, 1.000000, 0.000000},
{130, 176, 0.000000, 1.000000, 1.000000, 0.000000},
{131, 179, 0.000000, 1.000000, 1.000000, 0.000000},
{132, 180, 0.000000, 1.000000, 1.000000, 0.000000},
{129, 177, -1.000000, 0.000000, -1.000000, 0.000000},
{130, 178, -1.000000, 0.000000, -1.000000, 0.000000},
{131, 181, -1.000000, 0.000000, -1.000000, 0.000000},
{132, 182, -1.000000, 0.000000, -1.000000, 0.000000},
{133, 183, 0.000000, 1.000000, 1.000000, 0.000000},
{133, 185, -1.000000, 0.000000, -1.000000, 0.000000},
{134, 187, 0.000000, 1.000000, 1.000000, 0.000000},
{134, 189, -1.000000, 0.000000, -1.000000, 0.000000},
{135, 184, 0.000000, 1.000000, 1.000000, 0.000000},
{135, 186, -1.000000, 0.000000, -1.000000, 0.000000},
{136, 188, 0.000000, 1.000000, 1.000000, 0.000000},
{136, 190, -1.000000, 0.000000, -1.000000, 0.000000},
{137, 236, 0.000000, 1.000000, 1.000000, 0.000000},
{137, 235, -1.000000, 0.000000, -1.000000, 0.000000},
{138, 231, 0.000000, 1.000000, 1.000000, 0.000000},
{138, 232, -1.000000, 0.000000, -1.000000, 0.000000},
{139, 233, 0.000000, 1.000000, 1.000000, 0.000000},
{139, 234, -1.000000, 0.000000, -1.000000, 0.000000},
{140, 247, 0.000000, 1.000000, 1.000000, 0.000000},
{141, 245, 0.000000, 1.000000, 1.000000, 0.000000},
{141, 246, -1.000000, 0.000000, -1.000000, 0.000000},
{142, 237, 0.000000, 1.000000, 1.000000, 0.000000},
{142, 238, -1.000000, 0.000000, -1.000000, 0.000000},
{143, 239, 0.000000, 1.000000, 1.000000, 0.000000},
{143, 240, -1.000000, 0.000000, -1.000000, 0.000000},
{144, 248, 0.000000, 1.000000, 1.000000, 0.000000},
{145, 241, 0.000000, 1.000000, 1.000000, 0.000000},
{145, 242, -1.000000, 0.000000, -1.000000, 0.000000},
{146, 243, 0.000000, 1.000000, 1.000000, 0.000000},
{146, 244, -1.000000, 0.000000, -1.000000, 0.000000},
{147, 249, 0.000000, 1.000000, 1.000000, 0.000000},
{147, 250, -1.000000, 0.000000, -1.000000, 0.000000},
{148, 191, 0.000000, 1.000000, 1.000000, 0.000000},
{149, 192, -1.000000, 0.000000, -1.000000, 0.000000},
{149, 193, 0.000000, 1.000000, 1.000000, 0.000000},
{150, 194, -1.000000, 0.000000, -1.000000, 0.000000},
{150, 195, 0.000000, 1.000000, 1.000000, 0.000000},
{151, 196, 0.000000, 1.000000, 1.000000, 0.000000},
{152, 197, 0.000000, 1.000000, 1.000000, 0.000000},
{153, 200, 0.000000, 1.000000, 1.000000, 0.000000},
{154, 201, 0.000000, 1.000000, 1.000000, 0.000000},
{155, 198, 0.000000, 1.000000, 1.000000, 0.000000},
{156, 199, 0.000000, 1.000000, 1.000000, 0.000000},
{157, 202, 0.000000, 1.000000, 1.000000, 0.000000},
{158, 203, 0.000000, 1.000000, 1.000000, 0.000000},
{159, 204, 0.000000, 1.000000, 1.000000, 0.000000},
{160, 205, 0.000000, 1.000000, 1.000000, 0.000000},
{161, 206, 0.000000, 1.000000, 1.000000, 0.000000},
{162, 207, 0.000000, 0.200000, 5.000000, 0.000000},
{162, 207, 0.200000, 0.400000, -5.000000, 2.000000},
{162, 208, 0.200000, 0.400000, 5.000000, -1.000000},
{162, 208, 0.400000, 0.600000, -5.000000, 3.000000},
{162, 209, 0.400000, 0.600000, 5.000000, -2.000000},
{162, 209, 0.600000, 0.800000, -5.000000, 4.000000},
{162, 210, 0.600000, 0.800000, 5.000000, -3.000000},
{162, 210, 0.800000, 1.000000, -5.000000, 5.000000},
{163, 211, 0.000000, 1.000000, 1.000000, 0.000000},
{164, 212, 0.000000, 1.000000, 1.000000, 0.000000},
{165, 213, -1.000000, 0.000000, -1.000000, 0.000000},
{165, 214, 0.000000, 1.000000, 1.000000, 0.000000},
{166, 215, -1.000000, 0.000000, -1.000000, 0.000000},
{166, 216, 0.000000, 1.000000, 1.000000, 0.000000},
{167, 217, -1.000000, 0.000000, -1.000000, 0.000000},
{167, 218, 0.000000, 1.000000, 1.000000, 0.000000},
{168, 219, 0.000000, 1.000000, 1.000000, 0.000000},
{168, 221, -1.000000, 0.000000, -1.000000, 0.000000},
{169, 223, 0.000000, 1.000000, 1.000000, 0.000000},
{169, 225, -1.000000, 0.000000, -1.000000, 0.000000},
{170, 229, 0.000000, 1.000000, 1.000000, 0.000000},
{170, 227, -1.000000, 0.000000, -1.000000, 0.000000},
{171, 220, 0.000000, 1.000000, 1.000000, 0.000000},
{171, 222, -1.000000, 0.000000, -1.000000, 0.000000},
{172, 224, 0.000000, 1.000000, 1.000000, 0.000000},
{172, 226, -1.000000, 0.000000, -1.000000, 0.000000},
{173, 230, 0.000000, 1.000000, 1.000000, 0.000000},
{173, 228, -1.000000, 0.000000, -1.000000, 0.000000},
};
const TArray<TPair<float, float>> GuiControlRanges = {
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{0.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
{-1.000000, 1.000000},
};
const GuiControlsArray DefaultGuiValues{
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
1.000000,
1.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
0.000000,
};
GuiControlsArray ConvertGuiControlsToArray(const TMap<FString, float>& InGuiControls)
{
GuiControlsArray GuiControls;
GuiControls.Reserve(NumGuiControls);
for (int32 GuiNameIndex = 0; GuiNameIndex < NumGuiControls; ++GuiNameIndex)
{
if (const float* GuiValue = InGuiControls.Find(DefaultGuiNames[GuiNameIndex]))
{
GuiControls.Add(*GuiValue);
}
else
{
GuiControls.Add(DefaultGuiValues[GuiNameIndex]);
}
}
return GuiControls;
}
TMap<FString, float> ConvertRawControlsToMap(const RawControlsArray& InRawControls)
{
TMap<FString, float> RawControlsMap;
RawControlsMap.Reserve(NumRawControls);
for (int32 RawNameIndex = 0; RawNameIndex < NumRawControls; ++RawNameIndex)
{
RawControlsMap.Add(DefaultRawControlNames[RawNameIndex], InRawControls[RawNameIndex]);
}
return RawControlsMap;
}
TMap<FString, float> ConvertGuiToRawControls(const TMap<FString, float>& InGuiControls)
{
// Convert gui controls to array with default values if needed
const GuiControlsArray GuiControlsArray = ConvertGuiControlsToArray(InGuiControls);
RawControlsArray RawControlsArray;
RawControlsArray.Init(0.0, NumRawControls);
for (int32 MappingIndex = 0; MappingIndex < GuiToRawMappings.Num(); ++MappingIndex)
{
const GuiToRawControlInfo& GuiMapping = GuiToRawMappings[MappingIndex];
const float RangeStart = GuiControlRanges[GuiMapping.InputIndex].Key;
const float RangeEnd = GuiControlRanges[GuiMapping.InputIndex].Value;
const float GuiValue = GuiControlsArray[GuiMapping.InputIndex];
const bool bIsBelowRange = GuiMapping.From == RangeStart && GuiValue < GuiMapping.From;
const bool bIsAboveRange = GuiMapping.To == RangeEnd && GuiValue >= GuiMapping.To;
if ((GuiMapping.From <= GuiValue) && (GuiValue < GuiMapping.To))
{
RawControlsArray[GuiMapping.OutputIndex] += GuiMapping.Slope * GuiValue + GuiMapping.Cut;
}
else if (bIsBelowRange)
{
RawControlsArray[GuiMapping.OutputIndex] += GuiMapping.Slope * GuiMapping.From + GuiMapping.Cut; // clamp to minimum range value
}
else if (bIsAboveRange)
{
RawControlsArray[GuiMapping.OutputIndex] += GuiMapping.Slope * GuiMapping.To + GuiMapping.Cut; // clamp to maximum range value
}
}
TMap<FString, float> OutRawControls = ConvertRawControlsToMap(RawControlsArray);
return OutRawControls;
}
}
FAnimNode_BlendRealisticMetaHumanLipSync::FAnimNode_BlendRealisticMetaHumanLipSync()
{
// Initialize with default values
TArray<FString> ControlNames = URealisticMetaHumanLipSyncGenerator::GetControlNames();
for (const FString& ControlName : ControlNames)
{
TargetControlValues.Add(ControlName, 0.0f);
CurrentControlValues.Add(ControlName, 0.0f);
IdleStateValues.Add(ControlName, 0.0f);
}
}
void FAnimNode_BlendRealisticMetaHumanLipSync::Initialize_AnyThread(const FAnimationInitializeContext& Context)
{
SourcePose.Initialize(Context);
}
void FAnimNode_BlendRealisticMetaHumanLipSync::CacheBones_AnyThread(const FAnimationCacheBonesContext& Context)
{
SourcePose.CacheBones(Context);
}
void FAnimNode_BlendRealisticMetaHumanLipSync::Update_AnyThread(const FAnimationUpdateContext& Context)
{
SourcePose.Update(Context);
GetEvaluateGraphExposedInputs().Execute(Context);
// Get the latest control values from the generator
if (LipSyncGenerator.IsValid())
{
TMap<FString, float> NewControlValues = LipSyncGenerator->GetControlValues();
// Check if control values have changed
bool bValuesChanged = false;
for (const auto& Pair : NewControlValues)
{
float* OldValue = TargetControlValues.Find(Pair.Key);
if (!OldValue || FMath::Abs(*OldValue - Pair.Value) > KINDA_SMALL_NUMBER)
{
bValuesChanged = true;
break;
}
}
if (bValuesChanged)
{
// Update target values and reset timer
TargetControlValues = NewControlValues;
TimeSinceLastChange = 0.0f;
// Update idle state preservation with current active expressions
UpdateIdleStatePreservation();
}
else
{
// Increment time since last change
TimeSinceLastChange += Context.GetDeltaTime();
// Reset to idle state if no change for specified duration
if (TimeSinceLastChange >= ResetTime)
{
// Instead of directly setting values, smoothly transition to idle state
for (auto& Pair : TargetControlValues)
{
float IdleValue;
if (bPreserveIdleState && ShouldPreserveControl(Pair.Key))
{
// Use preserved idle state value instead of zero
IdleValue = IdleStateValues[Pair.Key];
}
else
{
// Reset to neutral for non-preserved controls
IdleValue = 0.0f;
}
// Only update target if it's different from current target
// This prevents constant updates during idle state
if (FMath::Abs(Pair.Value - IdleValue) > KINDA_SMALL_NUMBER)
{
Pair.Value = IdleValue;
}
}
// Update the generator with the new idle target values
LipSyncGenerator->SetControlValues(TargetControlValues);
}
}
}
// Smoothly interpolate current values towards target values
// This interpolation applies to both active speech and idle transitions
const float DeltaTime = Context.GetDeltaTime();
// Use different interpolation speeds for active speech vs idle transitions
const float EffectiveInterpolationSpeed = (TimeSinceLastChange >= ResetTime) ? IdleInterpolationSpeed : InterpolationSpeed;
for (auto& Pair : CurrentControlValues)
{
const FString& ControlName = Pair.Key;
float& CurrentValue = Pair.Value;
float TargetValue = 0.0f;
if (float* FoundValue = TargetControlValues.Find(ControlName))
{
TargetValue = *FoundValue;
}
CurrentValue = FMath::FInterpTo(CurrentValue, TargetValue, DeltaTime, EffectiveInterpolationSpeed);
}
}
void FAnimNode_BlendRealisticMetaHumanLipSync::Evaluate_AnyThread(FPoseContext& Output)
{
// Evaluate the source pose
SourcePose.Evaluate(Output);
const TMap<FString, float> SolverControlMap = RuntimeLipSync_GuiToRawControlsUtils::ConvertGuiToRawControls(CurrentControlValues);
// Apply the control values to the animation curves
for (const auto& Pair : SolverControlMap)
{
if (!RuntimeLipSync_GuiToRawControlsUtils::EyesCurveNames.Find(Pair.Key))
{
#if UE_VERSION_OLDER_THAN(5, 3, 0)
USkeleton* Skeleton = Output.AnimInstanceProxy->GetSkeleton();
SmartName::UID_Type NameUID = Skeleton->GetUIDByName(USkeleton::AnimCurveMappingName, *Pair.Key);
if (NameUID == SmartName::MaxUID)
{
continue;
}
Output.Curve.Set(NameUID, Pair.Value);
#else
Output.Curve.Set(*Pair.Key, Pair.Value);
#endif
}
}
}
void FAnimNode_BlendRealisticMetaHumanLipSync::GatherDebugData(FNodeDebugData& DebugData)
{
FString DebugLine = FString::Printf(TEXT("Blend Realistic MetaHuman Lip Sync"));
DebugData.AddDebugItem(DebugLine);
SourcePose.GatherDebugData(DebugData.BranchFlow(1.0f));
}
bool FAnimNode_BlendRealisticMetaHumanLipSync::ShouldPreserveControl(const FString& ControlName) const
{
if (!bPreserveIdleState)
{
return false;
}
// Eye-related controls
if (bPreserveEyeExpressions && (
ControlName.Contains(TEXT("eye")) ||
ControlName.Contains(TEXT("Eye")) ||
ControlName.Contains(TEXT("eyelid")) ||
ControlName.Contains(TEXT("eyelash"))
))
{
return true;
}
// Brow-related controls
if (bPreserveBrowExpressions && (
ControlName.Contains(TEXT("brow")) ||
ControlName.Contains(TEXT("Brow"))
))
{
return true;
}
// Mouth shape controls (excluding speech-specific movements)
if (bPreserveMouthShape && (
ControlName.Contains(TEXT("mouth")) ||
ControlName.Contains(TEXT("Mouth"))
))
{
// Exclude speech-specific mouth controls that should reset
if (ControlName.Contains(TEXT("tongue")) ||
ControlName.Contains(TEXT("Tongue")) ||
ControlName.Contains(TEXT("jaw")) ||
ControlName.Contains(TEXT("Jaw")))
{
return false;
}
return true;
}
return false;
}
void FAnimNode_BlendRealisticMetaHumanLipSync::UpdateIdleStatePreservation()
{
if (!bPreserveIdleState)
{
return;
}
// Update idle state values with current non-zero values that should be preserved
for (const auto& Pair : CurrentControlValues)
{
if (ShouldPreserveControl(Pair.Key) && FMath::Abs(Pair.Value) > KINDA_SMALL_NUMBER)
{
IdleStateValues[Pair.Key] = Pair.Value;
}
}
}