UEVR-1952 OpenXR motion controllers don't work unless one action for the motion controller is mapped. Need to do something about this.

-Duplicating from dev-vr
-If no profiles at all are bound we bind aim/grip to the kronos simple controller profile.
-Deleting the SimpleController OpenXRExtensionPlugin because we have better example plugins now (HandTracking, EyeTracking) and it is partially duplicated by this controller fallback code.
#jira UEVR-1952
#review-14255400
#rb Jules.Blok

[CL 14313024 by Jeff Fisher in 4.26 branch]
This commit is contained in:
Jeff Fisher
2020-09-14 17:23:51 -04:00
parent f47795ed6c
commit 2109235a7c
5 changed files with 30 additions and 125 deletions

View File

@@ -1,35 +0,0 @@
{
"FileVersion" : 3,
"Version" : 1,
"VersionName" : "1.0",
"FriendlyName" : "SimpleController",
"Description" : "SimpleController is a sample of an OpenXR extension plugin",
"Category" : "Virtual Reality",
"CreatedBy" : "Epic Games, Inc.",
"CreatedByURL" : "http://epicgames.com",
"DocsURL" : "",
"MarketplaceURL" : "",
"SupportURL" : "",
"EnabledByDefault" : false,
"CanContainContent" : false,
"IsBetaVersion" : false,
"Installed" : false,
"Modules" : [
{
"Name": "SimpleController",
"Type": "Runtime",
"LoadingPhase": "PostConfigInit",
"WhitelistPlatforms": [
"Win32",
"Win64",
"HoloLens"
]
}
],
"Plugins" : [
{
"Name": "OpenXR",
"Enabled": true
}
]
}

View File

@@ -1,41 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "SimpleController.h"
#include "InputCoreTypes.h"
#include "OpenXRCore.h"
#include <openxr/openxr.h>
#define LOCTEXT_NAMESPACE "SimpleController"
IMPLEMENT_MODULE(FSimpleController, SimpleController)
namespace SimpleKeys
{
const FKey SimpleController_Left_Select_Click("SimpleController_Left_Select_Click");
const FKey SimpleController_Left_Menu_Click("SimpleController_Left_Menu_Click");
const FKey SimpleController_Right_Select_Click("SimpleController_Right_Select_Click");
const FKey SimpleController_Right_Menu_Click("SimpleController_Right_Menu_Click");
}
void FSimpleController::StartupModule()
{
RegisterOpenXRExtensionModularFeature();
EKeys::AddMenuCategoryDisplayInfo("SimpleController", LOCTEXT("SimpleControllerSubCategory", "Simple Controller"), TEXT("GraphEditor.PadEvent_16x"));
EKeys::AddKey(FKeyDetails(SimpleKeys::SimpleController_Left_Select_Click, LOCTEXT("SimpleController_Left_Select_Click", "Simple Controller (L) Select"), FKeyDetails::GamepadKey | FKeyDetails::NotBlueprintBindableKey, "SimpleController"));
EKeys::AddKey(FKeyDetails(SimpleKeys::SimpleController_Left_Menu_Click, LOCTEXT("SimpleController_Left_Menu_Click", "Simple Controller (L) Menu"), FKeyDetails::GamepadKey | FKeyDetails::NotBlueprintBindableKey, "SimpleController"));
EKeys::AddKey(FKeyDetails(SimpleKeys::SimpleController_Right_Select_Click, LOCTEXT("SimpleController_Right_Select_Click", "Simple Controller (R) Select"), FKeyDetails::GamepadKey | FKeyDetails::NotBlueprintBindableKey, "SimpleController"));
EKeys::AddKey(FKeyDetails(SimpleKeys::SimpleController_Right_Menu_Click, LOCTEXT("SimpleController_Right_Menu_Click", "Simple Controller (R) Menu"), FKeyDetails::GamepadKey | FKeyDetails::NotBlueprintBindableKey, "SimpleController"));
}
bool FSimpleController::GetInteractionProfile(XrInstance InInstance, FString& OutKeyPrefix, XrPath& OutPath, bool& OutHasHaptics)
{
OutKeyPrefix = "SimpleController";
OutHasHaptics = true;
return xrStringToPath(InInstance, "/interaction_profiles/khr/simple_controller", &OutPath) == XR_SUCCESS;
}
#undef LOCTEXT_NAMESPACE

