Skip to content
Snippets Groups Projects
Commit 7e7a709d authored by David Gilbert's avatar David Gilbert :bug:
Browse files

- Added LiveLink Plugin Dependency to uplugin file.

- Fixed two missing includes that were throwing an error on my end.
- Added a general settings class to the toolkit, populated with only a LiveLink preset for now.
- Added functionality to the module to load and apply the default preset, added some guards to not do it twice (ART plugin crashes if that is done).
- Added LiveLink functionality to the Tracked Components.
- Added a change to the VRPawnMovement that manages to keep the rotation of the collider vertical even in the editor with LiveLink enabled.
- Added cave config assets (ips public).
- Added an example map that already includes the pawn with livelink + the cave root actor (no livelink yet there, todo).
- Added a (temporary) SteamVRPreset.uasset for LiveLink for testing purposes.
parent 3a95390a
No related branches found
No related tags found
2 merge requests!13Draft: Improve walking implementation,!9Draft: LiveLink capabilities and 4.27 config assets.
Showing
with 7075 additions and 58 deletions
File added
This diff is collapsed.
File added
This diff is collapsed.
File added
File added
...@@ -48,6 +48,10 @@ ...@@ -48,6 +48,10 @@
{ {
"Name": "nDisplay", "Name": "nDisplay",
"Enabled": true "Enabled": true
},
{
"Name": "LiveLink",
"Enabled": true
} }
] ]
} }
\ No newline at end of file
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "Misc/Optional.h" #include "Misc/Optional.h"
#include "DrawDebugHelpers.h" #include "DrawDebugHelpers.h"
#include "Components/WidgetComponent.h" #include "Components/WidgetComponent.h"
#include "UObject/ConstructorHelpers.h"
DEFINE_LOG_CATEGORY(LogVRInteractionComponent); DEFINE_LOG_CATEGORY(LogVRInteractionComponent);
......
...@@ -3,19 +3,20 @@ ...@@ -3,19 +3,20 @@
#include "Pawn/UniversalTrackedComponent.h" #include "Pawn/UniversalTrackedComponent.h"
#include "Camera/CameraComponent.h" #include "Camera/CameraComponent.h"
#include "Utility/VirtualRealityUtilities.h" #include "Utility/VirtualRealityUtilities.h"
#include "Roles/LiveLinkTransformTypes.h"
#include "ILiveLinkClient.h"
DEFINE_LOG_CATEGORY(LogUniversalTrackedComponent);
// Sets default values for this component's properties // Sets default values for this component's properties
UUniversalTrackedComponent::UUniversalTrackedComponent() UUniversalTrackedComponent::UUniversalTrackedComponent()
{ {
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true; PrimaryComponentTick.bCanEverTick = true;
PrimaryComponentTick.TickGroup = ETickingGroup::TG_PrePhysics;
} }
void UUniversalTrackedComponent::SetShowDeviceModel(const bool bShowControllerModel) void UUniversalTrackedComponent::SetShowDeviceModel(const bool bShowControllerModel)
{ {
if (!UVirtualRealityUtilities::IsHeadMountedMode() || TrackedComponent == nullptr) return; if (!UVirtualRealityUtilities::IsHeadMountedMode() || TrackedComponent == nullptr) return;
...@@ -33,11 +34,13 @@ void UUniversalTrackedComponent::BeginPlay() ...@@ -33,11 +34,13 @@ void UUniversalTrackedComponent::BeginPlay()
if (ProxyType == ETrackedComponentType::TCT_HEAD) if (ProxyType == ETrackedComponentType::TCT_HEAD)
{ {
TrackedComponent = GetOwner()->FindComponentByClass<UCameraComponent>(); TrackedComponent = GetOwner()->FindComponentByClass<UCameraComponent>();
}else }
else
{ {
/* Spawn Motion Controller Components in HMD Mode*/ /* Spawn Motion Controller Components in HMD Mode*/
UMotionControllerComponent* MotionController = Cast<UMotionControllerComponent>(GetOwner()->AddComponentByClass(UMotionControllerComponent::StaticClass(), false, FTransform::Identity, false)); UMotionControllerComponent* MotionController = Cast<UMotionControllerComponent>(GetOwner()->AddComponentByClass(UMotionControllerComponent::StaticClass(), false, FTransform::Identity, false));
// Todo: If bAlwaysUseLiveLinkTracking is true, those should be sourced by LiveLink
switch(ProxyType) switch(ProxyType)
{ {
case ETrackedComponentType::TCT_TRACKER_1: case ETrackedComponentType::TCT_TRACKER_1:
...@@ -47,6 +50,7 @@ void UUniversalTrackedComponent::BeginPlay() ...@@ -47,6 +50,7 @@ void UUniversalTrackedComponent::BeginPlay()
MotionController->SetTrackingMotionSource(FName("Special_2")); MotionController->SetTrackingMotionSource(FName("Special_2"));
break; break;
case ETrackedComponentType::TCT_RIGHT_HAND: case ETrackedComponentType::TCT_RIGHT_HAND:
MotionController->SetTrackingMotionSource(FName("Right"));
MotionController->SetTrackingMotionSource(FName("Right")); MotionController->SetTrackingMotionSource(FName("Right"));
break; break;
case ETrackedComponentType::TCT_LEFT_HAND: case ETrackedComponentType::TCT_LEFT_HAND:
...@@ -58,7 +62,13 @@ void UUniversalTrackedComponent::BeginPlay() ...@@ -58,7 +62,13 @@ void UUniversalTrackedComponent::BeginPlay()
TrackedComponent = MotionController; TrackedComponent = MotionController;
} }
}else if(UVirtualRealityUtilities::IsDesktopMode()){ if (TrackedComponent)
AttachToComponent(Cast<USceneComponent>(TrackedComponent), FAttachmentTransformRules::SnapToTargetIncludingScale);
}
// Check for bAlwaysUseLiveLinkTracking here too in case we want to use LiveLink in Editor/Desktop mode.
else if (UVirtualRealityUtilities::IsDesktopMode() && !bAlwaysUseLiveLinkTracking)
{
switch(ProxyType) switch(ProxyType)
{ {
case ETrackedComponentType::TCT_RIGHT_HAND: case ETrackedComponentType::TCT_RIGHT_HAND:
...@@ -71,40 +81,84 @@ void UUniversalTrackedComponent::BeginPlay() ...@@ -71,40 +81,84 @@ void UUniversalTrackedComponent::BeginPlay()
TrackedComponent = GetOwner()->GetRootComponent(); TrackedComponent = GetOwner()->GetRootComponent();
break; break;
} }
if (TrackedComponent) AttachToComponent(Cast<USceneComponent>(TrackedComponent), FAttachmentTransformRules::SnapToTargetIncludingScale);
}
// If we're either in the cave or using LiveLink, set it up here. Might want to differentiate between the two cases later on,
// for now both should be equivalent. Maybe set up some additional stuff automatically like presets etc.
else if (UVirtualRealityUtilities::IsRoomMountedMode() || bAlwaysUseLiveLinkTracking)
{
// Instead of using the clumsy LiveLinkComponentController, we just directly check the LiveLink Data in Tick later on.
// Set up this Component to Tick, and check weather Subject and Role is set.
TrackedComponent = this;
bUseLiveLinkTracking = true; // override this in case someone forgot to set it.
if (SubjectRepresentation.Subject.IsNone() || SubjectRepresentation.Role == nullptr)
{
UE_LOG(LogUniversalTrackedComponent, Error, TEXT("UUniversalTrackedComponent::BeginPlay(): No LiveLink Subject or Role is set! Tracking will not work"));
}
SetComponentTickEnabled(true);
}
} }
if(TrackedComponent) AttachToComponent(TrackedComponent, FAttachmentTransformRules::SnapToTargetIncludingScale); void UUniversalTrackedComponent::PostLoad()
{
Super::PostLoad();
// This is required in PostLoad (and theoretically in OnComponentCreated too) because just setting this in
// the constructor or PostInitializeProperties will load the CDO's property values.
// Just calling it in BeginPlay() won't let us see the LiveLink preview in the editor.
bTickInEditor = bAlwaysUseLiveLinkTracking;
PrimaryComponentTick.bStartWithTickEnabled = bAlwaysUseLiveLinkTracking;
}
#if WITH_EDITOR
void UUniversalTrackedComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
// Catch the change to bAlwaysUseLiveLinkTracking, and disable/enable tick respectively for in-editor tracking.
const FName PropertyName(PropertyChangedEvent.GetPropertyName());
if(PropertyName == GET_MEMBER_NAME_CHECKED(UUniversalTrackedComponent, bAlwaysUseLiveLinkTracking))
{
bTickInEditor = bAlwaysUseLiveLinkTracking;
SetComponentTickEnabled(bAlwaysUseLiveLinkTracking);
}
Super::PostEditChangeProperty(PropertyChangedEvent);
} }
#endif
void UUniversalTrackedComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) void UUniversalTrackedComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{ {
Super::TickComponent(DeltaTime, TickType, ThisTickFunction); Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if(TrackedComponent) return; /* Already attached */ // Check whether we need to update the component with new LiveLink data. This is either the case if
// nDisplay uses bUseLiveLinkTracking (Play Mode), or if bAlwaysUseLiveLinkTracking is true, then we tick both in Play Mode and Editor.
const bool bEvaluateLiveLink = bUseLiveLinkTracking || bAlwaysUseLiveLinkTracking;
/* Test for presence every frame and add as soon as they are there */ if(!bEvaluateLiveLink || SubjectRepresentation.Subject.IsNone() || SubjectRepresentation.Role == nullptr)
if (UVirtualRealityUtilities::IsRoomMountedMode())
{
switch(ProxyType)
{ {
case ETrackedComponentType::TCT_RIGHT_HAND: return;
case ETrackedComponentType::TCT_LEFT_HAND:
TrackedComponent = GetComponentForSelectedAttachment(AttachementType);
break;
case ETrackedComponentType::TCT_HEAD:
TrackedComponent = UVirtualRealityUtilities::GetNamedClusterComponent(ENamedClusterComponent::NCC_SHUTTERGLASSES);
break;
case ETrackedComponentType::TCT_TRACKER_1:
case ETrackedComponentType::TCT_TRACKER_2:
TrackedComponent = GetOwner()->GetRootComponent();
break;
} }
if(TrackedComponent) AttachToComponent(TrackedComponent, FAttachmentTransformRules::SnapToTargetIncludingScale); // Get the LiveLink interface and evaluate the current existing frame data for the given Subject and Role.
ILiveLinkClient& LiveLinkClient = IModularFeatures::Get().GetModularFeature<ILiveLinkClient>(ILiveLinkClient::ModularFeatureName);
FLiveLinkSubjectFrameData SubjectData;
const bool bHasValidData = LiveLinkClient.EvaluateFrame_AnyThread(SubjectRepresentation.Subject, SubjectRepresentation.Role, SubjectData);
if(!bHasValidData)
return;
// Assume we are using a Transform Role to track the components! This is a slightly dangerous assumption, and could be further improved.
const FLiveLinkTransformStaticData* StaticData = SubjectData.StaticData.Cast<FLiveLinkTransformStaticData>();
const FLiveLinkTransformFrameData* FrameData = SubjectData.FrameData.Cast<FLiveLinkTransformFrameData>();
if (StaticData && FrameData)
{
// Finally, apply the transform to this component according to the static data.
ApplyLiveLinkTransform(FrameData->Transform, *StaticData);
} }
} }
UMotionControllerComponent* UUniversalTrackedComponent::GetMotionControllerComponentByMotionSource(EControllerHand MotionSource) UMotionControllerComponent* UUniversalTrackedComponent::GetMotionControllerComponentByMotionSource(EControllerHand MotionSource) const
{ {
TArray<UActorComponent*> Components; TArray<UActorComponent*> Components;
GetOwner()->GetComponents(UMotionControllerComponent::StaticClass(),Components); GetOwner()->GetComponents(UMotionControllerComponent::StaticClass(),Components);
...@@ -123,19 +177,41 @@ UMotionControllerComponent* UUniversalTrackedComponent::GetMotionControllerCompo ...@@ -123,19 +177,41 @@ UMotionControllerComponent* UUniversalTrackedComponent::GetMotionControllerCompo
); );
} }
USceneComponent* UUniversalTrackedComponent::GetComponentForSelectedAttachment(EAttachementType AttachmentType) const void UUniversalTrackedComponent::ApplyLiveLinkTransform(const FTransform& Transform, const FLiveLinkTransformStaticData& StaticData)
{ {
switch (AttachmentType) if (bUseLocation && StaticData.bIsLocationSupported)
{ {
case EAttachementType::AT_NONE: return nullptr; if (bWorldTransform)
case EAttachementType::AT_HANDTARGET: {
if(ProxyType == ETrackedComponentType::TCT_RIGHT_HAND) return UVirtualRealityUtilities::GetNamedClusterComponent(ENamedClusterComponent::NCC_CAVE_RHT); this->SetWorldLocation(Transform.GetLocation(), bSweep, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::ResetPhysics);
if(ProxyType == ETrackedComponentType::TCT_LEFT_HAND) return UVirtualRealityUtilities::GetNamedClusterComponent(ENamedClusterComponent::NCC_CAVE_LHT); }
break; else
case EAttachementType::AT_FLYSTICK: {
return UVirtualRealityUtilities::GetNamedClusterComponent(ENamedClusterComponent::NCC_FLYSTICK); this->SetRelativeLocation(Transform.GetLocation(), bSweep, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::ResetPhysics);
break;
} }
return nullptr;
} }
if (bUseRotation && StaticData.bIsRotationSupported)
{
if (bWorldTransform)
{
this->SetWorldRotation(Transform.GetRotation(), bSweep, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::ResetPhysics);
}
else
{
this->SetRelativeRotation(Transform.GetRotation(), bSweep, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::ResetPhysics);
}
}
if (bUseScale && StaticData.bIsScaleSupported)
{
if (bWorldTransform)
{
this->SetWorldScale3D(Transform.GetScale3D());
}
else
{
this->SetRelativeScale3D(Transform.GetScale3D());
}
}
}
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "Pawn/VirtualRealityPawn.h" #include "Pawn/VirtualRealityPawn.h"
#include "GameFramework/InputSettings.h" #include "GameFramework/InputSettings.h"
#include "GameFramework/PlayerInput.h" #include "GameFramework/PlayerInput.h"
#include "Pawn/UniversalTrackedComponent.h" #include "Pawn/UniversalTrackedComponent.h"
...@@ -21,7 +18,7 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial ...@@ -21,7 +18,7 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial
AutoPossessPlayer = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events. AutoPossessPlayer = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events.
SetRootComponent(CreateDefaultSubobject<USceneComponent>(TEXT("Root"))); SetRootComponent(CreateDefaultSubobject<USceneComponent>(TEXT("Origin")));
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera")); CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
CameraComponent->SetupAttachment(RootComponent); CameraComponent->SetupAttachment(RootComponent);
...@@ -31,9 +28,13 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial ...@@ -31,9 +28,13 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial
Head->ProxyType = ETrackedComponentType::TCT_HEAD; Head->ProxyType = ETrackedComponentType::TCT_HEAD;
Head->SetupAttachment(RootComponent); Head->SetupAttachment(RootComponent);
CapsuleRotationFix = CreateDefaultSubobject<USceneComponent>(TEXT("CapsuleRotationFix"));
CapsuleRotationFix->SetUsingAbsoluteRotation(true);
CapsuleRotationFix->SetupAttachment(Head);
PawnMovement = CreateDefaultSubobject<UVRPawnMovement>(TEXT("Pawn Movement")); PawnMovement = CreateDefaultSubobject<UVRPawnMovement>(TEXT("Pawn Movement"));
PawnMovement->SetUpdatedComponent(RootComponent); PawnMovement->SetUpdatedComponent(RootComponent);
PawnMovement->SetHeadComponent(Head); PawnMovement->SetHeadComponent(CapsuleRotationFix);
RightHand = CreateDefaultSubobject<UUniversalTrackedComponent>(TEXT("Right Hand")); RightHand = CreateDefaultSubobject<UUniversalTrackedComponent>(TEXT("Right Hand"));
RightHand->ProxyType = ETrackedComponentType::TCT_RIGHT_HAND; RightHand->ProxyType = ETrackedComponentType::TCT_RIGHT_HAND;
......
#include "RWTHVRToolkit.h" #include "RWTHVRToolkit.h"
#include "ILiveLinkClient.h"
#include "LiveLinkClient.h"
#include "RWTHVRToolkitSettings.h"
#if WITH_EDITOR
#include "ISettingsModule.h"
#include "ISettingsSection.h"
#endif
#define LOCTEXT_NAMESPACE "FRWTHVRToolkitModule" #define LOCTEXT_NAMESPACE "FRWTHVRToolkitModule"
void FRWTHVRToolkitModule::StartupModule () void FRWTHVRToolkitModule::StartupModule ()
{ {
ConsoleActivation.Register(); ConsoleActivation.Register();
FCoreDelegates::OnFEngineLoopInitComplete.AddRaw(this, &FRWTHVRToolkitModule::OnEngineLoopInitComplete);
#if WITH_EDITOR
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
{
ISettingsSectionPtr SettingsSection = SettingsModule->RegisterSettings(
"Project", "Plugins", "RWTH VR Toolkit",
LOCTEXT("RWTHVRToolkitSettingsName", "RWTH VR Toolkit"),
LOCTEXT("RWTHVRToolkitSettingsDescription", "Configure the RWTH VR Toolkit."),
GetMutableDefault<URWTHVRToolkitSettings>()
);
if (SettingsSection.IsValid())
{
SettingsSection->OnModified().BindRaw(this, &FRWTHVRToolkitModule::HandleSettingsSaved);
}
}
#endif
} }
void FRWTHVRToolkitModule::ShutdownModule() void FRWTHVRToolkitModule::ShutdownModule()
{ {
ConsoleActivation.Unregister(); ConsoleActivation.Unregister();
#if WITH_EDITOR
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
{
SettingsModule->UnregisterSettings("Project", "Plugins", "RWTH VR Toolkit");
}
#endif
} }
void FRWTHVRToolkitModule::OnEngineLoopInitComplete()
{
ApplyDefaultPreset();
}
bool FRWTHVRToolkitModule::HandleSettingsSaved()
{
ApplyDefaultPreset();
return true;
}
void FRWTHVRToolkitModule::ApplyDefaultPreset()
{
ULiveLinkPreset* StartupPreset = GetDefault<URWTHVRToolkitSettings>()->DefaultLiveLinkPreset.LoadSynchronous();
if (StartupPreset != nullptr)
{
SetLiveLinkPreset(StartupPreset);
}
}
void FRWTHVRToolkitModule::SetLiveLinkPreset(ULiveLinkPreset* Preset)
{
// We should check for a currently applied preset/sources now, and if it includes the ART one.
// If it does, and is active, do not apply it again.
const FLiveLinkClient& LiveLinkClient = IModularFeatures::Get().GetModularFeature<FLiveLinkClient>(ILiveLinkClient::ModularFeatureName);
if (LiveLinkPreset == nullptr && LiveLinkClient.GetSources().Num() == 0 )
{
LiveLinkPreset = Preset;
LiveLinkPreset->ApplyToClient();
}
}
#undef LOCTEXT_NAMESPACE #undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FRWTHVRToolkitModule, RWTHVRToolkit) IMPLEMENT_MODULE(FRWTHVRToolkitModule, RWTHVRToolkit)
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "Interfaces/IHttpResponse.h" #include "Interfaces/IHttpResponse.h"
#include "HttpModule.h" #include "HttpModule.h"
#include "Misc/FileHelper.h"
#include "Runtime/ImageWrapper/Public/IImageWrapperModule.h" #include "Runtime/ImageWrapper/Public/IImageWrapperModule.h"
UExternalImage::UExternalImage(){} UExternalImage::UExternalImage(){}
......
...@@ -3,10 +3,15 @@ ...@@ -3,10 +3,15 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "LiveLinkRole.h"
#include "Components/SceneComponent.h" #include "Components/SceneComponent.h"
#include "MotionControllerComponent.h" #include "MotionControllerComponent.h"
#include "UniversalTrackedComponent.generated.h" #include "UniversalTrackedComponent.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogUniversalTrackedComponent, Log, All);
struct FLiveLinkTransformStaticData;
UENUM(BlueprintType) UENUM(BlueprintType)
enum class ETrackedComponentType : uint8 enum class ETrackedComponentType : uint8
{ {
...@@ -40,18 +45,83 @@ public: ...@@ -40,18 +45,83 @@ public:
// Sets default values for this component's properties // Sets default values for this component's properties
UUniversalTrackedComponent(); UUniversalTrackedComponent();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking") ETrackedComponentType ProxyType = ETrackedComponentType::TCT_HEAD; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking")
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking|nDisplay") EAttachementType AttachementType = EAttachementType::AT_NONE; ETrackedComponentType ProxyType = ETrackedComponentType::TCT_HEAD;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking|HMD", BlueprintSetter=SetShowDeviceModel) bool bShowDeviceModelInHMD = true;
/** Set whether LiveLink should always be enabled, even in the editor or desktop mode. Overrides bUseLiveLinkTracking.*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking")
bool bAlwaysUseLiveLinkTracking;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking|nDisplay")
EAttachementType AttachementType = EAttachementType::AT_NONE;
/** Set whether nDisplay should use LiveLink tracking. Requires a valid Subject Representation!*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking|nDisplay")
bool bUseLiveLinkTracking = true;
/** Set the LiveLink Subject Representation to be used by this component. */
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Tracking|nDisplay|LiveLink")
FLiveLinkSubjectRepresentation SubjectRepresentation;
/** Set the transform of the component in world space of in its local reference frame. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Tracking|nDisplay|LiveLink")
bool bWorldTransform = false;
/** Whether we should set the owning actor's location with the value coming from live link. */
UPROPERTY(EditAnywhere, Category = "Tracking|nDisplay|LiveLink")
bool bUseLocation = true;
/** Whether we should set the owning actor's rotation with the value coming from live link. */
UPROPERTY(EditAnywhere, Category = "Tracking|nDisplay|LiveLink")
bool bUseRotation = true;
/** Whether we should set the owning actor's scale with the value coming from live link. */
UPROPERTY(EditAnywhere, Category = "Tracking|nDisplay|LiveLink")
bool bUseScale = true;
/**
* Whether we sweep to the destination location, triggering overlaps along the way and stopping short of the target if blocked by something.
* Only the root component is swept and checked for blocking collision, child components move without sweeping. If collision is off, this has no effect.
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Tracking|nDisplay|LiveLink")
bool bSweep = false;
/**
* Whether we teleport the physics state (if physics collision is enabled for this object).
* If true, physics velocity for this object is unchanged (so ragdoll parts are not affected by change in location).
* If false, physics velocity is updated based on the change in position (affecting ragdoll parts).
* If CCD is on and not teleporting, this will affect objects along the entire sweep volume.
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Tracking|nDisplay|LiveLink")
bool bTeleport = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking|HMD", BlueprintSetter=SetShowDeviceModel)
bool bShowDeviceModelInHMD = true;
UFUNCTION(BlueprintSetter) UFUNCTION(BlueprintSetter)
void SetShowDeviceModel(const bool bShowControllerModel); void SetShowDeviceModel(const bool bShowControllerModel);
//~ Begin SceneComponent Interface
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void PostLoad() override;
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
//~ End SceneComponent Interface
private: private:
/**
* @brief Helper function that applies the LiveLink data to this component. Taken from the LiveLink Transform Controller.
* @param Transform Transform read from the LiveLink Client.
* @param StaticData Static data from the LiveLink Subject, defines what is and isn't supported.
* @return void
*/
void ApplyLiveLinkTransform(const FTransform& Transform, const FLiveLinkTransformStaticData& StaticData);
USceneComponent* TrackedComponent = nullptr; USceneComponent* TrackedComponent = nullptr;
UMotionControllerComponent* GetMotionControllerComponentByMotionSource(EControllerHand MotionSource); UMotionControllerComponent* GetMotionControllerComponentByMotionSource(EControllerHand MotionSource) const;
USceneComponent* GetComponentForSelectedAttachment(EAttachementType AttachmentType) const;
}; };
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "VRPawnMovement.h" #include "VRPawnMovement.h"
#include "VirtualRealityPawn.generated.h" #include "VirtualRealityPawn.generated.h"
class ULiveLinkComponentController;
/** /**
* *
*/ */
...@@ -29,6 +30,15 @@ public: ...@@ -29,6 +30,15 @@ public:
/* Movement */ /* Movement */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|Movement") UVRPawnMovement* PawnMovement; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|Movement") UVRPawnMovement* PawnMovement;
/** Workaround dummy component to prevent the Capsule from rotating in the editor, if LiveLink tracking is being used.
* This happens due to the rotation of the Capsule being set only while in Play Mode (instead of using e.g. absolute rotation).
* Additionally, there is an implicit race condition in Tick, due to LiveLink adjusting the parent's rotation, while the capsule
* then gets rotated back in Tick to be vertical. Depending on the order, LiveLink overrides the VRPawnMovement's rotation settings.
* The dummy seems to fix this, because its absolute rotation just catches all parent rotations and prevents them from
* overriding any of the capsules'.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn|Movement") USceneComponent* CapsuleRotationFix;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn|Movement") float BaseTurnRate = 45.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn|Movement") float BaseTurnRate = 45.0f;
/* CameraComponent */ /* CameraComponent */
......
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include "Fixes/ActivateConsoleInShipping.h" #include "Fixes/ActivateConsoleInShipping.h"
class ULiveLinkPreset;
class FRWTHVRToolkitModule : public IModuleInterface class FRWTHVRToolkitModule : public IModuleInterface
{ {
public: public:
virtual void StartupModule () override; virtual void StartupModule () override;
virtual void ShutdownModule() override; virtual void ShutdownModule() override;
void SetLiveLinkPreset(ULiveLinkPreset* Preset);
private: private:
void OnEngineLoopInitComplete();
bool HandleSettingsSaved();
void ApplyDefaultPreset();
FActivateConsoleInShipping ConsoleActivation; FActivateConsoleInShipping ConsoleActivation;
ULiveLinkPreset* LiveLinkPreset = nullptr;
}; };
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreTypes.h"
#include "UObject/Object.h"
#include "UObject/ObjectMacros.h"
#include "Engine/EngineTypes.h"
#include "Templates/SubclassOf.h"
#include "LiveLinkPreset.h"
#include "RWTHVRToolkitSettings.generated.h"
/**
* Settings for LiveLink.
*/
UCLASS(config=Game, defaultconfig)
class RWTHVRTOOLKIT_API URWTHVRToolkitSettings : public UObject
{
GENERATED_BODY()
public:
URWTHVRToolkitSettings() = default;
public:
/** The default preset that should be applied */
UPROPERTY(config, EditAnywhere, Category = "LiveLink")
TSoftObjectPtr<ULiveLinkPreset> DefaultLiveLinkPreset;
};
...@@ -26,12 +26,16 @@ public class RWTHVRToolkit : ModuleRules ...@@ -26,12 +26,16 @@ public class RWTHVRToolkit : ModuleRules
"Slate", "Slate",
"SlateCore", "SlateCore",
"DeveloperSettings", "DeveloperSettings",
"Http" "Http",
"LiveLink",
"LiveLinkInterface"
} }
); );
PrivateDependencyModuleNames.AddRange( PrivateDependencyModuleNames.AddRange(
new string[]{} new string[]{
"UnrealEd"
}
); );
DynamicallyLoadedModuleNames.AddRange( DynamicallyLoadedModuleNames.AddRange(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment