Config for building for Quest

This commit is contained in:
2024-05-29 11:53:41 +03:00
parent 15cbcf8752
commit 0db31c34d1
353 changed files with 74095 additions and 3 deletions

View File

@@ -0,0 +1,54 @@
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
#include "IInputDeviceModule.h"
#define OCULUS_INPUT_SUPPORTED_PLATFORMS (PLATFORM_WINDOWS && WINVER > 0x0502) || (PLATFORM_ANDROID_ARM || PLATFORM_ANDROID_ARM64)
/**
* The public interface to this module. In most cases, this interface is only public to sibling modules
* within this plugin.
*/
class IOculusXRInputModule : public IInputDeviceModule
{
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 IOculusXRInputModule& Get()
{
return FModuleManager::LoadModuleChecked<IOculusXRInputModule>("OculusXRInput");
}
/**
* 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("OculusXRInput");
}
/**
* Gets the number of Touch controllers that are active, so that games that require them can check to make sure they're present
*
* @return The number of Touch controllers that are active (but not necessarily tracked)
*/
virtual uint32 GetNumberOfTouchControllers() const = 0;
/**
* Gets the number of hands that are active, so that games that require them can check to make sure they're present
*
* @return The number of Hands that are active (but not necessarily tracked)
*/
virtual uint32 GetNumberOfHandControllers() const = 0;
virtual TSharedPtr<IInputDevice> GetInputDevice() const = 0;
};

View File

@@ -0,0 +1,61 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
// A class to render the currently connected controller.
// Similar to how hands are tracked.
#pragma once
#include "OculusXRInputFunctionLibrary.h"
#include "OculusXRFunctionLibrary.h"
#include "Components/StaticMeshComponent.h"
#include <Engine/StreamableManager.h>
// Must always be the last include.
#include "OculusXRControllerComponent.generated.h"
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = OculusHand)
class UOculusXRControllerComponent : public UStaticMeshComponent
{
GENERATED_BODY()
public:
UOculusXRControllerComponent();
virtual void BeginPlay() override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
/** The skeleton that will be loaded */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Properties")
EOculusXRSide SkeletonType;
/** Should this controller be rendered when using controller driven hand poses */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Properties")
bool RenderWhenUsingControllerDrivenHands;
private:
enum MeshLoadingState
{
None,
Loading,
Loaded
};
UStaticMesh* _runtimeMesh;
MeshLoadingState _meshLoadingState;
TSharedPtr<FStreamableHandle> _loadAssetHandle;
FStreamableManager _streamableManager;
EOculusXRControllerType _controllerType;
FSoftObjectPath _runtimeMeshPath;
EOculusXRControllerDrivenHandPoseTypes _cachedControllerHandType;
void InitializeMesh();
void MeshLoaded();
EOculusXRControllerType GetControllerType();
const FVector PositionOffsets
[EOculusXRSideCount]
[EOculusXRControllerDrivenHandPoseTypesCount];
const FVector RotationOffsets
[EOculusXRSideCount]
[EOculusXRControllerDrivenHandPoseTypesCount];
};

View File

@@ -0,0 +1,100 @@
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "OculusXRInputFunctionLibrary.h"
#include "Components/PoseableMeshComponent.h"
#include "OculusXRHandComponent.generated.h"
UENUM(BlueprintType)
enum class EOculusXRConfidenceBehavior : uint8
{
None,
HideActor
};
UENUM(BlueprintType)
enum class EOculusXRSystemGestureBehavior : uint8
{
None,
SwapMaterial
};
static const FQuat HandRootFixupRotation = FQuat(-0.5f, -0.5f, 0.5f, 0.5f);
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = OculusHand)
class OCULUSXRINPUT_API UOculusXRHandComponent : public UPoseableMeshComponent
{
GENERATED_UCLASS_BODY()
public:
virtual void BeginPlay() override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
/** The hand skeleton that will be loaded */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
EOculusXRHandType SkeletonType;
/** The hand mesh that will be applied to the skeleton */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
EOculusXRHandType MeshType;
/** Behavior for when hand tracking loses high confidence tracking */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
EOculusXRConfidenceBehavior ConfidenceBehavior = EOculusXRConfidenceBehavior::HideActor;
/** Behavior for when the system gesture is actived */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
EOculusXRSystemGestureBehavior SystemGestureBehavior = EOculusXRSystemGestureBehavior::SwapMaterial;
/** Material that gets applied to the hands when the system gesture is active */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
class UMaterialInterface* SystemGestureMaterial;
/** Whether or not to initialize physics capsules on the skeletal mesh */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
bool bInitializePhysics;
/** Whether or not the hand scale should update based on values from the runtime to match the users hand scale */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
bool bUpdateHandScale;
/** Material override for the runtime skeletal mesh */
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "HandProperties")
class UMaterialInterface* MaterialOverride;
/** Bone mapping for custom hand skeletal meshes */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CustomSkeletalMesh")
TMap<EOculusXRBone, FName> BoneNameMappings;
/** List of capsule colliders created for the skeletal mesh */
UPROPERTY(BlueprintReadOnly, Category = "HandProperties")
TArray<FOculusXRCapsuleCollider> CollisionCapsules;
/** Whether or not the runtime skeletal mesh has been loaded and initialized */
UPROPERTY(BlueprintReadOnly, Category = "HandProperties")
bool bSkeletalMeshInitialized = false;
protected:
virtual void SystemGesturePressed();
virtual void SystemGestureReleased();
private:
/** Whether or not this component has authority within the frame */
bool bHasAuthority;
/** Whether or not a custom hand mesh is being used */
bool bCustomHandMesh = false;
/** Whether or not the physics capsules have been initialized */
bool bInitializedPhysics = false;
USkeletalMesh* RuntimeSkeletalMesh;
UMaterialInterface* CachedBaseMaterial;
void InitializeSkeletalMesh();
void UpdateBonePose();
};