View File

@@ -1,15 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
#include "IOpenXRExtensionPlugin.h"
class FSimpleController : public IModuleInterface, public IOpenXRExtensionPlugin
{
public:
virtual void StartupModule() override;
virtual bool GetInteractionProfile(XrInstance InInstance, FString& OutKeyPrefix, XrPath& OutPath, bool& OutHasHaptics) override;
};

View File

@@ -1,34 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
namespace UnrealBuildTool.Rules
{
public class SimpleController : ModuleRules
{
public SimpleController(ReadOnlyTargetRules Target) : base(Target)
{
PrivateIncludePaths.AddRange(
new string[] {
"SimpleController/Private",
// ... add other private include paths required here ...
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"Core",
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"InputCore"
}
);
PublicDependencyModuleNames.Add("OpenXRHMD");
// Required to (delayload) link with OpenXR loader.
AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenXR");
}
}
}

View File

@@ -328,6 +328,8 @@ void FOpenXRInputPlugin::FOpenXRInput::BuildActions()
);
}
bool bGripAndAimBindingsAdded = false;
for (TPair<FString, FInteractionProfile>& Pair : Profiles)
{
FInteractionProfile& Profile = Pair.Value;
@@ -335,6 +337,8 @@ void FOpenXRInputPlugin::FOpenXRInput::BuildActions()
// Only suggest interaction profile bindings if the developer has provided bindings for them
if (Profile.Bindings.Num() > 0)
{
bGripAndAimBindingsAdded = true;
// Add the bindings for the controller pose and haptics
Profile.Bindings.Add(XrActionSuggestedBinding {
Controllers[EControllerHand::Left].GripAction, GetPath(Instance, "/user/hand/left/input/grip/pose")
@@ -368,6 +372,32 @@ void FOpenXRInputPlugin::FOpenXRInput::BuildActions()
XR_ENSURE(xrSuggestInteractionProfileBindings(Instance, &InteractionProfile));
}
}
// If we have no profile bindings at all we will bind grip/aim to the Kronos Simple Controller profile, so that motion controller grip/aim poses function by default.
if (!bGripAndAimBindingsAdded)
{
TArray<XrActionSuggestedBinding> Bindings;
Bindings.Add(XrActionSuggestedBinding{
Controllers[EControllerHand::Left].GripAction, GetPath(Instance, "/user/hand/left/input/grip/pose")
});
Bindings.Add(XrActionSuggestedBinding{
Controllers[EControllerHand::Right].GripAction, GetPath(Instance, "/user/hand/right/input/grip/pose")
});
Bindings.Add(XrActionSuggestedBinding{
Controllers[EControllerHand::Left].AimAction, GetPath(Instance, "/user/hand/left/input/aim/pose")
});
Bindings.Add(XrActionSuggestedBinding{
Controllers[EControllerHand::Right].AimAction, GetPath(Instance, "/user/hand/right/input/aim/pose")
});
XrInteractionProfileSuggestedBinding InteractionProfile;
InteractionProfile.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
InteractionProfile.next = nullptr;
InteractionProfile.interactionProfile = GetPath(Instance, "/interaction_profiles/khr/simple_controller");
InteractionProfile.countSuggestedBindings = Bindings.Num();
InteractionProfile.suggestedBindings = Bindings.GetData();
XR_ENSURE(xrSuggestInteractionProfileBindings(Instance, &InteractionProfile));
}
// Add an active set for each sub-action path so we can use the subaction paths later
// TODO: Runtimes already allow us to do the same by simply specifying "subactionPath"