diff --git a/.gitignore b/.gitignore index d8ac56a..b83b726 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ SourceArt/**/*.tga # Binary Files Binaries/* Plugins/*/Binaries/* +Package/* # Builds Build/* diff --git a/.vsconfig b/.vsconfig new file mode 100644 index 0000000..4db64f2 --- /dev/null +++ b/.vsconfig @@ -0,0 +1,17 @@ +{ + "version": "1.0", + "components": [ + "Microsoft.Net.Component.4.6.2.TargetingPack", + "Microsoft.VisualStudio.Component.VC.14.33.17.3.ARM64", + "Microsoft.VisualStudio.Component.VC.14.33.17.3.x86.x64", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64", + "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", + "Microsoft.VisualStudio.Component.Windows10SDK", + "Microsoft.VisualStudio.Workload.CoreEditor", + "Microsoft.VisualStudio.Workload.ManagedDesktop", + "Microsoft.VisualStudio.Workload.NativeCrossPlat", + "Microsoft.VisualStudio.Workload.NativeDesktop", + "Microsoft.VisualStudio.Workload.NativeGame", + "Microsoft.VisualStudio.Workload.Universal" + ] +} diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index 9cfd521..8ae783b 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -77,3 +77,45 @@ ChaosSettings=(DefaultThreadingModel=DedicatedThread,DedicatedThreadTickMode=Var [/Script/Engine.RendererSettings] r.DefaultFeature.AutoExposure=True +[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings] +bEnablePlugin=True +bAllowNetworkConnection=True +SecurityToken=8455596D433443C29879C1BCC83427BC +bIncludeInShipping=False +bAllowExternalStartInShipping=False +bCompileAFSProject=False +bUseCompression=False +bLogFiles=False +bReportStats=False +ConnectionType=USBOnly +bUseManualIPAddress=False +ManualIPAddress= + +[/Script/WindowsTargetPlatform.WindowsTargetSettings] +Compiler=Default +-TargetedRHIs=PCD3D_SM5 ++TargetedRHIs=PCD3D_SM5 ++TargetedRHIs=SF_VULKAN_SM5 +DefaultGraphicsRHI=DefaultGraphicsRHI_Default +AudioSampleRate=48000 +AudioCallbackBufferFrameSize=1024 +AudioNumBuffersToEnqueue=1 +AudioMaxChannels=0 +AudioNumSourceWorkers=4 +SpatializationPlugin= +SourceDataOverridePlugin= +ReverbPlugin= +OcclusionPlugin= +CompressionOverrides=(bOverrideCompressionTimes=False,DurationThreshold=5.000000,MaxNumRandomBranches=0,SoundCueQualityIndex=0) +CacheSizeKB=65536 +MaxChunkSizeOverrideKB=0 +bResampleForDevice=False +MaxSampleRate=48000.000000 +HighSampleRate=32000.000000 +MedSampleRate=24000.000000 +LowSampleRate=12000.000000 +MinSampleRate=8000.000000 +CompressionQualityModifier=1.000000 +AutoStreamingThreshold=0.000000 +SoundCueCookQualityIndex=-1 + diff --git a/Config/DefaultGame.ini b/Config/DefaultGame.ini index b0f8e34..98feff6 100644 --- a/Config/DefaultGame.ini +++ b/Config/DefaultGame.ini @@ -1,7 +1,24 @@ -[/Script/EngineSettings.GeneralProjectSettings] -ProjectID=C8EDD9AE4FAEB015ABE2FD8D8CB51B16 - -[/Script/UnrealEd.ProjectPackagingSettings] -IncludeDebugFiles=True -IncludeCrashReporter=True - +[/Script/EngineSettings.GeneralProjectSettings] +ProjectID=C8EDD9AE4FAEB015ABE2FD8D8CB51B16 + +[/Script/UnrealEd.ProjectPackagingSettings] +IncludeDebugFiles=True +IncludeCrashReporter=True + +[/Script/LiveLink.LiveLinkSettings] +-DefaultRoleSettings=(Role=Class'/Script/LiveLink.LiveLinkAnimationRole', FrameInterpolationProcessor=Class'/Script/LiveLink.LiveLinkAnimationFrameInterpolationProcessor') ++DefaultRoleSettings=(Role=None,SettingClass=/Script/CoreUObject.Class'"/Script/LiveLinkInterface.LiveLinkSubjectSettings"',FrameInterpolationProcessor=/Script/CoreUObject.Class'"/Script/LiveLink.LiveLinkAnimationFrameInterpolationProcessor"',FramePreProcessors=) +FrameInterpolationProcessor=/Script/CoreUObject.Class'/Script/LiveLink.LiveLinkBasicFrameInterpolationProcessor' +DefaultLiveLinkPreset=/Game/NewLiveLinkPreset.NewLiveLinkPreset +ClockOffsetCorrectionStep=0.000100 +DefaultMessageBusSourceMode=EngineTime +MessageBusPingRequestFrequency=1.000000 +MessageBusHeartbeatFrequency=1.000000 +MessageBusHeartbeatTimeout=2.000000 +MessageBusTimeBeforeRemovingInactiveSource=30.000000 +TimeWithoutFrameToBeConsiderAsInvalid=0.500000 +ValidColor=(R=0.000000,G=1.000000,B=0.000000,A=1.000000) +InvalidColor=(R=1.000000,G=1.000000,B=0.000000,A=1.000000) +TextSizeSource=16 +TextSizeSubject=12 + diff --git a/Config/DefaultInput.ini b/Config/DefaultInput.ini index dd90087..5c5faae 100644 --- a/Config/DefaultInput.ini +++ b/Config/DefaultInput.ini @@ -1,6 +1,87 @@ - - -[/Script/Engine.InputSettings] -bAlwaysShowTouchInterface=False -DefaultViewportMouseLockMode=LockOnCapture - + + +[/Script/Engine.InputSettings] +-AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) +-AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) +-AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) ++AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) +bAltEnterTogglesFullscreen=True +bF11TogglesFullscreen=True +bUseMouseForTouch=False +bEnableMouseSmoothing=True +bEnableFOVScaling=True +bCaptureMouseOnLaunch=True +bEnableLegacyInputScales=True +bEnableMotionControls=True +bFilterInputByPlatformUser=False +bShouldFlushPressedKeysOnViewportFocusLost=True +bEnableDynamicComponentInputBinding=True +bAlwaysShowTouchInterface=False +bShowConsoleOnFourFingerTap=True +bEnableGestureRecognizer=False +bUseAutocorrect=False +DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown +DefaultViewportMouseLockMode=LockOnCapture +FOVScale=0.011110 +DoubleClickTime=0.200000 +DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput +DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent +DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks +-ConsoleKeys=Tilde ++ConsoleKeys=Tilde + diff --git a/Content/Cube2_Blueprint.uasset b/Content/Cube2_Blueprint.uasset new file mode 100644 index 0000000..e5340ce Binary files /dev/null and b/Content/Cube2_Blueprint.uasset differ diff --git a/Content/NewLiveLinkPreset.uasset b/Content/NewLiveLinkPreset.uasset new file mode 100644 index 0000000..7e49e4a Binary files /dev/null and b/Content/NewLiveLinkPreset.uasset differ diff --git a/Plugins/Smartsuit/Content/Blueprints/RokokoLiveCamera.uasset b/Plugins/Smartsuit/Content/Blueprints/RokokoLiveCamera.uasset index 349a38f..2352c3a 100644 Binary files a/Plugins/Smartsuit/Content/Blueprints/RokokoLiveCamera.uasset and b/Plugins/Smartsuit/Content/Blueprints/RokokoLiveCamera.uasset differ diff --git a/Plugins/Smartsuit/Content/Blueprints/RokokoLiveProp_BP.uasset b/Plugins/Smartsuit/Content/Blueprints/RokokoLiveProp_BP.uasset index 26ab5b3..0100e6d 100644 Binary files a/Plugins/Smartsuit/Content/Blueprints/RokokoLiveProp_BP.uasset and b/Plugins/Smartsuit/Content/Blueprints/RokokoLiveProp_BP.uasset differ diff --git a/Plugins/Smartsuit/Content/Blueprints/RokokoSmartSuitActor.uasset b/Plugins/Smartsuit/Content/Blueprints/RokokoSmartSuitActor.uasset index d90b736..a8bc10d 100644 Binary files a/Plugins/Smartsuit/Content/Blueprints/RokokoSmartSuitActor.uasset and b/Plugins/Smartsuit/Content/Blueprints/RokokoSmartSuitActor.uasset differ diff --git a/Plugins/Smartsuit/Content/Maps/GettingStarted.umap b/Plugins/Smartsuit/Content/Maps/GettingStarted.umap index 4a8431e..d816444 100644 Binary files a/Plugins/Smartsuit/Content/Maps/GettingStarted.umap and b/Plugins/Smartsuit/Content/Maps/GettingStarted.umap differ diff --git a/Plugins/Smartsuit/Content/Materials/MarkerMaterial.uasset b/Plugins/Smartsuit/Content/Materials/MarkerMaterial.uasset new file mode 100644 index 0000000..b1da8b8 Binary files /dev/null and b/Plugins/Smartsuit/Content/Materials/MarkerMaterial.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/Newton/NewtonAlphaBoneRemappingAsset.uasset b/Plugins/Smartsuit/Content/Mesh/Newton/NewtonAlphaBoneRemappingAsset.uasset index 01339ba..ce28ad7 100644 Binary files a/Plugins/Smartsuit/Content/Mesh/Newton/NewtonAlphaBoneRemappingAsset.uasset and b/Plugins/Smartsuit/Content/Mesh/Newton/NewtonAlphaBoneRemappingAsset.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/Newton/newtonalpha_AnimBP.uasset b/Plugins/Smartsuit/Content/Mesh/Newton/newtonalpha_AnimBP.uasset index baa1805..24660b2 100644 Binary files a/Plugins/Smartsuit/Content/Mesh/Newton/newtonalpha_AnimBP.uasset and b/Plugins/Smartsuit/Content/Mesh/Newton/newtonalpha_AnimBP.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/ue5_manny/MI_Manny_01.uasset b/Plugins/Smartsuit/Content/Mesh/ue5_manny/MI_Manny_01.uasset new file mode 100644 index 0000000..c286b15 Binary files /dev/null and b/Plugins/Smartsuit/Content/Mesh/ue5_manny/MI_Manny_01.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/ue5_manny/MI_Manny_02.uasset b/Plugins/Smartsuit/Content/Mesh/ue5_manny/MI_Manny_02.uasset new file mode 100644 index 0000000..9ddce33 Binary files /dev/null and b/Plugins/Smartsuit/Content/Mesh/ue5_manny/MI_Manny_02.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny.uasset b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny.uasset new file mode 100644 index 0000000..95ea119 Binary files /dev/null and b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Actor.uasset b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Actor.uasset new file mode 100644 index 0000000..367812d Binary files /dev/null and b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Actor.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_PhysicsAsset.uasset b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_PhysicsAsset.uasset new file mode 100644 index 0000000..41d49c4 Binary files /dev/null and b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_PhysicsAsset.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Skeleton.uasset b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Skeleton.uasset new file mode 100644 index 0000000..ed5a137 Binary files /dev/null and b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Skeleton.uasset differ diff --git a/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Skeleton_AnimBP.uasset b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Skeleton_AnimBP.uasset new file mode 100644 index 0000000..10541f9 Binary files /dev/null and b/Plugins/Smartsuit/Content/Mesh/ue5_manny/ue5_manny_Skeleton_AnimBP.uasset differ diff --git a/Plugins/Smartsuit/Content/Widgets/ProfileItem.uasset b/Plugins/Smartsuit/Content/Widgets/ProfileItem.uasset index 5cd3e95..dfc7436 100644 Binary files a/Plugins/Smartsuit/Content/Widgets/ProfileItem.uasset and b/Plugins/Smartsuit/Content/Widgets/ProfileItem.uasset differ diff --git a/Plugins/Smartsuit/Content/Widgets/PropItem.uasset b/Plugins/Smartsuit/Content/Widgets/PropItem.uasset index 84112b3..2da904c 100644 Binary files a/Plugins/Smartsuit/Content/Widgets/PropItem.uasset and b/Plugins/Smartsuit/Content/Widgets/PropItem.uasset differ diff --git a/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidgetWithoutRemote_BP.uasset b/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidgetWithoutRemote_BP.uasset index 8fdf059..117c478 100644 Binary files a/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidgetWithoutRemote_BP.uasset and b/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidgetWithoutRemote_BP.uasset differ diff --git a/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidget_BP.uasset b/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidget_BP.uasset index 01301c3..0cbeec8 100644 Binary files a/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidget_BP.uasset and b/Plugins/Smartsuit/Content/Widgets/RokokoCommandAPIWidget_BP.uasset differ diff --git a/Plugins/Smartsuit/Lib/V8/Includes/SmartsuitDef.h b/Plugins/Smartsuit/Lib/V8/Includes/SmartsuitDef.h deleted file mode 100644 index 134115e..0000000 --- a/Plugins/Smartsuit/Lib/V8/Includes/SmartsuitDef.h +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once -#include - -#define SMARTSUIT_COMMAND_GET_BODY_DIMENSIONS 0x59 -#define SMARTSUIT_COMMAND_READ_HUB_INFO 0x63 -#define SMARTSUIT_COMMAND_RESET_KALMAN_FILTER 0x68 -#define SMARTSUIT_COMMAND_PERFORM_APOSE 0x60 -#define SMARTSUIT_COMMAND_BROADCAST_ADDR 0xAE -#define SMARTSUIT_COMMAND_USE_SPECIFIC_ADDR 0x56 -#define SMARTSUIT_COMMAND_USE_BROADCAST_ADDR 0x57 -#define SMARTSUIT_COMMAND_SET_BODY_DIMENSIONS 0x58 - - -/*! \brief Address of the hip sensor as received from the Smartsuit. */ -#define SENSOR_HIP 0xA0 -/*! \brief Address of the stomach position as received from the Smartsuit. */ -#define SENSOR_STOMACH 0xA1 -/*! \brief Address of the chest position as received from the Smartsuit. */ -#define SENSOR_CHEST 0xA2 -/*! \brief Address of the neck position as received from the Smartsuit. */ -#define SENSOR_NECK 0xA3 -/*! \brief Address of the head sensor as received from the Smartsuit. */ -#define SENSOR_HEAD 0x40 - -/*! \brief Address of the left hip sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_HIP 0x00 -/*! \brief Address of the left upper leg sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_UPPER_LEG 0x01 -/*! \brief Address of the left lower leg sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_LOWER_LEG 0x02 -/*! \brief Address of the left foot sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_FOOT 0x03 - -/*! \brief Address of the left shoulder sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_SHOULDER 0x21 -/*! \brief Address of the left upper arm sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_UPPER_ARM 0x22 -/*! \brief Address of the lower arm sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_LOWER_ARM 0x23 -/*! \brief Address of the left hand sensor as received from the Smartsuit. */ -#define SENSOR_LEFT_HAND 0x24 - -/*! \brief Address of the right shoulder sensor as received from the Smartsuit. */ -#define SENSOR_RIGHT_SHOULDER 0x61 -/*! \brief Address of the right upper arm sensor as received from the Smartsuit. */ -#define SENSOR_RIGHT_UPPER_ARM 0x62 -/*! \brief Address of the right lower arm sensor as received from the Smartsuit. */ -#define SENSOR_RIGHT_LOWER_ARM 0x63 -/*! \brief Address of the right hand sensor as received from the Smartsuit. */ -#define SENSOR_RIGHT_HAND 0x64 - -/*! \brief Address of the right upper leg sensor as received from the Smartsuit. */ -#define SENSOR_RIGHT_UPPER_LEG 0x81 -/*! \brief Address of the right lower leg sensor as received from the Smartsuit. */ -#define SENSOR_RIGHT_LOWER_LEG 0x82 -/*! \brief Address of the right foot sensor as received from the Smartsuit. */ -#define SENSOR_RIGHT_FOOT 0x83 - - -/*! \brief Detailed body dimensions. -* -* This struct describes the dimensions of the body in more detail by defining the individual bone lengths, as opposed to FBodyModel which contains more abstract lengths. -*/ -struct Body { - /// @private - char first_buffer; - /// @private - char first_buffer1; - /// @private - char first_buffer2; - /// @private - char first_buffer3; - - float _head; - float _neck; - float _middle_back; - float _shoulder_blade; - float _upper_arm; - float _forearm; - float _hand; - float _low_back; - float _hip; - float _hip_width; - float _thigh; - float _leg; - float _foot_length; - float _foot_height; - float _foot_width; - float _foot_heel_offset; - char name[32]; -}; - - -/*! \brief Information about specific sensor, including its status, rotation, position.*/ -struct SensorDef { - - /** - * The address of the Sensor in the Smartsuit. Represents its position. - * A list of all supported addresses can be found in ASmartsuitCommands - */ - uint16_t addr; - - /**Indicates weither there is another sensor connected after this, or this is the last sensor in a branch.*/ - char isAnotherSensorConnected; - - char behavior; - /**Indicates if the sensor detects metal or not.*/ - char command; - /**Holds information about the acceleration detected in the sensor during the last frame.*/ - float acceleration[3]; - - /** - * The rotation information for this sensor. This quaternion is represented in Smartsuits coordinate system. - * To get a quaternion in Unreal coordinate system use UQuaternion() instead. - */ - float quaternion[4]; - - /** Gyroscope information for this sensor.*/ - float gyro[3]; - - /** - * Position information for this sensor. This position is represented in Smartsuits coordinate system. - * To get the position in Unreal coordinate system use UPosition() instead. - */ - float position[3]; - - /** Timestamp information received from the sensor. This is the sensors internal clock.*/ - uint32_t microseconds; -}; - -struct HubInfo { - - uint32_t uniqueId[4]; - uint32_t firmware; - uint32_t bootloader; - uint32_t usbApiVersion; - uint32_t wifiApiVersion; - uint32_t btApiVersion; - unsigned char serialNumber[12]; - float latitude; - float longitude; - float earthMagFieldX; - float earthMagFieldY; - float gravity; -}; - - -/*! \brief Contains data that represent the last frame received from the Smartsuit. -* -* This struct represents a Smartsuit data frame as received from the Smartsuit. -* It also includes meta variables used to manage the state of the Smartsuit in Unreal. -*/ -struct SuitDataDef { - - /** The name of the Smartsuit. */ - char suitname[5]; - - /** Information about the sensors connected to this Smartsuit, like position, rotation, etc.*/ - SensorDef sensors[19]; - int sensorCount; - - /** The time to live indicator for this Smartsuit. This indica*/ - float ttl; - - - /** Indicator if the Smartsuit is broadcasting.*/ - bool isBroadcasting; - - /** Indicator if the Smartsuit has profile.*/ - bool hasProfile; - - /// @private. - bool profileToggle; - - /** The number of frames received from this Smartsuit during the last second.*/ - float fps; - - /// @private - int currFPSCount; - - /// @private - int lastFPSSecond; -}; - -class SmartsuitDef -{ -public: - SmartsuitDef(); - ~SmartsuitDef(); - int SayOne(); - -}; \ No newline at end of file diff --git a/Plugins/Smartsuit/Lib/V8/Includes/SmartsuitLib.h b/Plugins/Smartsuit/Lib/V8/Includes/SmartsuitLib.h deleted file mode 100644 index 29efbc9..0000000 --- a/Plugins/Smartsuit/Lib/V8/Includes/SmartsuitLib.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include -#include "SmartsuitDef.h" -class SmartsuitLib -{ -public: - SmartsuitLib(); - ~SmartsuitLib(); - SuitDataDef* ParseFrame(uint8_t *data, int bytes_read); - HubInfo* ParseInfo(uint8_t *data); - void ParseBody(Body* body, uint8_t *data); -}; - diff --git a/Plugins/Smartsuit/Lib/V8/Libraries/SmartsuitLib.x64.a b/Plugins/Smartsuit/Lib/V8/Libraries/SmartsuitLib.x64.a deleted file mode 100644 index 52043f5..0000000 Binary files a/Plugins/Smartsuit/Lib/V8/Libraries/SmartsuitLib.x64.a and /dev/null differ diff --git a/Plugins/Smartsuit/Lib/V8/Libraries/SmartsuitLib.x64.lib b/Plugins/Smartsuit/Lib/V8/Libraries/SmartsuitLib.x64.lib deleted file mode 100644 index 97aaf1e..0000000 Binary files a/Plugins/Smartsuit/Lib/V8/Libraries/SmartsuitLib.x64.lib and /dev/null differ diff --git a/Plugins/Smartsuit/Smartsuit.uplugin b/Plugins/Smartsuit/Smartsuit.uplugin index c2ffeb4..d046fe4 100644 --- a/Plugins/Smartsuit/Smartsuit.uplugin +++ b/Plugins/Smartsuit/Smartsuit.uplugin @@ -1,13 +1,13 @@ { "FileVersion": 3, "Version": 3, - "VersionName": "1.11.1", + "VersionName": "1.12.0", "FriendlyName": "Rokoko Studio Live", "Description": "Now you can use your Smartsuit Pro natively in Unreal! With Rokoko Studio Live you are able to stream and visualize Smartsuit Pro data inside Unreal Engine.", "Category": "Animation", "CreatedBy": "Rokoko Electronics ApS", "CreatedByURL": "https://www.rokoko.com", - "EngineVersion": "4.27.0", + "EngineVersion": ["5.0", "5.1", "5.2", 5.3], "DocsURL": "https://github.com/Rokoko/rokoko-studio-live-unreal-engine/wiki/Rokoko-Studio-Live-Plugin-for-Unreal-Engine", "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/7e20fe7d4247410cb4f7d3e162d61c21", "SupportURL": "", @@ -39,6 +39,10 @@ { "Name": "LiveLink", "Enabled": true + }, + { + "Name": "LiveLinkCamera", + "Enabled": true } ] } diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/AnimNode_ModifyFaceCurves.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/AnimNode_ModifyFaceCurves.cpp deleted file mode 100644 index b7f59ee..0000000 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/AnimNode_ModifyFaceCurves.cpp +++ /dev/null @@ -1,147 +0,0 @@ -//// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. -// -//#include "AnimNode_ModifyFaceCurves.h" -//#include "AnimationRuntime.h" -//#include "Animation/AnimInstanceProxy.h" -// -//FAnimNode_ModifyFaceCurves::FAnimNode_ModifyFaceCurves() -//{ -// ApplyMode = EModifyFaceCurvesApplyMode::Blend; -// Alpha = 1.f; -//} -// -//void FAnimNode_ModifyFaceCurves::Initialize_AnyThread(const FAnimationInitializeContext& Context) -//{ -// DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(Initialize_AnyThread) -// Super::Initialize_AnyThread(Context); -// SourcePose.Initialize(Context); -// -// // Init our last values array to be the right size -// if (ApplyMode == EModifyFaceCurvesApplyMode::WeightedMovingAverage) -// { -// LastCurveValues.Reset(CurveValues.Num()); -// LastCurveValues.AddZeroed(CurveValues.Num()); -// } -//} -// -//void FAnimNode_ModifyFaceCurves::CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) -//{ -// DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(CacheBones_AnyThread) -// Super::CacheBones_AnyThread(Context); -// SourcePose.CacheBones(Context); -//} -// -//void FAnimNode_ModifyFaceCurves::Evaluate_AnyThread(FPoseContext& Output) -//{ -// DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(Evaluate_AnyThread) -// FPoseContext SourceData(Output); -// SourcePose.Evaluate(SourceData); -// -// Output = SourceData; -// -// // Morph target and Material parameter curves -// USkeleton* Skeleton = Output.AnimInstanceProxy->GetSkeleton(); -// -// check(CurveNames.Num() == CurveValues.Num()); -// -// for (int32 ModIdx = 0; ModIdx < CurveNames.Num(); ModIdx++) -// { -// FName CurveName = CurveNames[ModIdx]; -// SmartName::UID_Type NameUID = Skeleton->GetUIDByName(USkeleton::AnimCurveMappingName, CurveName); -// if (NameUID != SmartName::MaxUID) -// { -// float CurveValue = CurveValues[ModIdx]; -// float CurrentValue = Output.Curve.Get(NameUID); -// -// // Use ApplyMode enum to decide how to apply -// if (ApplyMode == EModifyFaceCurvesApplyMode::Add) -// { -// Output.Curve.Set(NameUID, CurrentValue + CurveValue); -// } -// else if (ApplyMode == EModifyFaceCurvesApplyMode::Scale) -// { -// Output.Curve.Set(NameUID, CurrentValue * CurveValue); -// } -// else if (ApplyMode == EModifyFaceCurvesApplyMode::WeightedMovingAverage) -// { -// check(LastCurveValues.Num() == CurveValues.Num()); -// -// const float LastCurveValue = LastCurveValues[ModIdx]; -// const float WAvg = FMath::WeightedMovingAverage(CurrentValue, LastCurveValue, Alpha); -// // Update the last curve value for next run -// LastCurveValues[ModIdx] = WAvg; -// -// Output.Curve.Set(NameUID, WAvg); -// } -// else if (ApplyMode == EModifyFaceCurvesApplyMode::RemapCurve) -// { -// const float RemapScale = 1.f / FMath::Max(1.f - CurveValue, 0.01f); -// const float RemappedValue = FMath::Min(FMath::Max(CurrentValue - CurveValue, 0.f) * RemapScale, 1.f); -// Output.Curve.Set(NameUID, RemappedValue); -// } -// else // Blend -// { -// float UseAlpha = FMath::Clamp(Alpha, 0.f, 1.f); -// Output.Curve.Set(NameUID, FMath::Lerp(CurrentValue, CurveValue, UseAlpha)); -// } -// } -// } -// -// -// -// //if (Skeleton) -// //{ -// // ILiveLinkClient& LiveLinkClient = IModularFeatures::Get().GetModularFeature(ILiveLinkClient::ModularFeatureName); -// -// // FLiveLinkSubjectFrameData SubjectData; -// // if (LiveLinkClient.EvaluateFrame_AnyThread(SubjectRepresentation.Subject, SubjectRepresentation.Role, SubjectData)) -// // { -// // FLiveLinkSkeletonStaticData* StaticData = SubjectData.StaticData.Cast(); -// // FLiveLinkAnimationFrameData* FrameData = SubjectData.FrameData.Cast(); -// -// // if (StaticData && FrameData) -// // { -// // TransformData.ApplyTransform(CameraComponent, FrameData->Transform); -// -// // if (StaticData->bIsFieldOfViewSupported) { CameraComponent->SetFieldOfView(FrameData->FieldOfView); } -// // if (StaticData->bIsAspectRatioSupported) { CameraComponent->SetAspectRatio(FrameData->AspectRatio); } -// // if (StaticData->bIsProjectionModeSupported) { CameraComponent->SetProjectionMode(FrameData->ProjectionMode == ELiveLinkCameraProjectionMode::Perspective ? ECameraProjectionMode::Perspective : ECameraProjectionMode::Orthographic); } -// -// // if (UCineCameraComponent* CineCameraComponent = Cast(CameraComponent)) -// // { -// // if (StaticData->bIsFocalLengthSupported) { CineCameraComponent->CurrentFocalLength = FrameData->FocalLength; } -// // if (StaticData->bIsApertureSupported) { CineCameraComponent->CurrentAperture = FrameData->Aperture; } -// // if (StaticData->FilmBackWidth > 0.0f) { CineCameraComponent->Filmback.SensorWidth = StaticData->FilmBackWidth; } -// // if (StaticData->FilmBackHeight > 0.0f) { CineCameraComponent->Filmback.SensorHeight = StaticData->FilmBackHeight; } -// // if (StaticData->bIsFocusDistanceSupported) { CineCameraComponent->FocusSettings.ManualFocusDistance = FrameData->FocusDistance; } -// // } -// // } -// // } -// //} -//} -// -//void FAnimNode_ModifyFaceCurves::Update_AnyThread(const FAnimationUpdateContext& Context) -//{ -// DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(Update_AnyThread) -// // Run update on input pose nodes -// SourcePose.Update(Context); -// -// // Evaluate any BP logic plugged into this node -// GetEvaluateGraphExposedInputs().Execute(Context); -//} -// -//#if WITH_EDITOR -// -//void FAnimNode_ModifyFaceCurves::AddCurve(const FName& InName, float InValue) -//{ -// CurveValues.Add(InValue); -// CurveNames.Add(InName); -//} -// -//void FAnimNode_ModifyFaceCurves::RemoveCurve(int32 PoseIndex) -//{ -// CurveValues.RemoveAt(PoseIndex); -// CurveNames.RemoveAt(PoseIndex); -//} -// -//#endif // WITH_EDITOR diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/AnimNode_RokokoFacePose.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/AnimNode_RokokoFacePose.cpp index fd3efdf..0d97907 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/AnimNode_RokokoFacePose.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/AnimNode_RokokoFacePose.cpp @@ -83,7 +83,7 @@ void FAnimNode_RokokoFacePose::Evaluate_AnyThread(FPoseContext& Output) FLiveLinkSubjectName LiveLinkSubjectName = GetLiveLinkSubjectName(); - TSubclassOf SubjectRole = LiveLinkClient_AnyThread->GetSubjectRole(LiveLinkSubjectName); + TSubclassOf SubjectRole = LiveLinkClient_AnyThread->GetSubjectRole_AnyThread(LiveLinkSubjectName); if (SubjectRole) { if (SubjectRole->IsChildOf(ULiveLinkAnimationRole::StaticClass())) diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoBodyRemapAsset.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoBodyRemapAsset.cpp new file mode 100644 index 0000000..15c9e68 --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoBodyRemapAsset.cpp @@ -0,0 +1,284 @@ + +#include "RokokoBodyRemapAsset.h" + + +URokokoBodyMapData::URokokoBodyMapData() +{ + hip = "hip"; + + stomach = "stomach"; + + chest = "chest"; + + neck = "neck"; + + head = "head"; + + leftShoulder = "leftShoulder"; + + leftArm = "leftArm"; + + leftForearm = "leftForearm"; + + leftHand = "leftHand"; + + rightShoulder = "rightShoulder"; + + rightArm = "rightArm"; + + rightForearm = "rightForearm"; + + rightHand = "rightHand"; + + leftUpleg = "leftUpleg"; + + leftLeg = "leftLeg"; + + leftFoot = "leftFoot"; + + leftToe = "leftToe"; + + rightUpleg = "rightUpleg"; + + rightLeg = "rightLeg"; + + rightFoot = "rightFoot"; + + rightToe = "rightToe"; + + leftThumbProximal = "leftThumbProximal"; + + leftThumbMedial = "leftThumbMedial"; + + leftThumbDistal = "leftThumbDistal"; + + leftThumbTip = "leftThumbTip"; + + leftIndexProximal = "leftIndexProximal"; + + leftIndexMedial = "leftIndexMedial"; + + leftIndexDistal = "leftIndexDistal"; + + leftIndexTip = "leftIndexTip"; + + leftMiddleProximal = "leftMiddleProximal"; + + leftMiddleMedial = "leftMiddleMedial"; + + leftMiddleDistal = "leftMiddleDistal"; + + leftMiddleTip = "leftMiddleTip"; + + leftRingProximal = "leftRingProximal"; + + leftRingMedial = "leftRingMedial"; + + leftRingDistal = "leftRingDistal"; + + leftRingTip = "leftRingTip"; + + leftLittleProximal = "leftLittleProximal"; + + leftLittleMedial = "leftLittleMedial"; + + leftLittleDistal = "leftLittleDistal"; + + leftLittleTip = "leftLittleTip"; + + rightThumbProximal = "rightThumbProximal"; + + rightThumbMedial = "rightThumbMedial"; + + rightThumbDistal = "rightThumbDistal"; + + rightThumbTip = "rightThumbTip"; + + rightIndexProximal = "rightIndexProximal"; + + rightIndexMedial = "rightIndexMedial"; + + rightIndexDistal = "rightIndexDistal"; + + rightIndexTip = "rightIndexTip"; + + rightMiddleProximal = "rightMiddleProximal"; + + rightMiddleMedial = "rightMiddleMedial"; + + rightMiddleDistal = "rightMiddleDistal"; + + rightMiddleTip = "rightMiddleTip"; + + rightRingProximal = "rightRingProximal"; + + rightRingMedial = "rightRingMedial"; + + rightRingDistal = "rightRingDistal"; + + rightRingTip = "rightRingTip"; + + rightLittleProximal = "rightLittleProximal"; + + rightLittleMedial = "rightLittleMedial"; + + rightLittleDistal = "rightLittleDistal"; + + rightLittleTip = "rightLittleTip"; + + +} + + +void URokokoBodyMapData::InitializeTMap() +{ + NameMapping.Empty(); + + NameMapping.Add("hip", hip); + + NameMapping.Add("stomach", stomach); + + NameMapping.Add("chest", chest); + + NameMapping.Add("neck", neck); + + NameMapping.Add("head", head); + + NameMapping.Add("leftShoulder", leftShoulder); + + NameMapping.Add("leftArm", leftArm); + + NameMapping.Add("leftForearm", leftForearm); + + NameMapping.Add("leftHand", leftHand); + + NameMapping.Add("rightShoulder", rightShoulder); + + NameMapping.Add("rightArm", rightArm); + + NameMapping.Add("rightForearm", rightForearm); + + NameMapping.Add("rightHand", rightHand); + + NameMapping.Add("leftUpleg", leftUpleg); + + NameMapping.Add("leftLeg", leftLeg); + + NameMapping.Add("leftFoot", leftFoot); + + NameMapping.Add("leftToe", leftToe); + + NameMapping.Add("rightUpleg", rightUpleg); + + NameMapping.Add("rightLeg", rightLeg); + + NameMapping.Add("rightFoot", rightFoot); + + NameMapping.Add("rightToe", rightToe); + + NameMapping.Add("leftThumbProximal", leftThumbProximal); + + NameMapping.Add("leftThumbMedial", leftThumbMedial); + + NameMapping.Add("leftThumbDistal", leftThumbDistal); + + NameMapping.Add("leftThumbTip", leftThumbTip); + + NameMapping.Add("leftIndexProximal", leftIndexProximal); + + NameMapping.Add("leftIndexMedial", leftIndexMedial); + + NameMapping.Add("leftIndexDistal", leftIndexDistal); + + NameMapping.Add("leftIndexTip", leftIndexTip); + + NameMapping.Add("leftMiddleProximal", leftMiddleProximal); + + NameMapping.Add("leftMiddleMedial", leftMiddleMedial); + + NameMapping.Add("leftMiddleDistal", leftMiddleDistal); + + NameMapping.Add("leftMiddleTip", leftMiddleTip); + + NameMapping.Add("leftRingProximal", leftRingProximal); + + NameMapping.Add("leftRingMedial", leftRingMedial); + + NameMapping.Add("leftRingDistal", leftRingDistal); + + NameMapping.Add("leftRingTip", leftRingTip); + + NameMapping.Add("leftLittleProximal", leftLittleProximal); + + NameMapping.Add("leftLittleMedial", leftLittleMedial); + + NameMapping.Add("leftLittleDistal", leftLittleDistal); + + NameMapping.Add("leftLittleTip", leftLittleTip); + + NameMapping.Add("rightThumbProximal", rightThumbProximal); + + NameMapping.Add("rightThumbMedial", rightThumbMedial); + + NameMapping.Add("rightThumbDistal", rightThumbDistal); + + NameMapping.Add("rightThumbTip", rightThumbTip); + + NameMapping.Add("rightIndexProximal", rightIndexProximal); + + NameMapping.Add("rightIndexMedial", rightIndexMedial); + + NameMapping.Add("rightIndexDistal", rightIndexDistal); + + NameMapping.Add("rightIndexTip", rightIndexTip); + + NameMapping.Add("rightMiddleProximal", rightMiddleProximal); + + NameMapping.Add("rightMiddleMedial", rightMiddleMedial); + + NameMapping.Add("rightMiddleDistal", rightMiddleDistal); + + NameMapping.Add("rightMiddleTip", rightMiddleTip); + + NameMapping.Add("rightRingProximal", rightRingProximal); + + NameMapping.Add("rightRingMedial", rightRingMedial); + + NameMapping.Add("rightRingDistal", rightRingDistal); + + NameMapping.Add("rightRingTip", rightRingTip); + + NameMapping.Add("rightLittleProximal", rightLittleProximal); + + NameMapping.Add("rightLittleMedial", rightLittleMedial); + + NameMapping.Add("rightLittleDistal", rightLittleDistal); + + NameMapping.Add("rightLittleTip", rightLittleTip); +} + +//FName URokokoBodyMapData::GetRemappedBoneName_Implementation(FName CurveName) const +//{ +// if (auto RemappedName = NameMapping.Find(CurveName)) +// { +// return *RemappedName; +// } +// return ""; +//} +// +//void URokokoBodyMapData::Initialize() +//{ +// InitializeTMap(); +//} +//PRAGMA_DISABLE_OPTIMIZATION +FName URokokoBodyMapData::GetRemappedBoneName_Implementation(FName CurveName) const +{ + if (auto RemappedName = NameMapping.Find(CurveName)) + { + return *RemappedName; + } + + return ""; +} +//PRAGMA_ENABLE_OPTIMIZATION + diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoFaceMapData.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoFaceMapData.cpp new file mode 100644 index 0000000..34a32e3 --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoFaceMapData.cpp @@ -0,0 +1,17 @@ + +#include "RokokoFaceMapData.h" + + +FName URokokoFaceMapData::GetRemappedCurveName_Implementation(FName CurveName) const +{ + if (auto RemappedName = NameMapping.Find(CurveName)) + { + return *RemappedName; + } + return ""; +} + +void URokokoFaceMapData::Initialize() +{ + InitializeTMap(); +} \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoModule.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoModule.cpp new file mode 100644 index 0000000..c083def --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoModule.cpp @@ -0,0 +1,18 @@ +// Copyright 2019 Rokoko Electronics. All Rights Reserved. + +#include "RokokoModule.h" + +// class FRokokoModule : public IRokokoModule +// { +// virtual void StartupModule() override +// { +// +// } +// +// virtual void ShutdownModule() override +// { +// +// } +// }; +// +// IMPLEMENT_MODULE(FRokokoModule, Rokoko); diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoRemote.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoRemote.cpp index b7a3a8c..ded3f7c 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoRemote.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoRemote.cpp @@ -2,317 +2,160 @@ #include "RokokoRemote.h" -#include "Serialization/ArrayWriter.h" -#include "Runtime/Networking/Public/Common/UdpSocketBuilder.h" -#include "Runtime/Networking/Public/Common/UdpSocketReceiver.h" -#include "Async/Async.h" -#include "TimerManager.h" +#include "HttpModule.h" +#include "Interfaces/IHttpResponse.h" +#include "Dom/JsonObject.h" +#include "Serialization/JsonSerializer.h" ARokokoRemote::ARokokoRemote() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. - PrimaryActorTick.bCanEverTick = true; + PrimaryActorTick.bCanEverTick = false; - SenderSocket = nullptr; - ListenSocket = nullptr; - - UDPReceiver = nullptr; - - IPAddress = "192.168.1.133"; - - SenderPort = 55606; - ReceiverPort = 55606; } void ARokokoRemote::BeginPlay() { Super::BeginPlay(); - CurrentData.type = "Instance"; - CurrentData.version = 1; - CurrentData.provider = "PROVIDERNAME"; - CurrentData.faceId = "KQ452"; - CurrentData.deviceName = FPlatformProcess::ComputerName();//"DEVICENAME"; - CurrentData.connectedTo = ""; - CurrentData.requestedFrom = ""; - CurrentData.commandKey = ""; - CurrentData.commandPort = 0; - CurrentData.recording = false; - CurrentData.currentRecordingTime = 0.f; - CurrentData.numberOfLiveSuits = 1; - - StartUDPSender("TESTSOCKETSENDER", IPAddress, SenderPort); - //StartUDPReceiver("TESTSOCKETLISTENER", "192.168.1.133", 55606); - StartUDPReceiver("TESTSOCKETLISTENER", "0.0.0.0", ReceiverPort); - - GetWorld()->GetTimerManager().SetTimer(FTH_TestHandle, this, &ThisClass::SendData, 1.f, true); } void ARokokoRemote::EndPlay(const EEndPlayReason::Type EndPlayReason) { Super::EndPlay(EndPlayReason); - if (SenderSocket) - { - SenderSocket->Close(); - ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(SenderSocket); - } - - delete UDPReceiver; - UDPReceiver = nullptr; - - if (ListenSocket) - { - ListenSocket->Close(); - ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenSocket); - } -} - -void ARokokoRemote::SendData() -{ - Sender_SendData(); + } -bool ARokokoRemote::Sender_SendData() +ARokokoRemote *ARokokoRemote::GetFirstAvailableActor() { - if (!SenderSocket) - { - UE_LOG(LogTemp, Warning, TEXT("No sender socket")); - return false; - } - - int32 BytesSent = 0; - - FString MessageString = CurrentData.Serialize(); - TCHAR* serializedmessage = MessageString.GetCharArray().GetData(); - int32 size = FCString::Strlen(serializedmessage); - int32 sent = 0; - - SenderSocket->SendTo((uint8*)TCHAR_TO_UTF8(serializedmessage), size, BytesSent, *RemoteAddr); - - if (BytesSent <= 0) - { - const FString Str = "Socket is valid but the receiver received 0 bytes, make sure it is listening properly!"; - UE_LOG(LogTemp, Error, TEXT("%s"), *Str); - return false; - } - else + for (TObjectIterator It; It; ++It) { - UE_LOG(LogTemp, Warning, TEXT("Sent %d bytes"), BytesSent); + return *It; } - - return true; - + return nullptr; } -FString ARokokoRemote::GetCommandAPIKey() -{ - return CurrentData.commandKey; -} -int32 ARokokoRemote::GetCommandAPIPort() +void ARokokoRemote::OnProcessRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) { - return CurrentData.commandPort; -} - -bool ARokokoRemote::StartUDPSender(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort) -{ - RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); - - bool bIsValid; - RemoteAddr->SetIp(*TheIP, bIsValid); - RemoteAddr->SetPort(ThePort); - - if (!bIsValid) - { - UE_LOG(LogTemp, Warning, TEXT("IP address was not valid!")); - return false; - } - - SenderSocket = FUdpSocketBuilder(*YourChosenSocketName) - .AsReusable() - .WithBroadcast() - ; - - //check(SenderSocket->GetSocketType() == SOCKTYPE_Datagram); + int32 ResponseCode = HttpResponse->GetResponseCode(); + FString ResponseString = HttpResponse->GetContentAsString(); - int32 SendSize = 2 * 1024 * 1024; - SenderSocket->SetSendBufferSize(SendSize, SendSize); - SenderSocket->SetReceiveBufferSize(SendSize, SendSize); - - UE_LOG(LogTemp, Log, TEXT("****UDP**** Sender Initialized Successfully!!!")); - - return true; + OnCompletedRequest.Broadcast(ResponseCode, ResponseString, bSucceeded); } -bool ARokokoRemote::StartUDPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort) +void ARokokoRemote::OnInfoRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) { - UE_LOG(LogTemp, Warning, TEXT("RECEIVER INIT")); - - FIPv4Address Addr; - FIPv4Address::Parse(TheIP, Addr); - - FIPv4Endpoint Endpoint(Addr, ThePort); - - int32 BufferSize = 2 * 1024 * 1024; - - ListenSocket = FUdpSocketBuilder(*YourChosenSocketName).AsNonBlocking().AsReusable().BoundToEndpoint(Endpoint).WithReceiveBufferSize(BufferSize); - - //ListenSocket = FUdpSocketBuilder(*YourChosenSocketName).AsReusable().WithBroadcast(); - - if (!ListenSocket) - { - UE_LOG(LogTemp, Warning, TEXT("ListenSocket is null!")); - return false; - } - else - { - UE_LOG(LogTemp, Warning, TEXT("ListenSocket is valid!")); - } - - ListenSocket->SetReceiveBufferSize(BufferSize, BufferSize); - - FTimespan ThreadWaitTime = FTimespan::FromMilliseconds(100); - UDPReceiver = new FUdpSocketReceiver(ListenSocket, ThreadWaitTime, TEXT("UDP RECEIVER")); - UDPReceiver->OnDataReceived().BindUObject(this, &ThisClass::Recv); - UDPReceiver->Start(); - - return true; -} - -FString WriteBoolValue(bool InValue) -{ - return InValue ? "True" : "False"; -} + TSharedPtr JsonObject; + TSharedRef> Reader = TJsonReaderFactory<>::Create(HttpResponse->GetContentAsString()); -FString testfunc(const uint8* SrcBuffer, const uint32 SrcSize) -{ - FString Result; - Result.Reserve(SrcSize * 2); - // Convert and append each byte in the buffer - for (uint32 Count = 0; Count < SrcSize; Count++) + // Deserialize the json data given Reader and the actual object to deserialize + if (FJsonSerializer::Deserialize(Reader, JsonObject)) { - Result += TCHAR(SrcBuffer[Count]); + auto& Arr = JsonObject->GetArrayField("parameters"); + + TArray StringsDevices; + TArray StringsClips; + TArray StringsActors; + TArray StringsCharacters; + + int i = 0; + while (!Arr.IsEmpty()) + { + const FString ArgName = Arr[i]->AsString(); + if (ArgName == "DevicesIDs") + { + int Count = static_cast(Arr[i+1]->AsNumber()); + + for (int j = 0; j < Count; ++j) + { + StringsDevices.Add(Arr[i + 1 + j]->AsString()); + } + } + else if (ArgName == "Clips") + { + int Count = static_cast(Arr[i + 1]->AsNumber()); + + for (int j = 0; j < Count; ++j) + { + StringsClips.Add(Arr[i + 1 + j]->AsString()); + } + } + else if (ArgName == "Actors") + { + int Count = static_cast(Arr[i + 1]->AsNumber()); + + for (int j = 0; j < Count; ++j) + { + StringsActors.Add(Arr[i + 1 + j]->AsString()); + } + } + else if (ArgName == "Characters") + { + int Count = static_cast(Arr[i + 1]->AsNumber()); + + for (int j = 0; j < Count; ++j) + { + StringsCharacters.Add(Arr[i + 1 + j]->AsString()); + } + } + + i += 1; + } + + OnInfoRequest.Broadcast(StringsDevices, StringsClips, StringsActors, StringsCharacters); } - return Result; } -void ARokokoRemote::Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt) +void ARokokoRemote::OnTrackerRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) { - UE_LOG(LogTemp, Warning, TEXT("Received bytes: %d"), ArrayReaderPtr->Num()); - - FRokokoRemoteInstance Data2; - - //FString DataString = FString::FromHexBlob(ArrayReaderPtr->GetData(), ArrayReaderPtr->Num()); - //FString DataString = BytesToString(ArrayReaderPtr->GetData(), ArrayReaderPtr->Num()); - FString DataString = testfunc(ArrayReaderPtr->GetData(), ArrayReaderPtr->Num()); + const double WORLD_SCALE{ 100.0 }; TSharedPtr JsonObject; - TSharedRef> Reader = TJsonReaderFactory<>::Create(DataString); - if (FJsonSerializer::Deserialize(Reader, JsonObject)) - { - Data2 = FRokokoRemoteInstance(JsonObject); - } - + TSharedRef> Reader = TJsonReaderFactory<>::Create(HttpResponse->GetContentAsString()); - if (Data2.type == "studio-keep-alive") - { - CurrentData.commandPort = Data2.commandPort; - CurrentData.commandKey = Data2.commandKey; - } - else - if (Data2.type == "studio-request") - { - CurrentData.connectedTo = Data2.deviceName; - - - FString PCName = CurrentData.connectedTo; - - CurrentData.commandPort = Data2.commandPort; - CurrentData.commandKey = Data2.commandKey; - - AsyncTask(ENamedThreads::GameThread, [this, PCName]{OnConnected.Broadcast(PCName);}); - } - else - if (Data2.type == "studio-cancel-request") - { - CurrentData.connectedTo = ""; - UE_LOG(LogTemp, Warning, TEXT("DISCONNECT")); - - AsyncTask(ENamedThreads::GameThread, [this] {OnDisconnected.Broadcast();}); - } - else + // Deserialize the json data given Reader and the actual object to deserialize + if (FJsonSerializer::Deserialize(Reader, JsonObject)) { - + auto& Arr = JsonObject->GetArrayField("parameters"); + + if (!Arr.IsEmpty()) + { + auto& ObjectPosition = Arr[0]->AsObject(); + auto& ObjectRotation = Arr[1]->AsObject(); + + FVector Position(WORLD_SCALE * ObjectPosition->GetNumberField("X"), + -WORLD_SCALE * ObjectPosition->GetNumberField("Z"), + WORLD_SCALE * ObjectPosition->GetNumberField("Y")); + // TODO: do we need to convert rotation to UE coord system ?! + FQuat Rotation(ObjectRotation->GetNumberField("X"), ObjectRotation->GetNumberField("Y"), ObjectRotation->GetNumberField("Z"), + ObjectRotation->GetNumberField("W")); + + OnTrackerRequest.Broadcast(Position, Rotation); + } } - - Data2.DisplayValues(); } -FString FRokokoRemoteInstance::Serialize() -{ - TSharedPtr JsonObject = MakeShareable(new FJsonObject); - JsonObject->SetStringField(TEXT("type"), type); - JsonObject->SetNumberField(TEXT("version"), version); - JsonObject->SetStringField(TEXT("provider"), provider); - JsonObject->SetStringField(TEXT("faceId"), faceId); - JsonObject->SetStringField(TEXT("deviceName"), deviceName); - JsonObject->SetStringField(TEXT("connectedTo"), connectedTo); - JsonObject->SetStringField(TEXT("requestedFrom"), requestedFrom); - JsonObject->SetStringField(TEXT("commandKey"), commandKey); - JsonObject->SetNumberField(TEXT("commandPort"), commandPort); - JsonObject->SetBoolField(TEXT("recording"), recording); - JsonObject->SetNumberField(TEXT("currentRecordingTime"), currentRecordingTime); - JsonObject->SetNumberField(TEXT("numberOfLiveSuits"), numberOfLiveSuits); - JsonObject->SetBoolField(TEXT("commandApiOn"), commandApiOn); - JsonObject->SetBoolField(TEXT("commandApiLicense"), commandApiLicense); - JsonObject->SetBoolField(TEXT("faceLicense"), faceLicense); - FString OutputString = ""; - - TSharedRef> Writer = TJsonWriterFactory<>::Create(&OutputString); - FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); - - return OutputString; -} - -FRokokoRemoteInstance::FRokokoRemoteInstance(TSharedPtr jsonObject) +void ARokokoRemote::OnPlaybackRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) { - jsonObject->TryGetStringField("type", type); - jsonObject->TryGetNumberField(TEXT("version"), version); - jsonObject->TryGetStringField(TEXT("provider"), provider); - jsonObject->TryGetStringField(TEXT("faceId"), faceId); - jsonObject->TryGetStringField(TEXT("deviceName"), deviceName); - jsonObject->TryGetStringField(TEXT("connectedTo"), connectedTo); - jsonObject->TryGetStringField(TEXT("requestedFrom"), requestedFrom); - jsonObject->TryGetStringField(TEXT("commandKey"), commandKey); - jsonObject->TryGetNumberField(TEXT("commandPort"), commandPort); - jsonObject->TryGetBoolField(TEXT("recording"), recording); - double recordingTimeVal; - if (jsonObject->TryGetNumberField(TEXT("currentRecordingTime"), recordingTimeVal)) + TSharedPtr JsonObject; + TSharedRef> Reader = TJsonReaderFactory<>::Create(HttpResponse->GetContentAsString()); + + // Deserialize the json data given Reader and the actual object to deserialize + if (FJsonSerializer::Deserialize(Reader, JsonObject)) { - currentRecordingTime = recordingTimeVal; + auto& Arr = JsonObject->GetArrayField("parameters"); + + if (!Arr.IsEmpty()) + { + const double CurrentTime = Arr[0]->AsNumber(); + const bool IsPlaying = Arr[1]->AsBool(); + const double MinTime = Arr[2]->AsNumber(); + const double MaxTime = Arr[3]->AsNumber(); + const double PlaybackSpeed = Arr[4]->AsNumber(); + + OnPlaybackRequest.Broadcast(CurrentTime, IsPlaying, MinTime, MaxTime, PlaybackSpeed); + } } - jsonObject->TryGetNumberField(TEXT("numberOfLiveSuits"), numberOfLiveSuits); - jsonObject->TryGetBoolField(TEXT("commandApiOn"), commandApiOn); - jsonObject->TryGetBoolField(TEXT("commandApiLicense"), commandApiLicense); - jsonObject->TryGetBoolField(TEXT("faceLicense"), faceLicense); -} - -void FRokokoRemoteInstance::DisplayValues() -{ - UE_LOG(LogTemp, Warning, TEXT("type: %s"), *type); - UE_LOG(LogTemp, Warning, TEXT("version: %d"), version); - UE_LOG(LogTemp, Warning, TEXT("provider: %s"), *provider); - UE_LOG(LogTemp, Warning, TEXT("faceId: %s"), *faceId); - UE_LOG(LogTemp, Warning, TEXT("deviceName: %s"), *deviceName); - UE_LOG(LogTemp, Warning, TEXT("connectedTo: %s"), *connectedTo); - UE_LOG(LogTemp, Warning, TEXT("requestedFrom: %s"), *requestedFrom); - UE_LOG(LogTemp, Warning, TEXT("commandKey: %s"), *commandKey); - UE_LOG(LogTemp, Warning, TEXT("commandPort: %d"), commandPort); - UE_LOG(LogTemp, Warning, TEXT("recording: %s"), *WriteBoolValue(recording)); - UE_LOG(LogTemp, Warning, TEXT("currentRecordingTime: %f"), currentRecordingTime); - UE_LOG(LogTemp, Warning, TEXT("numberOfLiveSuits: %d"), numberOfLiveSuits); - UE_LOG(LogTemp, Warning, TEXT("commandApiOn: %s"), *WriteBoolValue(commandApiOn)); - UE_LOG(LogTemp, Warning, TEXT("commandApiLicense: %s"), *WriteBoolValue(commandApiLicense)); - UE_LOG(LogTemp, Warning, TEXT("faceLicense: %s"), *WriteBoolValue(faceLicense)); } \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitDefinitions.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoSkeletonData.cpp similarity index 87% rename from Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitDefinitions.cpp rename to Plugins/Smartsuit/Source/Smartsuit/Private/RokokoSkeletonData.cpp index 37daa44..ddf955d 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitDefinitions.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoSkeletonData.cpp @@ -1,7 +1,6 @@ // Copyright 2019 Rokoko Electronics. All Rights Reserved. -#include "SmartsuitDefinitions.h" -#include "Smartsuit.h" +#include "RokokoSkeletonData.h" #include "SmartsuitBlueprintLibrary.h" namespace SmartsuitBones @@ -71,13 +70,6 @@ namespace SmartsuitBones const FName rightLittleTip = FName(TEXT("rightLittleTip")); } -SmartsuitDefinitions::SmartsuitDefinitions() -{ -} - -SmartsuitDefinitions::~SmartsuitDefinitions() -{ -} FSuitData::FSuitData(bool InIsLive, TSharedPtr jsonObject) { @@ -97,6 +89,8 @@ FSuitData::FSuitData(bool InIsLive, TSharedPtr jsonObject) TSharedPtr Meta = jsonObject->GetObjectField("meta"); hasGloves = Meta->GetBoolField("hasGloves"); + hasLeftGlove = Meta->GetBoolField("hasLeftGlove"); + hasRightGlove = Meta->GetBoolField("hasRightGlove"); hasBody = Meta->GetBoolField("hasBody"); hasFace = Meta->GetBoolField("hasFace"); @@ -174,6 +168,30 @@ void FSuitData::ParseBone(TSharedPtr jsonObject, const FString& Bon TSharedPtr BoneObject = jsonObject->GetObjectField(BoneName); FVector SensorPosition = USmartsuitBlueprintLibrary::GetVectorField(BoneObject->GetObjectField("position")); FQuat SensorRotation = USmartsuitBlueprintLibrary::GetQuaternionField(BoneObject->GetObjectField("rotation")); - SmartsuitBones.Add(FName(*BoneName), FSmartsuitBone(FName(*BoneName), SensorPosition, SensorRotation)); + + bones.Add(FName(*BoneName), FSmartsuitBone(FName(*BoneName), SensorPosition, SensorRotation)); + } +} + + +FCharacterData::FCharacterData(bool InIsLive, TSharedPtr jsonObject) +{ + IsLive = InIsLive; + CharacterName = jsonObject->GetStringField("name"); + + TArray> JointsArray = jsonObject->GetArrayField("joints"); + + for(TArray< TSharedPtr< FJsonValue > >::TConstIterator JointsIter( JointsArray.CreateConstIterator() ); JointsIter; ++JointsIter) + { + const TSharedPtr< FJsonValue > JointEntry = *JointsIter; + const TSharedPtr< FJsonObject > JoinJSONObject = JointEntry->AsObject(); + + FString JointName = JoinJSONObject->GetStringField("name"); + int32 JointParentIndex = JoinJSONObject->GetIntegerField("parent"); + FVector JointPosition = USmartsuitBlueprintLibrary::GetVectorField(JoinJSONObject->GetObjectField("position")); + FQuat JointRotation = USmartsuitBlueprintLibrary::GetQuaternionField(JoinJSONObject->GetObjectField("rotation")); + + FTransform JointTransform(JointRotation, JointPosition, FVector::OneVector); + joints.Add(FRokokoCharacterJoint(*JointName, JointParentIndex, JointTransform)); } -} \ No newline at end of file +} diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoStudioCommandAPI.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoStudioCommandAPI.cpp index 76695c6..f7708ed 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoStudioCommandAPI.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/RokokoStudioCommandAPI.cpp @@ -6,15 +6,43 @@ #include "Interfaces/IHttpResponse.h" #include "Dom/JsonObject.h" #include "Serialization/JsonSerializer.h" +#include "RokokoRemote.h" -URokokoStudioCommandAPI::URokokoStudioCommandAPI() + +void URokokoStudioCommandAPI::Info(const FRokokoCommandAPI_IPInfo& IPInfo, bool ShouldIncludeDevices, bool ShouldIncludeClips, bool ShouldIncludeActors, bool ShouldIncludeCharacters) { - Default_SmartSuitName = "H23"; - Default_IPInfo.IPAddress = "127.0.0.1"; - Default_IPInfo.Port = "14053"; - Default_IPInfo.APIKey = "1234"; + TSharedPtr JsonObject = MakeShareable(new FJsonObject); + JsonObject->SetBoolField("devices_info", ShouldIncludeDevices); + JsonObject->SetBoolField("clips_info", ShouldIncludeClips); + JsonObject->SetBoolField("actors_info", ShouldIncludeActors); + JsonObject->SetBoolField("characters_info", ShouldIncludeCharacters); + FString JsonString; + TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); + FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); + + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v2/%s/info"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); + +#if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) + FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); +#else + TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); +#endif + HttpRequest->SetURL(URLPath); + HttpRequest->SetVerb(TEXT("POST")); + HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); + HttpRequest->SetContentAsString(JsonString); + + ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor(); + if (remote) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnInfoRequestComplete); + } + + HttpRequest->ProcessRequest(); } + + void URokokoStudioCommandAPI::Restart(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& SmartSuitName) { TSharedPtr JsonObject = MakeShareable(new FJsonObject); @@ -23,109 +51,274 @@ void URokokoStudioCommandAPI::Restart(const FRokokoCommandAPI_IPInfo& IPInfo, co TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); - FString URLPath = "http://" + IPInfo.IPAddress + ":" + IPInfo.Port + "/v1/" + IPInfo.APIKey + "/restart"; + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v1/%s/restart"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); - FString TrimmedUrl = URLPath; - TrimmedUrl.TrimStartAndEndInline(); +#if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) + FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); +#else + TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); +#endif + HttpRequest->SetURL(URLPath); + HttpRequest->SetVerb(TEXT("POST")); + HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); + HttpRequest->SetContentAsString(JsonString); + //HttpRequest->OnProcessRequestComplete().BindUObject(this, &URokokoStudioCommandAPI::OnProcessRequestComplete); + HttpRequest->ProcessRequest(); +} + +void URokokoStudioCommandAPI::ResetActor(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& ActorName) +{ + TSharedPtr JsonObject = MakeShareable(new FJsonObject); + JsonObject->SetStringField("device_id", ActorName); + FString JsonString; + TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); + FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); + + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v2/%s/resetactor"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); #if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); #else TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); #endif - HttpRequest->SetURL(TrimmedUrl); + HttpRequest->SetURL(URLPath); HttpRequest->SetVerb(TEXT("POST")); HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); HttpRequest->SetContentAsString(JsonString); - HttpRequest->OnProcessRequestComplete().BindUObject(this, &URokokoStudioCommandAPI::OnProcessRequestComplete); + + ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor(); + if (remote) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnProcessRequestComplete); + } + HttpRequest->ProcessRequest(); } -void URokokoStudioCommandAPI::Calibrate(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& SmartSuitName, int32 CountdownDelay) +void URokokoStudioCommandAPI::Calibrate(const FRokokoCommandAPI_IPInfo& IPInfo, const FRokokoCommandAPI_CalibrateInput& Params) { TSharedPtr JsonObject = MakeShareable(new FJsonObject); - //JsonObject->SetStringField("smartsuit_name", SmartSuitName); - JsonObject->SetNumberField("coundtown_delay", CountdownDelay); + JsonObject->SetStringField("device_id", Params.DeviceID); + JsonObject->SetNumberField("coundtown_delay", Params.CountdownDelay); + JsonObject->SetBoolField("skip_suit", Params.ShouldSkipSuit); + JsonObject->SetNumberField("skip_gloves", Params.ShouldSkipGloves); + JsonObject->SetNumberField("use_custom_pose", Params.UseCustomPose); + JsonObject->SetStringField("pose", Params.CustomPoseName); + FString JsonString; + TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); + FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); + + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v1/%s/calibrate"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); + +#if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) + FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); +#else + TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); +#endif + HttpRequest->SetURL(URLPath); + HttpRequest->SetVerb(TEXT("POST")); + HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); + HttpRequest->SetContentAsString(JsonString); + + ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor(); + if (remote) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnProcessRequestComplete); + } + + HttpRequest->ProcessRequest(); +} + + +void URokokoStudioCommandAPI::Playback(const FRokokoCommandAPI_IPInfo& IPInfo, const FRokokoCommandAPI_PlaybackInput& Params) +{ + TSharedPtr JsonObject = MakeShareable(new FJsonObject); + + JsonObject->SetBoolField("is_playing", Params.IsPlaying); + JsonObject->SetNumberField("current_time", Params.CurrentTime); + JsonObject->SetNumberField("playback_speed", Params.PlaybackSpeed); + JsonObject->SetNumberField("change_flag", Params.ChangeFlags); + FString JsonString; TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); - FString URLPath = "http://" + IPInfo.IPAddress + ":" + IPInfo.Port + "/v1/" + IPInfo.APIKey + "/calibrate"; + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v2/%s/playback"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); + +#if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) + FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); +#else + TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); +#endif + HttpRequest->SetURL(URLPath); + HttpRequest->SetVerb(TEXT("POST")); + HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); + HttpRequest->SetContentAsString(JsonString); + + if (ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor()) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnPlaybackRequestComplete); + } + + HttpRequest->ProcessRequest(); +} - FString TrimmedUrl = URLPath; - TrimmedUrl.TrimStartAndEndInline(); + +void URokokoStudioCommandAPI::Livestream(const FRokokoCommandAPI_IPInfo& IPInfo, bool ShouldLivestream) +{ + TSharedPtr JsonObject = MakeShareable(new FJsonObject); + + JsonObject->SetBoolField("enabled", ShouldLivestream); + + FString JsonString; + TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); + FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); + + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v2/%s/livestream"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); #if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); #else TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); #endif - HttpRequest->SetURL(TrimmedUrl); + HttpRequest->SetURL(URLPath); HttpRequest->SetVerb(TEXT("POST")); HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); HttpRequest->SetContentAsString(JsonString); - HttpRequest->OnProcessRequestComplete().BindUObject(this, &URokokoStudioCommandAPI::OnProcessRequestComplete); + + if (ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor()) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnProcessRequestComplete); + } + HttpRequest->ProcessRequest(); } -void URokokoStudioCommandAPI::StartRecording(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& FileName) +void URokokoStudioCommandAPI::StartRecording(const FRokokoCommandAPI_IPInfo& IPInfo, const FString FileName, const FTimecode StartTime) { TSharedPtr JsonObject = MakeShareable(new FJsonObject); - //JsonObject->SetStringField("filename", FileName); + JsonObject->SetStringField("filename", FileName); + JsonObject->SetStringField("time", StartTime.ToString()); FString JsonString; TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); - FString URLPath = "http://" + IPInfo.IPAddress + ":" + IPInfo.Port + "/v1/" + IPInfo.APIKey + "/recording/start"; + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v1/%s/recording/start"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); - FString TrimmedUrl = URLPath; - TrimmedUrl.TrimStartAndEndInline(); +#if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) + FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); +#else + TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); +#endif + HttpRequest->SetURL(URLPath); + HttpRequest->SetVerb(TEXT("POST")); + HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); + HttpRequest->SetContentAsString(JsonString); + ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor(); + if (remote) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnProcessRequestComplete); + } + HttpRequest->ProcessRequest(); +} + +void URokokoStudioCommandAPI::StopRecording(const FRokokoCommandAPI_IPInfo& IPInfo, const FTimecode EndTime, bool ShouldBackToLive) +{ + // prepare command options in json form + TSharedPtr JsonObject = MakeShareable(new FJsonObject); + JsonObject->SetStringField("time", EndTime.ToString()); // time is SMPTE format + JsonObject->SetBoolField("back_to_live", ShouldBackToLive); + FString JsonString; + TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); + FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); + + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v1/%s/recording/stop"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); #if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); #else TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); #endif - HttpRequest->SetURL(TrimmedUrl); + HttpRequest->SetURL(URLPath); HttpRequest->SetVerb(TEXT("POST")); HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); HttpRequest->SetContentAsString(JsonString); - HttpRequest->OnProcessRequestComplete().BindUObject(this, &URokokoStudioCommandAPI::OnProcessRequestComplete); + ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor(); + if (remote) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnProcessRequestComplete); + } HttpRequest->ProcessRequest(); } -void URokokoStudioCommandAPI::StopRecording(const FRokokoCommandAPI_IPInfo& IPInfo) +void URokokoStudioCommandAPI::Tracker(const FRokokoCommandAPI_IPInfo& IPInfo, const FRokokoCommandAPI_TrackerInput& Params) { - FString URLPath = "http://" + IPInfo.IPAddress + ":" + IPInfo.Port + "/v1/" + IPInfo.APIKey + "/recording/stop"; + const double WORLD_SCALE{ 0.01 }; - FString TrimmedUrl = URLPath; - TrimmedUrl.TrimStartAndEndInline(); + TSharedPtr JsonObject = MakeShareable(new FJsonObject); + + TSharedPtr PositionJsonObject = MakeShareable(new FJsonObject); + // convert UE coord system into target Studio coord system + const FVector Location{ Params.Transform.GetLocation() }; + PositionJsonObject->SetNumberField("X", WORLD_SCALE * Location.X); + PositionJsonObject->SetNumberField("Y", WORLD_SCALE * Location.Z); + PositionJsonObject->SetNumberField("Z", -WORLD_SCALE * Location.Y); + + // TODO: do we need to convert rotation into Studio coord system ? + TSharedPtr RotationJsonObject = MakeShareable(new FJsonObject); + const FQuat Rotation{ Params.Transform.GetRotation() }; + RotationJsonObject->SetNumberField("X", Rotation.X); + RotationJsonObject->SetNumberField("Y", Rotation.Y); + RotationJsonObject->SetNumberField("Z", Rotation.Z); + RotationJsonObject->SetNumberField("W", Rotation.W); + + JsonObject->SetStringField("device_id", Params.DeviceID); + JsonObject->SetStringField("bone_attached", Params.BoneName); + JsonObject->SetObjectField("position", PositionJsonObject); + JsonObject->SetObjectField("rotation", RotationJsonObject); + JsonObject->SetBoolField("is_query_only", Params.ShouldQueryOnly); + JsonObject->SetNumberField("timeout", Params.TimeoutTime); + FString JsonString; + TSharedRef> Writer = TJsonWriterFactory<>::Create(&JsonString); + FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); + + const FString URLPath = FString::Printf(TEXT("http://%s:%s/v2/%s/tracker"), *IPInfo.IPAddress, *IPInfo.Port, *IPInfo.APIKey); #if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 26) FHttpRequestRef HttpRequest = FHttpModule::Get().CreateRequest(); #else TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); #endif - HttpRequest->SetURL(TrimmedUrl); + HttpRequest->SetURL(URLPath); HttpRequest->SetVerb(TEXT("POST")); HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8")); - HttpRequest->OnProcessRequestComplete().BindUObject(this, &URokokoStudioCommandAPI::OnProcessRequestComplete); + HttpRequest->SetContentAsString(JsonString); + + if (ARokokoRemote* remote = ARokokoRemote::GetFirstAvailableActor()) + { + HttpRequest->OnProcessRequestComplete().BindUObject(remote, &ARokokoRemote::OnTrackerRequestComplete); + } HttpRequest->ProcessRequest(); } -PRAGMA_DISABLE_OPTIMIZATION +FRokokoCommandAPI_IPInfo URokokoStudioCommandAPI::GetDefaultIPInfo() +{ + FRokokoCommandAPI_IPInfo DefaultIPInfo; + DefaultIPInfo.IPAddress = "127.0.0.1"; + DefaultIPInfo.Port = "14053"; + DefaultIPInfo.APIKey = "1234"; + return DefaultIPInfo; +} + + +/* +//PRAGMA_DISABLE_OPTIMIZATION void URokokoStudioCommandAPI::SaveConfigFile(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& SmartSuitname) { Default_IPInfo = IPInfo; Default_SmartSuitName = SmartSuitname; SaveConfig(); } -PRAGMA_ENABLE_OPTIMIZATION +//PRAGMA_ENABLE_OPTIMIZATION +*/ -void URokokoStudioCommandAPI::OnProcessRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) -{ - int32 ResponseCode = HttpResponse->GetResponseCode(); - FString ResponseString = HttpResponse->GetContentAsString(); - - OnCompletedRequest.Broadcast(ResponseCode, ResponseString, bSucceeded); -} diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/Roles/LiveLinkSmartsuitRole.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/Roles/LiveLinkSmartsuitRole.cpp new file mode 100644 index 0000000..3439198 --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/Roles/LiveLinkSmartsuitRole.cpp @@ -0,0 +1,61 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "Roles/LiveLinkSmartsuitRole.h" +#include "Roles/LiveLinkSmartsuitTypes.h" +#include "Roles/LiveLinkAnimationBlueprintStructs.h" + +#define LOCTEXT_NAMESPACE "LiveLinkRole" + +UScriptStruct* ULiveLinkSmartsuitRole::GetStaticDataStruct() const +{ + return FLiveLinkSmartsuitStaticData::StaticStruct(); +} + +UScriptStruct* ULiveLinkSmartsuitRole::GetFrameDataStruct() const +{ + return FLiveLinkSmartsuitFrameData::StaticStruct(); +} + +UScriptStruct* ULiveLinkSmartsuitRole::GetBlueprintDataStruct() const +{ + return FLiveLinkSmartsuitBlueprintData::StaticStruct(); +} + +bool ULiveLinkSmartsuitRole::InitializeBlueprintData(const FLiveLinkSubjectFrameData& InSourceData, FLiveLinkBlueprintDataStruct& OutBlueprintData) const +{ + //bool bSuccess = false; + + //FLiveLinkSmartsuitBlueprintData* BlueprintData = OutBlueprintData.Cast(); + //const FLiveLinkSmartsuitStaticData* StaticData = InSourceData.StaticData.Cast(); + //const FLiveLinkSmartsuitFrameData* FrameData = InSourceData.FrameData.Cast(); + //if (BlueprintData && StaticData && FrameData) + //{ + // GetStaticDataStruct()->CopyScriptStruct(&BlueprintData->StaticData, StaticData); + // GetFrameDataStruct()->CopyScriptStruct(&BlueprintData->FrameData, FrameData); + // bSuccess = true; + //} + + //return bSuccess; + + bool bSuccess = false; + + //FSubjectFrameHandle* AnimationFrameHandle = OutBlueprintData.Cast(); + //const FLiveLinkSmartsuitStaticData* StaticData = InSourceData.StaticData.Cast(); + //const FLiveLinkSmartsuitFrameData* FrameData = InSourceData.FrameData.Cast(); + //if (AnimationFrameHandle && StaticData && FrameData) + //{ + // AnimationFrameHandle->SetCachedFrame(MakeShared(StaticData, FrameData)); + // bSuccess = true; + //} + + bSuccess = Super::InitializeBlueprintData(InSourceData, OutBlueprintData); + + return bSuccess; +} + +FText ULiveLinkSmartsuitRole::GetDisplayName() const +{ + return LOCTEXT("SmartsuitRole", "Smartsuit"); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitBlueprintLibrary.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitBlueprintLibrary.cpp index fe27fc9..48ced72 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitBlueprintLibrary.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitBlueprintLibrary.cpp @@ -2,6 +2,139 @@ #include "SmartsuitBlueprintLibrary.h" #include "VirtualProductionSource.h" +#include "Engine/SkeletalMesh.h" + + +FFace USmartsuitBlueprintLibrary::GetFaceByFaceID(FString faceId) +{ + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + return livelink->GetFaceByFaceID(faceId); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return FFace(); +} + +FFace USmartsuitBlueprintLibrary::GetFaceByProfileName(const FString& faceName, bool& found) +{ + found = false; + + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + FFace* temp = livelink->GetFaceByProfileName(faceName); + if (temp) + { + found = true; + return FFace(*temp); + } + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return FFace(); +} + +TArray USmartsuitBlueprintLibrary::GetAllFaces() +{ + TArray Faces; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + Faces = livelink->GetAllFaces(); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return Faces; +} + +TArray USmartsuitBlueprintLibrary::GetFacesNotAssociatedWithActor() +{ + TArray FacesNotPairedWithSuit; + for (auto& CurrentFace : GetAllFaces()) + { + bool FoundExistingProfileForFace = false; + + for (auto& CurrentSuit : GetAllSmartsuits()) + { + if (CurrentSuit.id == CurrentFace.profileName) + { + FoundExistingProfileForFace = true; + } + } + + if (!FoundExistingProfileForFace) + { + FacesNotPairedWithSuit.Add(CurrentFace); + } + } + return FacesNotPairedWithSuit; +} + + +FSuitData* USmartsuitBlueprintLibrary::GetSmartsuit(FString suitName) +{ + FSuitData* ReturnValue = nullptr; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + ReturnValue = livelink->GetSmartsuitByName(suitName); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + + return ReturnValue; +} + +bool USmartsuitBlueprintLibrary::GetSmartsuitByName(const FString& suitName, FSuitData& SuitData) +{ + if (FSuitData* smartsuit = GetSmartsuit(suitName)) + { + SuitData = *smartsuit; + return true; + } + SuitData = FSuitData(); + return false; +} + +TArray USmartsuitBlueprintLibrary::GetAllSmartsuits() +{ + TArray Smartsuits; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + Smartsuits = livelink->GetAllSmartsuits(); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return Smartsuits; +} + +TArray USmartsuitBlueprintLibrary::GetAvailableActorNames() +{ + TArray SmartsuitNames; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + SmartsuitNames = livelink->GetAvailableSmartsuitNames(); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return SmartsuitNames; +} ASmartsuitController* USmartsuitBlueprintLibrary::GetSmartsuitControllerByName(FString name) { @@ -43,6 +176,97 @@ ASmartsuitController* USmartsuitBlueprintLibrary::GetSmartsuitController(int id) return actor; } + +FProp* USmartsuitBlueprintLibrary::GetPropByNameFromVP(FString name, bool isLive) +{ + FProp* ReturnValue = nullptr; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + ReturnValue = livelink->GetPropByName(name, isLive); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return ReturnValue; +} + +TArray USmartsuitBlueprintLibrary::GetAllProps() +{ + TArray AllProps; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + + AllProps = livelink->GetAllProps(); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return AllProps; +} + +bool USmartsuitBlueprintLibrary::GetProp(FString name, /*bool isLive, */FProp& OutProp) +{ + if (FProp* prop = GetPropByNameFromVP(name, true)) + { + OutProp = *prop; + return true; + } + OutProp = FProp(); + return false; +} + +FTracker* USmartsuitBlueprintLibrary::GetTrackerByNameFromVP(FString name, bool isLive) +{ + FTracker* Tracker = nullptr; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + Tracker = livelink->GetTrackerByName(name, isLive); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return Tracker; +} + +FTracker USmartsuitBlueprintLibrary::GetTracker(FString name, bool isLive) +{ + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + return *livelink->GetTrackerByName(name, isLive); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); + } + return FTracker(); +} + +FTracker USmartsuitBlueprintLibrary::GetTrackerByConnectionIDFromVP(const FString& name, bool isLive, bool& found) +{ + found = false; + FTracker returnval; + FTracker* temp = nullptr; + auto livelink = FVirtualProductionSource::Get(); + if (livelink.IsValid()) + { + temp = livelink->GetTrackerByConnectionID(name, isLive); + } + if (temp) + { + returnval = *temp; + found = true; + } + return returnval; +} + + void USmartsuitBlueprintLibrary::JSONTest() { FString JsonTest = "{\"version\":0,\"timestamp\":3501.165771484375,\"playbackTimestamp\":36.01746044922,\"props\":[{\"name\":\"Camera-1\",\"id\":\"764cde8d-27d9-4a3a-ac60-e53af5ddfaac\",\"position\":{\"X\":0.62,\"Y\":1.53,\"z\":-0.417694},\"rotation\":{\"x\":0.00904452,\"y\":-0.832524,\"z\":0.063621,\"w\":0.550299},\"isLive\":false,\"profile\":{\"name\":\"Camera\",\"uuid\":\"camera-1\",\"dimensions\":{\"x\":0.23999198,\"y\":0.1805738,\"z\":0.0393033},\"color\":{\"x\":0.85888933,\"y\":0.274593,\"z\":0.380505},\"trackerOffset\":{\"position\":{\"x\":-0.0599549,\"y\":0.099993,\"z\":0.0},\"rotation\":{\"x\":-90.0,\"y\":0.0,\"z\":0.0}},\"pivot\":{\"position\":{\"x\":0.0,\"y\":0.0,\"z\":0.0199165},\"rotation\":{\"x\":0.0,\"y\":0.0,\"z\":0.0}},\"grips\":[],\"propType\":0}},{\"name\":\"Paddle-1\",\"id\":\"3d39d613-db56-49e1-923a-15a43ead2c09\",\"position\":{\"x\":-0.2098624,\"y\":0.34978352,\"z\":-0.2011109},\"rotation\":{\"x\":0.1669078,\"y\":0.8222,\"z\":0.478498,\"w\":-0.303668},\"isLive\":false,\"profile\":{\"name\":\"Stick\",\"uuid\":\"stick-1\",\"dimensions\":{\"x\":0.03033,\"y\":0.699071,\"z\":0.0399033},\"color\":{\"x\":0.6629,\"y\":0.239045,\"z\":0.9814636},\"trackerOffset\":{\"position\":{\"x\":0.0,\"y\":0.156449,\"z\":0.01165},\"rotation\":{\"x\":0.0,\"y\":0.0,\"z\":0.0}},\"pivot\":{\"position\":{\"x\":0.0,\"y\":0.3499355,\"z\":0.0},\"rotation\":{\"x\":0.0,\"y\":0.0,\"z\":180.0}},\"grips\":[],\"propType\":0}}],\"trackers\":[{\"name\":\"2\",\"connectionId\":\"H23\",\"position\":{\"x\":-0.865737,\"y\":1.471664,\"z\":-1.65637984},\"rotation\":{\"x\":0.65916397,\"y\":-0.088037,\"z\":-0.7399105,\"w\":-0.11258},\"isLive\":false,\"trackingResult\":200,\"trackerType\":1,\"RenderModelName\":\"\",\"battery\":0.5931},{\"name\":\"3\",\"connectionId\":\"764cde8d-27d9-4a3a-ac60-e53af5ddfaac\",\"position\":{\"x\":0.663784485,\"y\":1.6378482,\"z\":-0.474449},\"rotation\":{\"x\":-0.3851843,\"y\":-0.6338438,\"z\":-0.551294,\"w\":0.39638153},\"isLive\":false,\"trackingResult\":200,\"trackerType\":1,\"RenderModelName\":\"\",\"battery\":0.592131},{\"name\":\"8\",\"connectionId\":\"3d39d613-db56-49e1-923a-15a43ead2c09\",\"position\":{\"x\":-0.104797,\"y\":0.464008,\"z\":-0.07374},\"rotation\":{\"x\":-0.8070222,\"y\":0.1646839,\"z\":0.3036444,\"w\":0.478498},\"isLive\":false,\"trackingResult\":101,\"trackerType\":1,\"RenderModelName\":\"\",\"battery\":0.939142}],\"faces\":[]}"; @@ -137,7 +361,7 @@ FTransform USmartsuitBlueprintLibrary::GetRefPoseBoneTransform(USkeletalMeshComp { SkelMesh->ClearRefPoseOverride(); FReferenceSkeleton RefSkel; - RefSkel = SkelMesh->SkeletalMesh->RefSkeleton; + RefSkel = SkelMesh->GetSkeletalMeshAsset()->GetRefSkeleton(); BoneTransform = GetWorldSpaceTransform(RefSkel, RefSkel.FindBoneIndex(BoneName)); } @@ -156,7 +380,7 @@ FTransform USmartsuitBlueprintLibrary::GetBoneTransform(USkeletalMeshComponent* if (SkelMesh && !BoneName.IsNone()) { FReferenceSkeleton RefSkel; - RefSkel = SkelMesh->SkeletalMesh->RefSkeleton; + RefSkel = SkelMesh->GetSkeletalMeshAsset()->GetRefSkeleton(); BoneTransform = SkelMesh->GetBoneTransform(RefSkel.FindBoneIndex(BoneName)); } diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitController.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitController.cpp index 9893a65..1373bc4 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitController.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitController.cpp @@ -1,17 +1,14 @@ // Copyright 2019 Rokoko Electronics. All Rights Reserved. #include "SmartsuitController.h" -#include "Smartsuit.h" - +#include "VirtualProductionSource.h" // Sets default values ASmartsuitController::ASmartsuitController() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; - hubInfoRequested = false; bodyModelRequested = false; - hubInfo = nullptr; } // Called when the game starts or when spawned @@ -25,35 +22,19 @@ void ASmartsuitController::BeginPlay() } } -ARokokoReceiver* ASmartsuitController::GetReceiver() -{ - ARokokoReceiver* listener = nullptr; - // Find UObjects by type - for (TObjectIterator It; It; ++It) - { - if (It->enabled) - { - listener = *It; - break; - } - // ... - } - return listener; -} - // Called every frame void ASmartsuitController::Tick(float DeltaTime) { Super::Tick(DeltaTime); - ARokokoReceiver* listener = GetReceiver(); - if (!listener) + auto livelink = FVirtualProductionSource::Get(); + if (!livelink.IsValid()) { return; } if (AutoConnect) { - TArray suitnames = listener->GetAvailableSmartsuitNames(); + TArray suitnames = livelink->GetAvailableSmartsuitNames(); if (suitnames.Num() > 0) { suitname = suitnames[0]; @@ -65,77 +46,14 @@ void ASmartsuitController::Tick(float DeltaTime) return; } - FSuitData *data = listener->GetSmartsuit(suitname); + FSuitData *data = livelink->GetSmartsuitByName(suitname); if (!data) { return; } - if (!hubInfoRequested) - { - hubInfoRequested = true; - GetHubInfo(); - return; - } - //hasProfile = data->hasProfile; - //isBroadcast = data->isBroadcasting; - //fps = data->fps; - //if (fps > 0 && profileToggleState != data->profileToggle) - //{ - // profileToggleState = data->profileToggle; - //} -} - -//void ASmartsuitController::SendCommand(unsigned char cmd, uint8 *customData = nullptr, int customDataLength = 0) { -// if (!SupportsWiFi() && cmd != SMARTSUIT_COMMAND_READ_HUB_INFO) { -// UE_LOG(LogTemp, Warning, TEXT("Can't execute command, since this suit has an unsupported WiFi API version")); -// return; -// } -// -// uint32 myIp = GetLocalIP(); -// -// ARokokoReceiver * receiver = GetReceiver(); -// if (receiver && myIp != 0) { -// if (customData != nullptr) { -// //receiver->SendCommand(suitname, customData, customDataLength); -// } -// else { -// unsigned char data[4] = { GetByte(myIp, 3), GetByte(myIp, 2), cmd, cmd }; -// //receiver->SendCommand(suitname, data, sizeof(char) * 4); -// } -// } -//} - -void ASmartsuitController::Restart() { - //SendCommand(SMARTSUIT_COMMAND_RESET_KALMAN_FILTER); -} - -void ASmartsuitController::Calibrate() { - //SendCommand(SMARTSUIT_COMMAND_PERFORM_APOSE); -} - -void ASmartsuitController::Broadcast() { - //SendCommand(SMARTSUIT_COMMAND_USE_BROADCAST_ADDR); -} - -void ASmartsuitController::Unicast() { - //SendCommand(SMARTSUIT_COMMAND_USE_SPECIFIC_ADDR); -} - -void ASmartsuitController::SetBodyModel(FBodyModel bodyToSet) { - //unsigned char b[sizeof(Body)]; - //Body body = bodyToSet.GetBody(); - //memcpy(b, &body, sizeof(Body)); - - //SendCommand(0, b, sizeof(Body)); -} - -void ASmartsuitController::GetBodyModel() { - //SendCommand(SMARTSUIT_COMMAND_GET_BODY_DIMENSIONS); + } -void ASmartsuitController::GetHubInfo() { - //SendCommand(SMARTSUIT_COMMAND_READ_HUB_INFO); -} uint8 ASmartsuitController::GetByte(uint32 value, int i) { @@ -153,58 +71,6 @@ uint8 ASmartsuitController::GetByte(uint32 value, int i) } } -//uint32 ASmartsuitController::GetLocalIP() { -// -// ARokokoReceiver *receiver = GetReceiver(); -// if (!receiver) { -// return 0; -// } -// SuitData* data = receiver->GetSmartsuit(suitname); -// if (!data) { -// return 0; -// } -// -// bool canBind = false; -// TArray> addresses; -// if(!ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->GetLocalAdapterAddresses(addresses)) -// UE_LOG(LogTemp, Warning, TEXT("Failed to get local adapter addresses")); -// -// uint32 myIp; -// for (int i = 0; i < addresses.Num(); i++) { -// TSharedPtr anIp = addresses[i]; -// if (anIp->IsValid()) { -// anIp->GetIp(myIp); -// if (GetByte(myIp, 2) == GetByte(data->url, 2)) { -// return myIp; -// } -// } -// } -// -//#if PLATFORM_MAC -// // On Mac, the GetLocalAdapterAddresses function only returns the single wildcard ip 0.0.0.0, -// // so we use the linux function getifaddrs() to obtain the local ip in that case (see GetLocalMacIP) -// myIp = GetLocalMacIP(); -// if (GetByte(myIp, 2) == GetByte(data->url, 2)) { -// return myIp; -// } -//#endif -// -// return 0; -//} - -bool ASmartsuitController::SupportsWiFi() { - return hubInfo && ((hubInfo->wifiApiVersion >> 24) & 0xff) == SUPPORTED_MAJOR_WIFI_API; -} - -void ASmartsuitController::UpdateWiFiApiString() { - if (hubInfo) { - uint32 version = hubInfo->wifiApiVersion; - wifiApiVersion = FString::Printf(TEXT("%d.%d.%d"), ((version >> 24) & 0xff), ((version >> 16) & 0xff), ((version >> 8) & 0xff)); - if (!SupportsWiFi()) - wifiApiVersion.Append(TEXT(" - Unsupported!")); - } -} - #if PLATFORM_MAC #include diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitPoseNode.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitPoseNode.cpp index 9e23def..d7f3350 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitPoseNode.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitPoseNode.cpp @@ -1,12 +1,15 @@ // Copyright 2019 Rokoko Electronics. All Rights Reserved. #include "SmartsuitPoseNode.h" -#include "Smartsuit.h" #include "AnimationRuntime.h" -#include "SmartsuitDefinitions.h" +#include "LiveLinkCustomVersion.h" +#include "LiveLinkClient.h" +#include "RokokoSkeletonData.h" #include "Animation/AnimInstanceProxy.h" #include "Roles/LiveLinkAnimationRole.h" #include "SmartsuitBlueprintLibrary.h" +#include "Roles/LiveLinkSmartsuitRole.h" +#include "Roles/LiveLinkSmartsuitTypes.h" @@ -15,59 +18,15 @@ FSmartsuitPoseNode::FSmartsuitPoseNode() { - //UE_LOG(LogTemp, Warning, TEXT("Smartsuit Pose Node: Initializing...")); - //TPose = new SmartsuitTPose(); - - //Controller = nullptr; - //RelativeToStart = false; - //ScaleBones = false; - - //if (Bone_Map_Override_OLD->IsValidLowLevel()) - //{ - // BoneMap.hip = Bone_Map_Override_OLD->hip; - // BoneMap.stomach = Bone_Map_Override_OLD->stomach; - // BoneMap.chest = Bone_Map_Override_OLD->chest; - // BoneMap.neck = Bone_Map_Override_OLD->neck; - // BoneMap.head = Bone_Map_Override_OLD->head; - // BoneMap.headTop = Bone_Map_Override_OLD->headTop; - // BoneMap.leftShoulder = Bone_Map_Override_OLD->leftShoulder; - // BoneMap.leftArm = Bone_Map_Override_OLD->leftArm; - // BoneMap.leftForearm = Bone_Map_Override_OLD->leftForearm; - // BoneMap.leftHand = Bone_Map_Override_OLD->leftHand; - // BoneMap.leftFingerTip = Bone_Map_Override_OLD->leftFingerTip; - // BoneMap.rightShoulder = Bone_Map_Override_OLD->rightShoulder; - // BoneMap.rightArm = Bone_Map_Override_OLD->rightArm; - // BoneMap.rightForearm = Bone_Map_Override_OLD->rightForearm; - // BoneMap.rightHand = Bone_Map_Override_OLD->rightHand; - // BoneMap.rightFingerTip = Bone_Map_Override_OLD->rightFingerTip; - // BoneMap.leftUpleg = Bone_Map_Override_OLD->leftUpleg; - // BoneMap.leftLeg = Bone_Map_Override_OLD->leftLeg; - // BoneMap.leftFoot = Bone_Map_Override_OLD->leftFoot; - // BoneMap.leftToe = Bone_Map_Override_OLD->leftToe; - // BoneMap.rightUpleg = Bone_Map_Override_OLD->rightUpleg; - // BoneMap.rightLeg = Bone_Map_Override_OLD->rightLeg; - // BoneMap.rightFoot = Bone_Map_Override_OLD->rightFoot; - // BoneMap.rightToe = Bone_Map_Override_OLD->rightToe; - //} - - CurrentRetargetAsset = nullptr; } FSmartsuitPoseNode::~FSmartsuitPoseNode() { - //UE_LOG(LogTemp, Warning, TEXT("Smartsuit Pose Node: Cleaning up...")); - /*if (TPose) { - delete TPose; - }*/ } void FSmartsuitPoseNode::GatherDebugData(FNodeDebugData& DebugData) { FString DebugLine = DebugData.GetNodeName(this); - - //DebugLine += "("; - //AddDebugNodeData(DebugLine); - //DebugLine += FString::Printf(TEXT(" Will affect the whole body)")); DebugData.AddDebugItem(DebugLine); ComponentPose.GatherDebugData(DebugData); @@ -89,13 +48,8 @@ void FSmartsuitPoseNode::ApplySmartsuitRotation(FBoneReference bone, FQuat quat, FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); const FQuat BoneQuat(quat); NewBoneTM.SetRotation(BoneQuat); - //FTransform relativeTransform = MeshBases.GetComponentSpaceTransform(BoneMap.hipBone.GetCompactPoseIndex(BoneContainer)); - ////NewBoneTM.SetTranslation(dir) - //NewBoneTM = NewBoneTM * relativeTransform; - //UE_LOG(LogTemp, Warning, TEXT("position is : %f, %f, %f"), NewBoneTM.GetTranslation().X, NewBoneTM.GetTranslation().Y, NewBoneTM.GetTranslation().Z); FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); MeshBases.SetComponentSpaceTransform(CompactPoseBoneToModify, NewBoneTM); - //OutBoneTransforms.Add(FBoneTransform(bone.GetCompactPoseIndex(BoneContainer), NewBoneTM)); } void FSmartsuitPoseNode::ApplySmartsuitPosition(FBoneReference bone, FVector position, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases) @@ -130,13 +84,12 @@ void FSmartsuitPoseNode::ApplySmartsuitTransform(FBoneReference bone, FQuat quat FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(CompactPoseBoneToModify); FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); - //NewBoneTM.SetScale3D(scale); + const FQuat BoneQuat(quat); NewBoneTM.SetRotation(BoneQuat); NewBoneTM.SetTranslation(position); FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); MeshBases.SetComponentSpaceTransform(CompactPoseBoneToModify, NewBoneTM); - //OutBoneTransforms.Add(FBoneTransform(bone.GetCompactPoseIndex(BoneContainer), NewBoneTM)); } void FSmartsuitPoseNode::ApplySmartsuitRotationScale(FBoneReference bone, FQuat quat, FVector scale, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases) @@ -151,7 +104,6 @@ void FSmartsuitPoseNode::ApplySmartsuitRotationScale(FBoneReference bone, FQuat NewBoneTM.SetRotation(BoneQuat); FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); MeshBases.SetComponentSpaceTransform(CompactPoseBoneToModify, NewBoneTM); - //OutBoneTransforms.Add(FBoneTransform(bone.GetCompactPoseIndex(BoneContainer), NewBoneTM)); } float FSmartsuitPoseNode::DistanceBetweenTwoBones(FBoneReference bone1, FBoneReference bone2, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases) @@ -187,9 +139,7 @@ FTransform OriginalTransform(FBoneReference bone, EBoneControlSpace space, USkel FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(CompactPoseBoneToModify); FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); - //UE_LOG(LogTemp, Warning, TEXT("%s: %f, %f, %f, %f"), *name, NewBoneTM.GetRotation().X, NewBoneTM.GetRotation().Y, NewBoneTM.GetRotation().Z, NewBoneTM.GetRotation().W); return NewBoneTM; - //OutBoneTransforms.Add(FBoneTransform(bone.GetCompactPoseIndex(BoneContainer), NewBoneTM)); } TArray FSmartsuitPoseNode::GetAllBoneTransforms(FBoneReference bone, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases) @@ -209,56 +159,11 @@ TArray FSmartsuitPoseNode::GetAllBoneTransforms(FBoneReference bone, FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); result.Add(FTransform(NewBoneTM)); } - //UE_LOG(LogTemp, Warning, TEXT("%s: %f, %f, %f, %f"), *name, NewBoneTM.GetRotation().X, NewBoneTM.GetRotation().Y, NewBoneTM.GetRotation().Z, NewBoneTM.GetRotation().W); return result; - //OutBoneTransforms.Add(FBoneTransform(bone.GetCompactPoseIndex(BoneContainer), NewBoneTM)); } void FSmartsuitPoseNode::ApplyAllBonePositions(FBoneReference bone, float hipWidth, TArray transforms, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases) { - //const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer(); - //int index = 0; - //for (int i = bone.BoneIndex + 1; i < BoneContainer.GetNumBones(); i++) - //{ - // if (i == BoneMap.leftUpleg.BoneIndex || i == BoneMap.rightUpleg.BoneIndex) - // { - // FVector hipWPos = OriginalTransform(BoneMap.hip, space, SkelComp, MeshBases).GetTranslation(); - // - // FVector upLegWPos; - // if (i == BoneMap.leftUpleg.BoneIndex) - // { - // upLegWPos = OriginalTransform(BoneMap.leftUpleg, space, SkelComp, MeshBases).GetTranslation(); - // } - // else - // { - // upLegWPos = OriginalTransform(BoneMap.rightUpleg, space, SkelComp, MeshBases).GetTranslation(); - // } - // FVector diff = upLegWPos - hipWPos; - // FVector dir; - // float length; - // diff.ToDirectionAndLength(dir, length); - // FCompactPoseBoneIndex CompactPoseBoneToModify(i); - // FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(CompactPoseBoneToModify); - // //UE_LOG(LogTemp, Warning, TEXT("UpLeg found, will use world lenght: %f, with dir %f, %f, %f"), hipWidth / 2, diff.X, diff.Y, diff.Z); - - // //if (i == BoneMap.) - // FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); - // NewBoneTM.SetTranslation(hipWPos + (dir * (hipWidth / 2))); - // FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); - // MeshBases.SetComponentSpaceTransform(CompactPoseBoneToModify, NewBoneTM); - // } - // else - // { - // FCompactPoseBoneIndex CompactPoseBoneToModify(i); - // FTransform NewBoneTM = MeshBases.GetComponentSpaceTransform(CompactPoseBoneToModify); - // //if (i == BoneMap.) - // FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); - // NewBoneTM.SetTranslation(transforms[index].GetTranslation()); - // FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp->GetComponentTransform(), MeshBases, NewBoneTM, CompactPoseBoneToModify, space); - // MeshBases.SetComponentSpaceTransform(CompactPoseBoneToModify, NewBoneTM); - // } - // index++; - //} } FVector FSmartsuitPoseNode::GetBoneScale(FBoneReference scaleBone, FBoneReference bone1, FBoneReference bone2, float desiredDistance, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases) @@ -271,46 +176,17 @@ FVector FSmartsuitPoseNode::GetBoneScale(FBoneReference scaleBone, FBoneReferenc float FSmartsuitPoseNode::ScaleBonesToDistance(FBoneReference scaleBone, FBoneReference bone1, FBoneReference bone2, float desiredDistance, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases) { - //scale bones... - //FVector nextBonePosition = OriginalTransform(nextBone, EBoneControlSpace::BCS_ParentBoneSpace, SkelComp, MeshBases).GetTranslation(); - float currBoneDistance = DistanceBetweenTwoBones(bone1, bone2, space, SkelComp, MeshBases); FVector currScale = OriginalTransform(scaleBone, space, SkelComp, MeshBases).GetTranslation(); float boneScale = desiredDistance / currBoneDistance; - //float boneScale = 10.f; + ApplySmartsuitScale(scaleBone, FVector(boneScale, boneScale, boneScale), space, SkelComp, MeshBases); - - //ApplySmartsuitPosition(nextBone, nextBonePosition, EBoneControlSpace::BCS_ParentBoneSpace, SkelComp, MeshBases); return boneScale; } -//FQuat GetRotation(uint8 sensor, Sensor *sensors, int numOfSensors) -//{ -// for (int s = 0; s < numOfSensors; s++) -// { -// if (sensors[s].addr == sensor) -// { -// return sensors[s].Uquaternion(); -// } -// } -// return FQuat::Identity; -//} -// -//FVector GetPosition(uint8 sensor, Sensor *sensors, int numOfSensors) -//{ -// for (int s = 0; s < numOfSensors; s++) -// { -// if (sensors[s].addr == sensor) -// { -// return sensors[s].UPosition(); -// } -// } -// return FVector::ZeroVector; -//} - FQuat GetRotation2(const FName& BoneName, FSuitData* suitdata) { - if (auto SmartsuitBone = suitdata->SmartsuitBones.Find(BoneName)) + if (auto SmartsuitBone = suitdata->bones.Find(BoneName)) { return SmartsuitBone->Uquaternion(); } @@ -320,7 +196,7 @@ FQuat GetRotation2(const FName& BoneName, FSuitData* suitdata) FVector GetPosition2(const FName& BoneName, FSuitData* suitdata) { - if (auto SmartsuitBone = suitdata->SmartsuitBones.Find(BoneName)) + if (auto SmartsuitBone = suitdata->bones.Find(BoneName)) { return SmartsuitBone->UPosition(); } @@ -356,44 +232,46 @@ FVector GetPosition3(const FName& BoneName, FLiveLinkSubjectFrameData &InSubject return FVector::ZeroVector; } -PRAGMA_DISABLE_OPTIMIZATION +//PRAGMA_DISABLE_OPTIMIZATION void FSmartsuitPoseNode::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& Output, TArray& OutBoneTransforms) { USkeletalMeshComponent* SkelComp = Output.AnimInstanceProxy->GetSkelMeshComponent(); FCSPose& MeshBases = Output.Pose; check(OutBoneTransforms.Num() == 0); - //if (!Controller/* || !Controller->SupportsWiFi()*/) - //{ - // return; - //} - - ARokokoReceiver *receiver = GetReceiver(); - if (!receiver) - { - //UE_LOG(LogTemp, Warning, TEXT("No receiver")); - //return; - } - FSuitData* data = nullptr;//receiver->GetSmartsuit(Controller->suitname); - if (!data) - { - //UE_LOG(LogTemp, Warning, TEXT("No data for %s"), *Controller->suitname); - //return; - } - - if (!LiveLinkClient_AnyThread || !CurrentRetargetAsset) + + + if (!LiveLinkClient_AnyThread /*|| !CurrentRetargetAsset*/) { return; } - FLiveLinkSubjectFrameData SubjectFrameData; - FLiveLinkSubjectName LiveLinkSubjectName = GetLiveLinkSubjectName(); - TSubclassOf SubjectRole = LiveLinkClient_AnyThread->GetSubjectRole(LiveLinkSubjectName); + TSubclassOf SubjectRole = LiveLinkClient_AnyThread->GetSubjectRole_AnyThread(LiveLinkSubjectName); if (SubjectRole) { +#ifdef USE_SMARTSUIT_ANIMATION_ROLE + if (SubjectRole->IsChildOf(ULiveLinkSmartsuitRole::StaticClass())) + { + //Process animation data if the subject is from that type + if (LiveLinkClient_AnyThread->EvaluateFrame_AnyThread(LiveLinkSubjectName, ULiveLinkSmartsuitRole::StaticClass(), SubjectFrameData)) + { + + } + else + { + return; + } + + + } + else + { + return; + } +#else if (SubjectRole->IsChildOf(ULiveLinkAnimationRole::StaticClass())) { //Process animation data if the subject is from that type @@ -405,58 +283,36 @@ void FSmartsuitPoseNode::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseCo { return; } - } + + + } else { return; } +#endif } else { return; } - +#ifdef USE_SMARTSUIT_ANIMATION_ROLE + FLiveLinkSmartsuitStaticData* SkeletonData = SubjectFrameData.StaticData.Cast(); + FLiveLinkSmartsuitFrameData* FrameData = SubjectFrameData.FrameData.Cast(); +#else FLiveLinkSkeletonStaticData* SkeletonData = SubjectFrameData.StaticData.Cast(); FLiveLinkAnimationFrameData* FrameData = SubjectFrameData.FrameData.Cast(); +#endif + check(SkeletonData); check(FrameData); - - //SkeletonData->PropertyNames.Find() - - EBoneControlSpace TestBoneControlSpace = BCS_ComponentSpace; - if (!TPose.StoredTPose) + if (!TPose.StoredTPose /*&& CurrentRetargetAsset*/) { - - //if (RelativeToStart) - //{ - // if (data->Hip()) - // { - // TPose.startPos = FVector(OriginalTransform(BoneMap.hip, TestBoneControlSpace, SkelComp, MeshBases).GetTranslation()) - data->Hip()->UPosition();//SkelComp->GetComponentLocation(); - - // //TPose.startPos.X = 0; - // //TPose.startPos.Y = 0; - // //TPose.startPos.Z = 0; - // } - // else - // { - // TPose.startPos = FVector::ZeroVector; - // } - //} - //else - //{ - // TPose.startPos = FVector::ZeroVector; - // //SkelComp->SetWorldRotation(FRotator::ZeroRotator); - //} - - - - //TPose.startPos = FVector(OriginalTransform(BoneMap.hip, EBoneControlSpace::BCS_WorldSpace, SkelComp, MeshBases).GetTranslation()); - TPose.Pose.hip = OriginalTransform(BoneMap.hip, TestBoneControlSpace, SkelComp, MeshBases); TPose.Pose.stomach = OriginalTransform(BoneMap.stomach, TestBoneControlSpace, SkelComp, MeshBases); TPose.Pose.chest = OriginalTransform(BoneMap.chest, TestBoneControlSpace, SkelComp, MeshBases); @@ -529,6 +385,11 @@ void FSmartsuitPoseNode::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseCo FQuat modifier = FQuat::MakeFromEuler(FVector(0, 0, 180)); FQuat forwardModifier = FQuat::MakeFromEuler(FVector(0, 0, 90)); + // These duplicate variables are a bit redundant in their current state, however lets keep these around in case we need to negate an axis for example + FQuat LeftShoulderSpace = FQuat::MakeFromEuler(FVector(ShoulderSpace, 0.0f, 0.0f)); + FQuat RightShoulderSpace = FQuat::MakeFromEuler(FVector(ShoulderSpace, 0.0f, 0.0f)); + FQuat LeftArmSpace = FQuat::MakeFromEuler(FVector(ArmSpace, 0.0f, 0.0f)); + FQuat RightArmSpace = FQuat::MakeFromEuler(FVector(ArmSpace, 0.0f, 0.0f)); FQuat hipQuat = GetRotation3(SmartsuitBones::hip, SubjectFrameData);// *modifier; FVector hipPosition = GetPosition3(SmartsuitBones::hip, SubjectFrameData); @@ -536,12 +397,12 @@ void FSmartsuitPoseNode::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseCo FQuat chestQuat = GetRotation3(SmartsuitBones::chest, SubjectFrameData); FQuat neckQuat = GetRotation3(SmartsuitBones::neck, SubjectFrameData); FQuat headQuat = GetRotation3(SmartsuitBones::head, SubjectFrameData); - FQuat leftShoulderQuat = GetRotation3(SmartsuitBones::leftShoulder, SubjectFrameData); - FQuat leftArmQuat = GetRotation3(SmartsuitBones::leftUpperArm, SubjectFrameData); + FQuat leftShoulderQuat = GetRotation3(SmartsuitBones::leftShoulder, SubjectFrameData) * LeftShoulderSpace; + FQuat leftArmQuat = GetRotation3(SmartsuitBones::leftUpperArm, SubjectFrameData) * LeftArmSpace; FQuat leftForearmQuat = GetRotation3(SmartsuitBones::leftLowerArm, SubjectFrameData); FQuat leftHandQuat = GetRotation3(SmartsuitBones::leftHand, SubjectFrameData); - FQuat rightShoulderQuat = GetRotation3(SmartsuitBones::rightShoulder, SubjectFrameData); - FQuat rightArmQuat = GetRotation3(SmartsuitBones::rightUpperArm, SubjectFrameData); + FQuat rightShoulderQuat = GetRotation3(SmartsuitBones::rightShoulder, SubjectFrameData) * RightShoulderSpace; + FQuat rightArmQuat = GetRotation3(SmartsuitBones::rightUpperArm, SubjectFrameData) * RightArmSpace; FQuat rightForearmQuat = GetRotation3(SmartsuitBones::rightLowerArm, SubjectFrameData); FQuat rightHandQuat = GetRotation3(SmartsuitBones::rightHand, SubjectFrameData); FQuat leftUpLegQuat = GetRotation3(SmartsuitBones::leftUpLeg, SubjectFrameData); @@ -716,8 +577,29 @@ void FSmartsuitPoseNode::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseCo // ApplySmartsuitTransform(BoneMap.hip, SuitRotation, SuitLocation, FVector(1, 1, 1), SuitTransformBoneControlSpace, SkelComp, MeshBases); //} + // Apply root motion, if relevant + if (bApplyRootMotion) + { + FVector NewRootPosition = hipPosition; + NewRootPosition.Z = 0.0f; + + // Make sure to initialize root motion position, otherwise we will get erronous results + if (!bInitializedRootPosition) + { + OldRootPosition = NewRootPosition; + bInitializedRootPosition = true; + } + + FVector RootDelta = NewRootPosition - OldRootPosition; + OldRootPosition = NewRootPosition; + FTransform NewRootTransform; + NewRootTransform.SetRotation(FQuat::Identity); + NewRootTransform.SetScale3D(FVector::OneVector); + NewRootTransform.SetTranslation(RootDelta); + Output.AnimInstanceProxy->GetExtractedRootMotion().Accumulate(NewRootTransform); + } ApplySmartsuitRotation(BoneMap.stomach, stomachQuat* stomachExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); ApplySmartsuitRotation(BoneMap.chest, chestQuat* chestExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); @@ -740,114 +622,86 @@ void FSmartsuitPoseNode::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseCo ApplySmartsuitRotation(BoneMap.rightFoot, rightFootQuat* rightFootExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); ApplySmartsuitRotation(BoneMap.rightToe, rightToeQuat* rightToeExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftThumbProximal, leftThumbProximalQuat * leftThumbProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftThumbMedial, leftThumbMedialQuat * leftThumbMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftThumbDistal, leftThumbDistalQuat * leftThumbDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftThumbTip, leftThumbTipQuat * leftThumbTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftIndexProximal, leftIndexProximalQuat * leftIndexProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftIndexMedial, leftIndexMedialQuat * leftIndexMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftIndexDistal, leftIndexDistalQuat * leftIndexDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftIndexTip, leftIndexTipQuat * leftIndexTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftMiddleProximal, leftMiddleProximalQuat * leftMiddleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftMiddleMedial, leftMiddleMedialQuat * leftMiddleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftMiddleDistal, leftMiddleDistalQuat * leftMiddleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftMiddleTip, leftMiddleTipQuat * leftMiddleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftRingProximal, leftRingProximalQuat * leftRingProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftRingMedial, leftRingMedialQuat * leftRingMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftRingDistal, leftRingDistalQuat * leftRingDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftRingTip, leftRingTipQuat * leftRingTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftLittleProximal, leftLittleProximalQuat * leftLittleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftLittleMedial, leftLittleMedialQuat * leftLittleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftLittleDistal, leftLittleDistalQuat * leftLittleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.leftLittleTip, leftLittleTipQuat * leftLittleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightThumbProximal, rightThumbProximalQuat * rightThumbProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightThumbMedial, rightThumbMedialQuat * rightThumbMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightThumbDistal, rightThumbDistalQuat * rightThumbDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightThumbTip, rightThumbTipQuat * rightThumbTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightIndexProximal, rightIndexProximalQuat * rightIndexProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightIndexMedial, rightIndexMedialQuat * rightIndexMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightIndexDistal, rightIndexDistalQuat * rightIndexDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightIndexTip, rightIndexTipQuat * rightIndexTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightMiddleProximal, rightMiddleProximalQuat * rightMiddleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightMiddleMedial, rightMiddleMedialQuat * rightMiddleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightMiddleDistal, rightMiddleDistalQuat * rightMiddleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightMiddleTip, rightMiddleTipQuat * rightMiddleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightRingProximal, rightRingProximalQuat * rightRingProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightRingMedial, rightRingMedialQuat * rightRingMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightRingDistal, rightRingDistalQuat * rightRingDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightRingTip, rightRingTipQuat * rightRingTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightLittleProximal, rightLittleProximalQuat * rightLittleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightLittleMedial, rightLittleMedialQuat * rightLittleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightLittleDistal, rightLittleDistalQuat * rightLittleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); - ApplySmartsuitRotation(BoneMap.rightLittleTip, rightLittleTipQuat * rightLittleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + bool HasLeftGlove = true; + bool HasRightGlove = true; + + #ifdef USE_SMARTSUIT_ANIMATION_ROLE + HasLeftGlove = FrameData->HasLeftGlove; + HasRightGlove = FrameData->HasRightGlove; + #endif + + if(HasLeftGlove) + { + ApplySmartsuitRotation(BoneMap.leftThumbProximal, leftThumbProximalQuat * leftThumbProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftThumbMedial, leftThumbMedialQuat * leftThumbMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftThumbDistal, leftThumbDistalQuat * leftThumbDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftThumbTip, leftThumbTipQuat * leftThumbTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftIndexProximal, leftIndexProximalQuat * leftIndexProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftIndexMedial, leftIndexMedialQuat * leftIndexMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftIndexDistal, leftIndexDistalQuat * leftIndexDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftIndexTip, leftIndexTipQuat * leftIndexTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftMiddleProximal, leftMiddleProximalQuat * leftMiddleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftMiddleMedial, leftMiddleMedialQuat * leftMiddleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftMiddleDistal, leftMiddleDistalQuat * leftMiddleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftMiddleTip, leftMiddleTipQuat * leftMiddleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftRingProximal, leftRingProximalQuat * leftRingProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftRingMedial, leftRingMedialQuat * leftRingMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftRingDistal, leftRingDistalQuat * leftRingDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftRingTip, leftRingTipQuat * leftRingTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftLittleProximal, leftLittleProximalQuat * leftLittleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftLittleMedial, leftLittleMedialQuat * leftLittleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftLittleDistal, leftLittleDistalQuat * leftLittleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.leftLittleTip, leftLittleTipQuat * leftLittleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + } + + if (HasRightGlove) + { + ApplySmartsuitRotation(BoneMap.rightThumbProximal, rightThumbProximalQuat * rightThumbProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightThumbMedial, rightThumbMedialQuat * rightThumbMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightThumbDistal, rightThumbDistalQuat * rightThumbDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightThumbTip, rightThumbTipQuat * rightThumbTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightIndexProximal, rightIndexProximalQuat * rightIndexProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightIndexMedial, rightIndexMedialQuat * rightIndexMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightIndexDistal, rightIndexDistalQuat * rightIndexDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightIndexTip, rightIndexTipQuat * rightIndexTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightMiddleProximal, rightMiddleProximalQuat * rightMiddleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightMiddleMedial, rightMiddleMedialQuat * rightMiddleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightMiddleDistal, rightMiddleDistalQuat * rightMiddleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightMiddleTip, rightMiddleTipQuat * rightMiddleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightRingProximal, rightRingProximalQuat * rightRingProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightRingMedial, rightRingMedialQuat * rightRingMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightRingDistal, rightRingDistalQuat * rightRingDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightRingTip, rightRingTipQuat * rightRingTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightLittleProximal, rightLittleProximalQuat * rightLittleProximalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightLittleMedial, rightLittleMedialQuat * rightLittleMedialExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightLittleDistal, rightLittleDistalQuat * rightLittleDistalExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + ApplySmartsuitRotation(BoneMap.rightLittleTip, rightLittleTipQuat * rightLittleTipExpected, hipQuat, TestBoneControlSpace, SkelComp, MeshBases); + } } -PRAGMA_ENABLE_OPTIMIZATION +//PRAGMA_ENABLE_OPTIMIZATION bool FSmartsuitPoseNode::IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones) { return true; -// -// // if both bones are valid -// return (BoneMap.hip.IsValidToEvaluate(RequiredBones) && /*BoneMap.chest.IsValidToEvaluate(RequiredBones) &&*/ BoneMap.stomach.IsValidToEvaluate(RequiredBones) && -// BoneMap.neck.IsValidToEvaluate(RequiredBones) && BoneMap.head.IsValidToEvaluate(RequiredBones) /*&& BoneMap.headTop.IsValidToEvaluate(RequiredBones)*/ && -// BoneMap.leftShoulder.IsValidToEvaluate(RequiredBones) && BoneMap.leftArm.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftForearm.IsValidToEvaluate(RequiredBones) && BoneMap.leftHand.IsValidToEvaluate(RequiredBones) /*&& BoneMap.leftFingerTip.IsValidToEvaluate(RequiredBones)*/ && -// BoneMap.rightShoulder.IsValidToEvaluate(RequiredBones) && BoneMap.rightArm.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightForearm.IsValidToEvaluate(RequiredBones) && BoneMap.rightHand.IsValidToEvaluate(RequiredBones) /*&& BoneMap.rightFingerTip.IsValidToEvaluate(RequiredBones)*/ && -// BoneMap.leftUpleg.IsValidToEvaluate(RequiredBones) && BoneMap.leftLeg.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftFoot.IsValidToEvaluate(RequiredBones) && BoneMap.rightUpleg.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightLeg.IsValidToEvaluate(RequiredBones) && BoneMap.rightFoot.IsValidToEvaluate(RequiredBones) && -// /*BoneMap.leftToe.IsValidToEvaluate(RequiredBones)*/ /*&& BoneMap.rightToe.IsValidToEvaluate(RequiredBones)*/ -// BoneMap.leftThumbProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftThumbMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftThumbDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftThumbTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftIndexProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftIndexMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftIndexDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftIndexTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftMiddleProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftMiddleMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftMiddleDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftMiddleTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftRingProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftRingMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftRingDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftRingTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftLittleProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftLittleMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftLittleDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.leftLittleTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightThumbProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightThumbMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightThumbDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightThumbTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightIndexProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightIndexMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightIndexDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightIndexTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightMiddleProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightMiddleMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightMiddleDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightMiddleTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightRingProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightRingMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightRingDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightRingTip.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightLittleProximal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightLittleMedial.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightLittleDistal.IsValidToEvaluate(RequiredBones) && -// BoneMap.rightLittleTip.IsValidToEvaluate(RequiredBones) -// ); - } void FSmartsuitPoseNode::PreUpdate(const UAnimInstance* InAnimInstance) { Super::PreUpdate(InAnimInstance); + + ILiveLinkClient* ThisFrameClient = nullptr; + IModularFeatures& ModularFeatures = IModularFeatures::Get(); + if (ModularFeatures.IsModularFeatureAvailable(ILiveLinkClient::ModularFeatureName)) + { + ThisFrameClient = &IModularFeatures::Get().GetModularFeature(ILiveLinkClient::ModularFeatureName); + } + LiveLinkClient_AnyThread = ThisFrameClient; - LiveLinkClient_AnyThread = LiveLinkClient_GameThread.GetClient(); + CreateRetargetAsset(InAnimInstance); +} +void FSmartsuitPoseNode::CreateRetargetAsset(const UAnimInstance* InAnimInstance) +{ // Protection as a class graph pin does not honor rules on abstract classes and NoClear UClass* RetargetAssetPtr = RetargetAsset.Get(); if (!RetargetAssetPtr || RetargetAssetPtr->HasAnyClassFlags(CLASS_Abstract)) @@ -867,69 +721,6 @@ void FSmartsuitPoseNode::InitializeBoneReferences(const FBoneContainer& Required { if (CurrentRetargetAsset->IsValidLowLevel()) { - //BoneMap.hip = Bone_Map_Override_OLD->hip; - //BoneMap.stomach = Bone_Map_Override_OLD->stomach; - //BoneMap.chest = Bone_Map_Override_OLD->chest; - //BoneMap.neck = Bone_Map_Override_OLD->neck; - //BoneMap.head = Bone_Map_Override_OLD->head; - //BoneMap.leftShoulder = Bone_Map_Override_OLD->leftShoulder; - //BoneMap.leftArm = Bone_Map_Override_OLD->leftArm; - //BoneMap.leftForearm = Bone_Map_Override_OLD->leftForearm; - //BoneMap.leftHand = Bone_Map_Override_OLD->leftHand; - //BoneMap.rightShoulder = Bone_Map_Override_OLD->rightShoulder; - //BoneMap.rightArm = Bone_Map_Override_OLD->rightArm; - //BoneMap.rightForearm = Bone_Map_Override_OLD->rightForearm; - //BoneMap.rightHand = Bone_Map_Override_OLD->rightHand; - //BoneMap.leftUpleg = Bone_Map_Override_OLD->leftUpleg; - //BoneMap.leftLeg = Bone_Map_Override_OLD->leftLeg; - //BoneMap.leftFoot = Bone_Map_Override_OLD->leftFoot; - //BoneMap.leftToe = Bone_Map_Override_OLD->leftToe; - //BoneMap.rightUpleg = Bone_Map_Override_OLD->rightUpleg; - //BoneMap.rightLeg = Bone_Map_Override_OLD->rightLeg; - //BoneMap.rightFoot = Bone_Map_Override_OLD->rightFoot; - //BoneMap.rightToe = Bone_Map_Override_OLD->rightToe; - - //BoneMap.leftThumbProximal = Bone_Map_Override_OLD->leftThumbProximal; - //BoneMap.leftThumbMedial = Bone_Map_Override_OLD->leftThumbMedial; - //BoneMap.leftThumbDistal = Bone_Map_Override_OLD->leftThumbDistal; - //BoneMap.leftThumbTip = Bone_Map_Override_OLD->leftThumbTip; - //BoneMap.leftIndexProximal = Bone_Map_Override_OLD->leftIndexProximal; - //BoneMap.leftIndexMedial = Bone_Map_Override_OLD->leftIndexMedial; - //BoneMap.leftIndexDistal = Bone_Map_Override_OLD->leftIndexDistal; - //BoneMap.leftIndexTip = Bone_Map_Override_OLD->leftIndexTip; - //BoneMap.leftMiddleProximal = Bone_Map_Override_OLD->leftMiddleProximal; - //BoneMap.leftMiddleMedial = Bone_Map_Override_OLD->leftMiddleMedial; - //BoneMap.leftMiddleDistal = Bone_Map_Override_OLD->leftMiddleDistal; - //BoneMap.leftMiddleTip = Bone_Map_Override_OLD->leftMiddleTip; - //BoneMap.leftRingProximal = Bone_Map_Override_OLD->leftRingProximal; - //BoneMap.leftRingMedial = Bone_Map_Override_OLD->leftRingMedial; - //BoneMap.leftRingDistal = Bone_Map_Override_OLD->leftRingDistal; - //BoneMap.leftRingTip = Bone_Map_Override_OLD->leftRingTip; - //BoneMap.leftLittleProximal = Bone_Map_Override_OLD->leftLittleProximal; - //BoneMap.leftLittleMedial = Bone_Map_Override_OLD->leftLittleMedial; - //BoneMap.leftLittleDistal = Bone_Map_Override_OLD->leftLittleDistal; - //BoneMap.leftLittleTip = Bone_Map_Override_OLD->leftLittleTip; - //BoneMap.rightThumbProximal = Bone_Map_Override_OLD->rightThumbProximal; - //BoneMap.rightThumbMedial = Bone_Map_Override_OLD->rightThumbMedial; - //BoneMap.rightThumbDistal = Bone_Map_Override_OLD->rightThumbDistal; - //BoneMap.rightThumbTip = Bone_Map_Override_OLD->rightThumbTip; - //BoneMap.rightIndexProximal = Bone_Map_Override_OLD->rightIndexProximal; - //BoneMap.rightIndexMedial = Bone_Map_Override_OLD->rightIndexMedial; - //BoneMap.rightIndexDistal = Bone_Map_Override_OLD->rightIndexDistal; - //BoneMap.rightIndexTip = Bone_Map_Override_OLD->rightIndexTip; - //BoneMap.rightMiddleProximal = Bone_Map_Override_OLD->rightMiddleProximal; - //BoneMap.rightMiddleMedial = Bone_Map_Override_OLD->rightMiddleMedial; - //BoneMap.rightMiddleDistal = Bone_Map_Override_OLD->rightMiddleDistal; - //BoneMap.rightMiddleTip = Bone_Map_Override_OLD->rightMiddleTip; - //BoneMap.rightRingProximal = Bone_Map_Override_OLD->rightRingProximal; - //BoneMap.rightRingMedial = Bone_Map_Override_OLD->rightRingMedial; - //BoneMap.rightRingDistal = Bone_Map_Override_OLD->rightRingDistal; - //BoneMap.rightRingTip = Bone_Map_Override_OLD->rightRingTip; - //BoneMap.rightLittleProximal = Bone_Map_Override_OLD->rightLittleProximal; - //BoneMap.rightLittleMedial = Bone_Map_Override_OLD->rightLittleMedial; - //BoneMap.rightLittleDistal = Bone_Map_Override_OLD->rightLittleDistal; - //BoneMap.rightLittleTip = Bone_Map_Override_OLD->rightLittleTip; - BoneMap.hip = CurrentRetargetAsset->GetRemappedBoneName("hip"); BoneMap.stomach = CurrentRetargetAsset->GetRemappedBoneName("stomach"); BoneMap.chest = CurrentRetargetAsset->GetRemappedBoneName("chest"); @@ -1067,88 +858,30 @@ FLiveLinkSubjectName FSmartsuitPoseNode::GetLiveLinkSubjectName() #endif } -//USmartsuitBodyMapData::USmartsuitBodyMapData() -//{ -// hip = "hip"; -// stomach = "stomach"; -// chest = "chest"; -// neck = "neck"; -// head = "head"; -// leftShoulder = "leftShoulder"; -// leftArm = "leftArm"; -// leftForearm = "leftForearm"; -// leftHand = "leftHand"; -// rightShoulder = "rightShoulder"; -// rightArm = "rightArm"; -// rightForearm = "rightForearm"; -// rightHand = "rightHand"; -// leftUpleg = "leftUpleg"; -// leftLeg = "leftLeg"; -// leftFoot = "leftFoot"; -// leftToe = "leftToe"; -// rightUpleg = "rightUpleg"; -// rightLeg = "rightLeg"; -// rightFoot = "rightFoot"; -// rightToe = "rightToe"; -// leftThumbProximal = "leftThumbProximal"; -// leftThumbMedial = "leftThumbMedial"; -// leftThumbDistal = "leftThumbDistal"; -// leftThumbTip = "leftThumbTip"; -// leftIndexProximal = "leftIndexProximal"; -// leftIndexMedial = "leftIndexMedial"; -// leftIndexDistal = "leftIndexDistal"; -// leftIndexTip = "leftIndexTip"; -// leftMiddleProximal = "leftMiddleProximal"; -// leftMiddleMedial = "leftMiddleMedial"; -// leftMiddleDistal = "leftMiddleDistal"; -// leftMiddleTip = "leftMiddleTip"; -// leftRingProximal = "leftRingProximal"; -// leftRingMedial = "leftRingMedial"; -// leftRingDistal = "leftRingDistal"; -// leftRingTip = "leftRingTip"; -// leftLittleProximal = "leftLittleProximal"; -// leftLittleMedial = "leftLittleMedial"; -// leftLittleDistal = "leftLittleDistal"; -// leftLittleTip = "leftLittleTip"; -// rightThumbProximal = "rightThumbProximal"; -// rightThumbMedial = "rightThumbMedial"; -// rightThumbDistal = "rightThumbDistal"; -// rightThumbTip = "rightThumbTip"; -// rightIndexProximal = "rightIndexProximal"; -// rightIndexMedial = "rightIndexMedial"; -// rightIndexDistal = "rightIndexDistal"; -// rightIndexTip = "rightIndexTip"; -// rightMiddleProximal = "rightMiddleProximal"; -// rightMiddleMedial = "rightMiddleMedial"; -// rightMiddleDistal = "rightMiddleDistal"; -// rightMiddleTip = "rightMiddleTip"; -// rightRingProximal = "rightRingProximal"; -// rightRingMedial = "rightRingMedial"; -// rightRingDistal = "rightRingDistal"; -// rightRingTip = "rightRingTip"; -// rightLittleProximal = "rightLittleProximal"; -// rightLittleMedial = "rightLittleMedial"; -// rightLittleDistal = "rightLittleDistal"; -// rightLittleTip = "rightLittleTip"; -//} - -//FName URokokoBodyMapData::GetRemappedBoneName_Implementation(FName CurveName) const -//{ -// if (auto RemappedName = NameMapping.Find(CurveName)) -// { -// return *RemappedName; -// } -// return ""; -//} -// -//void URokokoBodyMapData::Initialize() -//{ -// InitializeTMap(); -//} void FSmartsuitPoseNode::OnInitializeAnimInstance(const FAnimInstanceProxy* InProxy, const UAnimInstance* InAnimInstance) { - CurrentRetargetAsset = nullptr; - Super::OnInitializeAnimInstance(InProxy, InAnimInstance); +} + +void FSmartsuitPoseNode::UpdateComponentPose_AnyThread(const FAnimationUpdateContext& Context) +{ + // Evaluate any BP logic plugged into this node + GetEvaluateGraphExposedInputs().Execute(Context); + + Super::UpdateComponentPose_AnyThread(Context); +} + +void FSmartsuitPoseNode::UpdateInternal(const FAnimationUpdateContext & Context) +{ + GetEvaluateGraphExposedInputs().Execute(Context); + + Super::UpdateInternal(Context); +} + +void FSmartsuitPoseNode::Initialize_AnyThread(const FAnimationInitializeContext& Context) +{ + GetEvaluateGraphExposedInputs().Execute(Context); + + Super::Initialize_AnyThread(Context); } \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitReceiver.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitReceiver.cpp deleted file mode 100644 index baff76b..0000000 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitReceiver.cpp +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2019 Rokoko Electronics. All Rights Reserved. - -#include "SmartsuitReceiver.h" -#include "Smartsuit.h" - - - -// Sets default values -ARokokoReceiver::ARokokoReceiver() -{ - // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. - PrimaryActorTick.bCanEverTick = true; - RokokoPortNumber = 14045; -} - -// Called when the game starts or when spawned -void ARokokoReceiver::BeginPlay() -{ - Super::BeginPlay(); - //StartListener(); - //enabled = true; - //realLife = true; -} - -void ARokokoReceiver::BeginDestroy() -{ - Super::BeginDestroy(); - //StopListener(); -} - -// Called every frame -void ARokokoReceiver::Tick(float DeltaTime) -{ - Super::Tick(DeltaTime); -} - - -void ARokokoReceiver::StartListener() -{ - //UE_LOG(LogTemp, Warning, TEXT("Listening...")); - ////listener.Start(streamingDataPort); - //VPlistener.Start(RokokoPortNumber); -} - -void ARokokoReceiver::StopListener() -{ - ////listener.Stop(); - //VPlistener.Stop(); - //UE_LOG(LogTemp, Warning, TEXT("Not listening...")); -} - -FFace ARokokoReceiver::GetFaceByFaceID(FString faceId) -{ - //return VPlistener.GetFaceByFaceID(faceId); - - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - return livelink->GetFaceByFaceID(faceId); - } - - return FFace(); -} - -FFace ARokokoReceiver::GetFaceByProfileName(const FString& faceName, bool& found) -{ - //return *VPlistener.GetFaceByProfileName(faceName); - - found = false; - FFace returnval; - - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - FFace* temp = livelink->GetFaceByProfileName(faceName); - if (temp) - { - returnval = *temp; - found = true; - } - } - return returnval; -} - -TArray ARokokoReceiver::GetAllFaces() -{ - //return VPlistener.GetAllFaces(); - TArray Faces; - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - Faces = livelink->GetAllFaces(); - } - - return Faces; -} - -TArray ARokokoReceiver::GetFacesNotAssociatedWithActor() -{ - TArray FacesNotPairedWithSuit; - for (auto CurrentFace : GetAllFaces()) - { - bool FoundExistingProfileForFace = false; - - for (auto CurrentSuit : GetAllSmartsuits()) - { - if (CurrentSuit.id == CurrentFace.profileName) - { - FoundExistingProfileForFace = true; - } - } - - if (!FoundExistingProfileForFace) - { - FacesNotPairedWithSuit.Add(CurrentFace); - } - } - return FacesNotPairedWithSuit; -} - -FSuitData* ARokokoReceiver::GetSmartsuit(FString suitName) -{ - //return VPlistener.GetSmartsuitByName(suitName); - FSuitData* ReturnValue = nullptr; - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - ReturnValue = livelink->GetSmartsuitByName(suitName); - } - else - { - UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); - } - - return ReturnValue; -} - -bool ARokokoReceiver::GetSmartsuitByName(const FString& suitName, FSuitData& SuitData) -{ - //return *VPlistener.GetSmartsuitByName(suitName); - - if (FSuitData* smartsuit = GetSmartsuit(suitName)) - { - SuitData = *smartsuit; - return true; - } - SuitData = FSuitData(); - return false; -} - -TArray ARokokoReceiver::GetAllSmartsuits() -{ - //return VPlistener.GetAllSmartsuits(); - - TArray Smartsuits; - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - Smartsuits = livelink->GetAllSmartsuits(); - } - - return Smartsuits; -} - -TArray ARokokoReceiver::GetAvailableSmartsuitNames() -{ - //return VPlistener.GetAvailableSmartsuitNames(); - TArray SmartsuitNames; - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - SmartsuitNames = livelink->GetAvailableSmartsuitNames(); - } - return SmartsuitNames; -} - - -FProp* ARokokoReceiver::GetPropByNameFromVP(FString name, bool isLive) -{ - //return VPlistener.GetPropByName(name, isLive); - - FProp* ReturnValue = nullptr; - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - ReturnValue = livelink->GetPropByName(name, isLive); - } - - return ReturnValue; -} -PRAGMA_DISABLE_OPTIMIZATION -TArray ARokokoReceiver::GetAllProps() -{ - //TArray result; - ////UE_LOG(LogTemp, Display, TEXT("Yeeee1")); - //bool found = false; - //int i = 0; - //for (TObjectIterator It; It; ++It) - //{ - // //UE_LOG(LogTemp, Display, TEXT("Looking up receiver %d"), i); - // i++; - // if (It->realLife) - // { - // found = true; - // //UE_LOG(LogTemp, Display, TEXT("Real life!")); - // result = It->VPlistener.GetAllProps(); - // } - //} - //if (!found) - //{ - // //UE_LOG(LogTemp, Display, TEXT("not Real life...")); - //} - ////UE_LOG(LogTemp, Display, TEXT("Yeeee2 %d"), result.Num()); - //return result; - - - TArray AllProps; - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - AllProps = livelink->GetAllProps(); - } - - return AllProps; -} -PRAGMA_ENABLE_OPTIMIZATION -bool ARokokoReceiver::GetProp(FString name, /*bool isLive, */FProp& OutProp) -{ - //for (TObjectIterator It; It; ++It) - //{ - // if (It->realLife) - // { - // OutProp = *It->GetPropByNameFromVP(name, true); - // return true; - // } - //} - //return false; - - //FProp result; - //for (TObjectIterator It; It; ++It) - //{ - // if (It->realLife) - // { - // result = *It->GetPropByNameFromVP(name, isLive); - // } - //} - //return result; - - if (FProp* prop = GetPropByNameFromVP(name, true)) - { - OutProp = *prop; - return true; - } - OutProp = FProp(); - return false; -} - -FTracker* ARokokoReceiver::GetTrackerByNameFromVP(FString name, bool isLive) -{ - //return VPlistener.GetTrackerByName(name, isLive); - FTracker* Tracker = nullptr; - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - Tracker = livelink->GetTrackerByName(name, isLive); - } - - return Tracker; -} - -FTracker ARokokoReceiver::GetTracker(FString name, bool isLive) -{ - FTracker result; - for (TObjectIterator It; It; ++It) - { - if (It->realLife) - { - result = *It->GetTrackerByNameFromVP(name, isLive); - } - } - return result; -} - -FTracker ARokokoReceiver::GetTrackerByConnectionIDFromVP(const FString& name, bool isLive, bool& found) -{ - found = false; - FTracker returnval; - FTracker* temp = nullptr;// = VPlistener.GetTrackerByConnectionID(name, isLive); - auto livelink = FVirtualProductionSource::Get(); - if (livelink.IsValid()) - { - temp = livelink->GetTrackerByConnectionID(name, isLive); - } - if (temp) - { - returnval = *temp; - found = true; - } - return returnval; -} - -void ARokokoReceiver::SetSupportsWiFiAPI(FString suitname) -{ - //listener.wifiSupportedSuits.Add(suitname); -} \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitStreamingNetwork.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitStreamingNetwork.cpp deleted file mode 100644 index e41cf0c..0000000 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitStreamingNetwork.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2019 Rokoko Electronics. All Rights Reserved. - -#include "SmartsuitStreamingNetwork.h" -#include "../Lib//V8/Includes/SmartsuitDef.h" -#include "../Lib//V8/Includes/SmartsuitLib.h" -#include "Smartsuit.h" - -SmartsuitStreamingNetwork::SmartsuitStreamingNetwork() -{ -// //we support maximum 10 suits. -// suitCount = 0; -// suits = new SuitData[10]; -// for (int i = 0; i < 10; i++) { -//#if PLATFORM_WINDOWS -// strcpy_s(suits[i].suitname, 5, "\0\0\0\0\0"); -//#else // using strlcpy on Android, Mac and iOS -// strlcpy(suits[i].suitname, "\0\0\0\0\0", 5); -//#endif -// suits[i].fps = 0; -// suits[i].currFPSCount = 0; -// suits[i].lastFPSSecond = -1; -// } -} - -SmartsuitStreamingNetwork::~SmartsuitStreamingNetwork() -{ - // // Stop the runnable - Stop(); - - if (Socket) { - Socket->Close(); - } - - // // And last but not least stop the main thread - if (Thread != NULL) - { - Thread->Kill(true); - delete Thread; - } -} - -void SmartsuitStreamingNetwork::Start(int port) -{ - //streaming_port = port; - //FString ThreadName(FString::Printf(TEXT("SmartsuitStreamingNetwork%ld"), (long)(FDateTime::UtcNow().ToUnixTimestamp()))); - //Thread = FRunnableThread::Create(this, *ThreadName, 8 * 1024, TPri_Normal); -} - - -bool SmartsuitStreamingNetwork::Init() -{ - //if (Socket == NULL) - //{ - // Socket = FUdpSocketBuilder(TEXT("SmartsuitStreamingNetwork")).BoundToAddress(FIPv4Address(0, 0, 0, 0)).BoundToPort(streaming_port).AsReusable().Build(); - // //allow the socket to listen to an already bounded address. - // Socket->SetReuseAddr(true); - // Stopping = false; - //} - //return true; - return true; -} - -uint32 SmartsuitStreamingNetwork::Run() -{ - //SmartsuitLib lib; - //while (!Stopping) - //{ - // auto addr_in = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); - // int32 bytes_read = 0; - // FString ret; - - // uint8 data[2048]; - // memset(data, '\0', 2048); - - // FDateTime time = FDateTime::UtcNow(); - // int seconds = time.ToUnixTimestamp(); - - // for (int i = 0; i < 10; i++) { - // if (strcmp(suits[i].suitname, "\0\0\0\0") != 0) { - // //update FPS for this suit. - // if (suits[i].lastFPSSecond != seconds) { - // suits[i].lastFPSSecond = seconds; - // suits[i].fps = suits[i].currFPSCount; - // suits[i].currFPSCount = 0; - // } - // } - // } - - // if (Socket) { - - // if (Socket->RecvFrom(data, sizeof(data), bytes_read, *addr_in)) { - // if (bytes_read == 0) { - // continue; - // } - // //UE_LOG(LogTemp, Warning, TEXT("received something3.....")); - - // SuitDataDef *def = lib.ParseFrame(data, bytes_read); - // SuitData sd; - - // // If you want to wait for the code above to complete do this: - // memcpy(sd.suitname, def->suitname, 4); - // sd.url = 0; - // addr_in->GetIp(sd.url); - - // //if (wifiSupportedSuits.Contains(FString(sd.suitname))) { - // sd.isBroadcasting = def->isBroadcasting; - // sd.hasProfile = def->hasProfile; - // sd.profileToggle = def->profileToggle; - // for (int i = 0; i < def->sensorCount; i++) - // { - // sd.sensors[i].addr = def->sensors[i].addr; - // sd.sensors[i].isAnotherSensorConnected = def->sensors[i].isAnotherSensorConnected; - // sd.sensors[i].behavior = def->sensors[i].behavior; - // sd.sensors[i].command = def->sensors[i].command; - // sd.sensors[i].acceleration.X = def->sensors[i].acceleration[0]; //X - // sd.sensors[i].acceleration.Y = def->sensors[i].acceleration[1]; //Y - // sd.sensors[i].acceleration.Z = def->sensors[i].acceleration[2];; ///Z - // sd.sensors[i].quaternion.W = def->sensors[i].quaternion[0]; //W - // sd.sensors[i].quaternion.X = def->sensors[i].quaternion[1]; //X - // sd.sensors[i].quaternion.Y = def->sensors[i].quaternion[2]; //Y - // sd.sensors[i].quaternion.Z = def->sensors[i].quaternion[3]; //Z - // sd.sensors[i].gyro.X = def->sensors[i].gyro[0];//X - // sd.sensors[i].gyro.Y = def->sensors[i].gyro[1];//Y - // sd.sensors[i].gyro.Z = def->sensors[i].gyro[2];//Z - // sd.sensors[i].position.X = def->sensors[i].position[0];//X - // sd.sensors[i].position.Y = def->sensors[i].position[1];//Y - // sd.sensors[i].position.Z = def->sensors[i].position[2];//Z - // sd.sensors[i].microseconds = def->sensors[i].microseconds; - // } - // delete def; - // def = nullptr; - // //find suit... - // int index = -1; - // bool newSuit = false; - // for (int i = 0; i < 10; i++) { - // if (strcmp(suits[i].suitname, "\0\0\0\0") == 0) { - // newSuit = true; - // index = i; - // break; - // } - // else if (strcmp(suits[i].suitname, sd.suitname) == 0) { - // index = i; - // //UE_LOG(LogTemp, Warning, TEXT("Saving... : %d"), index); - // break; - // } - // } - - // if (index != -1) { - // if (newSuit) { - // suitCount++; - // sd.lastFPSSecond = seconds; - // sd.fps = 0; - // sd.currFPSCount = 1; - // } - // else { - // sd.lastFPSSecond = suits[index].lastFPSSecond; - // sd.fps = suits[index].fps; - // sd.currFPSCount = suits[index].currFPSCount + 1; - // } - // memcpy(&(suits[index]), &sd, sizeof(SuitData)); - // } - - // auto livelink = FVirtualProductionSource::Get(); - // if (livelink.IsValid()) - // { - // SendSuitsToLiveLink(); - // } - // } - // } - //} - return 0; -} - -void SmartsuitStreamingNetwork::SendSuitsToLiveLink() -{ - //TArray suitArray; - //for (int i = 0; i < suitCount; i++) - //{ - // suitArray.Add(suits[i]); - //} - //auto livelink = FVirtualProductionSource::Get(); - //if (livelink.IsValid()) - //{ - // livelink->HandleSuits(suitArray); - //} -} \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitTPose.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitTPose.cpp index 6996228..162eb62 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitTPose.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/SmartsuitTPose.cpp @@ -1,7 +1,6 @@ // Copyright 2019 Rokoko Electronics. All Rights Reserved. #include "SmartsuitTPose.h" -#include "Smartsuit.h" SmartsuitTPose::SmartsuitTPose() { diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionFrame.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionFrame.cpp index 8dbb407..9bd338f 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionFrame.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionFrame.cpp @@ -14,13 +14,11 @@ VirtualProductionFrame::~VirtualProductionFrame() FProp::FProp(bool InIsLive, TSharedPtr jsonObject) { name = jsonObject->GetStringField("name"); - //id = jsonObject->GetStringField("id"); color = USmartsuitBlueprintLibrary::GetColorField(jsonObject); position = USmartsuitBlueprintLibrary::GetVectorField(jsonObject->GetObjectField("position")); rotation = USmartsuitBlueprintLibrary::GetQuaternionField(jsonObject->GetObjectField("rotation")); - //isLive = jsonObject->GetBoolField("isLive"); + isLive = InIsLive; - //profile = FProfile(jsonObject->GetObjectField("profile")); } FProfile::FProfile(TSharedPtr jsonObject) @@ -70,12 +68,131 @@ FTracker::FTracker(TSharedPtr jsonObject) battery = jsonObject->GetNumberField("battery"); } -FFace::FFace(TSharedPtr jsonObject, const FString& InActorName) + +FFace::FFace(const FFace& otherFace) + : profileName(otherFace.profileName) + , version(otherFace.version) + , provider(otherFace.provider) + , faceId(otherFace.faceId) + , actorName(otherFace.actorName) + , eyeBlinkLeft(otherFace.eyeBlinkLeft) + , eyeLookDownLeft(otherFace.eyeLookDownLeft) + , eyeLookInLeft(otherFace.eyeLookInLeft) + , eyeLookOutLeft(otherFace.eyeLookOutLeft) + , eyeLookUpLeft(otherFace.eyeLookUpLeft) + , eyeSquintLeft(otherFace.eyeSquintLeft) + , eyeWideLeft(otherFace.eyeWideLeft) + , eyeBlinkRight(otherFace.eyeBlinkRight) + , eyeLookDownRight(otherFace.eyeLookDownRight) + , eyeLookInRight(otherFace.eyeLookInRight) + , eyeLookOutRight(otherFace.eyeLookOutRight) + , eyeLookUpRight(otherFace.eyeLookUpRight) + , eyeSquintRight(otherFace.eyeSquintRight) + , eyeWideRight(otherFace.eyeWideRight) + , jawForward(otherFace.jawForward) + , jawLeft(otherFace.jawLeft) + , jawRight(otherFace.jawRight) + , jawOpen(otherFace.jawOpen) + , mouthClose(otherFace.mouthClose) + , mouthFunnel(otherFace.mouthFunnel) + , mouthPucker(otherFace.mouthPucker) + , mouthLeft(otherFace.mouthLeft) + , mouthRight(otherFace.mouthRight) + , mouthSmileLeft(otherFace.mouthSmileLeft) + , mouthSmileRight(otherFace.mouthSmileRight) + , mouthFrownLeft(otherFace.mouthFrownLeft) + , mouthFrownRight(otherFace.mouthFrownRight) + , mouthDimpleLeft(otherFace.mouthDimpleLeft) + , mouthDimpleRight(otherFace.mouthDimpleRight) + , mouthStretchLeft(otherFace.mouthStretchLeft) + , mouthStretchRight(otherFace.mouthStretchRight) + , mouthRollLower(otherFace.mouthRollLower) + , mouthRollUpper(otherFace.mouthRollUpper) + , mouthShrugLower(otherFace.mouthShrugLower) + , mouthShrugUpper(otherFace.mouthShrugUpper) + , mouthPressLeft(otherFace.mouthPressLeft) + , mouthPressRight(otherFace.mouthPressRight) + , mouthLowerDownLeft(otherFace.mouthLowerDownLeft) + , mouthLowerDownRight(otherFace.mouthLowerDownRight) + , mouthUpperUpLeft(otherFace.mouthUpperUpLeft) + , mouthUpperUpRight(otherFace.mouthUpperUpRight) + , browDownLeft(otherFace.browDownLeft) + , browDownRight(otherFace.browDownRight) + , browInnerUp(otherFace.browInnerUp) + , browOuterUpLeft(otherFace.browOuterUpLeft) + , browOuterUpRight(otherFace.browOuterUpRight) + , cheekPuff(otherFace.cheekPuff) + , cheekSquintLeft(otherFace.cheekSquintLeft) + , cheekSquintRight(otherFace.cheekSquintRight) + , noseSneerLeft(otherFace.noseSneerLeft) + , noseSneerRight(otherFace.noseSneerRight) + , tongueOut(otherFace.tongueOut) { +} - //profileName = jsonObject->GetStringField("profileName"); - //version = jsonObject->GetIntegerField("version"); - //provider = jsonObject->GetStringField("provider"); +FFace::FFace(FFace&& otherFace) + : profileName(MoveTemp(otherFace.profileName)) + , version(otherFace.version) + , provider(MoveTemp(otherFace.provider)) + , faceId(MoveTemp(otherFace.faceId)) + , actorName(MoveTemp(otherFace.actorName)) + , eyeBlinkLeft(otherFace.eyeBlinkLeft) + , eyeLookDownLeft(otherFace.eyeLookDownLeft) + , eyeLookInLeft(otherFace.eyeLookInLeft) + , eyeLookOutLeft(otherFace.eyeLookOutLeft) + , eyeLookUpLeft(otherFace.eyeLookUpLeft) + , eyeSquintLeft(otherFace.eyeSquintLeft) + , eyeWideLeft(otherFace.eyeWideLeft) + , eyeBlinkRight(otherFace.eyeBlinkRight) + , eyeLookDownRight(otherFace.eyeLookDownRight) + , eyeLookInRight(otherFace.eyeLookInRight) + , eyeLookOutRight(otherFace.eyeLookOutRight) + , eyeLookUpRight(otherFace.eyeLookUpRight) + , eyeSquintRight(otherFace.eyeSquintRight) + , eyeWideRight(otherFace.eyeWideRight) + , jawForward(otherFace.jawForward) + , jawLeft(otherFace.jawLeft) + , jawRight(otherFace.jawRight) + , jawOpen(otherFace.jawOpen) + , mouthClose(otherFace.mouthClose) + , mouthFunnel(otherFace.mouthFunnel) + , mouthPucker(otherFace.mouthPucker) + , mouthLeft(otherFace.mouthLeft) + , mouthRight(otherFace.mouthRight) + , mouthSmileLeft(otherFace.mouthSmileLeft) + , mouthSmileRight(otherFace.mouthSmileRight) + , mouthFrownLeft(otherFace.mouthFrownLeft) + , mouthFrownRight(otherFace.mouthFrownRight) + , mouthDimpleLeft(otherFace.mouthDimpleLeft) + , mouthDimpleRight(otherFace.mouthDimpleRight) + , mouthStretchLeft(otherFace.mouthStretchLeft) + , mouthStretchRight(otherFace.mouthStretchRight) + , mouthRollLower(otherFace.mouthRollLower) + , mouthRollUpper(otherFace.mouthRollUpper) + , mouthShrugLower(otherFace.mouthShrugLower) + , mouthShrugUpper(otherFace.mouthShrugUpper) + , mouthPressLeft(otherFace.mouthPressLeft) + , mouthPressRight(otherFace.mouthPressRight) + , mouthLowerDownLeft(otherFace.mouthLowerDownLeft) + , mouthLowerDownRight(otherFace.mouthLowerDownRight) + , mouthUpperUpLeft(otherFace.mouthUpperUpLeft) + , mouthUpperUpRight(otherFace.mouthUpperUpRight) + , browDownLeft(otherFace.browDownLeft) + , browDownRight(otherFace.browDownRight) + , browInnerUp(otherFace.browInnerUp) + , browOuterUpLeft(otherFace.browOuterUpLeft) + , browOuterUpRight(otherFace.browOuterUpRight) + , cheekPuff(otherFace.cheekPuff) + , cheekSquintLeft(otherFace.cheekSquintLeft) + , cheekSquintRight(otherFace.cheekSquintRight) + , noseSneerLeft(otherFace.noseSneerLeft) + , noseSneerRight(otherFace.noseSneerRight) + , tongueOut(otherFace.tongueOut) +{ +} + +FFace::FFace(TSharedPtr jsonObject, const FString& InActorName) +{ faceId = jsonObject->GetStringField("faceId"); actorName = InActorName; if (!jsonObject->TryGetStringField("profileName", profileName)) @@ -83,110 +200,58 @@ FFace::FFace(TSharedPtr jsonObject, const FString& InActorName) profileName = "NOPROFILENAME for " + faceId; } - //eyeBlinkLeft = jsonObject->GetNumberField("eyeBlinkLeft"); - //eyeLookDownLeft = jsonObject->GetNumberField("eyeLookDownLeft"); - //eyeLookInLeft = jsonObject->GetNumberField("eyeLookInLeft"); - //eyeLookOutLeft = jsonObject->GetNumberField("eyeLookOutLeft"); - //eyeLookUpLeft = jsonObject->GetNumberField("eyeLookUpLeft"); - //eyeSquintLeft = jsonObject->GetNumberField("eyeSquintLeft"); - //eyeWideLeft = jsonObject->GetNumberField("eyeWideLeft"); - //eyeBlinkRight = jsonObject->GetNumberField("eyeBlinkRight"); - //eyeLookDownRight = jsonObject->GetNumberField("eyeLookDownRight"); - //eyeLookInRight = jsonObject->GetNumberField("eyeLookInRight"); - //eyeLookOutRight = jsonObject->GetNumberField("eyeLookOutRight"); - //eyeLookUpRight = jsonObject->GetNumberField("eyeLookUpRight"); - //eyeSquintRight = jsonObject->GetNumberField("eyeSquintRight"); - //eyeWideRight = jsonObject->GetNumberField("eyeWideRight"); - //jawForward = jsonObject->GetNumberField("jawForward"); - //jawLeft = jsonObject->GetNumberField("jawLeft"); - //jawRight = jsonObject->GetNumberField("jawRight"); - //jawOpen = jsonObject->GetNumberField("jawOpen"); - //mouthClose = jsonObject->GetNumberField("mouthClose"); - //mouthFunnel = jsonObject->GetNumberField("mouthFunnel"); - //mouthPucker = jsonObject->GetNumberField("mouthPucker"); - //mouthLeft = jsonObject->GetNumberField("mouthLeft"); - //mouthRight = jsonObject->GetNumberField("mouthRight"); - //mouthSmileLeft = jsonObject->GetNumberField("mouthSmileLeft"); - //mouthSmileRight = jsonObject->GetNumberField("mouthSmileRight"); - //mouthFrownLeft = jsonObject->GetNumberField("mouthFrownLeft"); - //mouthFrownRight = jsonObject->GetNumberField("mouthFrownRight"); - //mouthDimpleLeft = jsonObject->GetNumberField("mouthDimpleLeft"); - //mouthDimpleRight = jsonObject->GetNumberField("mouthDimpleRight"); - //mouthStretchLeft = jsonObject->GetNumberField("mouthStretchLeft"); - //mouthStretchRight = jsonObject->GetNumberField("mouthStretchRight"); - //mouthRollLower = jsonObject->GetNumberField("mouthRollLower"); - //mouthRollUpper = jsonObject->GetNumberField("mouthRollUpper"); - //mouthShrugLower = jsonObject->GetNumberField("mouthShrugLower"); - //mouthShrugUpper = jsonObject->GetNumberField("mouthShrugUpper"); - //mouthPressLeft = jsonObject->GetNumberField("mouthPressLeft"); - //mouthPressRight = jsonObject->GetNumberField("mouthPressRight"); - //mouthLowerDownLeft = jsonObject->GetNumberField("mouthLowerDownLeft"); - //mouthLowerDownRight = jsonObject->GetNumberField("mouthLowerDownRight"); - //mouthUpperUpLeft = jsonObject->GetNumberField("mouthUpperUpLeft"); - //mouthUpperUpRight = jsonObject->GetNumberField("mouthUpperUpRight"); - //browDownLeft = jsonObject->GetNumberField("browDownLeft"); - //browDownRight = jsonObject->GetNumberField("browDownRight"); - //browInnerUp = jsonObject->GetNumberField("browInnerUp"); - //browOuterUpLeft = jsonObject->GetNumberField("browOuterUpLeft"); - //browOuterUpRight = jsonObject->GetNumberField("browOuterUpRight"); - //cheekPuff = jsonObject->GetNumberField("cheekPuff"); - //cheekSquintLeft = jsonObject->GetNumberField("cheekSquintLeft"); - //cheekSquintRight = jsonObject->GetNumberField("cheekSquintRight"); - //noseSneerLeft = jsonObject->GetNumberField("noseSneerLeft"); - //noseSneerRight = jsonObject->GetNumberField("noseSneerRight"); - //tongueOut = jsonObject->GetNumberField("tongueOut"); - - - eyeBlinkLeft = jsonObject->GetNumberField("eyeBlinkLeft") / 100.f; - eyeLookDownLeft = jsonObject->GetNumberField("eyeLookDownLeft") / 100.f; - eyeLookInLeft = jsonObject->GetNumberField("eyeLookInLeft") / 100.f; - eyeLookOutLeft = jsonObject->GetNumberField("eyeLookOutLeft") / 100.f; - eyeLookUpLeft = jsonObject->GetNumberField("eyeLookUpLeft") / 100.f; - eyeSquintLeft = jsonObject->GetNumberField("eyeSquintLeft") / 100.f; - eyeWideLeft = jsonObject->GetNumberField("eyeWideLeft") / 100.f; - eyeBlinkRight = jsonObject->GetNumberField("eyeBlinkRight") / 100.f; - eyeLookDownRight = jsonObject->GetNumberField("eyeLookDownRight") / 100.f; - eyeLookInRight = jsonObject->GetNumberField("eyeLookInRight") / 100.f; - eyeLookOutRight = jsonObject->GetNumberField("eyeLookOutRight") / 100.f; - eyeLookUpRight = jsonObject->GetNumberField("eyeLookUpRight") / 100.f; - eyeSquintRight = jsonObject->GetNumberField("eyeSquintRight") / 100.f; - eyeWideRight = jsonObject->GetNumberField("eyeWideRight") / 100.f; - jawForward = jsonObject->GetNumberField("jawForward") / 100.f; - jawLeft = jsonObject->GetNumberField("jawLeft") / 100.f; - jawRight = jsonObject->GetNumberField("jawRight") / 100.f; - jawOpen = jsonObject->GetNumberField("jawOpen") / 100.f; - mouthClose = jsonObject->GetNumberField("mouthClose") / 100.f; - mouthFunnel = jsonObject->GetNumberField("mouthFunnel") / 100.f; - mouthPucker = jsonObject->GetNumberField("mouthPucker") / 100.f; - mouthLeft = jsonObject->GetNumberField("mouthLeft") / 100.f; - mouthRight = jsonObject->GetNumberField("mouthRight") / 100.f; - mouthSmileLeft = jsonObject->GetNumberField("mouthSmileLeft") / 100.f; - mouthSmileRight = jsonObject->GetNumberField("mouthSmileRight") / 100.f; - mouthFrownLeft = jsonObject->GetNumberField("mouthFrownLeft") / 100.f; - mouthFrownRight = jsonObject->GetNumberField("mouthFrownRight") / 100.f; - mouthDimpleLeft = jsonObject->GetNumberField("mouthDimpleLeft") / 100.f; - mouthDimpleRight = jsonObject->GetNumberField("mouthDimpleRight") / 100.f; - mouthStretchLeft = jsonObject->GetNumberField("mouthStretchLeft") / 100.f; - mouthStretchRight = jsonObject->GetNumberField("mouthStretchRight") / 100.f; - mouthRollLower = jsonObject->GetNumberField("mouthRollLower") / 100.f; - mouthRollUpper = jsonObject->GetNumberField("mouthRollUpper") / 100.f; - mouthShrugLower = jsonObject->GetNumberField("mouthShrugLower") / 100.f; - mouthShrugUpper = jsonObject->GetNumberField("mouthShrugUpper") / 100.f; - mouthPressLeft = jsonObject->GetNumberField("mouthPressLeft") / 100.f; - mouthPressRight = jsonObject->GetNumberField("mouthPressRight") / 100.f; - mouthLowerDownLeft = jsonObject->GetNumberField("mouthLowerDownLeft") / 100.f; - mouthLowerDownRight = jsonObject->GetNumberField("mouthLowerDownRight") / 100.f; - mouthUpperUpLeft = jsonObject->GetNumberField("mouthUpperUpLeft") / 100.f; - mouthUpperUpRight = jsonObject->GetNumberField("mouthUpperUpRight") / 100.f; - browDownLeft = jsonObject->GetNumberField("browDownLeft") / 100.f; - browDownRight = jsonObject->GetNumberField("browDownRight") / 100.f; - browInnerUp = jsonObject->GetNumberField("browInnerUp") / 100.f; - browOuterUpLeft = jsonObject->GetNumberField("browOuterUpLeft") / 100.f; - browOuterUpRight = jsonObject->GetNumberField("browOuterUpRight") / 100.f; - cheekPuff = jsonObject->GetNumberField("cheekPuff") / 100.f; - cheekSquintLeft = jsonObject->GetNumberField("cheekSquintLeft") / 100.f; - cheekSquintRight = jsonObject->GetNumberField("cheekSquintRight") / 100.f; - noseSneerLeft = jsonObject->GetNumberField("noseSneerLeft") / 100.f; - noseSneerRight = jsonObject->GetNumberField("noseSneerRight") / 100.f; - tongueOut = jsonObject->GetNumberField("tongueOut") / 100.f; + constexpr float scale{ 0.01f }; + + eyeBlinkLeft = jsonObject->GetNumberField("eyeBlinkLeft") * scale; + eyeLookDownLeft = jsonObject->GetNumberField("eyeLookDownLeft") * scale; + eyeLookInLeft = jsonObject->GetNumberField("eyeLookInLeft") * scale; + eyeLookOutLeft = jsonObject->GetNumberField("eyeLookOutLeft") * scale; + eyeLookUpLeft = jsonObject->GetNumberField("eyeLookUpLeft") * scale; + eyeSquintLeft = jsonObject->GetNumberField("eyeSquintLeft") * scale; + eyeWideLeft = jsonObject->GetNumberField("eyeWideLeft") * scale; + eyeBlinkRight = jsonObject->GetNumberField("eyeBlinkRight") * scale; + eyeLookDownRight = jsonObject->GetNumberField("eyeLookDownRight") * scale; + eyeLookInRight = jsonObject->GetNumberField("eyeLookInRight") * scale; + eyeLookOutRight = jsonObject->GetNumberField("eyeLookOutRight") * scale; + eyeLookUpRight = jsonObject->GetNumberField("eyeLookUpRight") * scale; + eyeSquintRight = jsonObject->GetNumberField("eyeSquintRight") * scale; + eyeWideRight = jsonObject->GetNumberField("eyeWideRight") * scale; + jawForward = jsonObject->GetNumberField("jawForward") * scale; + jawLeft = jsonObject->GetNumberField("jawLeft") * scale; + jawRight = jsonObject->GetNumberField("jawRight") * scale; + jawOpen = jsonObject->GetNumberField("jawOpen") * scale; + mouthClose = jsonObject->GetNumberField("mouthClose") * scale; + mouthFunnel = jsonObject->GetNumberField("mouthFunnel") * scale; + mouthPucker = jsonObject->GetNumberField("mouthPucker") * scale; + mouthLeft = jsonObject->GetNumberField("mouthLeft") * scale; + mouthRight = jsonObject->GetNumberField("mouthRight") * scale; + mouthSmileLeft = jsonObject->GetNumberField("mouthSmileLeft") * scale; + mouthSmileRight = jsonObject->GetNumberField("mouthSmileRight") * scale; + mouthFrownLeft = jsonObject->GetNumberField("mouthFrownLeft") * scale; + mouthFrownRight = jsonObject->GetNumberField("mouthFrownRight") * scale; + mouthDimpleLeft = jsonObject->GetNumberField("mouthDimpleLeft") * scale; + mouthDimpleRight = jsonObject->GetNumberField("mouthDimpleRight") * scale; + mouthStretchLeft = jsonObject->GetNumberField("mouthStretchLeft") * scale; + mouthStretchRight = jsonObject->GetNumberField("mouthStretchRight") * scale; + mouthRollLower = jsonObject->GetNumberField("mouthRollLower") * scale; + mouthRollUpper = jsonObject->GetNumberField("mouthRollUpper") * scale; + mouthShrugLower = jsonObject->GetNumberField("mouthShrugLower") * scale; + mouthShrugUpper = jsonObject->GetNumberField("mouthShrugUpper") * scale; + mouthPressLeft = jsonObject->GetNumberField("mouthPressLeft") * scale; + mouthPressRight = jsonObject->GetNumberField("mouthPressRight") * scale; + mouthLowerDownLeft = jsonObject->GetNumberField("mouthLowerDownLeft") * scale; + mouthLowerDownRight = jsonObject->GetNumberField("mouthLowerDownRight") * scale; + mouthUpperUpLeft = jsonObject->GetNumberField("mouthUpperUpLeft") * scale; + mouthUpperUpRight = jsonObject->GetNumberField("mouthUpperUpRight") * scale; + browDownLeft = jsonObject->GetNumberField("browDownLeft") * scale; + browDownRight = jsonObject->GetNumberField("browDownRight") * scale; + browInnerUp = jsonObject->GetNumberField("browInnerUp") * scale; + browOuterUpLeft = jsonObject->GetNumberField("browOuterUpLeft") * scale; + browOuterUpRight = jsonObject->GetNumberField("browOuterUpRight") * scale; + cheekPuff = jsonObject->GetNumberField("cheekPuff") * scale; + cheekSquintLeft = jsonObject->GetNumberField("cheekSquintLeft") * scale; + cheekSquintRight = jsonObject->GetNumberField("cheekSquintRight") * scale; + noseSneerLeft = jsonObject->GetNumberField("noseSneerLeft") * scale; + noseSneerRight = jsonObject->GetNumberField("noseSneerRight") * scale; + tongueOut = jsonObject->GetNumberField("tongueOut") * scale; } diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionProp.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionProp.cpp index 07c4514..e6331a8 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionProp.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionProp.cpp @@ -1,7 +1,7 @@ // Copyright 2019 Rokoko Electronics. All Rights Reserved. #include "VirtualProductionProp.h" - +#include "VirtualProductionSource.h" UVirtualProductionProp::UVirtualProductionProp() { @@ -21,51 +21,24 @@ void UVirtualProductionProp::BeginPlay() CurrentLocation = parent->GetActorLocation(); } -ARokokoReceiver* UVirtualProductionProp::GetReceiver() -{ - ARokokoReceiver* listener = nullptr; - - for (TObjectIterator It; It; ++It) - { - //if (It->enabled) - { - listener = *It; - break; - } - } - return listener; -} - void UVirtualProductionProp::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - ARokokoReceiver* listener = GetReceiver(); - if (!listener) + auto livelink = FVirtualProductionSource::Get(); + if (!livelink.IsValid()) { - UE_LOG(LogTemp, Warning, TEXT("could not get receiver!!!")); + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); return; } - FProp* prop = listener->GetPropByNameFromVP(name, isLive); + FProp* prop = livelink->GetPropByName(name, isLive); if (!prop) { - UE_LOG(LogTemp, Warning, TEXT("could not get prop!!!")); + //UE_LOG(LogTemp, Warning, TEXT("could not get prop!!!")); return; } - //FVector LocalOffset(10.f, 10.f, 0.f); - - //FTransform TestTransform(prop->FQuatToRotator(), prop->UPosition(), FVector(scalePosition, scalePosition, scalePosition)); - - //if (useLocalSpace) - //{ - // TestTransform.TransformPosition(LocalOffset); - //} - - //parent->SetActorLocation(TestTransform.GetLocation()); - //parent->SetActorRotation(TestTransform.GetRotation()); - if (useLocalSpace) { parent->SetActorRelativeLocation(prop->UPosition() * scalePosition); @@ -76,6 +49,4 @@ void UVirtualProductionProp::TickComponent(float DeltaTime, ELevelTick TickType, parent->SetActorLocation(prop->UPosition() * scalePosition); parent->SetActorRotation(prop->FQuatToRotator()); } - - //parent->SetActorRotation(prop->FQuatToRotator()); } \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionSource.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionSource.cpp index 49a41ba..40713dc 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionSource.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionSource.cpp @@ -8,43 +8,39 @@ #include "Roles/LiveLinkLightRole.h" #include "Roles/LiveLinkLightTypes.h" #include "Features/IModularFeatures.h" +#include "Roles/LiveLinkSmartsuitRole.h" +#include "Roles/LiveLinkSmartsuitTypes.h" #include "VirtualProductionFrame.h" -#include "Smartsuit.h" #include "Runtime/Core/Public/Containers/UnrealString.h" -//#include "Engine.h" + #include "Runtime/JsonUtilities/Public/JsonObjectConverter.h" #include "Serialization/BufferArchive.h" #include "lz4frame.h" -#include "SmartsuitReceiver.h" + TSharedPtr FVirtualProductionSource::instance = nullptr; -FVirtualProductionSource::FVirtualProductionSource(const FText& InSourceType, const FText& InSourceMachineName, const FMessageAddress& InConnectionAddress) +FVirtualProductionSource::FVirtualProductionSource(FIPv4Endpoint address, const FText& InSourceType, const FText& InSourceMachineName, const FMessageAddress& InConnectionAddress) : SourceType(InSourceType) , SourceMachineName(InSourceMachineName) { Client = nullptr; + + m_NetworkAddress = address; + + UE_LOG(LogTemp, Warning, TEXT("Creating Virtual production source!!!")); - int32 RokokoPort; - for (TObjectIterator It; It; ++It) + if (InitSocket()) { - RokokoPort = It->RokokoPortNumber; - UE_LOG(LogTemp, Warning, TEXT("setting port to... %i"), RokokoPort); + StartRunnable(); } - - UE_LOG(LogTemp, Warning, TEXT("Creating Virtual production source!!!")); - - InitSocket(RokokoPort); - StartRunnable(RokokoPort); } FVirtualProductionSource::~FVirtualProductionSource() { UE_LOG(LogTemp, Warning, TEXT("Destroying Virtual production source!!!")); - - // Stop the runnable Stop(); ClearAllSubjects(); @@ -55,7 +51,7 @@ FVirtualProductionSource::~FVirtualProductionSource() } // And last but not least stop the main thread - if (Thread != NULL) + if (Thread != nullptr) { Thread->Kill(true); delete Thread; @@ -65,9 +61,7 @@ FVirtualProductionSource::~FVirtualProductionSource() void FVirtualProductionSource::ReceiveClient(ILiveLinkClient* InClient, FGuid InSourceGuid) { Client = InClient; - SourceGuid = InSourceGuid; - //instance = this; } bool FVirtualProductionSource::IsSourceStillValid() const @@ -85,7 +79,6 @@ void FVirtualProductionSource::HandleClearSubject(const FName subjectName) return; } - //Client->ClearSubject(subjectName); Client->RemoveSubject_AnyThread(FLiveLinkSubjectKey(SourceGuid,subjectName)); } @@ -99,14 +92,14 @@ void FVirtualProductionSource::ClearAllSubjects() { HandleClearSubject(faceNames[i]); } - for (int i = 0; i < suitNames.Num(); i++) + for (int i = 0; i < actorNames.Num(); i++) { - HandleClearSubject(suitNames[i]); + HandleClearSubject(actorNames[i]); } subjectNames.Empty(); faceNames.Empty(); - suitNames.Empty(); + actorNames.Empty(); } bool FVirtualProductionSource::RequestSourceShutdown() @@ -116,7 +109,7 @@ bool FVirtualProductionSource::RequestSourceShutdown() return true; } -void FVirtualProductionSource::HandleFaceData(FFace face) +void FVirtualProductionSource::HandleFaceData(const FFace& face) { //verify(Client != nullptr); @@ -134,64 +127,66 @@ void FVirtualProductionSource::HandleFaceData(FFace face) FLiveLinkStaticDataStruct StaticData(FLiveLinkSkeletonStaticData::StaticStruct()); FLiveLinkSkeletonStaticData* SkeletonData = StaticData.Cast(); - - SkeletonData->PropertyNames.Add("browDownLeft"); - SkeletonData->PropertyNames.Add("browDownRight"); - SkeletonData->PropertyNames.Add("browInnerUp"); - SkeletonData->PropertyNames.Add("browOuterUpLeft"); - SkeletonData->PropertyNames.Add("browOuterUpRight"); - SkeletonData->PropertyNames.Add("cheekPuff"); - SkeletonData->PropertyNames.Add("cheekSquintLeft"); - SkeletonData->PropertyNames.Add("cheekSquintRight"); - SkeletonData->PropertyNames.Add("eyeBlinkLeft"); - SkeletonData->PropertyNames.Add("eyeBlinkRight"); - SkeletonData->PropertyNames.Add("eyeLookDownLeft"); - SkeletonData->PropertyNames.Add("eyeLookDownRight"); - SkeletonData->PropertyNames.Add("eyeLookInLeft"); - SkeletonData->PropertyNames.Add("eyeLookInRight"); - SkeletonData->PropertyNames.Add("eyeLookOutLeft"); - SkeletonData->PropertyNames.Add("eyeLookOutRight"); - SkeletonData->PropertyNames.Add("eyeLookUpLeft"); - SkeletonData->PropertyNames.Add("eyeLookUpRight"); - SkeletonData->PropertyNames.Add("eyeSquintLeft"); - SkeletonData->PropertyNames.Add("eyeSquintRight"); - SkeletonData->PropertyNames.Add("eyeWideLeft"); - SkeletonData->PropertyNames.Add("eyeWideRight"); - SkeletonData->PropertyNames.Add("jawOpen"); - SkeletonData->PropertyNames.Add("jawForward"); - SkeletonData->PropertyNames.Add("jawLeft"); - SkeletonData->PropertyNames.Add("jawRight"); - SkeletonData->PropertyNames.Add("mouthClose"); - SkeletonData->PropertyNames.Add("mouthDimpleLeft"); - SkeletonData->PropertyNames.Add("mouthDimpleRight"); - SkeletonData->PropertyNames.Add("mouthFrownLeft"); - SkeletonData->PropertyNames.Add("mouthFrownRight"); - SkeletonData->PropertyNames.Add("mouthFunnel"); - SkeletonData->PropertyNames.Add("mouthLeft"); - SkeletonData->PropertyNames.Add("mouthLowerDownLeft"); - SkeletonData->PropertyNames.Add("mouthLowerDownRight"); - SkeletonData->PropertyNames.Add("mouthPressLeft"); - SkeletonData->PropertyNames.Add("mouthPressRight"); - SkeletonData->PropertyNames.Add("mouthPucker"); - SkeletonData->PropertyNames.Add("mouthRight"); - SkeletonData->PropertyNames.Add("mouthRollLower"); - SkeletonData->PropertyNames.Add("mouthRollUpper"); - SkeletonData->PropertyNames.Add("mouthShrugLower"); - SkeletonData->PropertyNames.Add("mouthShrugUpper"); - SkeletonData->PropertyNames.Add("mouthSmileLeft"); - SkeletonData->PropertyNames.Add("mouthSmileRight"); - SkeletonData->PropertyNames.Add("mouthStretchLeft"); - SkeletonData->PropertyNames.Add("mouthStretchRight"); - SkeletonData->PropertyNames.Add("mouthUpperUpLeft"); - SkeletonData->PropertyNames.Add("mouthUpperUpRight"); - SkeletonData->PropertyNames.Add("noseSneerLeft"); - SkeletonData->PropertyNames.Add("noseSneerRight"); - SkeletonData->PropertyNames.Add("tongueOut"); + SkeletonData->PropertyNames.Append( + { + "browDownLeft", + "browDownRight", + "browInnerUp", + "browOuterUpLeft", + "browOuterUpRight", + "cheekPuff", + "cheekSquintLeft", + "cheekSquintRight", + "eyeBlinkLeft", + "eyeBlinkRight", + "eyeLookDownLeft", + "eyeLookDownRight", + "eyeLookInLeft", + "eyeLookInRight", + "eyeLookOutLeft", + "eyeLookOutRight", + "eyeLookUpLeft", + "eyeLookUpRight", + "eyeSquintLeft", + "eyeSquintRight", + "eyeWideLeft", + "eyeWideRight", + "jawOpen", + "jawForward", + "jawLeft", + "jawRight", + "mouthClose", + "mouthDimpleLeft", + "mouthDimpleRight", + "mouthFrownLeft", + "mouthFrownRight", + "mouthFunnel", + "mouthLeft", + "mouthLowerDownLeft", + "mouthLowerDownRight", + "mouthPressLeft", + "mouthPressRight", + "mouthPucker", + "mouthRight", + "mouthRollLower", + "mouthRollUpper", + "mouthShrugLower", + "mouthShrugUpper", + "mouthSmileLeft", + "mouthSmileRight", + "mouthStretchLeft", + "mouthStretchRight", + "mouthUpperUpLeft", + "mouthUpperUpRight", + "noseSneerLeft", + "noseSneerRight", + "tongueOut" + }); Client->PushSubjectStaticData_AnyThread(Key, ULiveLinkAnimationRole::StaticClass(), MoveTemp(StaticData)); } -void FVirtualProductionSource::HandleSubjectData(FVirtualProductionSubject virtualProductionObject) +void FVirtualProductionSource::HandleSubjectData(const FVirtualProductionSubject& virtualProductionObject) { //verify(Client != nullptr); @@ -201,14 +196,14 @@ void FVirtualProductionSource::HandleSubjectData(FVirtualProductionSubject virtu return; } - subjectNames.Add(virtualProductionObject.name); + subjectNames.Add(virtualProductionObject.Name); - FLiveLinkSubjectKey Key = FLiveLinkSubjectKey(SourceGuid, virtualProductionObject.name); + FLiveLinkSubjectKey Key = FLiveLinkSubjectKey(SourceGuid, virtualProductionObject.Name); Client->RemoveSubject_AnyThread(Key); - if (virtualProductionObject.name.ToString().StartsWith("prop")) + if (virtualProductionObject.Name.ToString().StartsWith("prop")) { - FString subjectname = virtualProductionObject.name.ToString(); + FString subjectname = virtualProductionObject.Name.ToString(); int32 indexlastchar = -1; subjectname.FindLastChar(':', indexlastchar); FString testval = subjectname.RightChop(indexlastchar + 1); @@ -260,367 +255,261 @@ void FVirtualProductionSource::HandleSubjectData(FVirtualProductionSubject virtu //UE_LOG(LogTemp, Warning, TEXT("SKELETON!! "), skeleton); } -void FVirtualProductionSource::HandleSuitData(FSuitData suit) +void FVirtualProductionSource::HandleSuitData(const FSuitData& suit) { - suitNames.Add(suit.GetSubjectName()); + actorNames.Add(suit.GetSubjectName()); FLiveLinkSubjectKey Key = FLiveLinkSubjectKey(SourceGuid, suit.GetSubjectName()); - TArray boneNames; - boneNames.Add("Base"); - boneNames.Add("hip"); - boneNames.Add("spine"); - boneNames.Add("chest"); - boneNames.Add("neck"); - boneNames.Add("head"); - - boneNames.Add("leftShoulder"); - boneNames.Add("leftUpperArm"); - boneNames.Add("leftLowerArm"); - boneNames.Add("leftHand"); + static TArray boneNames = + { + "Base", + "hip", + "spine", + "chest", + "neck", + "head", + + "leftShoulder", + "leftUpperArm", + "leftLowerArm", + "leftHand", + + "rightShoulder", + "rightUpperArm", + "rightLowerArm", + "rightHand", + + "leftUpLeg", + "leftLeg", + "leftFoot", + + "rightUpLeg", + "rightLeg", + "rightFoot", + + "leftThumbProximal", + "leftThumbMedial", + "leftThumbDistal", + "leftThumbTip", + + "leftIndexProximal", + "leftIndexMedial", + "leftIndexDistal", + "leftIndexTip", + + "leftMiddleProximal", + "leftMiddleMedial", + "leftMiddleDistal", + "leftMiddleTip", + + "leftRingProximal", + "leftRingMedial", + "leftRingDistal", + "leftRingTip", + + "leftLittleProximal", + "leftLittleMedial", + "leftLittleDistal", + "leftLittleTip", + + "rightThumbProximal", + "rightThumbMedial", + "rightThumbDistal", + "rightThumbTip", + + "rightIndexProximal", + "rightIndexMedial", + "rightIndexDistal", + "rightIndexTip", + + "rightMiddleProximal", + "rightMiddleMedial", + "rightMiddleDistal", + "rightMiddleTip", + + "rightRingProximal", + "rightRingMedial", + "rightRingDistal", + "rightRingTip", + + "rightLittleProximal", + "rightLittleMedial", + "rightLittleDistal", + "rightLittleTip", + + "leftToe", + "rightToe", + }; - boneNames.Add("rightShoulder"); - boneNames.Add("rightUpperArm"); - boneNames.Add("rightLowerArm"); - boneNames.Add("rightHand"); - - boneNames.Add("leftUpLeg"); - boneNames.Add("leftLeg"); - boneNames.Add("leftFoot"); - - boneNames.Add("rightUpLeg"); - boneNames.Add("rightLeg"); - boneNames.Add("rightFoot"); - - boneNames.Add("leftThumbProximal"); - boneNames.Add("leftThumbMedial"); - boneNames.Add("leftThumbDistal"); - boneNames.Add("leftThumbTip"); - - boneNames.Add("leftIndexProximal"); - boneNames.Add("leftIndexMedial"); - boneNames.Add("leftIndexDistal"); - boneNames.Add("leftIndexTip"); - - boneNames.Add("leftMiddleProximal"); - boneNames.Add("leftMiddleMedial"); - boneNames.Add("leftMiddleDistal"); - boneNames.Add("leftMiddleTip"); - - boneNames.Add("leftRingProximal"); - boneNames.Add("leftRingMedial"); - boneNames.Add("leftRingDistal"); - boneNames.Add("leftRingTip"); - - boneNames.Add("leftLittleProximal"); - boneNames.Add("leftLittleMedial"); - boneNames.Add("leftLittleDistal"); - boneNames.Add("leftLittleTip"); - - boneNames.Add("rightThumbProximal"); - boneNames.Add("rightThumbMedial"); - boneNames.Add("rightThumbDistal"); - boneNames.Add("rightThumbTip"); - - boneNames.Add("rightIndexProximal"); - boneNames.Add("rightIndexMedial"); - boneNames.Add("rightIndexDistal"); - boneNames.Add("rightIndexTip"); - - boneNames.Add("rightMiddleProximal"); - boneNames.Add("rightMiddleMedial"); - boneNames.Add("rightMiddleDistal"); - boneNames.Add("rightMiddleTip"); - - boneNames.Add("rightRingProximal"); - boneNames.Add("rightRingMedial"); - boneNames.Add("rightRingDistal"); - boneNames.Add("rightRingTip"); - - boneNames.Add("rightLittleProximal"); - boneNames.Add("rightLittleMedial"); - boneNames.Add("rightLittleDistal"); - boneNames.Add("rightLittleTip"); - - boneNames.Add("leftToe"); - boneNames.Add("rightToe"); - TArray boneParents; - boneParents.Add(0); //0 - root - boneParents.Add(0); //1 - hip - boneParents.Add(1); //2 - spine - boneParents.Add(2); //3 - spine2 - boneParents.Add(3); //4 - neck - boneParents.Add(4); //5 - head - - boneParents.Add(3); //6 - LeftShoulder - boneParents.Add(6); //7 - LeftArm - boneParents.Add(7); //8 - LeftForearm - boneParents.Add(8); //9 - LeftHand - - boneParents.Add(3); //10 - RightShoulder - boneParents.Add(10); //11 - RightArm - boneParents.Add(11); //12 - RightForearm - boneParents.Add(12); //13 - RightHand - - boneParents.Add(1); //14 - LeftUpLeg - boneParents.Add(14); //15 - LeftLeg - boneParents.Add(15); //16 - LeftFoot - - boneParents.Add(1); //17 - RightUpLeg - boneParents.Add(17); //18 - RightLeg - boneParents.Add(18); //19 - RightFoot - - boneParents.Add(9); //20 - leftThumbProximal - boneParents.Add(20); //21 - leftThumbMedial - boneParents.Add(21); //22 - leftThumbDistal - boneParents.Add(22); //23 - leftThumbTip - - boneParents.Add(9); //24 - leftIndexProximal - boneParents.Add(24); //25 - leftIndexMedial - boneParents.Add(25); //26 - leftIndexDistal - boneParents.Add(26); //27 - leftIndexTip - - boneParents.Add(9); //28 - leftMiddleProximal - boneParents.Add(28); //29 - leftMiddleMedial - boneParents.Add(29); //30 - leftMiddleDistal - boneParents.Add(30); //31 - leftMiddleTip - - boneParents.Add(9); //32 - leftRingProximal - boneParents.Add(32); //33 - leftRingMedial - boneParents.Add(33); //34 - leftRingDistal - boneParents.Add(34); //35 - leftRingTip - - boneParents.Add(9); //36 - leftLittleProximal - boneParents.Add(36); //37 - leftLittleMedial - boneParents.Add(37); //38 - leftLittleDistal - boneParents.Add(38); //39 - leftLittleTip - - boneParents.Add(13); //40 - rightThumbProximal - boneParents.Add(40); //41 - rightThumbMedial - boneParents.Add(41); //42 - rightThumbDistal - boneParents.Add(42); //43 - rightThumbTip - - boneParents.Add(13); //44 - rightIndexProximal - boneParents.Add(44); //45 - rightIndexMedial - boneParents.Add(45); //46 - rightIndexDistal - boneParents.Add(46); //47 - rightIndexTip - - boneParents.Add(13); //48 - rightMiddleProximal - boneParents.Add(48); //49 - rightMiddleMedial - boneParents.Add(49); //50 - rightMiddleDistal - boneParents.Add(50); //51 - rightMiddleTip - - boneParents.Add(13); //52 - rightRingProximal - boneParents.Add(52); //53 - rightRingMedial - boneParents.Add(53); //54 - rightRingDistal - boneParents.Add(54); //55 - rightRingTip - - boneParents.Add(13); //56 - rightLittleProximal - boneParents.Add(56); //57 - rightLittleMedial - boneParents.Add(57); //58 - rightLittleDistal - boneParents.Add(58); //59 - rightLittleTip - - boneParents.Add(16); //60 - LeftToe - boneParents.Add(19); //61 - RightToe + static TArray boneParents = + { + 0, //0 - root + 0, //1 - hip + 1, //2 - spine + 2, //3 - spine2 + 3, //4 - neck + 4, //5 - head + + 3, //6 - LeftShoulder + 6, //7 - LeftArm + 7, //8 - LeftForearm + 8, //9 - LeftHand + + 3, //10 - RightShoulder + 10, //11 - RightArm + 11, //12 - RightForearm + 12, //13 - RightHand + + 1, //14 - LeftUpLeg + 14, //15 - LeftLeg + 15, //16 - LeftFoot + + 1, //17 - RightUpLeg + 17, //18 - RightLeg + 18, //19 - RightFoot + + 9, //20 - leftThumbProximal + 20, //21 - leftThumbMedial + 21, //22 - leftThumbDistal + 22, //23 - leftThumbTip + + 9, //24 - leftIndexProximal + 24, //25 - leftIndexMedial + 25, //26 - leftIndexDistal + 26, //27 - leftIndexTip + + 9, //28 - leftMiddleProximal + 28, //29 - leftMiddleMedial + 29, //30 - leftMiddleDistal + 30, //31 - leftMiddleTip + + 9, //32 - leftRingProximal + 32, //33 - leftRingMedial + 33, //34 - leftRingDistal + 34, //35 - leftRingTip + + 9, //36 - leftLittleProximal + 36, //37 - leftLittleMedial + 37, //38 - leftLittleDistal + 38, //39 - leftLittleTip + + 13, //40 - rightThumbProximal + 40, //41 - rightThumbMedial + 41, //42 - rightThumbDistal + 42, //43 - rightThumbTip + + 13, //44 - rightIndexProximal + 44, //45 - rightIndexMedial + 45, //46 - rightIndexDistal + 46, //47 - rightIndexTip + + 13, //48 - rightMiddleProximal + 48, //49 - rightMiddleMedial + 49, //50 - rightMiddleDistal + 50, //51 - rightMiddleTip + + 13, //52 - rightRingProximal + 52, //53 - rightRingMedial + 53, //54 - rightRingDistal + 54, //55 - rightRingTip + + 13, //56 - rightLittleProximal + 56, //57 - rightLittleMedial + 57, //58 - rightLittleDistal + 58, //59 - rightLittleTip + + 16, //60 - LeftToe + 19 //61 - RightToe + }; + + #ifdef USE_SMARTSUIT_ANIMATION_ROLE + FLiveLinkStaticDataStruct StaticData(FLiveLinkSmartsuitStaticData::StaticStruct()); + FLiveLinkSmartsuitStaticData* SkeletonData = StaticData.Cast(); + #else FLiveLinkStaticDataStruct StaticData(FLiveLinkSkeletonStaticData::StaticStruct()); FLiveLinkSkeletonStaticData* SkeletonData = StaticData.Cast(); + #endif + + SkeletonData->SetBoneNames(boneNames); SkeletonData->SetBoneParents(boneParents); if(Client) - Client->PushSubjectStaticData_AnyThread(Key, ULiveLinkAnimationRole::StaticClass(), MoveTemp(StaticData)); + { + #ifdef USE_SMARTSUIT_ANIMATION_ROLE + Client->PushSubjectStaticData_AnyThread(Key, ULiveLinkSmartsuitRole::StaticClass(), MoveTemp(StaticData)); + #else + Client->PushSubjectStaticData_AnyThread(Key, ULiveLinkAnimationRole::StaticClass(), MoveTemp(StaticData)); + #endif + } } -void FVirtualProductionSource::CreateJoint(TArray& transforms, int32 index, FSmartsuitBone* parent, FSmartsuitBone* sensor) +void FVirtualProductionSource::CreateJoint(TArray& transforms, int32 index, const FSmartsuitBone* parent, const FSmartsuitBone* sensor) { int32 transformIndex = transforms.AddUninitialized(1); if (!sensor) { - transforms[transformIndex].SetLocation(FVector(0, 0, 0)); + transforms[transformIndex].SetLocation(FVector::ZeroVector); transforms[transformIndex].SetRotation(FQuat::Identity); - transforms[transformIndex].SetScale3D(FVector(1, 1, 1)); + transforms[transformIndex].SetScale3D(FVector::OneVector); } - //else if (parent) - //{ - // FQuat parentRealRotation; - // if (index == -1) - // { - // parentRealRotation = parent->Uquaternion() * FQuat::MakeFromEuler(FVector(0, 0, 180)); - // } - // else - // { - // parentRealRotation = parent->Uquaternion(); - // } - - // //FVector realSensorPosition; - // //float chestOffset = 20; - // //if (sensor->addr == SENSOR_NECK) { - // // realSensorPosition - // // - // //} else if (sensor->addr == SENSOR_LEFT_SHOULDER || sensor->addr == SENSOR_RIGHT_SHOULDER) { - // // FVector direction = sensor->UPosition(); - // // direction.Normalize(); - // // realSensorPosition = sensor->UPosition() + (direction * (-chestOffset)); - // //} - // //else { - // // realSensorPosition = sensor->UPosition(); - // //} - - - // //FVector realParentPosition; - // //if (parent->addr == SENSOR_CHEST) { - - // //} - // //else { - // // realParentPosition = parent->UPosition(); - // //} - // if (sensor->name == SmartsuitBones::neck) - // { - // transforms[transformIndex].SetLocation(FVector(0, 20.150345, 0)); - // } - // else if (sensor->name == SmartsuitBones::rightShoulder) - // { - // transforms[transformIndex].SetLocation(FVector(7, 12.368073, 1.90378)); - // } - // else if (sensor->name == SmartsuitBones::leftShoulder) - // { - // transforms[transformIndex].SetLocation(FVector(-7, 12.368073, 1.90378)); - // } - // else - // { - // transforms[transformIndex].SetLocation(parentRealRotation.Inverse() * (sensor->UPosition() - parent->UPosition())); - // } - // transforms[transformIndex].SetRotation(parentRealRotation.Inverse() * sensor->Uquaternion()); - // transforms[transformIndex].SetScale3D(FVector(1, 1, 1)); - //} else { FQuat modifier = FQuat::MakeFromEuler(FVector(0, 0, 180)); transforms[transformIndex].SetLocation(sensor->UPosition()); transforms[transformIndex].SetRotation(sensor->Uquaternion() /** modifier*/); - transforms[transformIndex].SetScale3D(FVector(1, 1, 1)); + transforms[transformIndex].SetScale3D(FVector::OneVector); } } -/* -void FVirtualProductionSource::CreateJoint(TArray& transforms, int32 index, Sensor* parent, Sensor* sensor) { - - int32 transformIndex = transforms.AddUninitialized(1); - if (!sensor) - { - transforms[transformIndex].SetLocation(FVector(0, 0, 0)); - transforms[transformIndex].SetRotation(FQuat::Identity); - transforms[transformIndex].SetScale3D(FVector(1, 1, 1)); - } - else if (parent) - { - FQuat parentRealRotation; - if (index == -1) - { - parentRealRotation = parent->Uquaternion() * FQuat::MakeFromEuler(FVector(0, 0, 180)); - } - else - { - parentRealRotation = parent->Uquaternion(); - } - - //FVector realSensorPosition; - //float chestOffset = 20; - //if (sensor->addr == SENSOR_NECK) { - // realSensorPosition - // - //} else if (sensor->addr == SENSOR_LEFT_SHOULDER || sensor->addr == SENSOR_RIGHT_SHOULDER) { - // FVector direction = sensor->UPosition(); - // direction.Normalize(); - // realSensorPosition = sensor->UPosition() + (direction * (-chestOffset)); - //} - //else { - // realSensorPosition = sensor->UPosition(); - //} - - - //FVector realParentPosition; - //if (parent->addr == SENSOR_CHEST) { - - //} - //else { - // realParentPosition = parent->UPosition(); - //} - if (sensor->addr == SENSOR_NECK) - { - transforms[transformIndex].SetLocation(FVector(0, 20.150345, 0)); - } - else if (sensor->addr == SENSOR_RIGHT_SHOULDER) - { - transforms[transformIndex].SetLocation(FVector(7, 12.368073, 1.90378)); - } - else if (sensor->addr == SENSOR_LEFT_SHOULDER) - { - transforms[transformIndex].SetLocation(FVector(-7, 12.368073, 1.90378)); - } - else - { - transforms[transformIndex].SetLocation(parentRealRotation.Inverse() * (sensor->UPosition() - parent->UPosition())); - } - transforms[transformIndex].SetRotation(parentRealRotation.Inverse() * sensor->Uquaternion()); - transforms[transformIndex].SetScale3D(FVector(1, 1, 1)); - } - else - { - FQuat modifier = FQuat::MakeFromEuler(FVector(0, 0, 180)); - transforms[transformIndex].SetLocation(sensor->UPosition()); - transforms[transformIndex].SetRotation(sensor->Uquaternion() * modifier); - transforms[transformIndex].SetScale3D(FVector(1, 1, 1)); - } -} -*/ -void FVirtualProductionSource::HandleSuits(TArray suits) +void FVirtualProductionSource::HandleSuits(const TArray& suits) { //UE_LOG(LogTemp, Warning, TEXT("Handling faces %d"), faces.Num()); - existingSuits.Empty(); + existingActors.Empty(); notExistingSubjects.Empty(); for (int subjectIndex = 0; subjectIndex < suits.Num(); subjectIndex++) { - FSuitData subject = suits[subjectIndex]; + const FSuitData& subject = suits[subjectIndex]; //check in the known subjects list which ones don't exist anymore in subjects, and clear the ones that don't exist bool nameExists = false; - for (int suitNameIndex = 0; suitNameIndex < suitNames.Num(); suitNameIndex++) + for (int suitNameIndex = 0; suitNameIndex < actorNames.Num(); suitNameIndex++) { - if (subject.GetSubjectName() == suitNames[suitNameIndex]) + if (subject.GetSubjectName() == actorNames[suitNameIndex]) { nameExists = true; - existingSuits.Add(subject); + existingActors.Add(subject); break; } } if (!nameExists) { - existingSuits.Add(subject); + existingActors.Add(subject); HandleSuitData(subject); } //check in the subjects for the ones that don't exist in the known subjects list and create the ones that don't exist if (subjectIndex == suits.Num() - 1) { - for (int i = 0; i < suitNames.Num(); i++) + for (int i = 0; i < actorNames.Num(); i++) { bool subjectExists = false; - for (int j = 0; j < existingSuits.Num(); j++) + for (int j = 0; j < existingActors.Num(); j++) { - if (suitNames[i] == existingSuits[j].GetSubjectName()) + if (actorNames[i] == existingActors[j].GetSubjectName()) { subjectExists = true; } } if (!subjectExists) { - notExistingSubjects.Add(suitNames[i]); + notExistingSubjects.Add(actorNames[i]); } } @@ -628,23 +517,28 @@ void FVirtualProductionSource::HandleSuits(TArray suits) { //UE_LOG(LogTemp, Warning, TEXT("Removing face")); Client->RemoveSubject_AnyThread(FLiveLinkSubjectKey(SourceGuid, notExistingSubjects[i])); - suitNames.RemoveSingle(notExistingSubjects[i]); + actorNames.RemoveSingle(notExistingSubjects[i]); notExistingSubjects.RemoveAt(i); } } - //FTimer timer; + #ifdef USE_SMARTSUIT_ANIMATION_ROLE + FLiveLinkFrameDataStruct FrameData1(FLiveLinkSmartsuitFrameData::StaticStruct()); + FLiveLinkSmartsuitFrameData& AnimFrameData = *FrameData1.Cast(); + #else FLiveLinkFrameDataStruct FrameData1(FLiveLinkAnimationFrameData::StaticStruct()); FLiveLinkAnimationFrameData& AnimFrameData = *FrameData1.Cast(); + #endif + AnimFrameData.WorldTime = FLiveLinkWorldTime(/*(double)(timer.GetCurrentTime())*/); TArray transforms; transforms.Reset(62); int32 transformIndex = transforms.AddUninitialized(1); - transforms[transformIndex].SetLocation(FVector(0, 0, 0)); + transforms[transformIndex].SetLocation(FVector::ZeroVector); transforms[transformIndex].SetRotation(FQuat::Identity); - transforms[transformIndex].SetScale3D(FVector(1, 1, 1)); + transforms[transformIndex].SetScale3D(FVector::OneVector); CreateJoint(transforms, 0, nullptr, subject.Hip()); @@ -726,12 +620,155 @@ void FVirtualProductionSource::HandleSuits(TArray suits) AnimFrameData.Transforms.Append(transforms); + #ifdef USE_SMARTSUIT_ANIMATION_ROLE + AnimFrameData.HasLeftGlove = subject.hasLeftGlove; + AnimFrameData.HasRightGlove = subject.hasRightGlove; + #endif + + if(Client) + Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.GetSubjectName()), MoveTemp(FrameData1)); + } +} + +void FVirtualProductionSource::HandleCharacters(const TArray& characters) +{ + if (Client == nullptr) + { + UE_LOG(LogTemp, Warning, TEXT("Client was null!!!!!!")); + return; + } + + existingCharacters.Empty(); + notExistingSubjects.Empty(); + + for (int subjectIndex = 0; subjectIndex < characters.Num(); subjectIndex++) + { + const FCharacterData& subject = characters[subjectIndex]; + + //check in the known subjects list which ones don't exist anymore in subjects, and clear the ones that don't exist + bool nameExists = false; + for (int characterNameIndex = 0; characterNameIndex < characterNames.Num(); characterNameIndex++) + { + if (subject.GetSubjectName() == characterNames[characterNameIndex]) + { + nameExists = true; + existingCharacters.Add(subject); + break; + } + } + + if (!nameExists) + { + existingCharacters.Add(subject); + HandleCharacterData(subject); + } + //check in the subjects for the ones that don't exist in the known subjects list and create the ones that don't exist + if (subjectIndex == characters.Num() - 1) + { + for (int i = 0; i < actorNames.Num(); i++) + { + bool subjectExists = false; + for (int j = 0; j < existingCharacters.Num(); j++) + { + if (characterNames[i] == existingCharacters[j].GetSubjectName()) + { + subjectExists = true; + } + } + if (!subjectExists) + { + notExistingSubjects.Add(characterNames[i]); + } + } + + for (int i = 0; i < notExistingSubjects.Num(); i++) + { + //UE_LOG(LogTemp, Warning, TEXT("Removing face")); + Client->RemoveSubject_AnyThread(FLiveLinkSubjectKey(SourceGuid, notExistingSubjects[i])); + actorNames.RemoveSingle(notExistingSubjects[i]); + notExistingSubjects.RemoveAt(i); + } + } + + FLiveLinkFrameDataStruct FrameData1(FLiveLinkAnimationFrameData::StaticStruct()); + FLiveLinkAnimationFrameData& AnimFrameData = *FrameData1.Cast(); + + AnimFrameData.WorldTime = FLiveLinkWorldTime(); + + TArray transforms; + transforms.Reset(subject.joints.Num()); + FTransform tm; + + for(int x = 0; x < subject.joints.Num(); x++) + { + const int32 transformIndex = transforms.AddUninitialized(1); + const int parentIndex = subject.joints[x].parentIndex; + + if (parentIndex >= 0) + { + tm = subject.joints[x].transform.GetRelativeTransform(subject.joints[parentIndex].transform); + } + else + { + tm = subject.joints[x].transform; + } + + const FVector JointPosition = tm.GetLocation(); + const FQuat JointRotation = tm.GetRotation(); + + //convert meters to centimeters since values coming from unity are in meters + constexpr double WORLD_SCALE = 100.0; + FVector AdjustedJointPosition = FVector(-JointPosition.X * WORLD_SCALE, JointPosition.Z * WORLD_SCALE, JointPosition.Y * WORLD_SCALE); + + // Quaternions - Convert Rotations from Studio to UE + const FVector jointRotationEuler = JointRotation.Euler(); + const FQuat qx(FVector::UnitX(), FMath::DegreesToRadians(jointRotationEuler.X)); + const FQuat qy(FVector::UnitY(), FMath::DegreesToRadians(jointRotationEuler.Z)); + const FQuat qz(FVector::UnitZ(), -FMath::DegreesToRadians(jointRotationEuler.Y)); + + // Change Rotation Order + const FQuat qu = qy * qz * qx; + + transforms[transformIndex].SetComponents(qu, AdjustedJointPosition, FVector::One()); + } + + AnimFrameData.Transforms.Append(transforms); + if(Client) + { Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.GetSubjectName()), MoveTemp(FrameData1)); + } } } -void FVirtualProductionSource::HandleFace(TArray faces) +void FVirtualProductionSource::HandleCharacterData(const FCharacterData& character) +{ + characterNames.Add(character.GetSubjectName()); + + FLiveLinkSubjectKey Key = FLiveLinkSubjectKey(SourceGuid, character.GetSubjectName()); + + TArray boneNames; + TArray boneParents; + + for(int x = 0; x < character.joints.Num(); x++) + { + boneNames.Add(character.joints[x].name); + boneParents.Add(character.joints[x].parentIndex ); + } + + FLiveLinkStaticDataStruct StaticData(FLiveLinkSkeletonStaticData::StaticStruct()); + FLiveLinkSkeletonStaticData* SkeletonData = StaticData.Cast(); + + SkeletonData->SetBoneNames(boneNames); + SkeletonData->SetBoneParents(boneParents); + + if(Client) + { + Client->PushSubjectStaticData_AnyThread(Key, ULiveLinkAnimationRole::StaticClass(), MoveTemp(StaticData)); + } +} + +void FVirtualProductionSource::HandleFace(const TArray& faces) { //verify(Client != nullptr); @@ -746,7 +783,7 @@ void FVirtualProductionSource::HandleFace(TArray faces) notExistingSubjects.Empty(); for (int subjectIndex = 0; subjectIndex < faces.Num(); subjectIndex++) { - FFace subject = faces[subjectIndex]; + const FFace& subject = faces[subjectIndex]; //check in the known subjects list which ones don't exist anymore in subjects, and clear the ones that don't exist bool nameExists = false; @@ -798,70 +835,69 @@ void FVirtualProductionSource::HandleFace(TArray faces) FLiveLinkAnimationFrameData& AnimFrameData = *FrameData.Cast(); AnimFrameData.WorldTime = FLiveLinkWorldTime(/*(double)(timer.GetCurrentTime())*/); - - - AnimFrameData.PropertyValues.Add(subject.browDownLeft); - AnimFrameData.PropertyValues.Add(subject.browDownRight); - AnimFrameData.PropertyValues.Add(subject.browInnerUp); - AnimFrameData.PropertyValues.Add(subject.browOuterUpLeft); - AnimFrameData.PropertyValues.Add(subject.browOuterUpRight); - AnimFrameData.PropertyValues.Add(subject.cheekPuff); - AnimFrameData.PropertyValues.Add(subject.cheekSquintLeft); - AnimFrameData.PropertyValues.Add(subject.cheekSquintRight); - AnimFrameData.PropertyValues.Add(subject.eyeBlinkLeft); - AnimFrameData.PropertyValues.Add(subject.eyeBlinkRight); - AnimFrameData.PropertyValues.Add(subject.eyeLookDownLeft); - AnimFrameData.PropertyValues.Add(subject.eyeLookDownRight); - AnimFrameData.PropertyValues.Add(subject.eyeLookInLeft); - AnimFrameData.PropertyValues.Add(subject.eyeLookInRight); - AnimFrameData.PropertyValues.Add(subject.eyeLookOutLeft); - AnimFrameData.PropertyValues.Add(subject.eyeLookOutRight); - AnimFrameData.PropertyValues.Add(subject.eyeLookUpLeft); - AnimFrameData.PropertyValues.Add(subject.eyeLookUpRight); - AnimFrameData.PropertyValues.Add(subject.eyeSquintLeft); - AnimFrameData.PropertyValues.Add(subject.eyeSquintRight); - AnimFrameData.PropertyValues.Add(subject.eyeWideLeft); - AnimFrameData.PropertyValues.Add(subject.eyeWideRight); - AnimFrameData.PropertyValues.Add(subject.jawOpen); - AnimFrameData.PropertyValues.Add(subject.jawForward); - AnimFrameData.PropertyValues.Add(subject.jawLeft); - AnimFrameData.PropertyValues.Add(subject.jawRight); - AnimFrameData.PropertyValues.Add(subject.mouthClose); - AnimFrameData.PropertyValues.Add(subject.mouthDimpleLeft); - AnimFrameData.PropertyValues.Add(subject.mouthDimpleRight); - AnimFrameData.PropertyValues.Add(subject.mouthFrownLeft); - AnimFrameData.PropertyValues.Add(subject.mouthFrownRight); - AnimFrameData.PropertyValues.Add(subject.mouthFunnel); - AnimFrameData.PropertyValues.Add(subject.mouthLeft); - AnimFrameData.PropertyValues.Add(subject.mouthLowerDownLeft); - AnimFrameData.PropertyValues.Add(subject.mouthLowerDownRight); - AnimFrameData.PropertyValues.Add(subject.mouthPressLeft); - AnimFrameData.PropertyValues.Add(subject.mouthPressRight); - AnimFrameData.PropertyValues.Add(subject.mouthPucker); - AnimFrameData.PropertyValues.Add(subject.mouthRight); - AnimFrameData.PropertyValues.Add(subject.mouthRollLower); - AnimFrameData.PropertyValues.Add(subject.mouthRollUpper); - AnimFrameData.PropertyValues.Add(subject.mouthShrugLower); - AnimFrameData.PropertyValues.Add(subject.mouthShrugUpper); - AnimFrameData.PropertyValues.Add(subject.mouthSmileLeft); - AnimFrameData.PropertyValues.Add(subject.mouthSmileRight); - AnimFrameData.PropertyValues.Add(subject.mouthStretchLeft); - AnimFrameData.PropertyValues.Add(subject.mouthStretchRight); - AnimFrameData.PropertyValues.Add(subject.mouthUpperUpLeft); - AnimFrameData.PropertyValues.Add(subject.mouthUpperUpRight); - AnimFrameData.PropertyValues.Add(subject.noseSneerLeft); - AnimFrameData.PropertyValues.Add(subject.noseSneerRight); - AnimFrameData.PropertyValues.Add(subject.tongueOut); + AnimFrameData.PropertyValues.Append( + { + subject.browDownLeft, + subject.browDownRight, + subject.browInnerUp, + subject.browOuterUpLeft, + subject.browOuterUpRight, + subject.cheekPuff, + subject.cheekSquintLeft, + subject.cheekSquintRight, + subject.eyeBlinkLeft, + subject.eyeBlinkRight, + subject.eyeLookDownLeft, + subject.eyeLookDownRight, + subject.eyeLookInLeft, + subject.eyeLookInRight, + subject.eyeLookOutLeft, + subject.eyeLookOutRight, + subject.eyeLookUpLeft, + subject.eyeLookUpRight, + subject.eyeSquintLeft, + subject.eyeSquintRight, + subject.eyeWideLeft, + subject.eyeWideRight, + subject.jawOpen, + subject.jawForward, + subject.jawLeft, + subject.jawRight, + subject.mouthClose, + subject.mouthDimpleLeft, + subject.mouthDimpleRight, + subject.mouthFrownLeft, + subject.mouthFrownRight, + subject.mouthFunnel, + subject.mouthLeft, + subject.mouthLowerDownLeft, + subject.mouthLowerDownRight, + subject.mouthPressLeft, + subject.mouthPressRight, + subject.mouthPucker, + subject.mouthRight, + subject.mouthRollLower, + subject.mouthRollUpper, + subject.mouthShrugLower, + subject.mouthShrugUpper, + subject.mouthSmileLeft, + subject.mouthSmileRight, + subject.mouthStretchLeft, + subject.mouthStretchRight, + subject.mouthUpperUpLeft, + subject.mouthUpperUpRight, + subject.noseSneerLeft, + subject.noseSneerRight, + subject.tongueOut + }); Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.GetSubjectName()), MoveTemp(FrameData)); } } -void FVirtualProductionSource::HandleSubjectFrame(TArray FrameSubjects) +void FVirtualProductionSource::HandleSubjectFrame(const TArray& FrameSubjects) { - //verify(Client != nullptr); - if (Client == nullptr) { UE_LOG(LogTemp, Warning, TEXT("Client was null!!!!!!")); @@ -874,9 +910,9 @@ void FVirtualProductionSource::HandleSubjectFrame(TArrayPushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.name), MoveTemp(FrameData1)); + Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.Name), MoveTemp(FrameData1)); } else if (testval.StartsWith("light")) { - //FTimer timer; FLiveLinkFrameDataStruct FrameData1(FLiveLinkLightFrameData::StaticStruct()); FLiveLinkLightFrameData& LightFrameData = *FrameData1.Cast(); LightFrameData.WorldTime = FLiveLinkWorldTime(/*(double)(timer.GetCurrentTime())*/); LightFrameData.Transform = hardCodedTransform; - //CameraFrameData.LightColor = FColor::Green; - - Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.name), MoveTemp(FrameData1)); + + Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.Name), MoveTemp(FrameData1)); } else @@ -962,7 +996,7 @@ void FVirtualProductionSource::HandleSubjectFrame(TArrayPushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.name), MoveTemp(FrameData1)); + Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.Name), MoveTemp(FrameData1)); } } else @@ -974,9 +1008,39 @@ void FVirtualProductionSource::HandleSubjectFrame(TArrayPushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.name), MoveTemp(FrameData1)); + Client->PushSubjectFrameData_AnyThread(FLiveLinkSubjectKey(SourceGuid, subject.Name), MoveTemp(FrameData1)); + } + } +} + +TSharedPtr FVirtualProductionSource::Get() +{ + if (!instance) + { + IModularFeatures& ModularFeatures = IModularFeatures::Get(); + + if (ModularFeatures.IsModularFeatureAvailable(ILiveLinkClient::ModularFeatureName)) + { + bool bDoesAlreadyExist = false; + { + ILiveLinkClient& LiveLinkClient = IModularFeatures::Get().GetModularFeature(ILiveLinkClient::ModularFeatureName); + TArray Sources = LiveLinkClient.GetSources(); + for (FGuid SourceGuid : Sources) + { + if (LiveLinkClient.GetSourceType(SourceGuid).ToString() == "Studio") + { + //UE_LOG(LogTemp, Warning, TEXT("you can't add more than one instance of FVirtualProductionSource!!")); + bDoesAlreadyExist = true; + + //SetInstance(LiveLinkClient.getsour) + break; + } + } + } } } + + return instance; } TSharedPtr FVirtualProductionSource::CreateLiveLinkSource() @@ -1005,8 +1069,15 @@ TSharedPtr FVirtualProductionSource::CreateLiveLinkSou if (!bDoesAlreadyExist) { + // TODO: start source with a default streaming address and port + FIPv4Address address(FIPv4Address::Any); + + FIPv4Endpoint Endpoint; + Endpoint.Address = address; + Endpoint.Port = 14043; + ILiveLinkClient* LiveLinkClient = &IModularFeatures::Get().GetModularFeature(ILiveLinkClient::ModularFeatureName); - TSharedPtr Source = MakeShared(FText::FromString("Studio"), FText::FromString(""), FMessageAddress::NewAddress()); + TSharedPtr Source = MakeShared(Endpoint, FText::FromString("Studio"), FText::FromString(""), FMessageAddress::NewAddress()); FVirtualProductionSource::SetInstance(Source); LiveLinkClient->AddSource(Source); return Source; @@ -1027,393 +1098,200 @@ void FVirtualProductionSource::RemoveLiveLinkSource(TSharedPtrClearAllSubjects(); -// } -// //livelink->HandleClearSubject(FLiveLinkClearSubject(FString("subjectNames"))); -// -// if (Socket) -// { -// Socket->Close(); -// } -// -// // And last but not least stop the main thread -// if (Thread != NULL) -// { -// Thread->Kill(true); -// delete Thread; -// } -//} - - -void FVirtualProductionSource::StartRunnable(int port) -{ - streaming_port = port; FString ThreadName(FString::Printf(TEXT("VPStreamingNetwork%ld"), (long)(FDateTime::UtcNow().ToUnixTimestamp()))); - if (streaming_port) + if (m_NetworkAddress.Port) { - UE_LOG(LogTemp, Warning, TEXT("VP port... %i"), streaming_port); + UE_LOG(LogTemp, Warning, TEXT("VP port... %i"), m_NetworkAddress.Port); } Thread = FRunnableThread::Create(this, *ThreadName, 512 * 1024, TPri_Normal); } -bool FVirtualProductionSource::InitSocket(int port) +bool FVirtualProductionSource::InitSocket() { - streaming_port = port; - if (Socket == NULL) + if (Socket == nullptr) { - Socket = FUdpSocketBuilder(TEXT("VPStreamingNetwork")).BoundToAddress(FIPv4Address(0, 0, 0, 0)).BoundToPort(streaming_port).AsReusable().Build(); + Running = false; + Socket = FUdpSocketBuilder(TEXT("VPStreamingNetwork")).BoundToAddress(m_NetworkAddress.Address).BoundToPort(m_NetworkAddress.Port).AsReusable().Build(); + if (!Socket) + { + const FString addressStr = m_NetworkAddress.Address.ToString(); + UE_LOG(LogTemp, Error, TEXT("Failed to bind to address %s and port %i"), *addressStr, m_NetworkAddress.Port); + return false; + } + //allow the socket to listen to an already bounded address. Socket->SetReuseAddr(true); - Stopping = false; + Running = true; } return true; } FString BytesToStringFixed(const uint8* In, int32 Count) { - FString Broken = BytesToString(In, Count); - FString Fixed; - - for (int i = 0; i < Broken.Len(); i++) + FString Text = BytesToString(In, Count); + + for (int i = 0; i < Text.Len(); i++) { - const TCHAR c = Broken[i] - 1; - Fixed.AppendChar(c); + const TCHAR c = Text[i] - 1; + Text[i] = c; } - return Fixed; -} - -void FVirtualProductionSource::SendToLiveLink(TArray Subjects) -{ - //auto livelink = FVirtualProductionSource::Get(); - //if (livelink.IsValid()) - //{ - // livelink->HandleSubjectFrame(Subjects); - //} - - HandleSubjectFrame(Subjects); -} - -void FVirtualProductionSource::SendFacesToLivelink(TArray Subjects) -{ - //auto livelink = FVirtualProductionSource::Get(); - //if (livelink.IsValid()) - //{ - // livelink->HandleFace(Subjects); - //} - - HandleFace(Subjects); + return Text; } -void FVirtualProductionSource::SendSuitsToLiveLink(TArray Smartsuits) -{ - //auto livelink = FVirtualProductionSource::Get(); - //if (livelink.IsValid()) - //{ - // livelink->HandleSuits(Smartsuits); - //} - - HandleSuits(Smartsuits); - -} -PRAGMA_DISABLE_OPTIMIZATION +//PRAGMA_DISABLE_OPTIMIZATION uint32 FVirtualProductionSource::Run() { static LZ4F_decompressionContext_t g_dCtx; LZ4F_createDecompressionContext(&g_dCtx, LZ4F_VERSION); bool added = false; - while (!Stopping) - { - auto addr_in = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); - int32 bytes_read = 0; - FString ret; - uint8 data[32768]; - memset(data, '\0', 32768); + auto addr_in = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); + int32 bytes_read = 0; + FString ret; - FDateTime time = FDateTime::UtcNow(); - int seconds = time.ToUnixTimestamp(); - if (Socket) - { - if (Socket->RecvFrom(data, sizeof(data), bytes_read, *addr_in)) - { - if (bytes_read == 0) - { - continue; - } - //FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady([&]() - //{ - if (Stopping) break; - mtx.lock(); - FVirtualProductionFrame VPFrame; - - int32 UncompressedSize = 2097152; - - TArray UncompressedData; - UncompressedData.Empty(UncompressedSize); - UncompressedData.AddUninitialized(UncompressedSize); - - //FName FormatName = NAME_LZ4; - //if (!FCompression::UncompressMemory(FormatName, UncompressedData.GetData(), UncompressedSize, data, static_cast(bytes_read))) - //{ - // UE_LOG(LogTemp, Error, TEXT("FCompression::UncompressMemory - Failed to uncompress memory (%d/%d) from address %p using format %s, this may indicate the asset is corrupt!"), bytes_read, UncompressedSize, data, *FormatName.ToString()); - //} - - - //IFileManager* FileManager = &IFileManager::Get(); - uint32 WriteFlags = 0; - - //FString path = "C:/GitHub/rokoko-studio-live-unreal-engine_JSONV3/test12345678.lz4"; - //TUniquePtr Ar = TUniquePtr(FileManager->CreateFileWriter(*path, WriteFlags)); - //if (!Ar) - //{ - // UE_LOG(LogTemp, Error, TEXT("Could not write file %s!"), bytes_read, UncompressedSize, data, *FormatName.ToString()); - //} - //Ar->Serialize(const_cast(data), bytes_read); - //Ar->Close(); - - - size_t srcSize = (size_t)bytes_read; - size_t dstSize = (size_t)UncompressedData.Num(); - size_t decompressResult; - verify(srcSize >= 0); - verify(dstSize >= 0); - decompressResult = LZ4F_decompress(g_dCtx, UncompressedData.GetData(), &dstSize, data, &srcSize, NULL); - if (decompressResult != 0) { UE_LOG(LogTemp, Error, TEXT("Error decompressing frame : unfinished frame \n")); } - if (srcSize != (size_t)bytes_read) { UE_LOG(LogTemp, Error, TEXT("Error decompressing frame : read size incorrect \n")); } - - - //FString path2 = "C:/GitHub/rokoko-studio-live-unreal-engine_JSONV3/3actorstest.txt"; - //TUniquePtr Ar2 = TUniquePtr(FileManager->CreateFileWriter(*path2, WriteFlags)); - //if (!Ar2) - //{ - // UE_LOG(LogTemp, Error, TEXT("Could not write file %s!"), *path2); - //} - //Ar2->Serialize(UncompressedData.GetData(), dstSize); - //Ar2->Close(); - - - - - FString result = BytesToStringFixed(UncompressedData.GetData(), static_cast(dstSize)); - FString test = BytesToStringFixed(data, static_cast(bytes_read)); - //FString result = BytesToString(UncompressedData.GetData(), static_cast(UncompressedData.Num())); - //FString result = BytesToStringFixed(UncompressedData.GetData(), UncompressedData.Num()); - //FString result = BytesToStringFixed(data, static_cast(bytes_read)); - //UE_LOG(LogTemp, Warning, TEXT("received: %s"), *result); - //FJsonObjectConverter::JsonObjectStringToUStruct(result, &VPFrame, 0, 0); - - TSharedPtr JsonObject; - TSharedRef> Reader = TJsonReaderFactory<>::Create(result); - if (FJsonSerializer::Deserialize(Reader, JsonObject)) - { + constexpr int32 PacketSize{ 32768 }; + constexpr int32 UncompressedSize{ 2097152 }; - VPFrame.version = JsonObject->GetIntegerField("version"); - //VPFrame.timestamp = JsonObject->GetNumberField("timestamp"); - //VPFrame.playbackTimestamp = JsonObject->GetNumberField(""); + TArray PacketData; + PacketData.Empty(PacketSize); + PacketData.AddUninitialized(PacketSize); - //SCENE - { - TSharedPtr SceneObj = JsonObject->GetObjectField("scene"); - TArray> Livepropsarray = SceneObj->GetArrayField("props"); + TArray UncompressedData; + UncompressedData.Empty(UncompressedSize); + UncompressedData.AddUninitialized(UncompressedSize); - for (auto& currentprop : Livepropsarray) - { - VPFrame.props.Add(FProp(true, currentprop->AsObject())); - } - - if (SceneObj->HasField("actors")) - { - TArray> Livesuitsarray = SceneObj->GetArrayField("actors"); - for (auto& currentsuit : Livesuitsarray) - { - auto SuitData = FSuitData(true, currentsuit->AsObject()); - if (SuitData.hasFace) - { - auto JSONObjectface = currentsuit->AsObject()->GetObjectField("face"); - auto FaceData = FFace(JSONObjectface, SuitData.suitname); - SuitData.faceId = FaceData.faceId; - VPFrame.faces.Add(FaceData); - } - VPFrame.suits.Add(SuitData); - } - } - } + while (Running) + { + FDateTime time = FDateTime::UtcNow(); + int seconds = time.ToUnixTimestamp(); - ////LIVE - //{ - // TSharedPtr LiveObj = JsonObject->GetObjectField("live"); - // TArray> Livepropsarray = LiveObj->GetArrayField("props"); - - // for (auto& currentprop : Livepropsarray) - // { - // VPFrame.props.Add(FProp(true, currentprop->AsObject())); - // } - - // if (LiveObj->HasField("actors")) - // { - // TArray> Livesuitsarray = LiveObj->GetArrayField("actors"); - // for (auto& currentsuit : Livesuitsarray) - // { - // auto SuitData = FSuitData(true, currentsuit->AsObject()); - // if (SuitData.hasFace) - // { - // auto JSONObjectface = currentsuit->AsObject()->GetObjectField("face"); - // auto FaceData = FFace(JSONObjectface, SuitData.suitname); - // SuitData.faceId = FaceData.faceId; - // VPFrame.faces.Add(FaceData); - // } - // VPFrame.suits.Add(SuitData); - // } - // } - //} - - ////PLAYBACK - //{ - // TSharedPtr PlaybackObj = JsonObject->GetObjectField("playback"); - // TArray> Playbackpropsarray = PlaybackObj->GetArrayField("props"); - - // for (auto& currentprop : Playbackpropsarray) - // { - // VPFrame.props.Add(FProp(false, currentprop->AsObject())); - // } - - // if (PlaybackObj->HasField("actors")) - // { - // TArray> Playbacksuitsarray = PlaybackObj->GetArrayField("actors"); - // for (auto& currentsuit : Playbacksuitsarray) - // { - // auto SuitData = FSuitData(false, currentsuit->AsObject()); - // if (SuitData.hasFace) - // { - // auto JSONObjectface = currentsuit->AsObject()->GetObjectField("face"); - // auto FaceData = FFace(JSONObjectface, SuitData.suitname); - // SuitData.faceId = FaceData.faceId; - // VPFrame.faces.Add(FaceData); - // } - // VPFrame.suits.Add(SuitData); - // } - // } - //} + if (!Socket) + break; + if (!Socket->RecvFrom(PacketData.GetData(), PacketData.Num() * sizeof(uint8), bytes_read, *addr_in) + || bytes_read == 0) + { + continue; + } + if (!Running) + break; + + FVirtualProductionFrame VPFrame; + + size_t srcSize = static_cast(bytes_read); + size_t dstSize = static_cast(UncompressedData.Num()); + size_t decompressResult; + verify(srcSize >= 0); + verify(dstSize >= 0); + decompressResult = LZ4F_decompress(g_dCtx, UncompressedData.GetData(), &dstSize, PacketData.GetData(), &srcSize, nullptr); + if (decompressResult != 0) + { + UE_LOG(LogTemp, Error, TEXT("Error decompressing frame : unfinished frame \n")); + continue; + } + if (srcSize != (size_t)bytes_read) + { + UE_LOG(LogTemp, Error, TEXT("Error decompressing frame : read size incorrect \n")); + continue; + } + FString result = BytesToStringFixed(UncompressedData.GetData(), static_cast(dstSize)); + + TSharedPtr JsonObject; + TSharedRef> Reader = TJsonReaderFactory<>::Create(result); + if (FJsonSerializer::Deserialize(Reader, JsonObject)) + { + VPFrame.Version = JsonObject->GetStringField("version"); + + //SCENE + { + TSharedPtr SceneObj = JsonObject->GetObjectField("scene"); + TArray> Livepropsarray = SceneObj->GetArrayField("props"); + for (auto& currentprop : Livepropsarray) + { + auto NewProp = FProp(true, currentprop->AsObject()); + VPFrame.Props.Emplace(MoveTemp(NewProp)); } - - //if (!GlobalVPFrame) - //{ - // GlobalVPFrame = new FVirtualProductionFrame(); - //} - GlobalVPFrame.version = VPFrame.version; - GlobalVPFrame.props.Empty(); - GlobalVPFrame.trackers.Empty(); - GlobalVPFrame.faces.Empty(); - GlobalVPFrame.suits.Empty(); - - //auto livelink = FVirtualProductionSource::Get(); - - //if (livelink.IsValid()) + if (SceneObj->HasField("actors")) { - subjects.Empty(); - for (int i = 0; i < VPFrame.props.Num(); i++) - { - GlobalVPFrame.props.Add(VPFrame.props[i]); - FVirtualProductionSubject subject = GlobalVPFrame.props[i].GetSubject(); - subjects.Add(subject); - } - for (int i = 0; i < VPFrame.trackers.Num(); i++) - { - GlobalVPFrame.trackers.Add(VPFrame.trackers[i]); - FVirtualProductionSubject subject = GlobalVPFrame.trackers[i].GetSubject(); - subjects.Add(subject); - } - for (int i = 0; i < VPFrame.faces.Num(); i++) + TArray> Livesuitsarray = SceneObj->GetArrayField("actors"); + for (auto& currentsuit : Livesuitsarray) { - GlobalVPFrame.faces.Add(VPFrame.faces[i]); + auto SuitData = FSuitData(true, currentsuit->AsObject()); + if (SuitData.hasFace) + { + auto JSONObjectface = currentsuit->AsObject()->GetObjectField("face"); + auto FaceData = FFace(JSONObjectface, SuitData.suitname); + SuitData.faceId = FaceData.faceId; + VPFrame.Faces.Emplace(MoveTemp(FaceData)); + } + VPFrame.Actors.Emplace(MoveTemp(SuitData)); } - for (int i = 0; i < VPFrame.suits.Num(); i++) + } + + if (SceneObj->HasField("characters")) + { + TArray> CharactersArray = SceneObj->GetArrayField("characters"); + for (auto& currentcharacter : CharactersArray) { - GlobalVPFrame.suits.Add(VPFrame.suits[i]); + auto CharacterData = FCharacterData(true, currentcharacter->AsObject()); + VPFrame.Characters.Emplace(MoveTemp(CharacterData)); } - SendToLiveLink(subjects); - SendFacesToLivelink(GlobalVPFrame.faces); - SendSuitsToLiveLink(GlobalVPFrame.suits); } - //else - //{ - // for (int i = 0; i < VPFrame.props.Num(); i++) - // { - // GlobalVPFrame.props.Add(VPFrame.props[i]); - // } - // for (int i = 0; i < VPFrame.trackers.Num(); i++) - // { - // GlobalVPFrame.trackers.Add(VPFrame.trackers[i]); - // } - // for (int i = 0; i < VPFrame.faces.Num(); i++) - // { - // //UE_LOG(LogTemp, Warning, TEXT("face: %d - %s - %f"), VPFrame.faces[i].version, *VPFrame.faces[i].provider, VPFrame.faces[i].jawOpen); - // GlobalVPFrame.faces.Add(VPFrame.faces[i]); - // } - // for (int i = 0; i < VPFrame.suits.Num(); i++) - // { - // GlobalVPFrame.suits.Add(VPFrame.suits[i]); - // } - //} - //UE_LOG(LogTemp, Warning, TEXT("Faces... %i"), GlobalVPFrame.faces.Num()); - mtx.unlock(); - //}, TStatId(), NULL, ENamedThreads::GameThread); - - // If you want to wait for the code above to complete do this: - //FTaskGraphInterface::Get().WaitUntilTaskCompletes(Task); - } } + + mtx.lock(); + + GlobalVPFrame.Version = VPFrame.Version; + GlobalVPFrame.Props = MoveTemp(VPFrame.Props); + GlobalVPFrame.Trackers = MoveTemp(VPFrame.Trackers); + + Subjects.Empty(); + for (int i = 0; i < VPFrame.Props.Num(); i++) + { + FVirtualProductionSubject subject = GlobalVPFrame.Props[i].GetSubject(); + Subjects.Add(subject); + } + for (int i = 0; i < VPFrame.Trackers.Num(); i++) + { + FVirtualProductionSubject subject = GlobalVPFrame.Trackers[i].GetSubject(); + Subjects.Add(subject); + } + + GlobalVPFrame.Faces = MoveTemp(VPFrame.Faces); + GlobalVPFrame.Actors = MoveTemp(VPFrame.Actors); + GlobalVPFrame.Characters = MoveTemp(VPFrame.Characters); + + mtx.unlock(); + + HandleSubjectFrame(Subjects); + HandleFace(GlobalVPFrame.Faces); + HandleSuits(GlobalVPFrame.Actors); + HandleCharacters(GlobalVPFrame.Characters); } return 0; } -PRAGMA_ENABLE_OPTIMIZATION +//PRAGMA_ENABLE_OPTIMIZATION FProp* FVirtualProductionSource::GetPropByName(FString name, bool isLive) { FProp* result = nullptr; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.props.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Props.Num(); i++) { - if (name == GlobalVPFrame.props[i].name && GlobalVPFrame.props[i].isLive == isLive) + if (name == GlobalVPFrame.Props[i].name && GlobalVPFrame.Props[i].isLive == isLive) { - result = &GlobalVPFrame.props[i]; + result = &GlobalVPFrame.Props[i]; } } } @@ -1423,35 +1301,29 @@ FProp* FVirtualProductionSource::GetPropByName(FString name, bool isLive) TArray FVirtualProductionSource::GetAllProps() { - //return nullptr; TArray result; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.props.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Props.Num(); i++) { - result.Add(GlobalVPFrame.props[i]); - //result->Add + result.Add(GlobalVPFrame.Props[i]); } } mtx.unlock(); //UE_LOG(LogTemp, Display, TEXT("Yeeee3")); return result; - - //return GlobalVPFrame.props; } FTracker* FVirtualProductionSource::GetTrackerByName(FString name, bool isLive) { FTracker* result = nullptr; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.trackers.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Trackers.Num(); i++) { - if (name == GlobalVPFrame.trackers[i].name && GlobalVPFrame.trackers[i].isLive == isLive) + if (name == GlobalVPFrame.Trackers[i].name && GlobalVPFrame.Trackers[i].isLive == isLive) { - result = &GlobalVPFrame.trackers[i]; + result = &GlobalVPFrame.Trackers[i]; } } } @@ -1463,13 +1335,12 @@ FTracker* FVirtualProductionSource::GetTrackerByConnectionID(const FString& name { FTracker* result = nullptr; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.trackers.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Trackers.Num(); i++) { - if (name == GlobalVPFrame.trackers[i].connectionId /*&& GlobalVPFrame.trackers[i].isLive == isLive*/) + if (name == GlobalVPFrame.Trackers[i].connectionId /*&& GlobalVPFrame.trackers[i].isLive == isLive*/) { - result = &GlobalVPFrame.trackers[i]; + result = &GlobalVPFrame.Trackers[i]; } } } @@ -1481,13 +1352,12 @@ TArray FVirtualProductionSource::GetTrackersWithMatchingId(FString Con { TArray result; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.trackers.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Trackers.Num(); i++) { - if (ConnectionId == GlobalVPFrame.trackers[i].connectionId /*&& GlobalVPFrame.trackers[i].isLive == isLive*/) + if (ConnectionId == GlobalVPFrame.Trackers[i].connectionId /*&& GlobalVPFrame.trackers[i].isLive == isLive*/) { - result.Add(GlobalVPFrame.trackers[i]); + result.Add(GlobalVPFrame.Trackers[i]); } } } @@ -1497,22 +1367,22 @@ TArray FVirtualProductionSource::GetTrackersWithMatchingId(FString Con FSuitData* FVirtualProductionSource::GetSmartsuitByName(FString suitName) { - if (suitName.Len() == 0 || suitName.Compare(FString("")) == 0) + + if (suitName.IsEmpty() || suitName.Compare(FString("")) == 0) { return nullptr; } FSuitData* result = nullptr; mtx.lock(); - //if (GlobalVPFrame) { //should probably set the limit to the size of the suit array here? - for (int i = 0; i < GlobalVPFrame.suits.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Actors.Num(); i++) { - FString mySuitName(GlobalVPFrame.suits[i].suitname); - if (suitName.Compare(mySuitName) == 0 && mySuitName.Len() > 0) + FString mySuitName(GlobalVPFrame.Actors[i].suitname); + if (suitName.Compare(mySuitName) == 0 && !mySuitName.IsEmpty()) { - result = &(GlobalVPFrame.suits[i]); + result = &(GlobalVPFrame.Actors[i]); } } } @@ -1525,13 +1395,12 @@ TArray FVirtualProductionSource::GetAvailableSmartsuitNames() TArray result; //maybe we should set the limit to the size of the suits array mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.suits.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Actors.Num(); i++) { - if ((GlobalVPFrame.suits[i].suitname != "\0\0\0\0") /*&& GlobalVPFrame.suits[i].fps > 0*/) + if ((GlobalVPFrame.Actors[i].suitname != "\0\0\0\0") /*&& GlobalVPFrame.suits[i].fps > 0*/) { - result.Add(FString(GlobalVPFrame.suits[i].suitname)); + result.Add(FString(GlobalVPFrame.Actors[i].suitname)); } } } @@ -1544,13 +1413,12 @@ TArray FVirtualProductionSource::GetAllSmartsuits() TArray suits; //maybe we should set the limit to the size of the suits array mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.suits.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Actors.Num(); i++) { - if ((GlobalVPFrame.suits[i].suitname != "\0\0\0\0") /*&& GlobalVPFrame.suits[i].fps > 0*/) + if ((GlobalVPFrame.Actors[i].suitname != "\0\0\0\0") /*&& GlobalVPFrame.suits[i].fps > 0*/) { - suits.Add(GlobalVPFrame.suits[i]); + suits.Add(GlobalVPFrame.Actors[i]); } } } @@ -1560,35 +1428,31 @@ TArray FVirtualProductionSource::GetAllSmartsuits() FFace FVirtualProductionSource::GetFaceByFaceID(FString faceID) { - FFace result; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.faces.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Faces.Num(); i++) { - if (GlobalVPFrame.faces[i].faceId == faceID) + if (GlobalVPFrame.Faces[i].faceId == faceID) { - result = GlobalVPFrame.faces[i]; - break; + return FFace(GlobalVPFrame.Faces[i]); } } } mtx.unlock(); - return result; + return FFace(); } FFace* FVirtualProductionSource::GetFaceByProfileName(const FString& profileName) { FFace* result = nullptr; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.faces.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Faces.Num(); i++) { - if (GlobalVPFrame.faces[i].profileName == profileName) + if (GlobalVPFrame.Faces[i].profileName == profileName) { - result = &GlobalVPFrame.faces[i]; + result = &GlobalVPFrame.Faces[i]; break; } } @@ -1602,17 +1466,13 @@ TArray FVirtualProductionSource::GetAllFaces() { TArray result; mtx.lock(); - //if (GlobalVPFrame) { - for (int i = 0; i < GlobalVPFrame.faces.Num(); i++) + for (int i = 0; i < GlobalVPFrame.Faces.Num(); i++) { - result.Add(GlobalVPFrame.faces[i]); - //result->Add + result.Add(GlobalVPFrame.Faces[i]); } } mtx.unlock(); return result; - - //return GlobalVPFrame.faces; } \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionTracker.cpp b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionTracker.cpp index bf05060..f373ff2 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionTracker.cpp +++ b/Plugins/Smartsuit/Source/Smartsuit/Private/VirtualProductionTracker.cpp @@ -1,7 +1,8 @@ // Copyright 2019 Rokoko Electronics. All Rights Reserved. #include "VirtualProductionTracker.h" - +#include "VirtualProductionFrame.h" +#include "VirtualProductionSource.h" UVirtualProductionTracker::UVirtualProductionTracker() { @@ -21,40 +22,23 @@ void UVirtualProductionTracker::BeginPlay() CurrentLocation = parent->GetActorLocation(); } -ARokokoReceiver* UVirtualProductionTracker::GetReceiver() -{ - ARokokoReceiver* listener = nullptr; - - for (TObjectIterator It; It; ++It) - { - if (It->enabled) - { - listener = *It; - break; - } - } - return listener; -} - void UVirtualProductionTracker::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - ARokokoReceiver* listener = GetReceiver(); - if (!listener) + auto livelink = FVirtualProductionSource::Get(); + if (!livelink.IsValid()) { + UE_LOG(LogTemp, Warning, TEXT("can not get virtual production source!!!")); return; } - FTracker* tracker = listener->GetTrackerByNameFromVP(name, isLive); + FTracker* tracker = livelink->GetTrackerByName(name, isLive); if (!tracker) { return; } - //parent->SetActorLocation(tracker->UPosition() * scalePosition); - //parent->SetActorRotation(tracker->FQuatToRotator()); - if (useLocalSpace) { parent->SetActorRelativeLocation(tracker->UPosition() * scalePosition); diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/AnimNode_ModifyFaceCurves.h b/Plugins/Smartsuit/Source/Smartsuit/Public/AnimNode_ModifyFaceCurves.h deleted file mode 100644 index c94f6d2..0000000 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/AnimNode_ModifyFaceCurves.h +++ /dev/null @@ -1,77 +0,0 @@ -//// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. -// -//#pragma once -// -//#include "CoreMinimal.h" -//#include "UObject/ObjectMacros.h" -//#include "Animation/AnimNodeBase.h" -//#include "VirtualProductionSource.h" -//#include "AnimNode_ModifyFaceCurves.generated.h" -// -//UENUM() -//enum class EModifyFaceCurvesApplyMode : uint8 -//{ -// /** Add new value to input curve value */ -// Add, -// -// /** Scale input value by new value */ -// Scale, -// -// /** Blend input with new curve value, using Alpha setting on the node */ -// Blend, -// -// /** Blend the new curve value with the last curve value using Alpha to determine the weighting (.5 is a moving average, higher values react to new values faster, lower slower) */ -// WeightedMovingAverage, -// -// /** Remaps the new curve value between the CurveValues entry and 1.0 (.5 in CurveValues makes 0.51 map to 0.02) */ -// RemapCurve -//}; -// -///** Easy way to modify curve values on a pose */ -//USTRUCT(BlueprintInternalUseOnly) -//struct SMARTSUIT_API FAnimNode_ModifyFaceCurves : public FAnimNode_Base -//{ -// GENERATED_BODY() -// -// UPROPERTY(EditAnywhere, EditFixedSize, BlueprintReadWrite, Category = Links) -// FPoseLink SourcePose; -// -// UPROPERTY(EditAnywhere, BlueprintReadWrite, editfixedsize, Category = ModifyCurve, meta = (PinShownByDefault)) -// TArray CurveValues; -// -// UPROPERTY() -// TArray CurveNames; -// -// TArray LastCurveValues; -// -// UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ModifyCurve, meta = (PinShownByDefault)) -// float Alpha; -// -// //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ModifyCurve, meta = (PinShownByDefault)) -// //FName LiveLinkSubjectName; -// -// UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ModifyCurve, meta = (PinShownByDefault)) -// FLiveLinkSubjectRepresentation SubjectRepresentation; -// -// UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ModifyCurve, meta = (PinShownByDefault)) -// UVPFaceMorphTargetNameRemapping* MorphTargetRemapAsset; -// -// UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ModifyCurve) -// EModifyFaceCurvesApplyMode ApplyMode; -// -// FAnimNode_ModifyFaceCurves(); -// -// // FAnimNode_Base interface -// virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) override; -// virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) override; -// virtual void Evaluate_AnyThread(FPoseContext& Output) override; -// virtual void Update_AnyThread(const FAnimationUpdateContext& Context) override; -// // End of FAnimNode_Base interface -// -//#if WITH_EDITOR -// /** Add new curve being modified */ -// void AddCurve(const FName& InName, float InValue); -// /** Remove a curve from being modified */ -// void RemoveCurve(int32 PoseIndex); -//#endif // WITH_EDITOR -//}; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoBodyRemapAsset.h b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoBodyRemapAsset.h new file mode 100644 index 0000000..3aed62e --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoBodyRemapAsset.h @@ -0,0 +1,217 @@ +// Copyright 2023 Rokoko Electronics. All Rights Reserved. + +#pragma once + +#include "LiveLinkCustomVersion.h" +#include "LiveLinkRemapAsset.h" + +#include "RokokoBodyRemapAsset.generated.h" + + +UCLASS(BlueprintType) +class SMARTSUIT_API URokokoBodyMapData : public ULiveLinkRemapAsset +{ + GENERATED_BODY() + + //!< a constructor + URokokoBodyMapData(); + +public: + + FName GetRemappedBoneName_Implementation(FName CurveName) const override; + + virtual void Initialize() override + { + InitializeTMap(); + } + + UFUNCTION(BlueprintCallable, Category = BoneRemapping) + void InitializeTMap(); + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + TMap NameMapping; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName hip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName stomach; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName chest; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName neck; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName head; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftShoulder; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftArm; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftForearm; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftHand; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightShoulder; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightArm; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightForearm; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightHand; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftUpleg; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftLeg; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftFoot; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftToe; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightUpleg; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightLeg; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightFoot; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightToe; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftThumbProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftThumbMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftThumbDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftThumbTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftIndexProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftIndexMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftIndexDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftIndexTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftMiddleProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftMiddleMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftMiddleDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftMiddleTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftRingProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftRingMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftRingDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftRingTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftLittleProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftLittleMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftLittleDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName leftLittleTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightThumbProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightThumbMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightThumbDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightThumbTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightIndexProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightIndexMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightIndexDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightIndexTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightMiddleProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightMiddleMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightMiddleDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightMiddleTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightRingProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightRingMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightRingDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightRingTip; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightLittleProximal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightLittleMedial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightLittleDistal; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) + FName rightLittleTip; + +}; \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoFaceMapData.h b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoFaceMapData.h new file mode 100644 index 0000000..525b10d --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoFaceMapData.h @@ -0,0 +1,297 @@ +#pragma once + +#include "ILiveLinkClient.h" +#include "ILiveLinkSource.h" +#include "Runtime/RenderCore/Public/RenderCore.h" +#include "MessageEndpoint.h" +#include "VirtualProductionFrame.h" +#include "RokokoSkeletonData.h" +#include "Engine/DataAsset.h" +#include "LiveLinkRemapAsset.h" + +#include "RokokoFaceMapData.generated.h" + + +UCLASS(BlueprintType) +class SMARTSUIT_API URokokoFaceMapData : public ULiveLinkRemapAsset +{ + GENERATED_BODY() + + URokokoFaceMapData() + { + browDownLeft = "browDownLeft"; + browDownRight = "browDownRight"; + browInnerUp = "browInnerUp"; + browOuterUpLeft = "browOuterUpLeft"; + browOuterUpRight = "browOuterUpRight"; + cheekPuff = "cheekPuff"; + cheekSquintLeft = "cheekSquintLeft"; + cheekSquintRight = "cheekSquintRight"; + eyeBlinkLeft = "eyeBlinkLeft"; + eyeBlinkRight = "eyeBlinkRight"; + eyeLookDownLeft = "eyeLookDownLeft"; + eyeLookDownRight = "eyeLookDownRight"; + eyeLookInLeft = "eyeLookInLeft"; + eyeLookInRight = "eyeLookInRight"; + eyeLookOutLeft = "eyeLookOutLeft"; + eyeLookOutRight = "eyeLookOutRight"; + eyeLookUpLeft = "eyeLookUpLeft"; + eyeLookUpRight = "eyeLookUpRight"; + eyeSquintLeft = "eyeSquintLeft"; + eyeSquintRight = "eyeSquintRight"; + eyeWideLeft = "eyeWideLeft"; + eyeWideRight = "eyeWideRight"; + jawOpen = "jawOpen"; + jawForward = "jawForward"; + jawLeft = "jawLeft"; + jawRight = "jawRight"; + mouthClose = "mouthClose"; + mouthDimpleLeft = "mouthDimpleLeft"; + mouthDimpleRight = "mouthDimpleRight"; + mouthFrownLeft = "mouthFrownLeft"; + mouthFrownRight = "mouthFrownRight"; + mouthFunnel = "mouthFunnel"; + mouthLeft = "mouthLeft"; + mouthLowerDownLeft = "mouthLowerDownLeft"; + mouthLowerDownRight = "mouthLowerDownRight"; + mouthPressLeft = "mouthPressLeft"; + mouthPressRight = "mouthPressRight"; + mouthPucker = "mouthPucker"; + mouthRight = "mouthRight"; + mouthRollLower = "mouthRollLower"; + mouthRollUpper = "mouthRollUpper"; + mouthShrugLower = "mouthShrugLower"; + mouthShrugUpper = "mouthShrugUpper"; + mouthSmileLeft = "mouthSmileLeft"; + mouthSmileRight = "mouthSmileRight"; + mouthStretchLeft = "mouthStretchLeft"; + mouthStretchRight = "mouthStretchRight"; + mouthUpperUpLeft = "mouthUpperUpLeft"; + mouthUpperUpRight = "mouthUpperUpRight"; + noseSneerLeft = "noseSneerLeft"; + noseSneerRight = "noseSneerRight"; + tongueOut = "tongueOut"; + } +public: + + FName GetRemappedCurveName_Implementation(FName CurveName) const override; + + virtual void Initialize() override; + + UFUNCTION(BlueprintCallable, Category = MorphTargetRemapping) + void InitializeTMap() + { + NameMapping.Add("browDownLeft", browDownLeft); + NameMapping.Add("browDownRight", browDownRight); + NameMapping.Add("browInnerUp", browInnerUp); + NameMapping.Add("browOuterUpLeft", browOuterUpLeft); + NameMapping.Add("browOuterUpRight", browOuterUpRight); + NameMapping.Add("cheekPuff", cheekPuff); + NameMapping.Add("cheekSquintLeft", cheekSquintLeft); + NameMapping.Add("cheekSquintRight", cheekSquintRight); + NameMapping.Add("eyeBlinkLeft", eyeBlinkLeft); + NameMapping.Add("eyeBlinkRight", eyeBlinkRight); + NameMapping.Add("eyeLookDownLeft", eyeLookDownLeft); + NameMapping.Add("eyeLookDownRight", eyeLookDownRight); + NameMapping.Add("eyeLookInLeft", eyeLookInLeft); + NameMapping.Add("eyeLookInRight", eyeLookInRight); + NameMapping.Add("eyeLookOutLeft", eyeLookOutLeft); + NameMapping.Add("eyeLookOutRight", eyeLookOutRight); + NameMapping.Add("eyeLookUpLeft", eyeLookUpLeft); + NameMapping.Add("eyeLookUpRight", eyeLookUpRight); + NameMapping.Add("eyeSquintLeft", eyeSquintLeft); + NameMapping.Add("eyeSquintRight", eyeSquintRight); + NameMapping.Add("eyeWideLeft", eyeWideLeft); + NameMapping.Add("eyeWideRight", eyeWideRight); + NameMapping.Add("jawOpen", jawOpen); + NameMapping.Add("jawForward", jawForward); + NameMapping.Add("jawLeft", jawLeft); + NameMapping.Add("jawRight", jawRight); + NameMapping.Add("mouthClose", mouthClose); + NameMapping.Add("mouthDimpleLeft", mouthDimpleLeft); + NameMapping.Add("mouthDimpleRight", mouthDimpleRight); + NameMapping.Add("mouthFrownLeft", mouthFrownLeft); + NameMapping.Add("mouthFrownRight", mouthFrownRight); + NameMapping.Add("mouthFunnel", mouthFunnel); + NameMapping.Add("mouthLeft", mouthLeft); + NameMapping.Add("mouthLowerDownLeft", mouthLowerDownLeft); + NameMapping.Add("mouthLowerDownRight", mouthLowerDownRight); + NameMapping.Add("mouthPressLeft", mouthPressLeft); + NameMapping.Add("mouthPressRight", mouthPressRight); + NameMapping.Add("mouthPucker", mouthPucker); + NameMapping.Add("mouthRight", mouthRight); + NameMapping.Add("mouthRollLower", mouthRollLower); + NameMapping.Add("mouthRollUpper", mouthRollUpper); + NameMapping.Add("mouthShrugLower", mouthShrugLower); + NameMapping.Add("mouthShrugUpper", mouthShrugUpper); + NameMapping.Add("mouthSmileLeft", mouthSmileLeft); + NameMapping.Add("mouthSmileRight", mouthSmileRight); + NameMapping.Add("mouthStretchLeft", mouthStretchLeft); + NameMapping.Add("mouthStretchRight", mouthStretchRight); + NameMapping.Add("mouthUpperUpLeft", mouthUpperUpLeft); + NameMapping.Add("mouthUpperUpRight", mouthUpperUpRight); + NameMapping.Add("noseSneerLeft", noseSneerLeft); + NameMapping.Add("noseSneerRight", noseSneerRight); + NameMapping.Add("tongueOut", tongueOut); + } + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + TMap NameMapping; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName browDownLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName browDownRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName browInnerUp; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName browOuterUpLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName browOuterUpRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName cheekPuff; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName cheekSquintLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName cheekSquintRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeBlinkLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeBlinkRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookDownLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookDownRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookInLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookInRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookOutLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookOutRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookUpLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeLookUpRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeSquintLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeSquintRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeWideLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName eyeWideRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName jawOpen; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName jawForward; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName jawLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName jawRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthClose; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthDimpleLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthDimpleRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthFrownLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthFrownRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthFunnel; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthLowerDownLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthLowerDownRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthPressLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthPressRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthPucker; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthRollLower; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthRollUpper; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthShrugLower; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthShrugUpper; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthSmileLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthSmileRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthStretchLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthStretchRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthUpperUpLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName mouthUpperUpRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName noseSneerLeft; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName noseSneerRight; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) + FName tongueOut; + +}; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoModule.h b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoModule.h new file mode 100644 index 0000000..b316e49 --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoModule.h @@ -0,0 +1,47 @@ +// // Copyright 2019 Rokoko Electronics. All Rights Reserved. +// +// #pragma once +// //#include "ModuleManager.h" +// //#include "Modules/ModuleInterface.h" +// ///// @cond doc_hidden +// //class FSmartsuitModule : public IModuleInterface +// //{ +// //public: +// // +// // virtual void StartupModule() override; +// // virtual void ShutdownModule() override; +// //}; +// /// @endcond +// // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. +// +// #pragma once +// +// #include "CoreMinimal.h" +// #include "Modules/ModuleInterface.h" +// #include "Modules/ModuleManager.h" +// +// +// class IRokokoModule : public IModuleInterface +// { +// public: +// /** +// * Singleton-like access to this module's interface. This is just for convenience! +// * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already. +// * +// * @return Returns singleton instance, loading the module on demand if needed +// */ +// static inline IRokokoModule& Get() +// { +// return FModuleManager::LoadModuleChecked< IRokokoModule >("Smartsuit"); +// } +// +// /** +// * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true. +// * +// * @return True if the module is loaded and ready to use +// */ +// static inline bool IsAvailable() +// { +// return FModuleManager::Get().IsModuleLoaded("Smartsuit"); +// } +// }; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoRemote.h b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoRemote.h index 0800623..17db93c 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoRemote.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoRemote.h @@ -9,43 +9,15 @@ #include "Dom/JsonObject.h" #include "Serialization/JsonWriter.h" #include "Serialization/JsonSerializer.h" +#include "RokokoStudioCommandAPI.h" #include "RokokoRemote.generated.h" class FUdpSocketReceiver; -USTRUCT() -struct FRokokoRemoteInstance /*: IValuable*/ -{ -public: - GENERATED_BODY() - - FRokokoRemoteInstance() {} - FRokokoRemoteInstance(TSharedPtr jsonObject); - - FString Serialize(); - - void DisplayValues(); - - FString type; - int version; - FString provider; - FString faceId; - FString deviceName; - FString connectedTo; - FString requestedFrom; - FString commandKey; - int commandPort; - bool recording; - float currentRecordingTime; - int numberOfLiveSuits; - bool commandApiOn; - bool commandApiLicense; - bool faceLicense; -}; -DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnConnected, const FString&, ResponseContentString); -DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDisconnected); +//DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnConnected, const FString&, ResponseContentString); +//DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDisconnected); UCLASS() class SMARTSUIT_API ARokokoRemote : public AActor @@ -61,46 +33,22 @@ class SMARTSUIT_API ARokokoRemote : public AActor virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Default) - FString IPAddress; - - UPROPERTY() - FTimerHandle FTH_TestHandle; - - UPROPERTY(BlueprintAssignable) - FOnConnected OnConnected; - - UPROPERTY(BlueprintAssignable) - FOnDisconnected OnDisconnected; - - UFUNCTION(BlueprintPure, Category = Default) - FString GetCommandAPIKey(); - - UFUNCTION(BlueprintPure, Category = Default) - int32 GetCommandAPIPort(); - - TSharedPtr RemoteAddr; - - FSocket* SenderSocket; - - bool StartUDPSender(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort); - - bool Sender_SendData(); - - void SendData(); - - bool StartUDPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort); + static ARokokoRemote *GetFirstAvailableActor(); - FSocket* ListenSocket; + UPROPERTY(BlueprintAssignable, Category = "Command API") + FOnCompletedRequest OnCompletedRequest; - FUdpSocketReceiver* UDPReceiver; - void Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt); + UPROPERTY(BlueprintAssignable, Category = "Command API") + FOnInfoRequest OnInfoRequest; - FRokokoRemoteInstance CurrentData; + UPROPERTY(BlueprintAssignable, Category = "Command API") + FOnTrackerRequest OnTrackerRequest; - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Default) - int SenderPort; + UPROPERTY(BlueprintAssignable, Category = "Command API") + FOnPlaybackRequest OnPlaybackRequest; - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Default) - int ReceiverPort; + void OnProcessRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded); + void OnInfoRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded); + void OnTrackerRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded); + void OnPlaybackRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded); }; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitDefinitions.h b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoSkeletonData.h similarity index 72% rename from Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitDefinitions.h rename to Plugins/Smartsuit/Source/Smartsuit/Public/RokokoSkeletonData.h index 7eb99e0..df2a0c3 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitDefinitions.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoSkeletonData.h @@ -2,8 +2,10 @@ #pragma once -#include "../Lib/V8/Includes/SmartsuitDef.h" -#include "SmartsuitDefinitions.generated.h" +#include "Runtime/Launch/Resources/Version.h" + +#include "RokokoSkeletonData.generated.h" + /*! \file SmartsuitDefinitions.h \brief This file includes all definitions used by Smartsuit plugin. * @@ -177,150 +179,24 @@ namespace SmartsuitBones extern const FName rightLittleTip; } +USTRUCT() +struct FRokokoCharacterJoint +{ + GENERATED_BODY() + + FRokokoCharacterJoint() {} + FRokokoCharacterJoint(FName Name, int32 ParentIndex, const FTransform& Transform) + : name(Name) + , parentIndex(ParentIndex) + , transform(Transform) + {} -///*! \brief Information about specific sensor, including its status, rotation, position.*/ -//struct Sensor { -// -// /** -// * The address of the Sensor in the Smartsuit. Represents its position. -// * A list of all supported addresses can be found in ASmartsuitCommands -// */ -// uint16_t addr; -// -// /**Indicates weither there is another sensor connected after this, or this is the last sensor in a branch.*/ -// char isAnotherSensorConnected; -// -// char behavior; -// /**Indicates if the sensor detects metal or not.*/ -// char command; -// /**Holds information about the acceleration detected in the sensor during the last frame.*/ -// FVector acceleration; -// -// /** -// * The rotation information for this sensor. This quaternion is represented in Smartsuits coordinate system. -// * To get a quaternion in Unreal coordinate system use UQuaternion() instead. -// */ -// FQuat quaternion; -// -// /** Gyroscope information for this sensor.*/ -// FVector gyro; -// -// /** -// * Position information for this sensor. This position is represented in Smartsuits coordinate system. -// * To get the position in Unreal coordinate system use UPosition() instead. -// */ -// FVector position; -// -// /** Timestamp information received from the sensor. This is the sensors internal clock.*/ -// uint32_t microseconds; -// -// /// @private -// FQuat NED2Unreal(FQuat rotation) { -// /*FVector forward = rotation.GetForwardVector(); -// forward.Z = -forward.Z; -// FQuat result = */ -// FQuat result(rotation.X, rotation.Y, rotation.Z, rotation.W); -// //result.X = -result.X; -// result.Z = -result.Z; -// result.Y = -result.Y; -// FQuat modifier = FQuat::MakeFromEuler(FVector(180, 0, 90)); -// FQuat postModifier = FQuat::MakeFromEuler(FVector(0, 0, 180)); -// //result.Z = -result.Z; -// FQuat finalResult = modifier * result * postModifier; -// -// return FQuat(finalResult.X, finalResult.Y, finalResult.Z, finalResult.W); -// } -// -// -// -// /** -// * Get sensor rotation in Unreal coordinate system. -// * -// * @return Sensor rotation. -// */ -// FQuat Uquaternion() { -// -// if (FGenericPlatformMath::IsNaN(quaternion.X) || FGenericPlatformMath::IsNaN(quaternion.Y) || FGenericPlatformMath::IsNaN(quaternion.Z) || FGenericPlatformMath::IsNaN(quaternion.W)) { -// return FQuat::Identity; -// } -// return NED2Unreal(quaternion); -// -// } -// -// /** -// * Get sensor position in Unreal coordinate system. -// * -// * @return Sensor position. -// */ -// FVector UPosition() { -// if (FGenericPlatformMath::IsNaN(position.X) || FGenericPlatformMath::IsNaN(position.Y) || FGenericPlatformMath::IsNaN(position.Z)) { -// return FVector::ZeroVector; -// } -// return FVector(100.0f*position.Y, -100.0f*position.X, -100.0f*position.Z); -// } -//}; - - -///*! \brief Contains data that represent the last frame received from the Smartsuit. -//* -//* This struct represents a Smartsuit data frame as received from the Smartsuit. -//* It also includes meta variables used to manage the state of the Smartsuit in Unreal. -//*/ -//struct SuitData { -// -// /** The name of the Smartsuit. */ -// char suitname[5]; -// -// /** Information about the sensors connected to this Smartsuit, like position, rotation, etc.*/ -// Sensor sensors[19]; -// -// /** The time to live indicator for this Smartsuit. This indica*/ -// float ttl; -// -// /** The ip address of the Smartsuit.*/ -// uint32 url; -// -// /** Indicator if the Smartsuit is broadcasting.*/ -// bool isBroadcasting; -// -// /** Indicator if the Smartsuit has profile.*/ -// bool hasProfile; -// -// /// @private. -// bool profileToggle; -// -// /** The number of frames received from this Smartsuit during the last second.*/ -// float fps; -// -// /// @private -// int currFPSCount; -// -// /// @private -// int lastFPSSecond; -// -// /** -// * Shortcut function to get the Hip sensor information for this Smartsuit. -// * -// * @return The Sensor information that corresponds to hip, if no sensor is found, it returns nullptr. -// */ -// Sensor* Hip() { -// return GetSensor(SENSOR_HIP); -// } -// -// Sensor* GetSensor(uint16_t address) { -// for (int i = 0; i < 19; i++) { -// if (sensors[i].addr == address) { -// return &(sensors[i]); -// } -// } -// return nullptr; -// } -// -// FName GetSubjectName() { -// return FName(*FString(ANSI_TO_TCHAR(suitname))); -// } -//}; - + FName name; + int32 parentIndex; + FVector position; + FQuat rotation; + FTransform transform; +}; USTRUCT() struct FSmartsuitBone @@ -328,7 +204,11 @@ struct FSmartsuitBone GENERATED_BODY() FSmartsuitBone() {} - FSmartsuitBone(FName Name, FVector Position, FQuat Rotation) { name = Name; position = Position; rotation = Rotation; } + FSmartsuitBone(FName Name, FVector Position, FQuat Rotation) + : name(Name) + , position(Position) + , rotation(Rotation) + {} FQuat NED2Unreal(FQuat InRotation) { @@ -336,9 +216,9 @@ struct FSmartsuitBone result.Z = -result.Z; result.Y = -result.Y; - FQuat modifier = FQuat::MakeFromEuler(FVector(180, 0, 90)); - FQuat postModifier = FQuat::MakeFromEuler(FVector(0, 0, 180)); - FQuat finalResult = modifier * result * postModifier; + static FQuat modifier = FQuat::MakeFromEuler(FVector(180, 0, 90)); + static FQuat postModifier = FQuat::MakeFromEuler(FVector(0, 0, 180)); + const FQuat finalResult = modifier * result * postModifier; return FQuat(finalResult.X, finalResult.Y, finalResult.Z, finalResult.W); } @@ -347,29 +227,28 @@ struct FSmartsuitBone { FQuat result(rotation.Z, rotation.X, rotation.Y, rotation.W); - FQuat modifier = FQuat::MakeFromEuler(FVector(90, 0, -90)); - + static FQuat modifier = FQuat::MakeFromEuler(FVector(90, 0, -90)); result *= modifier; return result; - - //return NED2Unreal(rotation); } FVector UPosition() const { - return FVector(100.0f * position.Z, 100.0f * position.X, 100.0f * position.Y); + return FVector(WORLD_SCALE * position.Z, WORLD_SCALE * position.X, WORLD_SCALE * position.Y); } FName name; FVector position; FQuat rotation; + + constexpr static float WORLD_SCALE{ 100.0f }; }; -/*! \brief Contains data that represent the last frame received from the Smartsuit. +/*! \brief Contains data that represent the last frame received from the Rokoko Actor. * -* This struct represents a Smartsuit data frame as received from the Smartsuit. -* It also includes meta variables used to manage the state of the Smartsuit in Unreal. +* This struct represents a skeleton data frame as received from the Studio Actor. +* It also includes meta variables used to manage the state of the Actor in Unreal. */ USTRUCT(BlueprintType) struct FSuitData @@ -385,46 +264,52 @@ struct FSuitData UPROPERTY(BlueprintReadOnly, Category=Default) FString suitname; - uint32_t timestamp; + uint32_t timestamp{ 0 }; UPROPERTY(BlueprintReadOnly, Category=Default) FString id; UPROPERTY(BlueprintReadOnly, Category=Default) - bool isLive; + bool isLive{ false }; /** The name of the profile. */ UPROPERTY(BlueprintReadOnly, Category = Default) FString profileName; UPROPERTY(BlueprintReadOnly, Category = Default) - bool hasGloves; + bool hasGloves{ false }; + + UPROPERTY(BlueprintReadOnly, Category = Default) + bool hasLeftGlove{ false }; UPROPERTY(BlueprintReadOnly, Category = Default) - bool hasBody; + bool hasRightGlove{ false }; UPROPERTY(BlueprintReadOnly, Category = Default) - bool hasFace; + bool hasBody{ false }; + + UPROPERTY(BlueprintReadOnly, Category = Default) + bool hasFace{ false }; UPROPERTY(BlueprintReadOnly, Category = Default) FString faceId; UPROPERTY(BlueprintReadOnly, Category = Default) - FLinearColor color; + FLinearColor color{ FLinearColor::White }; - TMap SmartsuitBones; + TMap bones; - FSmartsuitBone* Hip() + const FSmartsuitBone* Hip() const { return GetBoneByName("hip"); } - FSmartsuitBone* GetBoneByName(const FName& BoneName) + const FSmartsuitBone* GetBoneByName(const FName& BoneName) const { - return SmartsuitBones.Find(BoneName); + return bones.Find(BoneName); } - FName GetSubjectName() + FName GetSubjectName() const { FString TempSubjectName = "actor:" + suitname + ":body"; #if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 25) @@ -435,15 +320,37 @@ struct FSuitData } }; - -/// @cond doc_hidden -/** -* -*/ -class SMARTSUIT_API SmartsuitDefinitions +USTRUCT(BlueprintType) +struct FCharacterData { -public: - SmartsuitDefinitions(); - ~SmartsuitDefinitions(); + GENERATED_BODY() + + FCharacterData(){} + FCharacterData(bool InIsLive, TSharedPtr jsonObject); + + /** The name of the Smartsuit. */ + UPROPERTY(BlueprintReadOnly, Category=Default) + FString CharacterName; + + uint32_t Timestamp{ 0 }; + + UPROPERTY(BlueprintReadOnly, Category=Default) + FString Id; + + UPROPERTY(BlueprintReadOnly, Category=Default) + bool IsLive{ false }; + + + TArray joints; + + + FName GetSubjectName() const + { + FString TempSubjectName = "character:" + CharacterName + ":body"; +#if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 25) + return FName(TempSubjectName); +#else + return FName(*TempSubjectName); +#endif + } }; -/// @endcond \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoStudioCommandAPI.h b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoStudioCommandAPI.h index c327459..f30f305 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoStudioCommandAPI.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/RokokoStudioCommandAPI.h @@ -12,53 +12,136 @@ struct FRokokoCommandAPI_IPInfo { GENERATED_BODY() - UPROPERTY(BlueprintReadWrite, Category="Command API") + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") FString IPAddress; - UPROPERTY(BlueprintReadWrite, Category="Command API") + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") FString Port; - UPROPERTY(BlueprintReadWrite, Category="Command API") + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") FString APIKey; }; +USTRUCT(BlueprintType) +struct FRokokoCommandAPI_CalibrateInput +{ + GENERATED_BODY() + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + FString DeviceID; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + int32 CountdownDelay{ 1 }; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + bool ShouldSkipSuit{ false }; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + bool ShouldSkipGloves{ false }; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + bool UseCustomPose{ false }; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + FString CustomPoseName; +}; + +USTRUCT(BlueprintType) +struct FRokokoCommandAPI_TrackerInput +{ + GENERATED_BODY() + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + FString DeviceID; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + FString BoneName; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + FTransform Transform; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + float TimeoutTime{ 2.f }; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + bool ShouldQueryOnly{ false }; +}; + +UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true")) +enum class EPlaybackChange : uint8 +{ + NONE = 0 UMETA(Hidden), + IsPlaying = 1 << 0, + CurrentTime = 1 << 1, + GotoFirstFrame = 1 << 2, + GotoLastFrame = 1 << 3, + PlaybackSpeed = 1 << 4, +}; +ENUM_CLASS_FLAGS(EPlaybackChange); + +USTRUCT(BlueprintType) +struct FRokokoCommandAPI_PlaybackInput +{ + GENERATED_BODY() + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + bool IsPlaying{ false }; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + double CurrentTime{ 0.0 }; + + UPROPERTY(BlueprintReadWrite, Category = "Rokoko Command API") + float PlaybackSpeed{ 1.0f }; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (Bitmask, BitmaskEnum = EPlaybackChange)) + int32 ChangeFlags = 0; +}; + DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnCompletedRequest, int32, ResponseCode, const FString&, ResponseContentString, bool, bSucceeded); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FOnInfoRequest, const TArray&, Devices, const TArray&, Clips, const TArray&, Actors, const TArray&, Characters); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnTrackerRequest, FVector, Position, FQuat, Rotation); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FOnPlaybackRequest, double, CurrentTime, bool, IsPlaying, double, MinTime, double, MaxTime, double, PlaybackSpeedMultiplier ); /** - * + * Expose blueprint library of command API communication methods + * that could be used to calibrate, start recording, do a global position correct and etc. + * Communication configuration is defined by FRokokoCommandAPI_IPInfo */ -UCLASS(Config="RokokoStudioCommandAPI",BlueprintType) -class SMARTSUIT_API URokokoStudioCommandAPI : public UObject +UCLASS(meta=(ScriptName = "RokokoStudioCommandAPI")) +class SMARTSUIT_API URokokoStudioCommandAPI : public UBlueprintFunctionLibrary { GENERATED_BODY() public: - URokokoStudioCommandAPI(); + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Request info about scene clips, input devices, actors, etc.")) + static void Info(const FRokokoCommandAPI_IPInfo& IPInfo, bool ShouldIncludeDevices, bool ShouldIncludeClips, bool ShouldIncludeActors, bool ShouldIncludeCharacters); + + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Request a given actor restart operation")) + static void Restart(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& SmartSuitName); - UFUNCTION(BlueprintCallable, Category="Command API") - void Restart(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& SmartSuitName); + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Request a given actor reset to a root position")) + static void ResetActor(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& ActorName); - UFUNCTION(BlueprintCallable, Category="Command API") - void Calibrate(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& SmartSuitName, int32 CountdownDelay=3); + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Request a given actor calibration")) + static void Calibrate(const FRokokoCommandAPI_IPInfo& IPInfo, const FRokokoCommandAPI_CalibrateInput& Params); - UFUNCTION(BlueprintCallable, Category="Command API") - void StartRecording(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& FileName); + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Request a recording start")) + static void StartRecording(const FRokokoCommandAPI_IPInfo& IPInfo, const FString FileName, const FTimecode StartTime); - UFUNCTION(BlueprintCallable, Category="Command API") - void StopRecording(const FRokokoCommandAPI_IPInfo& IPInfo); + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Request a recording stop")) + static void StopRecording(const FRokokoCommandAPI_IPInfo& IPInfo, const FTimecode EndTime, bool ShouldBackToLive); - UPROPERTY(BlueprintAssignable, Category="Command API") - FOnCompletedRequest OnCompletedRequest; + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Request a given actor global position correction")) + static void Tracker(const FRokokoCommandAPI_IPInfo& IPInfo, const FRokokoCommandAPI_TrackerInput& Params); - UPROPERTY(Config, BlueprintReadOnly, Category="Command API") - FRokokoCommandAPI_IPInfo Default_IPInfo; + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Take control over the scene timeline playback")) + static void Playback(const FRokokoCommandAPI_IPInfo& IPInfo, const FRokokoCommandAPI_PlaybackInput& Params); - UPROPERTY(Config, BlueprintReadOnly, Category="Command API") - FString Default_SmartSuitName; + UFUNCTION(BlueprintCallable, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Take control over the custom live stream enabled state")) + static void Livestream(const FRokokoCommandAPI_IPInfo& IPInfo, bool ShouldLiveStream); - UFUNCTION(BlueprintCallable, Category="Command API") - void SaveConfigFile(const FRokokoCommandAPI_IPInfo& IPInfo, const FString& SmartSuitname); + UFUNCTION(BlueprintPure, Category = "Rokoko Command API", meta = (BlueprintThreadSafe, ToolTip = "Returns a default configuration for a command api calls")) + static FRokokoCommandAPI_IPInfo GetDefaultIPInfo(); - void OnProcessRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded); }; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/Roles/LiveLinkSmartsuitRole.h b/Plugins/Smartsuit/Source/Smartsuit/Public/Roles/LiveLinkSmartsuitRole.h new file mode 100644 index 0000000..7dcdb29 --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/Roles/LiveLinkSmartsuitRole.h @@ -0,0 +1,26 @@ +// Copyright 2019 Rokoko Electronics. All Rights Reserved. + +#pragma once + +#include "Roles/LiveLinkAnimationRole.h" +#include "LiveLinkSmartsuitRole.generated.h" + +/** + * Role associated for Smartsuit data. + */ +UCLASS(BlueprintType, meta = (DisplayName = "Smartsuit Role")) +class SMARTSUIT_API ULiveLinkSmartsuitRole : public ULiveLinkAnimationRole +{ + GENERATED_BODY() + +public: + //~ Begin ULiveLinkRole interface + virtual UScriptStruct* GetStaticDataStruct() const override; + virtual UScriptStruct* GetFrameDataStruct() const override; + virtual UScriptStruct* GetBlueprintDataStruct() const override; + + virtual bool InitializeBlueprintData(const FLiveLinkSubjectFrameData& InSourceData, FLiveLinkBlueprintDataStruct& OutBlueprintData) const override; + + virtual FText GetDisplayName() const override; + //~ End ULiveLinkRole interface +}; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/Roles/LiveLinkSmartsuitTypes.h b/Plugins/Smartsuit/Source/Smartsuit/Public/Roles/LiveLinkSmartsuitTypes.h new file mode 100644 index 0000000..a2e44f7 --- /dev/null +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/Roles/LiveLinkSmartsuitTypes.h @@ -0,0 +1,61 @@ +// Copyright 2019 Rokoko Electronics. All Rights Reserved. + +#pragma once + +#include "LiveLinkTypes.h" +#include "Roles/LiveLinkTransformTypes.h" +#include "Roles/LiveLinkAnimationTypes.h" +#include "Roles/LiveLinkAnimationBlueprintStructs.h" +#include "LiveLinkSmartsuitTypes.generated.h" + +/** + * Static data for Smartsuit data. + */ +USTRUCT(BlueprintType) +struct SMARTSUIT_API FLiveLinkSmartsuitStaticData : public FLiveLinkSkeletonStaticData +{ + GENERATED_BODY() + +public: + +}; + +/** + * Dynamic data for Smartsuit + */ +USTRUCT(BlueprintType) +struct SMARTSUIT_API FLiveLinkSmartsuitFrameData : public FLiveLinkAnimationFrameData +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LiveLink", Interp) + bool HasLeftGlove = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LiveLink", Interp) + bool HasRightGlove = false; + +}; + +USTRUCT(BlueprintType) +struct SMARTSUIT_API FLiveLinkCharactersFrameData : public FLiveLinkAnimationFrameData +{ + GENERATED_BODY() +public: +}; + +/** + * Facility structure to handle camera data in blueprint + */ +USTRUCT(BlueprintType) +struct SMARTSUIT_API FLiveLinkSmartsuitBlueprintData : public FSubjectFrameHandle +{ + GENERATED_BODY() + + //// Static data that should not change every frame + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LiveLink") + //FLiveLinkSmartsuitStaticData StaticData; + + //// Dynamic data that can change every frame + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LiveLink") + //FLiveLinkSmartsuitFrameData FrameData; +}; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/Smartsuit.h b/Plugins/Smartsuit/Source/Smartsuit/Public/Smartsuit.h index 3fe60a8..3f84ee1 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/Smartsuit.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/Smartsuit.h @@ -20,6 +20,7 @@ #include "Modules/ModuleInterface.h" #include "Modules/ModuleManager.h" + class ISmartsuitModule : public IModuleInterface { public: diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitBlueprintLibrary.h b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitBlueprintLibrary.h index 81db0b3..39d1827 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitBlueprintLibrary.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitBlueprintLibrary.h @@ -25,12 +25,84 @@ class USmartsuitBlueprintLibrary : public UBlueprintFunctionLibrary GENERATED_BODY() public: + + UFUNCTION(BlueprintCallable, Category = "Rokoko") + static FFace GetFaceByFaceID(FString faceName); + + UFUNCTION(BlueprintCallable, Category = "Rokoko") + static FFace GetFaceByProfileName(const FString& faceName, bool& found); + + UFUNCTION(BlueprintCallable, Category = "Rokoko") + static TArray GetAllFaces(); + + UFUNCTION(BlueprintCallable, Category = "Rokoko") + static TArray GetFacesNotAssociatedWithActor(); + + /** + * This function returns the last frame of data received from a Smartsuit with the given name. + * If there is no data for the given name, then nullptr will return. + * + * @param suitName The smartsuit name to get the last data for. + * @return Returns the last frame received for the smartsuit with name suitName. If no frame is found, it will return nullptr. + */ + static FSuitData* GetSmartsuit(FString suitName); + + UFUNCTION(BlueprintCallable, Category = "Rokoko") + static bool GetSmartsuitByName(const FString& suitName, FSuitData& SuitData); + + /** + * Lists the names of all known Smartsuits connected to this computer. + * It will only list the currently active Smartsuits. + * + * @return Returns an array with all the available in the network Smartsuit names. + */ + UFUNCTION(BlueprintCallable, Category = "Rokoko", meta = (BlueprintThreadSafe, ToolTip = "Returns actor names in the current live link source")) + static TArray GetAvailableActorNames(); + + UFUNCTION(BlueprintCallable, Category = "Rokoko") + static TArray GetAllSmartsuits(); + + static FProp* GetPropByNameFromVP(FString name, bool isLive); + FTracker* GetTrackerByNameFromVP(FString name, bool isLive); + + UFUNCTION(BlueprintPure, Category = "Rokoko") + static FTracker GetTrackerByConnectionIDFromVP(const FString& name, bool isLive, bool& found); + + + UFUNCTION(BlueprintPure, Category = "Rokoko", meta = (ToolTip = "Calls a function in VPStreamingNetwork to retrieve all props.")) + static TArray GetAllProps(); + + + UFUNCTION(BlueprintPure, Category = "Rokoko", meta = (ToolTip = "Calls a function in VPStreamingNetwork to retrieve a prop by name.")) + static bool GetProp(FString name, /*bool isLive, */FProp& OutProp); + + + UFUNCTION(BlueprintPure, Category = "Rokoko", meta = (ToolTip = "Calls a function in VPStreamingNetwork to retrieve a tracker by name.")) + static FTracker GetTracker(FString name, bool isLive); + + + UFUNCTION(BlueprintPure, Category = "Rokoko", meta = (ToolTip = "Converts Quaternions into rotators.")) + static FRotator FQuatToRotator(FQuat rotation) + { + FQuat result(rotation.Z, rotation.X, rotation.Y, rotation.W); + FRotator Rotator = result.Rotator(); + return Rotator; + } + + UFUNCTION(BlueprintPure, Category = "Rokoko", meta = (ToolTip = "Converts position into Unreal position.")) + static FVector UPosition(FVector position) + { + return FVector(100.0f*position.Z, 100.0f*position.X, 100.0f*position.Y); + } + /// @endcond + + /*! \brief Returns a SmartsuitController by the name. * * @param name The name of the Smartsuit to look for. * @return A SmartsuitController that has the specified Smartsuit name, if non found, it will return nullptr. */ - UFUNCTION(BlueprintPure, Category = "Smartsuit", meta = (BlueprintThreadSafe, ToolTip = "Returns the SmartsuitController given the Smartsuit name.")) + UFUNCTION(BlueprintPure, Category = "Rokoko", meta = (BlueprintThreadSafe, ToolTip = "Returns the SmartsuitController given the Smartsuit name.")) static ASmartsuitController* GetSmartsuitControllerByName(FString name); /*! \brief Returns a SmartsuitController from its index ID. @@ -38,7 +110,7 @@ class USmartsuitBlueprintLibrary : public UBlueprintFunctionLibrary * @param id The index id that will look up for. * @return A SmartsuitController that has the specified index id, if non found, it will return nullptr. */ - UFUNCTION(BlueprintPure, Category = "Smartsuit", meta = (BlueprintThreadSafe, ToolTip = "Returns a SmartsuitController given it's Index ID. The Index ID is specified in the SmartsuitController details.")) + UFUNCTION(BlueprintPure, Category = "Rokoko", meta = (BlueprintThreadSafe, ToolTip = "Returns a SmartsuitController given it's Index ID. The Index ID is specified in the SmartsuitController details.")) static ASmartsuitController* GetSmartsuitController(int id); UFUNCTION(BlueprintCallable, Category=Test) @@ -52,7 +124,7 @@ class USmartsuitBlueprintLibrary : public UBlueprintFunctionLibrary static FQuat GetQuaternionField(TSharedPtr jsonObject); - UFUNCTION(BlueprintCallable, Category = "Smartsuit") + UFUNCTION(BlueprintCallable, Category = "Rokoko") static void CreateVirtualProductionSource(); static FTransform GetWorldSpaceTransform(FReferenceSkeleton RefSkel, int32 BoneIdx); @@ -61,9 +133,9 @@ class USmartsuitBlueprintLibrary : public UBlueprintFunctionLibrary static FTransform GetBoneTransform(USkeletalMeshComponent* SkelMesh, FName BoneName); - UFUNCTION(BlueprintPure, Category = "Smartsuit") + UFUNCTION(BlueprintPure, Category = "Rokoko") static FVector GetPropLocation(FProp InProp); - UFUNCTION(BlueprintPure, Category = "Smartsuit") + UFUNCTION(BlueprintPure, Category = "Rokoko") static FRotator GetPropRotation(FProp InProp); }; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitController.h b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitController.h index ecdef05..bac1ad9 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitController.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitController.h @@ -3,9 +3,7 @@ #pragma once #include "GameFramework/Actor.h" -#include "SmartsuitStreamingNetwork.h" -#include "SmartsuitReceiver.h" -#include "SmartsuitDefinitions.h" +#include "RokokoSkeletonData.h" #include "SmartsuitController.generated.h" @@ -65,61 +63,6 @@ struct FBodyModel HeelOffset = 0.08; } - /** - * Breaks the BodyModel into individual body dimensions and returns a Body struct representing these dimensions. - */ - Body GetBody() - { - Body b; - b.first_buffer = SMARTSUIT_COMMAND_SET_BODY_DIMENSIONS; - b.first_buffer1 = SMARTSUIT_COMMAND_SET_BODY_DIMENSIONS; - b.first_buffer2 = SMARTSUIT_COMMAND_SET_BODY_DIMENSIONS; - b.first_buffer3 = SMARTSUIT_COMMAND_SET_BODY_DIMENSIONS;//put last byte of ip here. - b._head = (fabs(TotalHeight) - fabs(ShoulderHeight)) * .7f; - b._neck = (fabs(TotalHeight) - fabs(ShoulderHeight)) * .3f; - b._middle_back = (fabs(ShoulderHeight) - fabs(HipHeight)) * .414f; - b._low_back = (fabs(ShoulderHeight) - fabs(HipHeight)) * .433f; - b._hip = (fabs(ShoulderHeight) - fabs(HipHeight)) * .153f; - b._shoulder_blade = fabs(ShoulderWidth) * .5f; - float arm = (fabs(ArmSpan) - fabs(ShoulderWidth)) / 2.0f; - b._upper_arm = arm * .391f; - b._forearm = arm * .352f; - b._hand = arm * .257f; - float leg = (fabs(HipHeight) - fabs(AnkleHeight)); - b._thigh = leg * .517f; - b._leg = leg * .483f; - b._foot_height = fabs(AnkleHeight); - b._foot_length = fabs(FootLength); - b._foot_heel_offset = fabs(HeelOffset); - b._foot_width = fabs(FootLength) * .25f; - b._hip_width = fabs(HipWidth); - //strcpy(b.name, "unreal\0\0"); - return b; - } - - /** - * Calculates and sets the BodyModel dimensions from a detailed Body dimensions struct. - * - * @param value the Body dimensions to set to this BodyModel. - */ - void SetBody(Body value) - { - - Name = "unreal"; - - HipHeight = value._foot_height + value._leg + value._thigh; - ShoulderHeight = HipHeight + value._hip + value._low_back + value._middle_back; - TotalHeight = ShoulderHeight + value._neck + value._head; - HipWidth = value._hip_width; - ShoulderWidth = value._shoulder_blade * 2.0f; - ArmSpan = (value._shoulder_blade + value._upper_arm + value._forearm + value._hand) * 2.0f; - AnkleHeight = value._foot_height; - FootLength = value._foot_length; - HeelOffset = value._foot_heel_offset; - } - - - }; /*! \brief SmartsuitController is an UE Actor that provides methods to communicate with a Smartsuit and send commands to it. @@ -179,136 +122,18 @@ class SMARTSUIT_API ASmartsuitController : public AActor UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = SmartsuitReadOnly, meta = (ToolTip = "Read-only: Indicates the current known BodyProfile for the Smartsuit connected to this SmartsuitController.")) FBodyModel bodyModel; - /*! \brief Restart the Smartsuit binded to this Controller. - * - * Restart the Smartsuit binded to this Controller. - */ - UFUNCTION(BlueprintCallable, Category = "Smartsuit", meta = (ToolTip = "Send a restart command to the Smartsuit binded to this Controller.")) - void Restart(); - - /*! \brief Performs an A-pose calibration to the Smartsuit. - * - * Performs an A-pose calibration to the Smartsuit. - */ - UFUNCTION(BlueprintCallable, Category = "Smartsuit", meta = (ToolTip = "Send an A-pose calibration command to the Smartsuit binded to this Controller.")) - void Calibrate(); - - /*! \brief Set the Smartsuit in broadcast mode. - * - * Requests the Smartsuit to broadcast its live streaming. This way more devices can listen to the same Smartsuit, as well as more applications in the same computer. - * This setting may affect the WiFi performance. - */ - UFUNCTION(BlueprintCallable, Category = "Smartsuit", meta = (ToolTip = "Send a request to make the Smartsuit, Broadcast it's UDP messages. This only applies for the real-time motion data. Not command responses.")) - void Broadcast(); - - /*! \brief Set the Smartsuit in unicast mode. - * - * Requests the Smartsuit to unicast its live streaming. This way only one application in one device will have access to data from the Smartsuit. - * This setting provides the best WiFiPerformance. - */ - UFUNCTION(BlueprintCallable, Category = "Smartsuit", meta = (ToolTip = "Send a request to make the Smartsuit, Unicast it's UDP messages to the current device. This only applies for the real-time motion data. Not command responses.")) - void Unicast(); - - /*! \brief Set the BodyModel in the Smartsuit. - * - * Sends a BodyModel to the Smartsuit. If the Smartsuit received the BodyModel successfully, the SmartsuitController updates its own BodyModel reference to match the one it sent. - */ - UFUNCTION(BlueprintCallable, Category = "Smartsuit", meta = (ToolTip = "Send a command to set a BodyModel to the Smartsuit binded to this Controller.")) - void SetBodyModel(FBodyModel bodyToSet); - - /*! \brief Get the BodyModel from the Smartsuit. - * - * Asks the Smartsuit about the BodyModel it is running. When the Smartsuit responds, the SmartsuitController updates its BodyModel reference to match the one received from the Smartsuit. - */ - UFUNCTION(BlueprintCallable, Category = "Smartsuit", meta = (ToolTip = "Sends a request to the Smartsuit to ask what BodyModel the Smartsuit is using. Once the Controller receives the response. It updates it's BodyModel to match the one the Smartsuit is using.")) - void GetBodyModel(); - /*! \brief Various Developer Tests.*/ UFUNCTION(BlueprintCallable, Category = "Smartsuit", meta = (ToolTip = "Tests")) void DoTests(); - ///*! \brief Returns a SmartsuitController by the name. - //* - //* @param name The name of the Smartsuit to look for. - //* @return A SmartsuitController that has the specified Smartsuit name, if non found, it will return nullptr. - //*/ - //UFUNCTION(BlueprintPure, Category = "Smartsuit", meta = (BlueprintThreadSafe, ToolTip = "Returns the SmartsuitController given the Smartsuit name.")) - //static ASmartsuitController* GetSmartsuitControllerByName(FString name){ - // ASmartsuitController * actor = nullptr; - // // Find UObjects by type - // //UE_LOG(LogTemp, Warning, TEXT("Looking for actors...%s"), *name); - - // for (TObjectIterator It; It; ++It) - // { - // if (It->realLife) { - // ASmartsuitController* curActor = *It; - // FString mySuitName = curActor->suitname; - // //UE_LOG(LogTemp, Warning, TEXT("Looking for actor.. %s == %s"), *mySuitName, *name); - // if (name.Compare(mySuitName) == 0) { - // //UE_LOG(LogTemp, Warning, TEXT("Actors match!!")); - // actor = curActor; - // break; - // } - // } - // //else { - // // UE_LOG(LogTemp, Warning, TEXT("Actors no match..")); - // //} - // // ... - // } - - - // return actor; - //} - // - ///*! \brief Returns a SmartsuitController from its index ID. - //* - //* @param id The index id that will look up for. - //* @return A SmartsuitController that has the specified index id, if non found, it will return nullptr. - //*/ - //UFUNCTION(BlueprintPure, Category = "Smartsuit", meta = (BlueprintThreadSafe, ToolTip = "Returns a SmartsuitController given it's Index ID. The Index ID is specified in the SmartsuitController details.")) - //static ASmartsuitController* GetSmartsuitController(int id){ - // ASmartsuitController * actor = nullptr; - // // Find UObjects by type - // //UE_LOG(LogTemp, Warning, TEXT("Looking for actors...%s"), *name); - - // for (TObjectIterator It; It; ++It) - // { - // if (It->realLife) { - // ASmartsuitController* curActor = *It; - // //UE_LOG(LogTemp, Warning, TEXT("Looking for actor.. %s == %s"), *mySuitName, *name); - // if (id == curActor->IndexID) { - // //UE_LOG(LogTemp, Warning, TEXT("Actors match!!")); - // actor = curActor; - // break; - // } - // } - // //else { - // // UE_LOG(LogTemp, Warning, TEXT("Actors no match..")); - // //} - // // ... - // } - - - // return actor; - //} - - /// @cond no_doc - bool SupportsWiFi(); - /// @endcond - bool IsRealLife() { return realLife; } private: - ARokokoReceiver* GetReceiver(); - uint32 GetLocalIP(); + uint32 GetLocalMacIP(); uint8 GetByte(uint32 val, int i); - bool hubInfoRequested; - bool bodyModelRequested; - HubInfo* hubInfo; - void GetHubInfo(); - void UpdateWiFiApiString(); - void SendCommand(unsigned char cmd, uint8 *customData, int customDataLength); + bool bodyModelRequested; + protected: /*! \brief Indicates if this instance of the actor is in play mode and not an instance from the editor.*/ bool realLife = false; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitPoseNode.h b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitPoseNode.h index aac531e..b698d1d 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitPoseNode.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitPoseNode.h @@ -2,482 +2,18 @@ #pragma once -//#include "UObject/NoExportTypes.h" -//#include "Engine.h" -//#include "AnimNode_SkeletalControlBase.h" #include "Runtime/AnimGraphRuntime/Public/BoneControllers/AnimNode_SkeletalControlBase.h" #include "LiveLinkClientReference.h" -#include "SmartsuitReceiver.h" +#include "LiveLinkCustomVersion.h" +#include "LiveLinkRemapAsset.h" +#include "LiveLinkTypes.h" + #include "SmartsuitController.h" #include "SmartsuitTPose.h" #include "SmartsuitPoseNode.generated.h" class ILiveLinkClient; -UCLASS(BlueprintType) -class SMARTSUIT_API URokokoBodyMapData : public ULiveLinkRemapAsset -{ - GENERATED_BODY() - - URokokoBodyMapData() - { - hip = "hip"; - - stomach = "stomach"; - - chest = "chest"; - - neck = "neck"; - - head = "head"; - - leftShoulder = "leftShoulder"; - - leftArm = "leftArm"; - - leftForearm = "leftForearm"; - - leftHand = "leftHand"; - - rightShoulder = "rightShoulder"; - - rightArm = "rightArm"; - - rightForearm = "rightForearm"; - - rightHand = "rightHand"; - - leftUpleg = "leftUpleg"; - - leftLeg = "leftLeg"; - - leftFoot = "leftFoot"; - - leftToe = "leftToe"; - - rightUpleg = "rightUpleg"; - - rightLeg = "rightLeg"; - - rightFoot = "rightFoot"; - - rightToe = "rightToe"; - - leftThumbProximal = "leftThumbProximal"; - - leftThumbMedial = "leftThumbMedial"; - - leftThumbDistal = "leftThumbDistal"; - - leftThumbTip = "leftThumbTip"; - - leftIndexProximal = "leftIndexProximal"; - - leftIndexMedial = "leftIndexMedial"; - - leftIndexDistal = "leftIndexDistal"; - - leftIndexTip = "leftIndexTip"; - - leftMiddleProximal = "leftMiddleProximal"; - - leftMiddleMedial = "leftMiddleMedial"; - - leftMiddleDistal = "leftMiddleDistal"; - - leftMiddleTip = "leftMiddleTip"; - - leftRingProximal = "leftRingProximal"; - - leftRingMedial = "leftRingMedial"; - - leftRingDistal = "leftRingDistal"; - - leftRingTip = "leftRingTip"; - - leftLittleProximal = "leftLittleProximal"; - - leftLittleMedial = "leftLittleMedial"; - - leftLittleDistal = "leftLittleDistal"; - - leftLittleTip = "leftLittleTip"; - - rightThumbProximal = "rightThumbProximal"; - - rightThumbMedial = "rightThumbMedial"; - - rightThumbDistal = "rightThumbDistal"; - - rightThumbTip = "rightThumbTip"; - - rightIndexProximal = "rightIndexProximal"; - - rightIndexMedial = "rightIndexMedial"; - - rightIndexDistal = "rightIndexDistal"; - - rightIndexTip = "rightIndexTip"; - - rightMiddleProximal = "rightMiddleProximal"; - - rightMiddleMedial = "rightMiddleMedial"; - - rightMiddleDistal = "rightMiddleDistal"; - - rightMiddleTip = "rightMiddleTip"; - - rightRingProximal = "rightRingProximal"; - - rightRingMedial = "rightRingMedial"; - - rightRingDistal = "rightRingDistal"; - - rightRingTip = "rightRingTip"; - - rightLittleProximal = "rightLittleProximal"; - - rightLittleMedial = "rightLittleMedial"; - - rightLittleDistal = "rightLittleDistal"; - - rightLittleTip = "rightLittleTip"; - - - } -public: - - FName GetRemappedBoneName_Implementation(FName CurveName) const override - { - if (auto RemappedName = NameMapping.Find(CurveName)) - { - return *RemappedName; - } - return ""; - } - - virtual void Initialize() override - { - InitializeTMap(); - } - - UFUNCTION(BlueprintCallable, Category = BoneRemapping) - void InitializeTMap() - { - NameMapping.Add("hip", hip); - - NameMapping.Add("stomach", stomach); - - NameMapping.Add("chest", chest); - - NameMapping.Add("neck", neck); - - NameMapping.Add("head", head); - - NameMapping.Add("leftShoulder", leftShoulder); - - NameMapping.Add("leftArm", leftArm); - - NameMapping.Add("leftForearm", leftForearm); - - NameMapping.Add("leftHand", leftHand); - - NameMapping.Add("rightShoulder", rightShoulder); - - NameMapping.Add("rightArm", rightArm); - - NameMapping.Add("rightForearm", rightForearm); - - NameMapping.Add("rightHand", rightHand); - - NameMapping.Add("leftUpleg", leftUpleg); - - NameMapping.Add("leftLeg", leftLeg); - - NameMapping.Add("leftFoot", leftFoot); - - NameMapping.Add("leftToe", leftToe); - - NameMapping.Add("rightUpleg", rightUpleg); - - NameMapping.Add("rightLeg", rightLeg); - - NameMapping.Add("rightFoot", rightFoot); - - NameMapping.Add("rightToe", rightToe); - - NameMapping.Add("leftThumbProximal", leftThumbProximal); - - NameMapping.Add("leftThumbMedial", leftThumbMedial); - - NameMapping.Add("leftThumbDistal", leftThumbDistal); - - NameMapping.Add("leftThumbTip", leftThumbTip); - - NameMapping.Add("leftIndexProximal", leftIndexProximal); - - NameMapping.Add("leftIndexMedial", leftIndexMedial); - - NameMapping.Add("leftIndexDistal", leftIndexDistal); - - NameMapping.Add("leftIndexTip", leftIndexTip); - - NameMapping.Add("leftMiddleProximal", leftMiddleProximal); - - NameMapping.Add("leftMiddleMedial", leftMiddleMedial); - - NameMapping.Add("leftMiddleDistal", leftMiddleDistal); - - NameMapping.Add("leftMiddleTip", leftMiddleTip); - - NameMapping.Add("leftRingProximal", leftRingProximal); - - NameMapping.Add("leftRingMedial", leftRingMedial); - - NameMapping.Add("leftRingDistal", leftRingDistal); - - NameMapping.Add("leftRingTip", leftRingTip); - - NameMapping.Add("leftLittleProximal", leftLittleProximal); - - NameMapping.Add("leftLittleMedial", leftLittleMedial); - - NameMapping.Add("leftLittleDistal", leftLittleDistal); - - NameMapping.Add("leftLittleTip", leftLittleTip); - - NameMapping.Add("rightThumbProximal", rightThumbProximal); - - NameMapping.Add("rightThumbMedial", rightThumbMedial); - - NameMapping.Add("rightThumbDistal", rightThumbDistal); - - NameMapping.Add("rightThumbTip", rightThumbTip); - - NameMapping.Add("rightIndexProximal", rightIndexProximal); - - NameMapping.Add("rightIndexMedial", rightIndexMedial); - - NameMapping.Add("rightIndexDistal", rightIndexDistal); - - NameMapping.Add("rightIndexTip", rightIndexTip); - - NameMapping.Add("rightMiddleProximal", rightMiddleProximal); - - NameMapping.Add("rightMiddleMedial", rightMiddleMedial); - - NameMapping.Add("rightMiddleDistal", rightMiddleDistal); - - NameMapping.Add("rightMiddleTip", rightMiddleTip); - - NameMapping.Add("rightRingProximal", rightRingProximal); - - NameMapping.Add("rightRingMedial", rightRingMedial); - - NameMapping.Add("rightRingDistal", rightRingDistal); - - NameMapping.Add("rightRingTip", rightRingTip); - - NameMapping.Add("rightLittleProximal", rightLittleProximal); - - NameMapping.Add("rightLittleMedial", rightLittleMedial); - - NameMapping.Add("rightLittleDistal", rightLittleDistal); - - NameMapping.Add("rightLittleTip", rightLittleTip); - - - - } - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - TMap NameMapping; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName hip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName stomach; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName chest; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName neck; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName head; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftShoulder; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftArm; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftForearm; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftHand; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightShoulder; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightArm; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightForearm; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightHand; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftUpleg; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftLeg; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftFoot; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftToe; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightUpleg; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightLeg; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightFoot; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightToe; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftThumbProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftThumbMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftThumbDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftThumbTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftIndexProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftIndexMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftIndexDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftIndexTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftMiddleProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftMiddleMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftMiddleDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftMiddleTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftRingProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftRingMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftRingDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftRingTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftLittleProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftLittleMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftLittleDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName leftLittleTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightThumbProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightThumbMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightThumbDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightThumbTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightIndexProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightIndexMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightIndexDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightIndexTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightMiddleProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightMiddleMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightMiddleDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightMiddleTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightRingProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightRingMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightRingDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightRingTip; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightLittleProximal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightLittleMedial; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightLittleDistal; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = BoneRemapping) - FName rightLittleTip; - - -}; /*! \brief Bone reference mapping that is used to map bones between Smartsuit sensors and skeleton.*/ USTRUCT() @@ -672,198 +208,6 @@ struct SMARTSUIT_API FSmartsuitBodyMap FBoneReference rightLittleTip; }; -//UCLASS(BlueprintType) -//class SMARTSUIT_API USmartsuitBodyMapData : public UDataAsset -//{ -// GENERATED_BODY() -// -// USmartsuitBodyMapData(); -//public: -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName hip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName stomach; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName chest; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName neck; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName head; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftShoulder; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftArm; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftForearm; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftHand; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightShoulder; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightArm; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightForearm; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightHand; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftUpleg; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftLeg; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftFoot; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftToe; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightUpleg; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightLeg; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightFoot; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightToe; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftThumbProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftThumbMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftThumbDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftThumbTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftIndexProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftIndexMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftIndexDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftIndexTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftMiddleProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftMiddleMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftMiddleDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftMiddleTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftRingProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftRingMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftRingDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftRingTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftLittleProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftLittleMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftLittleDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName leftLittleTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightThumbProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightThumbMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightThumbDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightThumbTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightIndexProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightIndexMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightIndexDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightIndexTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightMiddleProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightMiddleMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightMiddleDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightMiddleTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightRingProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightRingMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightRingDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightRingTip; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightLittleProximal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightLittleMedial; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightLittleDistal; -// -// UPROPERTY(EditAnywhere, Category = SkeletalControl) -// FName rightLittleTip; -//}; - /*! \brief An animation controller which poses a humanoid character to the pose as received from the Smartsuit. * @@ -879,9 +223,6 @@ struct SMARTSUIT_API FSmartsuitPoseNode : public FAnimNode_SkeletalControlBase UPROPERTY(/*EditAnywhere, BlueprintReadWrite, Category = SmartsuitAnimationSetup, meta = (NeverAsPin, ToolTip = "A mapping between the Smartsuit expected bone names and the bones that will animate from the Smartsuit component. Every bone is required for the animation to work properly.")*/) FSmartsuitBodyMap BoneMap; - //UPROPERTY(EditAnywhere, Category = SmartsuitAnimationSetup) - //USmartsuitBodyMapData* Bone_Map_Override_OLD; - UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Category = Retarget, meta = (PinShownByDefault)) TSubclassOf RetargetAsset; @@ -890,23 +231,20 @@ struct SMARTSUIT_API FSmartsuitPoseNode : public FAnimNode_SkeletalControlBase void OnInitializeAnimInstance(const FAnimInstanceProxy* InProxy, const UAnimInstance* InAnimInstance) override; - /** The smartsuit controller to use. This defines which Smartsuit to use for the animation. */ - //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SmartsuitAnimationSetup, meta = (AlwaysAsPin, ToolTip = "The SmartsuitController that will be used to animate this character. This is required for the animation to work.")) - //ASmartsuitController *Controller; - - //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SourceData, meta = (PinShownByDefault)) - //FLiveLinkSubjectName LiveLinkSubjectName; - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SourceData, meta = (PinShownByDefault)) FName RokokoActorName; - ///** Indicates weither the character should maintain it's XY position or override it from the position of the Smartsuit. If this is true then the character will have an offset from the actual Smartsuit position so he remains in the same position when the game begins. */ - //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SmartsuitAnimationSetup, meta = (PinHiddenByDefault, ToolTip = "When this is True the animation will keep the starting position in the XY-plane of the character when the game starts. This way the character will not jump out of his initial position. Its Z position however will be identical to the one received from the Smartsuit.")) - //bool RelativeToStart; + /** If enabled, root motion will be applied from this pose. This can help prevent characters from moving through walls etc. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = RootMotion, meta = (PinShownByDefault)) + bool bApplyRootMotion{ false }; + + /** Use to shoulder space. Tweaks the clavicle/shoulder rotation, around approx. the character up axis. Make sure that skeleton axis are imported correctly into Unreal! Defaults to 0.0f */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Space, meta = (PinShownByDefault)) + float ShoulderSpace{0.0f}; - /** Indicates if the character should scale to match the Smartsuit dimensions. This makes the character motion to be 1-1 with the player, but it may cause skinning issues with the character. */ - //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SmartsuitAnimationSetup, meta = (NeverAsPin, ToolTip = "Scale bones to match the BodyModel dimensions. This will make the animation look more natural on the character but may cause unusual effects on the mesh.")) - // bool ScaleBones; + /** Use to tweak arm space. Tweaks the upper arm rotation around approx. the character forward axis. Make sure that skeleton axis are imported correctly into Unreal! Defaults to 0.0f */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Space, meta = (PinShownByDefault)) + float ArmSpace{ 0.0f }; /// @private SmartsuitTPose TPose; @@ -931,6 +269,16 @@ struct SMARTSUIT_API FSmartsuitPoseNode : public FAnimNode_SkeletalControlBase FLiveLinkSubjectName GetLiveLinkSubjectName(); + void CreateRetargetAsset(const UAnimInstance* InAnimInstance); + + void UpdateComponentPose_AnyThread(const FAnimationUpdateContext& Context) override; + + virtual void UpdateInternal(const FAnimationUpdateContext& Context) override; + + virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) override; + + //virtual bool Serialize(FArchive& Ar); + private: //bool firstTime = true; // FAnimNode_SkeletalControlBase interface @@ -947,21 +295,12 @@ struct SMARTSUIT_API FSmartsuitPoseNode : public FAnimNode_SkeletalControlBase void ApplyAllBonePositions(FBoneReference bone, float hipWidth, TArray transforms, EBoneControlSpace space, USkeletalMeshComponent* SkelComp, FCSPose& MeshBases); // End of FAnimNode_SkeletalControlBase interface - ARokokoReceiver* GetReceiver() { - ARokokoReceiver * listener = nullptr; - // Find UObjects by type - for (TObjectIterator It; It; ++It) - { - if (It->enabled) { - listener = *It; - break; - } - // ... - } - return listener; - } FLiveLinkClientReference LiveLinkClient_GameThread; ILiveLinkClient* LiveLinkClient_AnyThread; + // Root motion support + bool bInitializedRootPosition{}; + FVector OldRootPosition{}; + }; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitReceiver.h b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitReceiver.h deleted file mode 100644 index 69c96c0..0000000 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitReceiver.h +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2019 Rokoko Electronics. All Rights Reserved. - -#pragma once - -#include "GameFramework/Actor.h" -#include "SmartsuitStreamingNetwork.h" -//#include "VPStreamingNetwork.h" -#include "VirtualProductionFrame.h" -//#include "Engine.h" -#include "UObject/UObjectIterator.h" -#include "SmartsuitReceiver.generated.h" - -/*! \brief This AActor class implements the network layer between unreal and the SmartsuitPro. - * - * It is necessary to have one instance of this ARokokoReceiver in your level in order for Unreal Engine to be able to listen to Smartsuits. - */ -UCLASS(meta = (ToolTip = "A SmartsuitReceiver implements the network interface between Smartsuit and Unreal. This is required for SmartsuitController to work properly. You can have only one SmartsuitReceiver at the same time.")) -class SMARTSUIT_API ARokokoReceiver : public AActor -{ - GENERATED_BODY() - -public: - /// @private Sets default values for this actor's properties - ARokokoReceiver(); - - /// @private Called when the game starts or when spawned - virtual void BeginPlay() override; - - /// @private - virtual void BeginDestroy() override; - /// @private Called every frame - virtual void Tick(float DeltaSeconds) override; - - /// @private - bool enabled = false; - - /** - * Starts the SmartsuitReceiver socket so it listens for Smartsuits. - */ - UFUNCTION(BlueprintCallable, Category = "Rokoko") - void StartListener(); - - /** - * Stops the SmartsuitReceiver socket so it stops listening for Smartsuits. - */ - UFUNCTION(BlueprintCallable, Category = "Rokoko") - void StopListener(); - - UFUNCTION(BlueprintCallable, Category = Default) - FFace GetFaceByFaceID(FString faceName); - - UFUNCTION(BlueprintCallable, Category = Default) - FFace GetFaceByProfileName(const FString& faceName, bool& found); - - UFUNCTION(BlueprintCallable, Category = Default) - TArray GetAllFaces(); - - UFUNCTION(BlueprintCallable, Category = Default) - TArray GetFacesNotAssociatedWithActor(); - - /** - * This function returns the last frame of data received from a Smartsuit with the given name. - * If there is no data for the given name, then nullptr will return. - * - * @param suitName The smartsuit name to get the last data for. - * @return Returns the last frame received for the smartsuit with name suitName. If no frame is found, it will return nullptr. - */ - FSuitData* GetSmartsuit(FString suitName); - - UFUNCTION(BlueprintCallable, Category = Default) - bool GetSmartsuitByName(const FString& suitName, FSuitData& SuitData); - - /** - * Lists the names of all known Smartsuits connected to this computer. - * It will only list the currently active Smartsuits. - * - * @return Returns an array with all the available in the network Smartsuit names. - */ - UFUNCTION(BlueprintCallable, Category = Default) - TArray GetAvailableSmartsuitNames(); - - UFUNCTION(BlueprintCallable, Category = Default) - TArray GetAllSmartsuits(); - - /** - * The port number used to listen for the streaming data of Smartsuits. - */ - //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Smartsuit) - //int streamingDataPort = 14041; - - /** - * The port number used to listen for trackers and props data. - */ - //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production") - //int VPListenPort = 14045; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production") - int RokokoPortNumber; - - FProp* GetPropByNameFromVP(FString name, bool isLive); - FTracker* GetTrackerByNameFromVP(FString name, bool isLive); - - UFUNCTION(BlueprintPure, Category = "VirtualProduction") - FTracker GetTrackerByConnectionIDFromVP(const FString& name, bool isLive, bool& found); - - /// @cond nodoc - //Body* CheckForBodyCommand(FString suitname); - //HubInfo* CheckForHubInfo(FString suitname); - void SetSupportsWiFiAPI(FString suitname); - - UFUNCTION(BlueprintPure, Category = "VirtualProduction", meta = (ToolTip = "Calls a function in VPStreamingNetwork to retrieve all props.")) - static TArray GetAllProps(); - //{ - // TArray result; - // //UE_LOG(LogTemp, Display, TEXT("Yeeee1")); - // bool found = false; - // int i = 0; - // for (TObjectIterator It; It; ++It) - // { - // //UE_LOG(LogTemp, Display, TEXT("Looking up receiver %d"), i); - // i++; - // if (It->realLife) - // { - // found = true; - // //UE_LOG(LogTemp, Display, TEXT("Real life!")); - // result = It->VPlistener.GetAllProps(); - // } - // } - // if (!found) - // { - // //UE_LOG(LogTemp, Display, TEXT("not Real life...")); - // } - // //UE_LOG(LogTemp, Display, TEXT("Yeeee2 %d"), result.Num()); - // return result; - //} - - UFUNCTION(BlueprintPure, Category = "VirtualProduction", meta = (ToolTip = "Calls a function in VPStreamingNetwork to retrieve a prop by name.")) - bool GetProp(FString name, /*bool isLive, */FProp& OutProp); - //{ - // FProp result; - // for (TObjectIterator It; It; ++It) - // { - // if (It->realLife) - // { - // result = *It->GetPropByNameFromVP(name, isLive); - // } - // } - // return result; - //} - - UFUNCTION(BlueprintPure, Category = "VirtualProduction", meta = (ToolTip = "Calls a function in VPStreamingNetwork to retrieve a tracker by name.")) - static FTracker GetTracker(FString name, bool isLive); - //{ - // FTracker result; - // for (TObjectIterator It; It; ++It) - // { - // if (It->realLife) { - // result = *It->GetTrackerByNameFromVP(name, isLive); - // } - // } - // return result; - //} - - UFUNCTION(BlueprintPure, Category = "VirtualProduction", meta = (ToolTip = "Converts Quaternions into rotators.")) - static FRotator FQuatToRotator(FQuat rotation) - { - FQuat result(rotation.Z, rotation.X, rotation.Y, rotation.W); - FRotator Rotator = result.Rotator(); - return Rotator; - } - - UFUNCTION(BlueprintPure, Category = "VirtualProduction", meta = (ToolTip = "Converts position into Unreal position.")) - static FVector UPosition(FVector position) - { - return FVector(100.0f*position.Z, 100.0f*position.X, 100.0f*position.Y); - } - /// @endcond - -private: - //SmartsuitStreamingNetwork listener; - //VPStreamingNetwork VPlistener; - -protected: - /*! \brief Indicates if this instance of the actor is in play mode and not an instance from the editor.*/ - bool realLife = false; -}; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitStreamingNetwork.h b/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitStreamingNetwork.h deleted file mode 100644 index 712ff5f..0000000 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/SmartsuitStreamingNetwork.h +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2019 Rokoko Electronics. All Rights Reserved. - -#pragma once - -//#include "Networking.h" -#include "Runtime/Sockets/Public/Sockets.h" -#include "Runtime/Sockets/Public/SocketSubsystem.h" -#include "Runtime/Networking/Public/Common/UdpSocketBuilder.h" -#include "Runtime/Core/Public/HAL/Runnable.h" -#include "Runtime/Core/Public/HAL/RunnableThread.h" -#include "VirtualProductionSource.h" -#include "VirtualProductionFrame.h" - -#include "SmartsuitDefinitions.h" -// Default endpoint for the server -#define DEFAULT_ENDPOINT FIPv4Endpoint(FIPv4Address(127, 0, 0, 1), 5005) -class ILiveLinkClient; -struct FLiveLinkPongMessage; -struct FLiveLinkSubjectDataMessage; -struct FLiveLinkSubjectFrameMessage; -struct FLiveLinkHeartbeatMessage; -struct FLiveLinkClearSubject; - - -struct FLiveLinkSubjectDataMessage; -struct FLiveLinkClearSubject; - - - -/// @cond doc_hidden -/** -* Network implementation for receiving live stream from Smartsuits. -*/ -class SMARTSUIT_API SmartsuitStreamingNetwork : public FRunnable -{ -public: - SmartsuitStreamingNetwork(); - ~SmartsuitStreamingNetwork(); - - - /// @private - virtual bool Init() override; - - /// @private - virtual uint32 Run() override; - - /** - * Checks whether the listener is listening for incoming connections. - * - * @return true if it is listening, false otherwise. - */ - bool IsActive() const - { - return (!Stopping); - } - - /** - * Stop the Socket and the Thread which handles Smartsuit data streams. - */ - virtual void Stop() override - { - Stopping = true; - } - - /** - * Starts the socket and the thread which handles Smarttsuit data streams. - * - * @param port The port number to bind. - */ - void Start(int port); - - /// @private - virtual void Exit() override { } - - /** - * The buffer which holds information about all active Smartsuits. The buffer currently has size for 10 Smartsuits. - */ - FSuitData *suits; - - TSet wifiSupportedSuits; - -private: - int streaming_port; - FSocket *Socket = NULL; - - /** Used to tell that the thread is stopping */ - bool Stopping; - - /** Connection thread, used to not block the editor when waiting for connections */ - FRunnableThread* Thread = NULL; - void SendSuitsToLiveLink(); - int suitCount; -}; -/// @endcond \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionFrame.h b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionFrame.h index 0e6b879..cd791b9 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionFrame.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionFrame.h @@ -5,13 +5,11 @@ #include "CoreMinimal.h" #include "Dom/JsonValue.h" #include "Dom/JsonObject.h" -//#include "SmartsuitBlueprintLibrary.h" -#include "SmartsuitDefinitions.h" +#include "Runtime/Launch/Resources/Version.h" +#include "RokokoSkeletonData.h" #include "VirtualProductionFrame.generated.h" -//#include "JsonUtilities.h" - class VirtualProductionFrame { public: @@ -26,15 +24,15 @@ struct FRadiusReferencePoint { UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Grip radius.")) /**Holds information about the radius.*/ - float radius; + float radius{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Grip position.")) /**Holds information about the position during the last frame.*/ - FVector position; + FVector position{ FVector::ZeroVector }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Grip rotation.")) /**Holds information about the rotation during the last frame.*/ - FQuat rotation; + FQuat rotation{ FQuat::Identity }; FRadiusReferencePoint() {} FRadiusReferencePoint(TSharedPtr jsonObject); @@ -47,11 +45,11 @@ struct FReferencePoint { /**Holds information about the position during the last frame.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Pivot position.")) - FVector position; + FVector position{ FVector::ZeroVector }; /**Holds information about the rotation during the last frame.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Pivot rotation.")) - FQuat rotation; + FQuat rotation{ FQuat::Identity }; FReferencePoint() {} FReferencePoint(TSharedPtr jsonObject); @@ -73,11 +71,11 @@ struct FProfile /** Holds information about the dimensions. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Profile's dimensions.")) - FVector dimensions; + FVector dimensions{ FVector::OneVector }; /** Holds information about the color. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Profile's color.")) - FLinearColor color; + FLinearColor color{ FLinearColor::White }; /** Tracker offset position and rotation. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Tracker Offset.")) @@ -93,22 +91,25 @@ struct FProfile /** Prop type. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Profile's prop type.")) - int propType; + int propType{ 0 }; FProfile() {} FProfile(TSharedPtr jsonObject); }; +/// +/// One tracker or prop in the scene +/// struct FVirtualProductionSubject { - FVector position; - FQuat rotation; - FName name; + FVector Position; + FQuat Rotation; + FName Name; FVirtualProductionSubject(FVector in_position, FQuat in_rotation, FName in_name) { - position = in_position; - rotation = in_rotation; - name = in_name; + Position = in_position; + Rotation = in_rotation; + Name = in_name; } }; @@ -123,7 +124,7 @@ struct FProp { FString name; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Rotation information.")) - FColor color; + FColor color{ FColor::White }; /** ID of the prop. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Prop's id.")) @@ -131,15 +132,15 @@ struct FProp { /**Holds information about the position during the last frame.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Position information.")) - FVector position; + FVector position{ FVector::ZeroVector }; /**Holds information about the rotation during the last frame.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Rotation information.")) - FQuat rotation; + FQuat rotation{ FQuat::Identity }; /**Indicates wether the prop is live.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Information about whether a prop is live or not.")) - bool isLive; + bool isLive{ false }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Information about prop's profile.")) FProfile profile; @@ -190,23 +191,23 @@ struct FTracker { /**Holds information about the position during the last frame.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Position information.")) - FVector position; + FVector position{ FVector::ZeroVector }; /**Holds information about the rotation during the last frame.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Rotation information.")) - FQuat rotation; + FQuat rotation{ FQuat::Identity }; /**Indicates whether the tracker is live.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Information about whether a tracker is live or not.")) - bool isLive; + bool isLive{ false }; /**Holds the tracking result.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Information about the result of the tracking.")) - int trackingResult; + int trackingResult{ 0 }; /**Indicates the type of the tracker.*/ UPROPERTY() - int trackerType; + int trackerType{ 0 }; /**.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Render Model Name.")) @@ -214,7 +215,7 @@ struct FTracker { /**.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Battery information.")) - float battery; + float battery{ 0.0f }; ///** //* Get sensor position in Unreal coordinate system. @@ -247,12 +248,16 @@ struct FFace GENERATED_USTRUCT_BODY() FFace() {} + FFace(const FFace& otherFace); + FFace(FFace&& otherFace); FFace(TSharedPtr jsonObject, const FString& InActorName); + FFace& operator = (const FFace& otherFace) = default; + UPROPERTY(BlueprintReadOnly, Category = "Virtual Production") FString profileName; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Face's version.")) - int version; + int version{ 0 }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Face's provider.")) FString provider; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Face's ID.")) @@ -260,111 +265,111 @@ struct FFace UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Face's ID.")) FString actorName; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeBlinkLeft; + float eyeBlinkLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookDownLeft; + float eyeLookDownLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookInLeft; + float eyeLookInLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookOutLeft; + float eyeLookOutLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookUpLeft; + float eyeLookUpLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeSquintLeft; + float eyeSquintLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeWideLeft; + float eyeWideLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeBlinkRight; + float eyeBlinkRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookDownRight; + float eyeLookDownRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookInRight; + float eyeLookInRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookOutRight; + float eyeLookOutRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeLookUpRight; + float eyeLookUpRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeSquintRight; + float eyeSquintRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float eyeWideRight; + float eyeWideRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float jawForward; + float jawForward{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float jawLeft; + float jawLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float jawRight; + float jawRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float jawOpen; + float jawOpen{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthClose; + float mouthClose{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthFunnel; + float mouthFunnel{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthPucker; + float mouthPucker{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthLeft; + float mouthLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthRight; + float mouthRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthSmileLeft; + float mouthSmileLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthSmileRight; + float mouthSmileRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthFrownLeft; + float mouthFrownLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthFrownRight; + float mouthFrownRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthDimpleLeft; + float mouthDimpleLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthDimpleRight; + float mouthDimpleRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthStretchLeft; + float mouthStretchLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthStretchRight; + float mouthStretchRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthRollLower; + float mouthRollLower{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthRollUpper; + float mouthRollUpper{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthShrugLower; + float mouthShrugLower{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthShrugUpper; + float mouthShrugUpper{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthPressLeft; + float mouthPressLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthPressRight; + float mouthPressRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthLowerDownLeft; + float mouthLowerDownLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthLowerDownRight; + float mouthLowerDownRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthUpperUpLeft; + float mouthUpperUpLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float mouthUpperUpRight; + float mouthUpperUpRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float browDownLeft; + float browDownLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float browDownRight; + float browDownRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float browInnerUp; + float browInnerUp{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float browOuterUpLeft; + float browOuterUpLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float browOuterUpRight; + float browOuterUpRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float cheekPuff; + float cheekPuff{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float cheekSquintLeft; + float cheekSquintLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float cheekSquintRight; + float cheekSquintRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float noseSneerLeft; + float noseSneerLeft{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float noseSneerRight; + float noseSneerRight{ 0.0f }; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Faces blendshape")) - float tongueOut; + float tongueOut{ 0.0f }; - FName GetSubjectName() + FName GetSubjectName() const { FString TempSubjectName = "actor:" + actorName + ":face"; #if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 25) @@ -383,25 +388,23 @@ struct FVirtualProductionFrame { /**Indicates the VP frame version.*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "Virtual Production version.")) - int version; + FString Version; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "List of props.")) /** Array of props. */ - TArray props; + TArray Props; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "List of trackers.")) /** Array of trackers. */ - TArray trackers; + TArray Trackers; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Virtual Production", meta = (ToolTip = "List of faces.")) - TArray faces; + TArray Faces; UPROPERTY() - TArray suits; - - //FVirtualProductionFrame (){} -}; + TArray Actors; -struct LiveLinkSuit { + UPROPERTY() + TArray Characters; -}; \ No newline at end of file +}; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionProp.h b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionProp.h index cbc0f1f..6fe0892 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionProp.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionProp.h @@ -4,7 +4,6 @@ #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "GameFramework/Actor.h" -#include "SmartsuitReceiver.h" #include "VirtualProductionProp.generated.h" @@ -43,6 +42,4 @@ class SMARTSUIT_API UVirtualProductionProp : public UActorComponent FVector CurrentLocation; AActor* parent; -private: - ARokokoReceiver* GetReceiver(); }; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionSource.h b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionSource.h index b6eb6e3..28b83ad 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionSource.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionSource.h @@ -7,7 +7,7 @@ #include "Runtime/RenderCore/Public/RenderCore.h" #include "MessageEndpoint.h" #include "VirtualProductionFrame.h" -#include "SmartsuitDefinitions.h" +#include "RokokoSkeletonData.h" #include "Engine/DataAsset.h" #include "LiveLinkRemapAsset.h" @@ -17,14 +17,10 @@ #include "Runtime/Networking/Public/Common/UdpSocketBuilder.h" #include "Runtime/Core/Public/HAL/Runnable.h" #include "Runtime/Core/Public/HAL/RunnableThread.h" -//#include "Runtime/Core/Public/Unix/UnixCriticalSection.h" #include #include "VirtualProductionFrame.h" -//#include "VirtualProductionSource.h" -#define DEFAULT_ENDPOINT FIPv4Endpoint(FIPv4Address(127, 0, 0, 1), 5005) - -#include "VirtualProductionSource.generated.h" +//#include "VirtualProductionSource.generated.h" class ILiveLinkClient; @@ -34,606 +30,15 @@ struct FLiveLinkSubjectFrameMessage; struct FLiveLinkHeartbeatMessage; struct FLiveLinkClearSubject; -//USTRUCT() -//struct FVPMorphTargetMapping -//{ -// GENERATED_BODY() -// -// UPROPERTY() -// FName CurveName; -// -// UPROPERTY() -// FName CurveNameOverride; -//}; - -UCLASS(BlueprintType) -class SMARTSUIT_API URokokoFaceMapData : public ULiveLinkRemapAsset -{ - GENERATED_BODY() - - URokokoFaceMapData() - { - browDownLeft = "browDownLeft"; - browDownRight = "browDownRight"; - browInnerUp = "browInnerUp"; - browOuterUpLeft = "browOuterUpLeft"; - browOuterUpRight = "browOuterUpRight"; - cheekPuff = "cheekPuff"; - cheekSquintLeft = "cheekSquintLeft"; - cheekSquintRight = "cheekSquintRight"; - eyeBlinkLeft = "eyeBlinkLeft"; - eyeBlinkRight = "eyeBlinkRight"; - eyeLookDownLeft = "eyeLookDownLeft"; - eyeLookDownRight = "eyeLookDownRight"; - eyeLookInLeft = "eyeLookInLeft"; - eyeLookInRight = "eyeLookInRight"; - eyeLookOutLeft = "eyeLookOutLeft"; - eyeLookOutRight = "eyeLookOutRight"; - eyeLookUpLeft = "eyeLookUpLeft"; - eyeLookUpRight = "eyeLookUpRight"; - eyeSquintLeft = "eyeSquintLeft"; - eyeSquintRight = "eyeSquintRight"; - eyeWideLeft = "eyeWideLeft"; - eyeWideRight = "eyeWideRight"; - jawOpen = "jawOpen"; - jawForward = "jawForward"; - jawLeft = "jawLeft"; - jawRight = "jawRight"; - mouthClose = "mouthClose"; - mouthDimpleLeft = "mouthDimpleLeft"; - mouthDimpleRight = "mouthDimpleRight"; - mouthFrownLeft = "mouthFrownLeft"; - mouthFrownRight = "mouthFrownRight"; - mouthFunnel = "mouthFunnel"; - mouthLeft = "mouthLeft"; - mouthLowerDownLeft = "mouthLowerDownLeft"; - mouthLowerDownRight = "mouthLowerDownRight"; - mouthPressLeft = "mouthPressLeft"; - mouthPressRight = "mouthPressRight"; - mouthPucker = "mouthPucker"; - mouthRight = "mouthRight"; - mouthRollLower = "mouthRollLower"; - mouthRollUpper = "mouthRollUpper"; - mouthShrugLower = "mouthShrugLower"; - mouthShrugUpper = "mouthShrugUpper"; - mouthSmileLeft = "mouthSmileLeft"; - mouthSmileRight = "mouthSmileRight"; - mouthStretchLeft = "mouthStretchLeft"; - mouthStretchRight = "mouthStretchRight"; - mouthUpperUpLeft = "mouthUpperUpLeft"; - mouthUpperUpRight = "mouthUpperUpRight"; - noseSneerLeft = "noseSneerLeft"; - noseSneerRight = "noseSneerRight"; - tongueOut = "tongueOut"; - } -public: - - FName GetRemappedCurveName_Implementation(FName CurveName) const override; - - virtual void Initialize() override; - - UFUNCTION(BlueprintCallable, Category = MorphTargetRemapping) - void InitializeTMap() - { - NameMapping.Add("browDownLeft", browDownLeft); - NameMapping.Add("browDownRight", browDownRight); - NameMapping.Add("browInnerUp", browInnerUp); - NameMapping.Add("browOuterUpLeft", browOuterUpLeft); - NameMapping.Add("browOuterUpRight", browOuterUpRight); - NameMapping.Add("cheekPuff", cheekPuff); - NameMapping.Add("cheekSquintLeft", cheekSquintLeft); - NameMapping.Add("cheekSquintRight", cheekSquintRight); - NameMapping.Add("eyeBlinkLeft", eyeBlinkLeft); - NameMapping.Add("eyeBlinkRight", eyeBlinkRight); - NameMapping.Add("eyeLookDownLeft", eyeLookDownLeft); - NameMapping.Add("eyeLookDownRight", eyeLookDownRight); - NameMapping.Add("eyeLookInLeft", eyeLookInLeft); - NameMapping.Add("eyeLookInRight", eyeLookInRight); - NameMapping.Add("eyeLookOutLeft", eyeLookOutLeft); - NameMapping.Add("eyeLookOutRight", eyeLookOutRight); - NameMapping.Add("eyeLookUpLeft", eyeLookUpLeft); - NameMapping.Add("eyeLookUpRight", eyeLookUpRight); - NameMapping.Add("eyeSquintLeft", eyeSquintLeft); - NameMapping.Add("eyeSquintRight", eyeSquintRight); - NameMapping.Add("eyeWideLeft", eyeWideLeft); - NameMapping.Add("eyeWideRight", eyeWideRight); - NameMapping.Add("jawOpen", jawOpen); - NameMapping.Add("jawForward", jawForward); - NameMapping.Add("jawLeft", jawLeft); - NameMapping.Add("jawRight", jawRight); - NameMapping.Add("mouthClose", mouthClose); - NameMapping.Add("mouthDimpleLeft", mouthDimpleLeft); - NameMapping.Add("mouthDimpleRight", mouthDimpleRight); - NameMapping.Add("mouthFrownLeft", mouthFrownLeft); - NameMapping.Add("mouthFrownRight", mouthFrownRight); - NameMapping.Add("mouthFunnel", mouthFunnel); - NameMapping.Add("mouthLeft", mouthLeft); - NameMapping.Add("mouthLowerDownLeft", mouthLowerDownLeft); - NameMapping.Add("mouthLowerDownRight", mouthLowerDownRight); - NameMapping.Add("mouthPressLeft", mouthPressLeft); - NameMapping.Add("mouthPressRight", mouthPressRight); - NameMapping.Add("mouthPucker", mouthPucker); - NameMapping.Add("mouthRight", mouthRight); - NameMapping.Add("mouthRollLower", mouthRollLower); - NameMapping.Add("mouthRollUpper", mouthRollUpper); - NameMapping.Add("mouthShrugLower", mouthShrugLower); - NameMapping.Add("mouthShrugUpper", mouthShrugUpper); - NameMapping.Add("mouthSmileLeft", mouthSmileLeft); - NameMapping.Add("mouthSmileRight", mouthSmileRight); - NameMapping.Add("mouthStretchLeft", mouthStretchLeft); - NameMapping.Add("mouthStretchRight", mouthStretchRight); - NameMapping.Add("mouthUpperUpLeft", mouthUpperUpLeft); - NameMapping.Add("mouthUpperUpRight", mouthUpperUpRight); - NameMapping.Add("noseSneerLeft", noseSneerLeft); - NameMapping.Add("noseSneerRight", noseSneerRight); - NameMapping.Add("tongueOut", tongueOut); - } - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - TMap NameMapping; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName browDownLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName browDownRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName browInnerUp; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName browOuterUpLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName browOuterUpRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName cheekPuff; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName cheekSquintLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName cheekSquintRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeBlinkLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeBlinkRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookDownLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookDownRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookInLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookInRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookOutLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookOutRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookUpLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeLookUpRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeSquintLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeSquintRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeWideLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName eyeWideRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName jawOpen; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName jawForward; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName jawLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName jawRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthClose; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthDimpleLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthDimpleRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthFrownLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthFrownRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthFunnel; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthLowerDownLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthLowerDownRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthPressLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthPressRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthPucker; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthRollLower; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthRollUpper; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthShrugLower; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthShrugUpper; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthSmileLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthSmileRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthStretchLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthStretchRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthUpperUpLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName mouthUpperUpRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName noseSneerLeft; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName noseSneerRight; - - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) - FName tongueOut; - -}; - -//UCLASS(BlueprintType) -//class SMARTSUIT_API UVPFaceMorphTargetNameRemapping : public UDataAsset -//{ -// GENERATED_BODY() -// -// UVPFaceMorphTargetNameRemapping() -// { -// browDownLeft = "browDownLeft"; -// browDownRight = "browDownRight"; -// browInnerUp = "browInnerUp"; -// browOuterUpLeft = "browOuterUpLeft"; -// browOuterUpRight = "browOuterUpRight"; -// cheekPuff = "cheekPuff"; -// cheekSquintLeft = "cheekSquintLeft"; -// cheekSquintRight = "cheekSquintRight"; -// eyeBlinkLeft = "eyeBlinkLeft"; -// eyeBlinkRight = "eyeBlinkRight"; -// eyeLookDownLeft = "eyeLookDownLeft"; -// eyeLookDownRight = "eyeLookDownRight"; -// eyeLookInLeft = "eyeLookInLeft"; -// eyeLookInRight = "eyeLookInRight"; -// eyeLookOutLeft = "eyeLookOutLeft"; -// eyeLookOutRight = "eyeLookOutRight"; -// eyeLookUpLeft = "eyeLookUpLeft"; -// eyeLookUpRight = "eyeLookUpRight"; -// eyeSquintLeft = "eyeSquintLeft"; -// eyeSquintRight = "eyeSquintRight"; -// eyeWideLeft = "eyeWideLeft"; -// eyeWideRight = "eyeWideRight"; -// jawOpen = "jawOpen"; -// jawForward = "jawForward"; -// jawLeft = "jawLeft"; -// jawRight = "jawRight"; -// mouthClose = "mouthClose"; -// mouthDimpleLeft = "mouthDimpleLeft"; -// mouthDimpleRight = "mouthDimpleRight"; -// mouthFrownLeft = "mouthFrownLeft"; -// mouthFrownRight = "mouthFrownRight"; -// mouthFunnel = "mouthFunnel"; -// mouthLeft = "mouthLeft"; -// mouthLowerDownLeft = "mouthLowerDownLeft"; -// mouthLowerDownRight = "mouthLowerDownRight"; -// mouthPressLeft = "mouthPressLeft"; -// mouthPressRight = "mouthPressRight"; -// mouthPucker = "mouthPucker"; -// mouthRight = "mouthRight"; -// mouthRollLower = "mouthRollLower"; -// mouthRollUpper = "mouthRollUpper"; -// mouthShrugLower = "mouthShrugLower"; -// mouthShrugUpper = "mouthShrugUpper"; -// mouthSmileLeft = "mouthSmileLeft"; -// mouthSmileRight = "mouthSmileRight"; -// mouthStretchLeft = "mouthStretchLeft"; -// mouthStretchRight = "mouthStretchRight"; -// mouthUpperUpLeft = "mouthUpperUpLeft"; -// mouthUpperUpRight = "mouthUpperUpRight"; -// noseSneerLeft = "noseSneerLeft"; -// noseSneerRight = "noseSneerRight"; -// tongueOut = "tongueOut"; -// } -//public: -// -// UFUNCTION(BlueprintCallable, Category = MorphTargetRemapping) -// void InitializeTMap() -// { -// NameMapping.Add("browDownLeft", browDownLeft); -// NameMapping.Add("browDownRight", browDownRight); -// NameMapping.Add("browInnerUp", browInnerUp); -// NameMapping.Add("browOuterUpLeft", browOuterUpLeft); -// NameMapping.Add("browOuterUpRight", browOuterUpRight); -// NameMapping.Add("cheekPuff", cheekPuff); -// NameMapping.Add("cheekSquintLeft", cheekSquintLeft); -// NameMapping.Add("cheekSquintRight", cheekSquintRight); -// NameMapping.Add("eyeBlinkLeft", eyeBlinkLeft); -// NameMapping.Add("eyeBlinkRight", eyeBlinkRight); -// NameMapping.Add("eyeLookDownLeft", eyeLookDownLeft); -// NameMapping.Add("eyeLookDownRight", eyeLookDownRight); -// NameMapping.Add("eyeLookInLeft", eyeLookInLeft); -// NameMapping.Add("eyeLookInRight", eyeLookInRight); -// NameMapping.Add("eyeLookOutLeft", eyeLookOutLeft); -// NameMapping.Add("eyeLookOutRight", eyeLookOutRight); -// NameMapping.Add("eyeLookUpLeft", eyeLookUpLeft); -// NameMapping.Add("eyeLookUpRight", eyeLookUpRight); -// NameMapping.Add("eyeSquintLeft", eyeSquintLeft); -// NameMapping.Add("eyeSquintRight", eyeSquintRight); -// NameMapping.Add("eyeWideLeft", eyeWideLeft); -// NameMapping.Add("eyeWideRight", eyeWideRight); -// NameMapping.Add("jawOpen", jawOpen); -// NameMapping.Add("jawForward", jawForward); -// NameMapping.Add("jawLeft", jawLeft); -// NameMapping.Add("jawRight", jawRight); -// NameMapping.Add("mouthClose", mouthClose); -// NameMapping.Add("mouthDimpleLeft", mouthDimpleLeft); -// NameMapping.Add("mouthDimpleRight", mouthDimpleRight); -// NameMapping.Add("mouthFrownLeft", mouthFrownLeft); -// NameMapping.Add("mouthFrownRight", mouthFrownRight); -// NameMapping.Add("mouthFunnel", mouthFunnel); -// NameMapping.Add("mouthLeft", mouthLeft); -// NameMapping.Add("mouthLowerDownLeft", mouthLowerDownLeft); -// NameMapping.Add("mouthLowerDownRight", mouthLowerDownRight); -// NameMapping.Add("mouthPressLeft", mouthPressLeft); -// NameMapping.Add("mouthPressRight", mouthPressRight); -// NameMapping.Add("mouthPucker", mouthPucker); -// NameMapping.Add("mouthRight", mouthRight); -// NameMapping.Add("mouthRollLower", mouthRollLower); -// NameMapping.Add("mouthRollUpper", mouthRollUpper); -// NameMapping.Add("mouthShrugLower", mouthShrugLower); -// NameMapping.Add("mouthShrugUpper", mouthShrugUpper); -// NameMapping.Add("mouthSmileLeft", mouthSmileLeft); -// NameMapping.Add("mouthSmileRight", mouthSmileRight); -// NameMapping.Add("mouthStretchLeft", mouthStretchLeft); -// NameMapping.Add("mouthStretchRight", mouthStretchRight); -// NameMapping.Add("mouthUpperUpLeft", mouthUpperUpLeft); -// NameMapping.Add("mouthUpperUpRight", mouthUpperUpRight); -// NameMapping.Add("noseSneerLeft", noseSneerLeft); -// NameMapping.Add("noseSneerRight", noseSneerRight); -// NameMapping.Add("tongueOut", tongueOut); -// } -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// TMap NameMapping; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName browDownLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName browDownRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName browInnerUp; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName browOuterUpLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName browOuterUpRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName cheekPuff; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName cheekSquintLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName cheekSquintRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeBlinkLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeBlinkRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookDownLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookDownRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookInLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookInRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookOutLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookOutRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookUpLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeLookUpRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeSquintLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeSquintRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeWideLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName eyeWideRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName jawOpen; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName jawForward; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName jawLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName jawRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthClose; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthDimpleLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthDimpleRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthFrownLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthFrownRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthFunnel; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthLowerDownLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthLowerDownRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthPressLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthPressRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthPucker; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthRollLower; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthRollUpper; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthShrugLower; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthShrugUpper; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthSmileLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthSmileRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthStretchLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthStretchRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthUpperUpLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName mouthUpperUpRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName noseSneerLeft; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName noseSneerRight; -// -// UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MorphTargetRemapping) -// FName tongueOut; -// -//}; - /** - * + * reading udp packets in separate thread and output extracted data into static and dynamic data of different roles */ class SMARTSUIT_API FVirtualProductionSource : public ILiveLinkSource, public FRunnable { public: - FVirtualProductionSource(const FText& InSourceType, const FText& InSourceMachineName, const FMessageAddress& InConnectionAddress); - // : SourceType(InSourceType) - // , SourceMachineName(InSourceMachineName) - //{ - // Client = nullptr; - // - // int32 RokokoPort; - // for (TObjectIterator It; It; ++It) - // { - // RokokoPort = It->RokokoPortNumber; - // UE_LOG(LogTemp, Warning, TEXT("setting port to... %i"), RokokoPort); - // } - - // InitSocket(RokokoPort); - // StartRunnable(RokokoPort); - //} - + FVirtualProductionSource(FIPv4Endpoint address, const FText& InSourceType, const FText& InSourceMachineName, const FMessageAddress& InConnectionAddress); + FVirtualProductionSource() { Client = nullptr; @@ -648,31 +53,35 @@ class SMARTSUIT_API FVirtualProductionSource : public ILiveLinkSource, public FR virtual FText GetSourceType() const { return SourceType; } virtual FText GetSourceMachineName() const { return SourceMachineName; } virtual FText GetSourceStatus() const { return SourceStatus; } - static TSharedPtr Get() { return instance; } + - void HandleSubjectFrame(TArray virtualProductionObject); - void HandleFace(TArray faces); - void HandleSuits(TArray suits); + void HandleSubjectFrame(const TArray& virtualProductionObject); + void HandleFace(const TArray& faces); + void HandleSuits(const TArray& suits); + void HandleCharacters(const TArray& characters); void ClearAllSubjects(); static void SetInstance(TSharedPtr NewInstance) { instance = NewInstance; } - + static TSharedPtr Get(); static TSharedPtr CreateLiveLinkSource(); static void RemoveLiveLinkSource(TSharedPtr InSource); private: void HandleClearSubject(const FName subjectName); - void HandleSubjectData(FVirtualProductionSubject virtualProductionObject); - void HandleFaceData(FFace face); - void HandleSuitData(FSuitData suit); - void CreateJoint(TArray& transforms, int32 index, FSmartsuitBone* parent, FSmartsuitBone* sensor); - //void CreateJoint(TArray& transforms, int32 index, Sensor* parent, Sensor* sensor); + void HandleSubjectData(const FVirtualProductionSubject& virtualProductionObject); + void HandleFaceData(const FFace& face); + void HandleSuitData(const FSuitData& suit); + void HandleCharacterData(const FCharacterData& character); + void CreateJoint(TArray& transforms, int32 index, const FSmartsuitBone* parent, const FSmartsuitBone* sensor); + TArray subjectNames; TArray faceNames; - TArray suitNames; + TArray actorNames; + TArray characterNames; TArray existingSubjects; TArray existingFaces; - TArray existingSuits; + TArray existingActors; + TArray existingCharacters; TArray notExistingSubjects; @@ -686,12 +95,11 @@ class SMARTSUIT_API FVirtualProductionSource : public ILiveLinkSource, public FR FText SourceStatus; //singleton instance - //static FVirtualProductionSource *instance; static TSharedPtr instance; public: /// @private - virtual bool InitSocket(int port); + virtual bool InitSocket(); /// @private virtual uint32 Run() override; @@ -703,7 +111,7 @@ class SMARTSUIT_API FVirtualProductionSource : public ILiveLinkSource, public FR */ bool IsActive() const { - return (!Stopping); + return (Running); } /** @@ -711,7 +119,7 @@ class SMARTSUIT_API FVirtualProductionSource : public ILiveLinkSource, public FR */ virtual void Stop() override { - Stopping = true; + Running = false; } /** @@ -719,7 +127,7 @@ class SMARTSUIT_API FVirtualProductionSource : public ILiveLinkSource, public FR * * @param port The port number to bind. */ - void StartRunnable(int port); + void StartRunnable(); /// @private virtual void Exit() override { } @@ -739,23 +147,23 @@ class SMARTSUIT_API FVirtualProductionSource : public ILiveLinkSource, public FR FFace* GetFaceByProfileName(const FString& profileName); TArray GetAllFaces(); + // TODO: GetAllCharacters private: std::mutex mtx; - //FPThreadsCriticalSection FCriticalSection; - int streaming_port; - FSocket* Socket = NULL; + + // network receiver data + FIPv4Endpoint m_NetworkAddress; + bool m_NetworkBindAnyAddress; + bool m_NetworkBroadcast; + + FSocket* Socket{ nullptr }; /** Used to tell that the thread is stopping */ - bool Stopping; - //FVirtualProductionSource* livelink = FVirtualProductionSource::Get(); - //TArray subjectNames; + bool Running; + /** Connection thread, used to not block the editor when waiting for connections */ - FRunnableThread* Thread = NULL; + FRunnableThread* Thread{ nullptr }; FVirtualProductionFrame GlobalVPFrame; - //TSharedPtr GetLiveLink() { return FVirtualProductionSource::Get(); } - TArray subjects; - void SendToLiveLink(TArray Subjects); - void SendFacesToLivelink(TArray Subjects); - void SendSuitsToLiveLink(TArray Smartsuits); - + TArray Subjects; + }; diff --git a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionTracker.h b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionTracker.h index 26fe2c8..fe1c013 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionTracker.h +++ b/Plugins/Smartsuit/Source/Smartsuit/Public/VirtualProductionTracker.h @@ -4,7 +4,6 @@ #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "GameFramework/Actor.h" -#include "SmartsuitReceiver.h" #include "VirtualProductionTracker.generated.h" @@ -42,7 +41,4 @@ class SMARTSUIT_API UVirtualProductionTracker : public UActorComponent FVector CurrentLocation; AActor* parent; - -private: - ARokokoReceiver* GetReceiver(); }; \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/Smartsuit/Smartsuit.Build.cs b/Plugins/Smartsuit/Source/Smartsuit/Smartsuit.Build.cs index 381a318..7a3d8e7 100644 --- a/Plugins/Smartsuit/Source/Smartsuit/Smartsuit.Build.cs +++ b/Plugins/Smartsuit/Source/Smartsuit/Smartsuit.Build.cs @@ -35,22 +35,23 @@ public Smartsuit(ReadOnlyTargetRules Target) : base (Target) // ); - // PrivateIncludePaths.AddRange( - // new string[] { - // "Smartsuit/Private", - // "LiveLink/Private", + // PrivateIncludePaths.AddRange( + // new string[] { + // "Smartsuit/Private", + // "LiveLink/Private", - // // ... add other private include paths required here ... - //} - // ); + // // ... add other private include paths required here ... + //} + // ); + PublicDefinitions.Add("USE_SMARTSUIT_ANIMATION_ROLE"); PublicDependencyModuleNames.AddRange( new string[] { //"Core", //"Core", "AnimGraph", "BlueprintGraph", "AnimGraphRuntime", "CoreUObject", "Engine", "Sockets", "Networking", - "Core", "CoreUObject", "Engine", "Sockets", "Http", "Networking", "AnimGraphRuntime", "Json", "JsonUtilities", "LiveLink", "RenderCore", "InputCore"/*, "LiveLinkInterface"*/ + "Core", "CoreUObject", "Engine", "Sockets", "HTTP", "Networking", "AnimGraphRuntime", "Json", "JsonUtilities", "LiveLink", "RenderCore", "InputCore", "LiveLinkInterface", "LiveLinkAnimationCore" // ... add other public dependencies that you statically link with here ... } ); @@ -95,7 +96,7 @@ public Smartsuit(ReadOnlyTargetRules Target) : base (Target) } ); - LoadSmartsuitMagic(Target); + //LoadSmartsuitMagic(Target); //PublicDefinitions.Add("LZ4F_STATIC_LINKING_ONLY"); diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/AnimGraphNode_ModifyFaceCurves.cpp b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/AnimGraphNode_ModifyFaceCurves.cpp deleted file mode 100644 index 5486ffd..0000000 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/AnimGraphNode_ModifyFaceCurves.cpp +++ /dev/null @@ -1,167 +0,0 @@ -//// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. -// -//#include "AnimGraphNode_ModifyFaceCurves.h" -//#include "Textures/SlateIcon.h" -//#include "GraphEditorActions.h" -//#include "ScopedTransaction.h" -//#include "Kismet2/CompilerResultsLog.h" -//#include "AnimationGraphSchema.h" -//#include "BlueprintActionDatabaseRegistrar.h" -//#include "Framework/Commands/UIAction.h" -//#include "ToolMenus.h" -//#include "Kismet2/BlueprintEditorUtils.h" -// -//#define LOCTEXT_NAMESPACE "ModifyCurve" -// -// -//UAnimGraphNode_ModifyFaceCurves::UAnimGraphNode_ModifyFaceCurves() -//{ -//} -// -//FString UAnimGraphNode_ModifyFaceCurves::GetNodeCategory() const -//{ -// return TEXT("Skeletal Control Nodes"); -//} -// -//FText UAnimGraphNode_ModifyFaceCurves::GetTooltipText() const -//{ -// return GetNodeTitle(ENodeTitleType::ListView); -//} -// -//FText UAnimGraphNode_ModifyFaceCurves::GetNodeTitle(ENodeTitleType::Type TitleType) const -//{ -// return LOCTEXT("AnimGraphNode_ModifyFaceCurves_Title", "Modify Face Curves"); -//} -// -// -//TArray UAnimGraphNode_ModifyFaceCurves::GetCurvesToAdd() const -//{ -// TArray CurvesToAdd; -// -// const FSmartNameMapping* Mapping = GetAnimBlueprint()->TargetSkeleton->GetSmartNameContainer(USkeleton::AnimCurveMappingName); -// if (Mapping) -// { -// Mapping->FillNameArray(CurvesToAdd); -// -// for (FName ExistingCurveName : Node.CurveNames) -// { -// CurvesToAdd.RemoveSingleSwap(ExistingCurveName, false); -// } -// -// CurvesToAdd.Sort(FNameLexicalLess()); -// } -// -// return CurvesToAdd; -//} -// -//void UAnimGraphNode_ModifyFaceCurves::GetAddCurveMenuActions(FMenuBuilder& MenuBuilder) const -//{ -// TArray CurvesToAdd = GetCurvesToAdd(); -// for (FName CurveName : CurvesToAdd) -// { -// FUIAction Action = FUIAction(FExecuteAction::CreateUObject(const_cast(this), &UAnimGraphNode_ModifyFaceCurves::AddCurvePin, CurveName)); -// MenuBuilder.AddMenuEntry(FText::FromName(CurveName), FText::GetEmpty(), FSlateIcon(), Action); -// } -//} -// -//void UAnimGraphNode_ModifyFaceCurves::GetRemoveCurveMenuActions(FMenuBuilder& MenuBuilder) const -//{ -// for (FName CurveName : Node.CurveNames) -// { -// FUIAction Action = FUIAction(FExecuteAction::CreateUObject(const_cast(this), &UAnimGraphNode_ModifyFaceCurves::RemoveCurvePin, CurveName)); -// MenuBuilder.AddMenuEntry(FText::FromName(CurveName), FText::GetEmpty(), FSlateIcon(), Action); -// } -//} -// -// -//void UAnimGraphNode_ModifyFaceCurves::GetNodeContextMenuActions(UToolMenu* Menu, UGraphNodeContextMenuContext* Context) const -//{ -// if (!Context->bIsDebugging) -// { -// FToolMenuSection& Section = Menu->AddSection("AnimGraphNodeModifyFaceCurves", LOCTEXT("ModifyFaceCurves", "Modify Face Curves")); -// -// // Clicked pin -// if (Context->Pin != NULL) -// { -// // Get proeprty from pin -// FProperty* AssociatedProperty; -// int32 ArrayIndex; -// GetPinAssociatedProperty(GetFNodeType(), Context->Pin, /*out*/ AssociatedProperty, /*out*/ ArrayIndex); -// FName PinPropertyName = AssociatedProperty->GetFName(); -// -// if (PinPropertyName == GET_MEMBER_NAME_CHECKED(FAnimNode_ModifyFaceCurves, CurveValues) && Context->Pin->Direction == EGPD_Input) -// { -// FString PinName = Context->Pin->PinFriendlyName.ToString(); -// FUIAction Action = FUIAction( FExecuteAction::CreateUObject(const_cast(this), &UAnimGraphNode_ModifyFaceCurves::RemoveCurvePin, FName(*PinName)) ); -// FText RemovePinLabelText = FText::Format(LOCTEXT("RemoveThisPin", "Remove This Curve Pin: {0}"), FText::FromString(PinName)); -// Section.AddMenuEntry("RemoveThisPin", RemovePinLabelText, LOCTEXT("RemoveThisPinTooltip", "Remove this curve pin from this node"), FSlateIcon(), Action); -// } -// } -// -// // If we have more curves to add, create submenu to offer them -// if (GetCurvesToAdd().Num() > 0) -// { -// Section.AddSubMenu( -// "AddCurvePin", -// LOCTEXT("AddCurvePin", "Add Curve Pin"), -// LOCTEXT("AddCurvePinTooltip", "Add a new pin to drive a curve"), -// FNewMenuDelegate::CreateUObject(this, &UAnimGraphNode_ModifyFaceCurves::GetAddCurveMenuActions)); -// } -// -// // If we have curves to remove, create submenu to offer them -// if (Node.CurveNames.Num() > 0) -// { -// Section.AddSubMenu( -// "RemoveCurvePin", -// LOCTEXT("RemoveCurvePin", "Remove Curve Pin"), -// LOCTEXT("RemoveCurvePinTooltip", "Remove a pin driving a curve"), -// FNewMenuDelegate::CreateUObject(this, &UAnimGraphNode_ModifyFaceCurves::GetRemoveCurveMenuActions)); -// } -// } -//} -// -//void UAnimGraphNode_ModifyFaceCurves::RemoveCurvePin(FName CurveName) -//{ -// // Make sure we have a curve pin with that name -// int32 CurveIndex = Node.CurveNames.Find(CurveName); -// if (CurveIndex != INDEX_NONE) -// { -// FScopedTransaction Transaction( LOCTEXT("RemoveCurvePinTrans", "Remove Curve Pin") ); -// Modify(); -// -// Node.RemoveCurve(CurveIndex); -// -// ReconstructNode(); -// FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(GetBlueprint()); -// } -//} -// -//void UAnimGraphNode_ModifyFaceCurves::AddCurvePin(FName CurveName) -//{ -// // Make sure it doesn't already exist -// int32 CurveIndex = Node.CurveNames.Find(CurveName); -// if (CurveIndex == INDEX_NONE) -// { -// FScopedTransaction Transaction(LOCTEXT("AddCurvePinTrans", "Add Curve Pin")); -// Modify(); -// -// Node.AddCurve(CurveName, 0.f); -// -// ReconstructNode(); -// FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(GetBlueprint()); -// } -//} -// -// -//void UAnimGraphNode_ModifyFaceCurves::CustomizePinData(UEdGraphPin* Pin, FName SourcePropertyName, int32 ArrayIndex) const -//{ -// if (SourcePropertyName == GET_MEMBER_NAME_CHECKED(FAnimNode_ModifyFaceCurves, CurveValues)) -// { -// if (Node.CurveNames.IsValidIndex(ArrayIndex)) -// { -// Pin->PinFriendlyName = FText::FromName(Node.CurveNames[ArrayIndex]); -// } -// } -//} -// -//#undef LOCTEXT_NAMESPACE diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/SmartsuitPose.cpp b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/SmartsuitPose.cpp index cec78bf..3b5f02d 100644 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/SmartsuitPose.cpp +++ b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/SmartsuitPose.cpp @@ -2,6 +2,7 @@ #include "SmartsuitPose.h" #include "SmartsuitEditor.h" +#include "LiveLinkRemapAsset.h" #include "SmartsuitEditorPrivatePCH.h" //#include "CompilerResultsLog.h" @@ -38,73 +39,98 @@ void USmartsuitPose::CheckForWarnings(FString name, FBoneReference bone, USkelet } } } - +//PRAGMA_DISABLE_OPTIMIZATION void USmartsuitPose::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) { - if (Node.CurrentRetargetAsset->IsValidLowLevel()) + + Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog); + + //if (Node.Bone_Map_Override_OLD->IsValidLowLevel()) + //{ + // Node.BoneMap.hip = Node.Bone_Map_Override_OLD->hip; + // Node.BoneMap.stomach = Node.Bone_Map_Override_OLD->stomach; + // Node.BoneMap.chest = Node.Bone_Map_Override_OLD->chest; + // Node.BoneMap.neck = Node.Bone_Map_Override_OLD->neck; + // Node.BoneMap.head = Node.Bone_Map_Override_OLD->head; + // Node.BoneMap.leftShoulder = Node.Bone_Map_Override_OLD->leftShoulder; + // Node.BoneMap.leftArm = Node.Bone_Map_Override_OLD->leftArm; + // Node.BoneMap.leftForearm = Node.Bone_Map_Override_OLD->leftForearm; + // Node.BoneMap.leftHand = Node.Bone_Map_Override_OLD->leftHand; + // Node.BoneMap.rightShoulder = Node.Bone_Map_Override_OLD->rightShoulder; + // Node.BoneMap.rightArm = Node.Bone_Map_Override_OLD->rightArm; + // Node.BoneMap.rightForearm = Node.Bone_Map_Override_OLD->rightForearm; + // Node.BoneMap.rightHand = Node.Bone_Map_Override_OLD->rightHand; + // Node.BoneMap.leftUpleg = Node.Bone_Map_Override_OLD->leftUpleg; + // Node.BoneMap.leftLeg = Node.Bone_Map_Override_OLD->leftLeg; + // Node.BoneMap.leftFoot = Node.Bone_Map_Override_OLD->leftFoot; + // Node.BoneMap.leftToe = Node.Bone_Map_Override_OLD->leftToe; + // Node.BoneMap.rightUpleg = Node.Bone_Map_Override_OLD->rightUpleg; + // Node.BoneMap.rightLeg = Node.Bone_Map_Override_OLD->rightLeg; + // Node.BoneMap.rightFoot = Node.Bone_Map_Override_OLD->rightFoot; + // Node.BoneMap.rightToe = Node.Bone_Map_Override_OLD->rightToe; + // Node.BoneMap.leftThumbProximal = Node.Bone_Map_Override_OLD->leftThumbProximal; + // Node.BoneMap.leftThumbMedial = Node.Bone_Map_Override_OLD->leftThumbMedial; + // Node.BoneMap.leftThumbDistal = Node.Bone_Map_Override_OLD->leftThumbDistal; + // Node.BoneMap.leftThumbTip = Node.Bone_Map_Override_OLD->leftThumbTip; + // Node.BoneMap.leftIndexProximal = Node.Bone_Map_Override_OLD->leftIndexProximal; + // Node.BoneMap.leftIndexMedial = Node.Bone_Map_Override_OLD->leftIndexMedial; + // Node.BoneMap.leftIndexDistal = Node.Bone_Map_Override_OLD->leftIndexDistal; + // Node.BoneMap.leftIndexTip = Node.Bone_Map_Override_OLD->leftIndexTip; + // Node.BoneMap.leftMiddleProximal = Node.Bone_Map_Override_OLD->leftMiddleProximal; + // Node.BoneMap.leftMiddleMedial = Node.Bone_Map_Override_OLD->leftMiddleMedial; + // Node.BoneMap.leftMiddleDistal = Node.Bone_Map_Override_OLD->leftMiddleDistal; + // Node.BoneMap.leftMiddleTip = Node.Bone_Map_Override_OLD->leftMiddleTip; + // Node.BoneMap.leftRingProximal = Node.Bone_Map_Override_OLD->leftRingProximal; + // Node.BoneMap.leftRingMedial = Node.Bone_Map_Override_OLD->leftRingMedial; + // Node.BoneMap.leftRingDistal = Node.Bone_Map_Override_OLD->leftRingDistal; + // Node.BoneMap.leftRingTip = Node.Bone_Map_Override_OLD->leftRingTip; + // Node.BoneMap.leftLittleProximal = Node.Bone_Map_Override_OLD->leftLittleProximal; + // Node.BoneMap.leftLittleMedial = Node.Bone_Map_Override_OLD->leftLittleMedial; + // Node.BoneMap.leftLittleDistal = Node.Bone_Map_Override_OLD->leftLittleDistal; + // Node.BoneMap.leftLittleTip = Node.Bone_Map_Override_OLD->leftLittleTip; + // Node.BoneMap.rightThumbProximal = Node.Bone_Map_Override_OLD->rightThumbProximal; + // Node.BoneMap.rightThumbMedial = Node.Bone_Map_Override_OLD->rightThumbMedial; + // Node.BoneMap.rightThumbDistal = Node.Bone_Map_Override_OLD->rightThumbDistal; + // Node.BoneMap.rightThumbTip = Node.Bone_Map_Override_OLD->rightThumbTip; + // Node.BoneMap.rightIndexProximal = Node.Bone_Map_Override_OLD->rightIndexProximal; + // Node.BoneMap.rightIndexMedial = Node.Bone_Map_Override_OLD->rightIndexMedial; + // Node.BoneMap.rightIndexDistal = Node.Bone_Map_Override_OLD->rightIndexDistal; + // Node.BoneMap.rightIndexTip = Node.Bone_Map_Override_OLD->rightIndexTip; + // Node.BoneMap.rightMiddleProximal = Node.Bone_Map_Override_OLD->rightMiddleProximal; + // Node.BoneMap.rightMiddleMedial = Node.Bone_Map_Override_OLD->rightMiddleMedial; + // Node.BoneMap.rightMiddleDistal = Node.Bone_Map_Override_OLD->rightMiddleDistal; + // Node.BoneMap.rightMiddleTip = Node.Bone_Map_Override_OLD->rightMiddleTip; + // Node.BoneMap.rightRingProximal = Node.Bone_Map_Override_OLD->rightRingProximal; + // Node.BoneMap.rightRingMedial = Node.Bone_Map_Override_OLD->rightRingMedial; + // Node.BoneMap.rightRingDistal = Node.Bone_Map_Override_OLD->rightRingDistal; + // Node.BoneMap.rightRingTip = Node.Bone_Map_Override_OLD->rightRingTip; + // Node.BoneMap.rightLittleProximal = Node.Bone_Map_Override_OLD->rightLittleProximal; + // Node.BoneMap.rightLittleMedial = Node.Bone_Map_Override_OLD->rightLittleMedial; + // Node.BoneMap.rightLittleDistal = Node.Bone_Map_Override_OLD->rightLittleDistal; + // Node.BoneMap.rightLittleTip = Node.Bone_Map_Override_OLD->rightLittleTip; + + UClass* RetargetAssetPtr = Node.RetargetAsset.Get(); + + if(IsValid(RetargetAssetPtr)) + { + FString Msg = "retarget asset: " + Node.RetargetAsset->GetName(); + MessageLog.Note(*Msg, this); + + + //ForSkeleton + Node.CurrentRetargetAsset = NewObject(GetTransientPackage(), RetargetAssetPtr); + Node.CurrentRetargetAsset->Initialize(); + } + else { - //Node.BoneMap.hip = Node.Bone_Map_Override_OLD->hip; - //Node.BoneMap.stomach = Node.Bone_Map_Override_OLD->stomach; - //Node.BoneMap.chest = Node.Bone_Map_Override_OLD->chest; - //Node.BoneMap.neck = Node.Bone_Map_Override_OLD->neck; - //Node.BoneMap.head = Node.Bone_Map_Override_OLD->head; - //Node.BoneMap.leftShoulder = Node.Bone_Map_Override_OLD->leftShoulder; - //Node.BoneMap.leftArm = Node.Bone_Map_Override_OLD->leftArm; - //Node.BoneMap.leftForearm = Node.Bone_Map_Override_OLD->leftForearm; - //Node.BoneMap.leftHand = Node.Bone_Map_Override_OLD->leftHand; - //Node.BoneMap.rightShoulder = Node.Bone_Map_Override_OLD->rightShoulder; - //Node.BoneMap.rightArm = Node.Bone_Map_Override_OLD->rightArm; - //Node.BoneMap.rightForearm = Node.Bone_Map_Override_OLD->rightForearm; - //Node.BoneMap.rightHand = Node.Bone_Map_Override_OLD->rightHand; - //Node.BoneMap.leftUpleg = Node.Bone_Map_Override_OLD->leftUpleg; - //Node.BoneMap.leftLeg = Node.Bone_Map_Override_OLD->leftLeg; - //Node.BoneMap.leftFoot = Node.Bone_Map_Override_OLD->leftFoot; - //Node.BoneMap.leftToe = Node.Bone_Map_Override_OLD->leftToe; - //Node.BoneMap.rightUpleg = Node.Bone_Map_Override_OLD->rightUpleg; - //Node.BoneMap.rightLeg = Node.Bone_Map_Override_OLD->rightLeg; - //Node.BoneMap.rightFoot = Node.Bone_Map_Override_OLD->rightFoot; - //Node.BoneMap.rightToe = Node.Bone_Map_Override_OLD->rightToe; - //Node.BoneMap.leftThumbProximal = Node.Bone_Map_Override_OLD->leftThumbProximal; - //Node.BoneMap.leftThumbMedial = Node.Bone_Map_Override_OLD->leftThumbMedial; - //Node.BoneMap.leftThumbDistal = Node.Bone_Map_Override_OLD->leftThumbDistal; - //Node.BoneMap.leftThumbTip = Node.Bone_Map_Override_OLD->leftThumbTip; - //Node.BoneMap.leftIndexProximal = Node.Bone_Map_Override_OLD->leftIndexProximal; - //Node.BoneMap.leftIndexMedial = Node.Bone_Map_Override_OLD->leftIndexMedial; - //Node.BoneMap.leftIndexDistal = Node.Bone_Map_Override_OLD->leftIndexDistal; - //Node.BoneMap.leftIndexTip = Node.Bone_Map_Override_OLD->leftIndexTip; - //Node.BoneMap.leftMiddleProximal = Node.Bone_Map_Override_OLD->leftMiddleProximal; - //Node.BoneMap.leftMiddleMedial = Node.Bone_Map_Override_OLD->leftMiddleMedial; - //Node.BoneMap.leftMiddleDistal = Node.Bone_Map_Override_OLD->leftMiddleDistal; - //Node.BoneMap.leftMiddleTip = Node.Bone_Map_Override_OLD->leftMiddleTip; - //Node.BoneMap.leftRingProximal = Node.Bone_Map_Override_OLD->leftRingProximal; - //Node.BoneMap.leftRingMedial = Node.Bone_Map_Override_OLD->leftRingMedial; - //Node.BoneMap.leftRingDistal = Node.Bone_Map_Override_OLD->leftRingDistal; - //Node.BoneMap.leftRingTip = Node.Bone_Map_Override_OLD->leftRingTip; - //Node.BoneMap.leftLittleProximal = Node.Bone_Map_Override_OLD->leftLittleProximal; - //Node.BoneMap.leftLittleMedial = Node.Bone_Map_Override_OLD->leftLittleMedial; - //Node.BoneMap.leftLittleDistal = Node.Bone_Map_Override_OLD->leftLittleDistal; - //Node.BoneMap.leftLittleTip = Node.Bone_Map_Override_OLD->leftLittleTip; - //Node.BoneMap.rightThumbProximal = Node.Bone_Map_Override_OLD->rightThumbProximal; - //Node.BoneMap.rightThumbMedial = Node.Bone_Map_Override_OLD->rightThumbMedial; - //Node.BoneMap.rightThumbDistal = Node.Bone_Map_Override_OLD->rightThumbDistal; - //Node.BoneMap.rightThumbTip = Node.Bone_Map_Override_OLD->rightThumbTip; - //Node.BoneMap.rightIndexProximal = Node.Bone_Map_Override_OLD->rightIndexProximal; - //Node.BoneMap.rightIndexMedial = Node.Bone_Map_Override_OLD->rightIndexMedial; - //Node.BoneMap.rightIndexDistal = Node.Bone_Map_Override_OLD->rightIndexDistal; - //Node.BoneMap.rightIndexTip = Node.Bone_Map_Override_OLD->rightIndexTip; - //Node.BoneMap.rightMiddleProximal = Node.Bone_Map_Override_OLD->rightMiddleProximal; - //Node.BoneMap.rightMiddleMedial = Node.Bone_Map_Override_OLD->rightMiddleMedial; - //Node.BoneMap.rightMiddleDistal = Node.Bone_Map_Override_OLD->rightMiddleDistal; - //Node.BoneMap.rightMiddleTip = Node.Bone_Map_Override_OLD->rightMiddleTip; - //Node.BoneMap.rightRingProximal = Node.Bone_Map_Override_OLD->rightRingProximal; - //Node.BoneMap.rightRingMedial = Node.Bone_Map_Override_OLD->rightRingMedial; - //Node.BoneMap.rightRingDistal = Node.Bone_Map_Override_OLD->rightRingDistal; - //Node.BoneMap.rightRingTip = Node.Bone_Map_Override_OLD->rightRingTip; - //Node.BoneMap.rightLittleProximal = Node.Bone_Map_Override_OLD->rightLittleProximal; - //Node.BoneMap.rightLittleMedial = Node.Bone_Map_Override_OLD->rightLittleMedial; - //Node.BoneMap.rightLittleDistal = Node.Bone_Map_Override_OLD->rightLittleDistal; - //Node.BoneMap.rightLittleTip = Node.Bone_Map_Override_OLD->rightLittleTip; + // FString Msg = "could not get retarget asset!"; + // MessageLog.Warning(*Msg, this); + } + bool CheckBoneOverrides = true; + + if (Node.CurrentRetargetAsset->IsValidLowLevel()) + { Node.BoneMap.hip = Node.CurrentRetargetAsset->GetRemappedBoneName("hip"); Node.BoneMap.stomach = Node.CurrentRetargetAsset->GetRemappedBoneName("stomach"); Node.BoneMap.chest = Node.CurrentRetargetAsset->GetRemappedBoneName("chest"); @@ -170,11 +196,13 @@ void USmartsuitPose::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, F else { FFormatNamedArguments Args; - FString Msg = "Bone map override not set!"; + FString Msg = "Bone map override appears to not be set. If is set, try recompiling"; MessageLog.Warning(*Msg, this); + + CheckBoneOverrides = false; } - if(ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad)) + if(CheckBoneOverrides && ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad)) { CheckForWarnings("Hip", Node.BoneMap.hip, ForSkeleton, MessageLog); CheckForWarnings("Stomach", Node.BoneMap.stomach, ForSkeleton, MessageLog); @@ -244,7 +272,7 @@ void USmartsuitPose::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, F //if (Node.Controller == NULL) { // MessageLog.Warning(*LOCTEXT("NoSmartsuit", "@@ - Smartsuit Controller is not set.").ToString(), this); //} - Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog); + } FText USmartsuitPose::GetControllerDescription() const @@ -302,6 +330,13 @@ void USmartsuitPose::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) //ModifyBone->TranslationSpace = Node.TranslationSpace; //ModifyBone->RotationSpace = Node.RotationSpace; //ModifyBone->ScaleSpace = Node.ScaleSpace; + + //ModifyBone->Bone_Map_Override_OLD = Node.Bone_Map_Override_OLD; + //ModifyBone->CurrentRetargetAsset = Node.CurrentRetargetAsset; + + Node.RetargetAsset = ModifyBone->RetargetAsset; + + //Node.CurrentRetargetAsset = ModifyBone->CurrentRetargetAsset; } //FEditorModeID USmartsuitPose::GetEditorMode() const @@ -324,6 +359,24 @@ void USmartsuitPose::CopyPinDefaultsToNodeData(UEdGraphPin* InPin) //{ // GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FSmartsuitPoseNode, Scale), Node.Scale); //} + + //if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FSmartsuitPoseNode, Bone_Map_Override_OLD)) + //{ + // //GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FSmartsuitPoseNode, Bone_Map_Override_OLD), Node.Bone_Map_Override_OLD); + //} + + +} + +void USmartsuitPose::PreloadRequiredAssets() +{ + Super::PreloadRequiredAssets(); + + + PreloadObject(Node.RetargetAsset); + + } +//PRAGMA_ENABLE_OPTIMIZATION #undef LOCTEXT_NAMESPACE diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.cpp b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.cpp index e459f8f..576163f 100644 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.cpp +++ b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.cpp @@ -1,9 +1,10 @@ // Copyright 2019 Rokoko Electronics. All Rights Reserved. #include "VirtualProductionSourceEditor.h" +#include "VirtualProductionSource.h" #include "LiveLinkMessageBusFinder.h" #include "Widgets/Layout/SBox.h" - +#include "Interfaces/IPv4/IPv4Endpoint.h" #include "MessageEndpointBuilder.h" #define LOCTEXT_NAMESPACE "VirtualProductionSourceEditor" @@ -67,28 +68,61 @@ void SVirtualProductionSourceEditor::Construct(const FArguments& Args) OnSourceSelected = Args._OnSourceSelected; LastTickTime = 0.0; + // default values + FIPv4Address address(FIPv4Address::Any); + + FIPv4Endpoint Endpoint; + Endpoint.Address = address; + Endpoint.Port = 14043; + ChildSlot [ SNew(SBox) .HeightOverride(200) - .WidthOverride(200) - [ - SAssignNew(ListView, SListView) - .ListItemsSource(&PollData) - .SelectionMode(ESelectionMode::SingleToggle) - .OnGenerateRow(this, &SVirtualProductionSourceEditor::MakeSourceListViewWidget) - .OnSelectionChanged(this, &SVirtualProductionSourceEditor::OnSourceListSelectionChanged) - .HeaderRow - ( - SNew(SHeaderRow) - + SHeaderRow::Column(ProviderPollUI::TypeColumnName) - .FillWidth(43.0f) - .DefaultLabel(LOCTEXT("TypeColumnHeaderName", "Source Type")) - + SHeaderRow::Column(ProviderPollUI::MachineColumnName) - .FillWidth(43.0f) - .DefaultLabel(LOCTEXT("MachineColumnHeaderName", "Source Machine")) - ) - ] + .WidthOverride(200) + [ + SNew(SVerticalBox) + + SVerticalBox::Slot() + .AutoHeight() + [ + SNew(SHorizontalBox) + + SHorizontalBox::Slot() + .HAlign(HAlign_Left) + .FillWidth(0.5f) + [ + SNew(STextBlock) + .Text(LOCTEXT("UDPAddress", "Network Address:Port")) + ] + + SHorizontalBox::Slot() + .HAlign(HAlign_Fill) + .FillWidth(0.5f) + [ + SAssignNew(m_NetworkAddress, SEditableTextBox) + .Text(FText::FromString(Endpoint.ToString())) + .OnTextCommitted(this, &SVirtualProductionSourceEditor::OnEndpointChanged) + ] + ] + + SVerticalBox::Slot() + .HAlign(HAlign_Right) + .AutoHeight() + [ + SAssignNew(ListView, SListView) + .ListItemsSource(&PollData) + .SelectionMode(ESelectionMode::SingleToggle) + .OnGenerateRow(this, &SVirtualProductionSourceEditor::MakeSourceListViewWidget) + .OnSelectionChanged(this, &SVirtualProductionSourceEditor::OnSourceListSelectionChanged) + .HeaderRow + ( + SNew(SHeaderRow) + + SHeaderRow::Column(ProviderPollUI::TypeColumnName) + .FillWidth(43.0f) + .DefaultLabel(LOCTEXT("TypeColumnHeaderName", "Source Type")) + + SHeaderRow::Column(ProviderPollUI::MachineColumnName) + .FillWidth(43.0f) + .DefaultLabel(LOCTEXT("MachineColumnHeaderName", "Source Machine")) + ) + ] + ] ]; } @@ -97,8 +131,9 @@ void SVirtualProductionSourceEditor::Tick(const FGeometry& AllottedGeometry, con const double CurrentTickTime = FPlatformTime::Seconds(); if (CurrentTickTime - LastTickTime > 1.f) { + bool bIsValidProvider = true; #if ENGINE_MAJOR_VERSION == 5 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 24) - FProviderPollResult *result = new FProviderPollResult(FMessageAddress::NewAddress(), FString("Studio"), FString(""), 0.0); + FProviderPollResult *result = new FProviderPollResult(FMessageAddress::NewAddress(), FString("Studio"), FString(""), 0.0, bIsValidProvider); #else FProviderPollResult* result = new FProviderPollResult(FMessageAddress::NewAddress(), FString("Studio"), FString("")); #endif @@ -123,7 +158,35 @@ TSharedRef SVirtualProductionSourceEditor::MakeSourceListViewWidget(F void SVirtualProductionSourceEditor::OnSourceListSelectionChanged(FProviderPollResultPtr PollResult, ESelectInfo::Type SelectionType) { SelectedResult = PollResult; - OnSourceSelected.ExecuteIfBound(SelectedResult); + + TSharedPtr address = m_NetworkAddress.Pin(); + if (address.IsValid()) + { + FIPv4Endpoint Endpoint; + if (FIPv4Endpoint::Parse(address->GetText().ToString(), Endpoint)) + { + SCreationInfo info{ + Endpoint + }; + + OnSourceSelected.ExecuteIfBound(info, SelectedResult); + } + } +} + +void SVirtualProductionSourceEditor::OnEndpointChanged(const FText& NewValue, ETextCommit::Type) +{ + TSharedPtr address = m_NetworkAddress.Pin(); + if (address.IsValid()) + { + FIPv4Endpoint Endpoint; + if (!FIPv4Endpoint::Parse(NewValue.ToString(), Endpoint)) + { + Endpoint.Address = FIPv4Address::Any; + Endpoint.Port = 14043; + address->SetText(FText::FromString(Endpoint.ToString())); + } + } } #undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.h b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.h index 105c641..6461be1 100644 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.h +++ b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceEditor.h @@ -18,29 +18,34 @@ class VirtualProductionSourceEditor #include "IMessageContext.h" #include "MessageEndpoint.h" #include "Widgets/DeclarativeSyntaxSupport.h" -//#include "VPStreamingNetwork.h" -#include "SmartsuitReceiver.h" #include "VirtualProductionFrame.h" #include "Misc/Guid.h" #include "LiveLink/Public/LiveLinkMessageBusFinder.h" +#include "Interfaces/IPv4/IPv4Endpoint.h" -//struct FLiveLinkPongMessage; struct FMessageAddress; struct FProviderPollResult; class ITableRow; class STableViewBase; +class SEditableTextBox; -//typedef TSharedPtr FProviderPollResultPtr; +struct SCreationInfo +{ + FIPv4Endpoint m_Address; + bool m_UseLZ4Compression; // TODO: +}; -DECLARE_DELEGATE_OneParam(FOnVirtualProductionSourceSelected, FProviderPollResultPtr); class SVirtualProductionSourceEditor : public SCompoundWidget { +public: + DECLARE_DELEGATE_TwoParams(FOnVirtualProductionSourceSelected, SCreationInfo, FProviderPollResultPtr); + SLATE_BEGIN_ARGS(SVirtualProductionSourceEditor){} SLATE_EVENT(FOnVirtualProductionSourceSelected, OnSourceSelected) SLATE_END_ARGS() - ~SVirtualProductionSourceEditor(); + virtual ~SVirtualProductionSourceEditor(); void Construct(const FArguments& Args); @@ -53,8 +58,9 @@ class SVirtualProductionSourceEditor : public SCompoundWidget virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime); private: + void OnEndpointChanged(const FText& NewValue, ETextCommit::Type); - //void HandlePongMessage(const FLiveLinkPongMessage& Message, const TSharedRef& Context); + TWeakPtr m_NetworkAddress; TSharedRef MakeSourceListViewWidget(FProviderPollResultPtr PollResult, const TSharedRef& OwnerTable) const; @@ -68,14 +74,10 @@ class SVirtualProductionSourceEditor : public SCompoundWidget FOnVirtualProductionSourceSelected OnSourceSelected; - //TSharedPtr MessageEndpoint; - FGuid CurrentPollRequest; // Time since our UI was last ticked, allow us to refresh if we haven't been onscreen for a while double LastTickTime; - ARokokoReceiver *receiver; - //VPStreamingNetwork *VPnet; FVirtualProductionFrame *VPFrame; }; \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.cpp b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.cpp index 8756ca4..f960754 100644 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.cpp +++ b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.cpp @@ -5,6 +5,7 @@ #include "VirtualProductionSourceEditor.h" #include "LiveLinkMessageBusFinder.h" #include "Features/IModularFeatures.h" +#include "Interfaces/IPv4/IPv4Endpoint.h" #define LOCTEXT_NAMESPACE "VirtualProductionSourceFactory" @@ -21,7 +22,7 @@ FText UVirtualProductionSourceFactory::GetSourceTooltip() const TSharedPtr UVirtualProductionSourceFactory::BuildCreationPanel(FOnLiveLinkSourceCreated OnLiveLinkSourceCreated) const { return SNew(SVirtualProductionSourceEditor) - .OnSourceSelected(FOnVirtualProductionSourceSelected::CreateUObject(this, &UVirtualProductionSourceFactory::OnSourceSelected, OnLiveLinkSourceCreated)); + .OnSourceSelected(SVirtualProductionSourceEditor::FOnVirtualProductionSourceSelected::CreateUObject(this, &UVirtualProductionSourceFactory::OnSourceSelected, OnLiveLinkSourceCreated)); } UVirtualProductionSourceFactory::EMenuType UVirtualProductionSourceFactory::GetMenuType() const @@ -39,7 +40,7 @@ UVirtualProductionSourceFactory::EMenuType UVirtualProductionSourceFactory::GetM return EMenuType::Disabled; } -void UVirtualProductionSourceFactory::OnSourceSelected(FProviderPollResultPtr SelectedSource, FOnLiveLinkSourceCreated InOnLiveLinkSourceCreated) const +void UVirtualProductionSourceFactory::OnSourceSelected(SCreationInfo info, FProviderPollResultPtr SelectedSource, FOnLiveLinkSourceCreated InOnLiveLinkSourceCreated) const { if (SelectedSource.IsValid()) { @@ -67,7 +68,7 @@ void UVirtualProductionSourceFactory::OnSourceSelected(FProviderPollResultPtr Se } #endif - TSharedPtr SharedPtr = MakeShared(FText::FromString(SelectedSource->Name), FText::FromString(SelectedSource->MachineName), SelectedSource->Address); + TSharedPtr SharedPtr = MakeShared(info.m_Address, FText::FromString(SelectedSource->Name), FText::FromString(SelectedSource->MachineName), SelectedSource->Address); FVirtualProductionSource::SetInstance(SharedPtr); FString ConnectionString = FString::Printf(TEXT("Name=\"%s\""), *SelectedSource->Name); InOnLiveLinkSourceCreated.ExecuteIfBound(SharedPtr, MoveTemp(ConnectionString)); @@ -81,8 +82,19 @@ TSharedPtr UVirtualProductionSourceFactory::CreateSource(const { return TSharedPtr(); } + FIPv4Endpoint DeviceEndPoint; + if (!FIPv4Endpoint::Parse(ConnectionString, DeviceEndPoint)) + { + // use default address, failed to parse connection address + UE_LOG(LogTemp, Warning, TEXT("use default address, failed to parse connection address")); + DeviceEndPoint.Address = FIPv4Address::Any; + DeviceEndPoint.Port = 14043; + } + + TSharedPtr newSource = MakeShared(DeviceEndPoint, FText::FromString(Name), FText::GetEmpty(), FMessageAddress()); + FVirtualProductionSource::SetInstance(newSource); - return MakeShared(FText::FromString(Name), FText::GetEmpty(), FMessageAddress()); + return newSource; } #undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.h b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.h index 686ee80..a79c975 100644 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.h +++ b/Plugins/Smartsuit/Source/SmartsuitEditor/Private/VirtualProductionSourceFactory.h @@ -5,6 +5,7 @@ #include "CoreMinimal.h" #include "LiveLinkSourceFactory.h" #include "LiveLinkMessageBusFinder.h" +#include "VirtualProductionSourceEditor.h" #include "VirtualProductionSourceFactory.generated.h" class SVirtualProductionSourceEditor; @@ -22,5 +23,5 @@ class UVirtualProductionSourceFactory : public ULiveLinkSourceFactory virtual TSharedPtr CreateSource(const FString& ConnectionString) const override; private: - void OnSourceSelected(FProviderPollResultPtr SelectedSource, FOnLiveLinkSourceCreated OnLiveLinkSourceCreated) const; + void OnSourceSelected(SCreationInfo info, FProviderPollResultPtr SelectedSource, FOnLiveLinkSourceCreated OnLiveLinkSourceCreated) const; }; diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Public/AnimGraphNode_ModifyFaceCurves.h b/Plugins/Smartsuit/Source/SmartsuitEditor/Public/AnimGraphNode_ModifyFaceCurves.h deleted file mode 100644 index 5971a19..0000000 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Public/AnimGraphNode_ModifyFaceCurves.h +++ /dev/null @@ -1,50 +0,0 @@ -//// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. -// -//#pragma once -// -//#include "CoreMinimal.h" -//#include "UObject/ObjectMacros.h" -//#include "AnimGraphNode_Base.h" -//#include "AnimNode_ModifyFaceCurves.h" -//#include "AnimGraphNode_ModifyFaceCurves.generated.h" -// -//class FMenuBuilder; -// -///** Easy way to modify curve values on a pose */ -//UCLASS(MinimalAPI) -//class UAnimGraphNode_ModifyFaceCurves : public UAnimGraphNode_Base -//{ -// GENERATED_BODY() -// -// UPROPERTY(EditAnywhere, Category=Settings) -// FAnimNode_ModifyFaceCurves Node; -// -//public: -// UAnimGraphNode_ModifyFaceCurves(); -// -// // UEdGraphNode interface -// virtual FText GetTooltipText() const override; -// virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; -// // End of UEdGraphNode interface -// -// // UAnimGraphNode_Base interface -// virtual FString GetNodeCategory() const override; -// virtual void CustomizePinData(UEdGraphPin* Pin, FName SourcePropertyName, int32 ArrayIndex) const override; -// // End of UAnimGraphNode_Base interface -// -// // UK2Node interface -// virtual void GetNodeContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const override; -// // End of UK2Node interface -// -//private: -// /** Remove a curve pin with the given name */ -// void RemoveCurvePin(FName CurveName); -// /** Add a curve pin with the given name */ -// void AddCurvePin(FName CurveName); -// /** Create submenu with options for curves to add */ -// void GetAddCurveMenuActions(FMenuBuilder& MenuBuilder) const; -// /** Create submenu with options for curves to remove */ -// void GetRemoveCurveMenuActions(FMenuBuilder& MenuBuilder) const; -// /** Returns list of curves we have not added yet */ -// TArray GetCurvesToAdd() const; -//}; diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/Public/SmartsuitPose.h b/Plugins/Smartsuit/Source/SmartsuitEditor/Public/SmartsuitPose.h index c5e1bf1..b6e7637 100644 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/Public/SmartsuitPose.h +++ b/Plugins/Smartsuit/Source/SmartsuitEditor/Public/SmartsuitPose.h @@ -30,6 +30,8 @@ class SMARTSUITEDITOR_API USmartsuitPose : public UAnimGraphNode_SkeletalControl //virtual FEditorModeID GetEditorMode() const override; virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override; virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override; + + virtual void PreloadRequiredAssets() override; // End of UAnimGraphNode_Base interface // UAnimGraphNode_SkeletalControlBase interface diff --git a/Plugins/Smartsuit/Source/SmartsuitEditor/SmartsuitEditor.Build.cs b/Plugins/Smartsuit/Source/SmartsuitEditor/SmartsuitEditor.Build.cs index f2171e1..a9b1b48 100644 --- a/Plugins/Smartsuit/Source/SmartsuitEditor/SmartsuitEditor.Build.cs +++ b/Plugins/Smartsuit/Source/SmartsuitEditor/SmartsuitEditor.Build.cs @@ -42,7 +42,9 @@ public SmartsuitEditor(ReadOnlyTargetRules Target) : base(Target) "AnimGraphRuntime", "Smartsuit", "LiveLinkInterface", - "LiveLink" + "LiveLink", + "LiveLinkAnimationCore", + "Networking" // ... add other public dependencies that you statically link with here ... } ); @@ -57,7 +59,8 @@ public SmartsuitEditor(ReadOnlyTargetRules Target) : base(Target) "SlateCore", "Slate", - "LiveLinkInterface" + "LiveLinkInterface", + "Networking" //"ToolMenus" } ); diff --git a/README.md b/README.md index 6548074..0f4189a 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,13 @@ This plugin let's you stream animation data from Rokoko Studio into Unreal Engin --- ## Requirements -- Unreal Engine 4.27.2 -- Rokoko Studio 1.19.0b +- Unreal Engine 5.x +- Rokoko Studio or Rokoko Studio Legacy (starting from 1.19.0b) ## Features - Live stream data: * Up to five actors that can all include both body, face (52 blendshapes) and finger data at the same time. + * Character data * Camera data * Props data - Control Rokoko Studio from within Unreal Engine @@ -45,9 +46,9 @@ _Note: You can skip this step by getting the plugin from the Unreal Engine marke https://unrealengine.com/marketplace/en-US/product/smartsuit-plugin -For the plugin to work at its current state you need this development build of Rokoko Studio: [https://developer.cloud.unity3d.com/share/share.html?shareId=-koPxa5S4I](https://developer.cloud.unity3d.com/share/share.html?shareId=-koPxa5S4I) +For the plugin to work at its current state you need this development buid of Rokoko Studio: [https://developer.cloud.unity3d.com/share/share.html?shareId=-koPxa5S4I](https://developer.cloud.unity3d.com/share/share.html?shareId=-koPxa5S4I) -Then you need to download the Studio Live plugin and install it manually by moving it into your Unreal project's **plugins folder:** [https://github.com/Rokoko/rokoko-studio-live-unreal-engine/tree/4.25_jsonv3/Plugins](https://github.com/Rokoko/rokoko-studio-live-unreal-engine/tree/4.25_jsonv3/Plugins) +Then you need to download the Studio Live plugin and install it manualy by moving it into your Unreal project's **plugins folder:** [https://github.com/Rokoko/rokoko-studio-live-unreal-engine/tree/4.25_jsonv3/Plugins](https://github.com/Rokoko/rokoko-studio-live-unreal-engine/tree/4.25_jsonv3/Plugins) _Note: If your unreal project doesn't have a plugins folder, then create a folder called "Plugins"._ @@ -59,11 +60,11 @@ Open up Visual Studio Installer and click on Individual Components. Then search -If it still doesn't work install these optional packages under **desktop development with C++.** +If it still doesn't work install theise optional packages under **desktop development with C++.** -When the unreal project is open, go into settings → Plugins and search for **Rokoko Studio Live** and make sure the enable mark is on. If you clicked enable you have to restart the unreal project. +When the unreal project is open, go into settings → Plugins and search for **Rokoko Studio Live** and make sure the enable mark is on. If you clicked enable you have to restart the urneal project. **Setting up the character inside Unreal Engine 4.25** diff --git a/UnrealSampleProject.uproject b/UnrealSampleProject.uproject index d022c2c..04a6db6 100644 --- a/UnrealSampleProject.uproject +++ b/UnrealSampleProject.uproject @@ -1,42 +1,45 @@ -{ - "FileVersion": 3, - "EngineAssociation": "4.27", - "Category": "", - "Description": "", - "Modules": [ - { - "Name": "UnrealSampleProject", - "Type": "Runtime", - "LoadingPhase": "Default", - "AdditionalDependencies": [ - "LiveLinkInterface", - "CoreUObject" - ] - } - ], - "Plugins": [ - { - "Name": "VirtualCamera", - "Enabled": true - }, - { - "Name": "LiveLink", - "Enabled": true - }, - { - "Name": "Smartsuit", - "Enabled": true, - "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/7e20fe7d4247410cb4f7d3e162d61c21" - }, - { - "Name": "SteamVR", - "Enabled": false, - "SupportedTargetPlatforms": [ - "Win32", - "Win64", - "Linux", - "Mac" - ] - } - ] +{ + "FileVersion": 3, + "EngineAssociation": "5.2", + "Category": "", + "Description": "", + "Modules": [ + { + "Name": "UnrealSampleProject", + "Type": "Runtime", + "LoadingPhase": "Default", + "AdditionalDependencies": [ + "LiveLinkInterface", + "CoreUObject" + ] + } + ], + "Plugins": [ + { + "Name": "VirtualCamera", + "Enabled": true, + "SupportedTargetPlatforms": [ + "Win64", + "Linux" + ] + }, + { + "Name": "LiveLink", + "Enabled": true + }, + { + "Name": "Smartsuit", + "Enabled": true, + "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/7e20fe7d4247410cb4f7d3e162d61c21" + }, + { + "Name": "SteamVR", + "Enabled": false, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Mac" + ] + } + ] } \ No newline at end of file diff --git a/build_plugin.bat b/build_plugin.bat new file mode 100644 index 0000000..cc43be4 --- /dev/null +++ b/build_plugin.bat @@ -0,0 +1,16 @@ +set PLUGINNAME=Smartsuit +set ENGINEDIR=H:\Program Files\Epic Games\UE_5.2 +set RUNUAT=%ENGINEDIR%\Engine\Build\BatchFiles\RunUAT.bat +set package_dir=%~dp0Build\Plugins\%PLUGINNAME% +set plugin_dir=%~dp0Plugins\%PLUGINNAME% + +rmdir %package_dir% /s /q + +call "%RUNUAT%" BuildPlugin -Plugin="%plugin_dir%\%PLUGINNAME%.uplugin" -Package=%package_dir% -Rocket + +rmdir %plugin_dir%\Binaries /s /q +rmdir %plugin_dir%\Intermediate /s /q + +Robocopy "%package_dir%\Binaries" "%plugin_dir%\Binaries" /E + +pause \ No newline at end of file