View File

@@ -0,0 +1,350 @@
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Components/CapsuleComponent.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "OculusXRInputFunctionLibrary.generated.h"
UENUM(BlueprintType)
enum class EOculusXRHandType : uint8
{
None,
HandLeft,
HandRight,
};
UENUM(BlueprintType)
enum class EOculusXRSide : uint8
{
None = 0,
Left = 1,
Right = 2,
};
const int EOculusXRSideCount = 3;
UENUM(BlueprintType)
enum class EOculusXRTrackingConfidence : uint8
{
Low,
High
};
UENUM(BlueprintType)
enum class EOculusXRFinger : uint8
{
Thumb,
Index,
Middle,
Ring,
Pinky,
Invalid
};
/**
* EOculusXRBone is enum representing the Bone Ids that come from the Oculus Runtime.
*/
UENUM(BlueprintType)
enum class EOculusXRBone : uint8
{
Wrist_Root UMETA(DisplayName = "Wrist Root"),
Hand_Start = Wrist_Root UMETA(DisplayName = "Hand Start"),
Forearm_Stub UMETA(DisplayName = "Forearm Stub"),
Thumb_0 UMETA(DisplayName = "Thumb0"),
Thumb_1 UMETA(DisplayName = "Thumb1"),
Thumb_2 UMETA(DisplayName = "Thumb2"),
Thumb_3 UMETA(DisplayName = "Thumb3"),
Index_1 UMETA(DisplayName = "Index1"),
Index_2 UMETA(DisplayName = "Index2"),
Index_3 UMETA(DisplayName = "Index3"),
Middle_1 UMETA(DisplayName = "Middle1"),
Middle_2 UMETA(DisplayName = "Middle2"),
Middle_3 UMETA(DisplayName = "Middle3"),
Ring_1 UMETA(DisplayName = "Ring1"),
Ring_2 UMETA(DisplayName = "Ring2"),
Ring_3 UMETA(DisplayName = "Ring3"),
Pinky_0 UMETA(DisplayName = "Pinky0"),
Pinky_1 UMETA(DisplayName = "Pinky1"),
Pinky_2 UMETA(DisplayName = "Pinky2"),
Pinky_3 UMETA(DisplayName = "Pinky3"),
Thumb_Tip UMETA(DisplayName = "Thumb Tip"),
Max_Skinnable = Thumb_Tip UMETA(DisplayName = "Max Skinnable"),
Index_Tip UMETA(DisplayName = "Index Tip"),
Middle_Tip UMETA(DisplayName = "Middle Tip"),
Ring_Tip UMETA(DisplayName = "Ring Tip"),
Pinky_Tip UMETA(DisplayName = "Pinky Tip"),
Hand_End UMETA(DisplayName = "Hand End"),
Bone_Max = Hand_End UMETA(DisplayName = "Hand Max"),
Invalid UMETA(DisplayName = "Invalid")
};
/** Defines the haptics location of controller hands for tracking. */
UENUM(BlueprintType)
enum class EOculusXRHandHapticsLocation : uint8
{
Hand = 0, // Haptics is applied to the whole controller
Thumb, // Haptics is applied to the thumb finger location
Index, // Haptics is applied to the index finger location
HandHapticsLocation_Count UMETA(Hidden, DisplayName = "<INVALID>"),
};
/** Define how a controllers button touches will be used to generate a hand pose. */
UENUM(BlueprintType)
enum class EOculusXRControllerDrivenHandPoseTypes : uint8
{
None = 0, // Controllers do not generate any hand poses.
Natural, // Controller button inputs will be used to generate a normal hand pose.
Controller, // Controller button inputs will be used to generate a hand pose holding a controller.
};
const int EOculusXRControllerDrivenHandPoseTypesCount = 3;
struct FOculusXRHapticsDesc
{
FOculusXRHapticsDesc(
EOculusXRHandHapticsLocation ILocation = EOculusXRHandHapticsLocation::Hand,
bool bIAppend = false)
: Location(ILocation), bAppend(bIAppend)
{
}
void Restart()
{
Location = EOculusXRHandHapticsLocation::Hand;
bAppend = false;
}
EOculusXRHandHapticsLocation Location;
bool bAppend;
};
/**
* FOculusXRCapsuleCollider is a struct that contains information on the physics/collider capsules created by the runtime for hands.
*
* @var Capsule The UCapsuleComponent that is the collision capsule on the bone. Use this to register for overlap/collision events
* @var BoneIndex The Bone that this collision capsule is parented to. Corresponds to the EOculusXRBone enum.
*
*/
USTRUCT(BlueprintType)
struct OCULUSXRINPUT_API FOculusXRCapsuleCollider
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, Category = "OculusLibrary|HandTracking")
UCapsuleComponent* Capsule = nullptr;
UPROPERTY(BlueprintReadOnly, Category = "OculusLibrary|HandTracking")
EOculusXRBone BoneId = EOculusXRBone::Wrist_Root;
};
UCLASS()
class OCULUSXRINPUT_API UOculusXRInputFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|HandTracking")
static EOculusXRFinger ConvertBoneToFinger(const EOculusXRBone Bone);
DECLARE_MULTICAST_DELEGATE_FourParams(FHandMovementFilterDelegate, EControllerHand, FVector*, FRotator*, bool*);
static FHandMovementFilterDelegate HandMovementFilter; /// Called to modify Hand position and orientation whenever it is queried
/**
* Creates a new runtime hand skeletal mesh.
*
* @param HandSkeletalMesh (out) Skeletal Mesh object that will be used for the runtime hand mesh
* @param SkeletonType (in) The skeleton type that will be used for generating the hand bones
* @param MeshType (in) The mesh type that will be used for generating the hand mesh
* @param WorldTometers (in) Optional change to the world to meters conversion value
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|HandTracking")
static bool GetHandSkeletalMesh(USkeletalMesh* HandSkeletalMesh, EOculusXRHandType SkeletonType, EOculusXRHandType MeshType, const float WorldToMeters = 100.0f);
/**
* Initializes physics capsules for collision and physics on the runtime mesh
*
* @param SkeletonType (in) The skeleton type that will be used to generated the capsules
* @param HandComponent (in) The skinned mesh component that the capsules will be attached to
* @param WorldTometers (in) Optional change to the world to meters conversion value
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|HandTracking")
static TArray<FOculusXRCapsuleCollider> InitializeHandPhysics(EOculusXRHandType SkeletonType, USkinnedMeshComponent* HandComponent, const float WorldToMeters = 100.0f);
/**
* Get the rotation of a specific bone
*
* @param DeviceHand (in) The hand to get the rotations from
* @param BoneId (in) The specific bone to get the rotation from
* @param ControllerIndex (in) Optional different controller index
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static FQuat GetBoneRotation(const EOculusXRHandType DeviceHand, const EOculusXRBone BoneId, const int32 ControllerIndex = 0);
/**
* Get the pointer pose
*
* @param DeviceHand (in) The hand to get the pointer pose from
* @param ControllerIndex (in) Optional different controller index
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static FTransform GetPointerPose(const EOculusXRHandType DeviceHand, const int32 ControllerIndex = 0);
/**
* Check if the pointer pose is a valid pose
*
* @param DeviceHand (in) The hand to get the pointer status from
* @param ControllerIndex (in) Optional different controller index
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static bool IsPointerPoseValid(const EOculusXRHandType DeviceHand, const int32 ControllerIndex = 0);
/**
* Get the tracking confidence of the hand
*
* @param DeviceHand (in) The hand to get tracking confidence of
* @param ControllerIndex (in) Optional different controller index
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static EOculusXRTrackingConfidence GetTrackingConfidence(const EOculusXRHandType DeviceHand, const int32 ControllerIndex = 0);
/**
* Get the tracking confidence of a finger
*
* @param DeviceHand (in) The hand to get tracking confidence of
* @param ControllerIndex (in) Optional different controller index
* @param Finger (in) The finger to get tracking confidence of
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static EOculusXRTrackingConfidence GetFingerTrackingConfidence(const EOculusXRHandType DeviceHand, const EOculusXRFinger Finger, const int32 ControllerIndex = 0);
/**
* Get the scale of the hand
*
* @param DeviceHand (in) The hand to get scale of
* @param ControllerIndex (in) Optional different controller index
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static float GetHandScale(const EOculusXRHandType DeviceHand, const int32 ControllerIndex = 0);
/**
* Get the user's dominant hand
*
* @param ControllerIndex (in) Optional different controller index
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static EOculusXRHandType GetDominantHand(const int32 ControllerIndex = 0);
/**
* Check if hand tracking is enabled currently
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static bool IsHandTrackingEnabled();
/**
* Check if the hand position is valid
*
* @param DeviceHand (in) The hand to get the position from
* @param ControllerIndex (in) Optional different controller index
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static bool IsHandPositionValid(const EOculusXRHandType DeviceHand, const int32 ControllerIndex = 0);
/**
* Get the bone name from the bone index
*
* @param BoneIndex (in) Bone index to get the name of
*/
UFUNCTION(BlueprintPure, Category = "OculusLibrary|HandTracking")
static FString GetBoneName(EOculusXRBone BoneId);
/**
* Play a haptic feedback curve on the player's controller with location support.
* The curve data will be sampled and sent to controller to vibrate a specific location at each frame.
* @param HapticEffect The haptic effect to play
* @param Hand Which hand to play the effect on
* @param Location Which hand location to play the effect on
* @param Scale Scale between 0.0 and 1.0 on the intensity of playback
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static void PlayCurveHapticEffect(class UHapticFeedbackEffect_Curve* HapticEffect, EControllerHand Hand, EOculusXRHandHapticsLocation Location = EOculusXRHandHapticsLocation::Hand, float Scale = 1.f, bool bLoop = false);
/**
* Play a haptic feedback buffer on the player's controller with location support.
* In each frame, the buffer data will be sampled and the individual sampled data will be sent to controller to vibrate a specific location.
* @param HapticEffect The haptic effect to play
* @param Hand Which hand to play the effect on
* @param Location Which hand location to play the effect on
* @param Scale Scale between 0.0 and 1.0 on the intensity of playback
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static void PlayBufferHapticEffect(class UHapticFeedbackEffect_Buffer* HapticEffect, EControllerHand Hand, EOculusXRHandHapticsLocation Location = EOculusXRHandHapticsLocation::Hand, float Scale = 1.f, bool bLoop = false);
/**
* Play a haptic feedback buffer on the player's controller.
* All buffer data will be sent to controller together in one frame.
* Data duration should be no greater than controller's maximum haptics duration which can be queried with GetMaxHapticDuration.
* @param HapticEffect The haptic effect to play
* @param Hand Which hand to play the effect on
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static void PlayAmplitudeEnvelopeHapticEffect(class UHapticFeedbackEffect_Buffer* HapticEffect, EControllerHand Hand);
/**
* Play a haptic feedback soundwave on the player's controller.
* In each frame, the soundwave data will be split into a batch of data and sent to controller.
* The data duration of each frame is equal to controller's maximum haptics duration which can be queried with GetMaxHapticDuration.
* @param HapticEffect The haptic effect to play
* @param Hand Which hand to play the effect on
* @param bAppend False: any existing samples will be cleared and a new haptic effect will begin; True: samples will be appended to the currently playing effect
* @param Scale Scale between 0.0 and 1.0 on the intensity of playback
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static void PlaySoundWaveHapticEffect(class UHapticFeedbackEffect_SoundWave* HapticEffect, EControllerHand Hand, bool bAppend = false, float Scale = 1.f, bool bLoop = false);
/**
* Stops a playing haptic feedback curve at a specific location.
* @param HapticEffect The haptic effect to stop
* @param Hand Which hand to stop the effect for
* @param Location Which hand location to play the effect on
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static void StopHapticEffect(EControllerHand Hand, EOculusXRHandHapticsLocation Location = EOculusXRHandHapticsLocation::Hand);
/**
* Set the value of the haptics for the specified hand and location directly, using frequency and amplitude. NOTE: If a curve is already
* playing for this hand, it will be cancelled in favour of the specified values.
*
* @param Frequency The normalized frequency [0.0, 1.0] to play through the haptics system
* @param Amplitude The normalized amplitude [0.0, 1.0] to set the haptic feedback to
* @param Hand Which hand to play the effect on
* @param Location Which hand location to play the effect on
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static void SetHapticsByValue(const float Frequency, const float Amplitude, EControllerHand Hand, EOculusXRHandHapticsLocation Location = EOculusXRHandHapticsLocation::Hand);
/**
* Get the controller haptics sample rate.
* @param Hand Which hand to play the effect on
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static float GetControllerSampleRateHz(EControllerHand Hand);
/**
* Get the maximum duration (in seconds) that the controller haptics can handle each time.
* @param Hand Which hand to play the effect on
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static int GetMaxHapticDuration(EControllerHand Hand);
/**
* Set if / how controller inputs are used to build a syntheic hand pose.
* @param Type How the hand should be posed.
*/
UFUNCTION(BlueprintCallable, Category = "OculusLibrary|Controller")
static void SetControllerDrivenHandPoses(EOculusXRControllerDrivenHandPoseTypes Type);
};