Config for building for Quest
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
/**
|
||||
* The public interface to this module. In most cases, this interface is only public to sibling modules
|
||||
* within this plugin.
|
||||
*/
|
||||
class IOculusXRMovementModule : 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 IOculusXRMovementModule& Get()
|
||||
{
|
||||
return FModuleManager::GetModuleChecked<IOculusXRMovementModule>("OculusXRMovement");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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("OculusXRMovement");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the LiveLinkSource associated with this IOculusXRMovementModule.
|
||||
*
|
||||
* @return Shared pointer to the Meta MovementSDK source.
|
||||
*/
|
||||
virtual TSharedPtr<class ILiveLinkSource> GetLiveLinkSource() = 0;
|
||||
|
||||
/**
|
||||
* Checks if the LiveLinkSource has been created.
|
||||
*
|
||||
* @return True if the LiveLinkSource has been created with GetLiveLinkSource or AddLiveLinkSource.
|
||||
*/
|
||||
virtual bool IsLiveLinkSourceValid() const = 0;
|
||||
|
||||
/**
|
||||
* Make sure Meta MovementSDK Live Link source exist.
|
||||
*/
|
||||
virtual void AddLiveLinkSource() = 0;
|
||||
|
||||
/**
|
||||
* Destroy Meta MovementSDK Live Link source.
|
||||
*/
|
||||
virtual void RemoveLiveLinkSource() = 0;
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/PoseableMeshComponent.h"
|
||||
|
||||
#include "OculusXRMovementTypes.h"
|
||||
|
||||
#include "OculusXRBodyTrackingComponent.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EOculusXRBodyTrackingMode : uint8
|
||||
{
|
||||
PositionAndRotation,
|
||||
RotationOnly,
|
||||
NoTracking
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, DisplayName = "OculusXR Body Tracking Component"), ClassGroup = OculusXRHMD)
|
||||
class OCULUSXRMOVEMENT_API UOculusXRBodyTrackingComponent : public UPoseableMeshComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UOculusXRBodyTrackingComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
/**
|
||||
* Restore all bones to their initial transforms
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Movement")
|
||||
void ResetAllBoneTransforms();
|
||||
|
||||
/**
|
||||
* How are the results of body tracking applied to the mesh.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement")
|
||||
EOculusXRBodyTrackingMode BodyTrackingMode;
|
||||
|
||||
/**
|
||||
* The bone name associated with each bone ID.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TMap<EOculusXRBoneID, FName> BoneNames;
|
||||
|
||||
/**
|
||||
* Do not apply body state to bones if confidence is lower than this value. Confidence is in range [0,1].
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement", meta = (ClampMin = "0", ClampMax = "1", UIMin = "0", UIMax = "1"))
|
||||
float ConfidenceThreshold;
|
||||
|
||||
private:
|
||||
bool InitializeBodyBones();
|
||||
|
||||
// One meter in unreal world units.
|
||||
float WorldToMeters;
|
||||
|
||||
// The index of each mapped bone after the discovery and association of bone names.
|
||||
TMap<EOculusXRBoneID, int32> MappedBoneIndices;
|
||||
|
||||
// Saved body state.
|
||||
FOculusXRBodyState BodyState;
|
||||
|
||||
// Stop the tracker just once.
|
||||
static int TrackingInstanceCount;
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "Components/PoseableMeshComponent.h"
|
||||
|
||||
#include "OculusXRMovementTypes.h"
|
||||
|
||||
#include "OculusXREyeTrackingComponent.generated.h"
|
||||
|
||||
struct FOculusXREyeTrackingData
|
||||
{
|
||||
public:
|
||||
FOculusXREyeTrackingData()
|
||||
: EyeIsMapped(false)
|
||||
, MappedBoneName(NAME_None)
|
||||
{
|
||||
}
|
||||
|
||||
bool EyeIsMapped;
|
||||
FName MappedBoneName;
|
||||
FQuat InitialRotation;
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, DisplayName = "OculusXR Eye Tracking Component"), ClassGroup = OculusXRHMD)
|
||||
class OCULUSXRMOVEMENT_API UOculusXREyeTrackingComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UOculusXREyeTrackingComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
/**
|
||||
* Reset the rotation values of the eyes to their initial rotation
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Oculus|Movement")
|
||||
void ClearRotationValues();
|
||||
|
||||
/**
|
||||
* The name of the poseable mesh component that this component targets for eyes glazes movement.
|
||||
* This must be the name of a component on this actor.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
FName TargetMeshComponentName;
|
||||
|
||||
/**
|
||||
* The map of eye to mesh bone that this component supports.
|
||||
* Names are validated on (@see BeginPlay) so only valid bone names will be targeted.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TMap<EOculusXREye, FName> EyeToBone;
|
||||
|
||||
/**
|
||||
* Update the target mesh position when eye state changes
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement")
|
||||
bool bUpdatePosition;
|
||||
|
||||
/**
|
||||
* Update the target mesh rotation when eye state changes
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement")
|
||||
bool bUpdateRotation;
|
||||
|
||||
/**
|
||||
* Do not accept an eye gaze state if confidence is lower than this value. Confidence is in range [0,1].
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement")
|
||||
float ConfidenceThreshold;
|
||||
|
||||
/**
|
||||
* Bypass eye gaze state validity.
|
||||
*
|
||||
* @Note: It doesn't check the confidence (@see ConfidenceThreshold). The eye gaze state can be marked as invalid. This flag bypass that state flag.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement")
|
||||
bool bAcceptInvalid;
|
||||
|
||||
private:
|
||||
bool InitializeEyes();
|
||||
|
||||
// One meter in unreal world units.
|
||||
float WorldToMeters;
|
||||
|
||||
// Per eye, eye tracking data
|
||||
TStaticArray<FOculusXREyeTrackingData, static_cast<uint32>(EOculusXREye::COUNT)> PerEyeData;
|
||||
|
||||
// The mesh component targeted for eyes
|
||||
UPROPERTY()
|
||||
UPoseableMeshComponent* TargetPoseableMeshComponent;
|
||||
|
||||
// Stop the tracker just once.
|
||||
static int TrackingInstanceCount;
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
#include "OculusXRMorphTargetsController.h"
|
||||
#include "OculusXRMovementTypes.h"
|
||||
|
||||
#include "OculusXRFaceTrackingComponent.generated.h"
|
||||
|
||||
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, DisplayName = "OculusXR Face Tracking Component"), ClassGroup = OculusXRHMD)
|
||||
class OCULUSXRMOVEMENT_API UOculusXRFaceTrackingComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UOculusXRFaceTrackingComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
/**
|
||||
* Set face expression value with expression key and value(0-1).
|
||||
*
|
||||
* @param Expression : The expression key that will be modified.
|
||||
* @param Value : The new value to assign to the expression, 0 will remove all changes.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|OculusXRFaceTracking", meta = (UnsafeDuringActorConstruction = "true"))
|
||||
void SetExpressionValue(EOculusXRFaceExpression Expression, float Value);
|
||||
|
||||
/**
|
||||
* Get a face expression value given an expression key.
|
||||
*
|
||||
* @param Expression : The expression key that will be queried.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|OculusXRFaceTracking")
|
||||
float GetExpressionValue(EOculusXRFaceExpression Expression) const;
|
||||
|
||||
/**
|
||||
* Clears all face expression values.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|OculusXRFaceTracking")
|
||||
void ClearExpressionValues();
|
||||
|
||||
/**
|
||||
* The name of the skinned mesh component that this component targets for facial expression.
|
||||
* This must be the name of a component on this actor.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
FName TargetMeshComponentName;
|
||||
|
||||
/**
|
||||
* If the face data is invalid for at least this or longer than this time then all face blendshapes/morph targets are reset to zero.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
float InvalidFaceDataResetTime;
|
||||
|
||||
/**
|
||||
* The list of expressions that this component supports.
|
||||
* Names are validated on startup so only valid morph targets on the skeletal mesh will be targeted.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TMap<EOculusXRFaceExpression, FName> ExpressionNames;
|
||||
|
||||
/**
|
||||
* An array of optional expression modifiers that can be applied.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TArray<FOculusXRFaceExpressionModifier> ExpressionModifiers;
|
||||
|
||||
/**
|
||||
* This flag determines if the face should be updated or not during the components tick.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement")
|
||||
bool bUpdateFace;
|
||||
|
||||
/**
|
||||
* This flag determines if the face should be modified with Expression Modifiers or not during the components tick.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "OculusXR|Movement")
|
||||
bool bUseModifiers;
|
||||
|
||||
private:
|
||||
bool InitializeFaceTracking();
|
||||
|
||||
// The mesh component targeted for expressions
|
||||
UPROPERTY()
|
||||
USkinnedMeshComponent* TargetMeshComponent;
|
||||
|
||||
// Which mapped expressions are valid
|
||||
TStaticArray<bool, static_cast<uint32>(EOculusXRFaceExpression::COUNT)> ExpressionValid;
|
||||
|
||||
// Morph targets controller
|
||||
FOculusXRMorphTargetsController MorphTargets;
|
||||
|
||||
FOculusXRFaceState FaceState;
|
||||
|
||||
// Timer that counts up until we reset morph curves if we've failed to get face state
|
||||
float InvalidFaceStateTimer;
|
||||
|
||||
// Stop the tracker just once.
|
||||
static int TrackingInstanceCount;
|
||||
};
|
||||
@@ -0,0 +1,143 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "LiveLinkRetargetAsset.h"
|
||||
#include "OculusXRMovementTypes.h"
|
||||
#include "Containers/StaticArray.h"
|
||||
#include "BonePose.h"
|
||||
|
||||
#include "OculusXRLiveLinkRetargetBodyAsset.generated.h"
|
||||
|
||||
UENUM(BlueprintType, meta = (DisplayName = "Axis"))
|
||||
enum class EOculusXRAxis : uint8
|
||||
{
|
||||
X = 0 UMETA(DisplayName = "X"),
|
||||
Y = 1 UMETA(DisplayName = "Y"),
|
||||
Z = 2 UMETA(DisplayName = "Z"),
|
||||
NegativeX = 3 UMETA(DisplayName = "-X"),
|
||||
NegativeY = 4 UMETA(DisplayName = "-Y"),
|
||||
NegativeZ = 5 UMETA(DisplayName = "-Z"),
|
||||
};
|
||||
|
||||
UENUM(BlueprintType, meta = (DisplayName = "Retargeting mode"))
|
||||
enum class EOculusXRRetargetingMode : uint8
|
||||
{
|
||||
Full UMETA(DisplayName = "Rotations and positions"),
|
||||
Rotations UMETA(DisplayName = "Only rotations"),
|
||||
RotationsPlusRoot UMETA(DisplayName = "Rotations and root position"),
|
||||
RotationsPlusHips UMETA(DisplayName = "Rotations and hips position"),
|
||||
None UMETA(DisplayName = "Disabled"),
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType, meta = (DisplayName = "Bone local correction"))
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRBoneCorrection
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
FOculusXRBoneCorrection()
|
||||
: PositionOffset(FVector::ZeroVector), RotationOffset(FRotator::ZeroRotator){};
|
||||
|
||||
/**
|
||||
* Position offset in local space.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
FVector PositionOffset;
|
||||
|
||||
/**
|
||||
* Rotation offset in local space.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
FRotator RotationOffset;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType, meta = (DisplayName = "Correction applied to set of bones"))
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRBoneCorrectionSet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
FOculusXRBoneCorrectionSet(){};
|
||||
|
||||
/**
|
||||
* Set of bones to which the correction will be applied.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
TSet<EOculusXRBoneID> Bones;
|
||||
|
||||
/**
|
||||
* The correction for this set.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
FOculusXRBoneCorrection BoneCorrection;
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, meta = (DisplayName = "MetaXR MovementSDK LiveLink retarget body asset"), ClassGroup = OculusXRHMD)
|
||||
class OCULUSXRMOVEMENT_API UOculusXRLiveLinkRetargetBodyAsset : public ULiveLinkRetargetAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void Initialize() override;
|
||||
virtual void BuildPoseFromAnimationData(float DeltaTime, const FLiveLinkSkeletonStaticData* InSkeletonData, const FLiveLinkAnimationFrameData* InFrameData, FCompactPose& OutPose) override;
|
||||
|
||||
/**
|
||||
* Remapping from bone ID to target skeleton's bone name.
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, Category = "OculusXR|Movement")
|
||||
TMap<EOculusXRBoneID, FName> BoneRemapping;
|
||||
|
||||
/**
|
||||
* Correction applied to all bones.
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, Category = "OculusXR|Movement")
|
||||
FOculusXRBoneCorrection GlobalCorrection;
|
||||
|
||||
/**
|
||||
* Groups of local bone corrections.
|
||||
*
|
||||
* Order matters. A bone can be corrected multiple times.
|
||||
* Corrections will be applied with the same order as in this array.
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, Category = "OculusXR|Movement")
|
||||
TArray<FOculusXRBoneCorrectionSet> LocalCorrections;
|
||||
|
||||
/**
|
||||
* Switch between retargeting modes.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
EOculusXRRetargetingMode RetargetingMode;
|
||||
|
||||
/**
|
||||
* Forward vector axis is the direction towards which the target mesh is oriented.
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, Category = "OculusXR|Movement")
|
||||
EOculusXRAxis ForwardMesh;
|
||||
|
||||
private:
|
||||
// Scale the source tracking positions. This will be initialized with WorldToMeters value.
|
||||
float Scale;
|
||||
|
||||
// Movement tracking is oriented towards X axis.
|
||||
const EOculusXRAxis ForwardTracking{ EOculusXRAxis::X };
|
||||
|
||||
// Transform from tracking to mesh space.
|
||||
FTransform TrackingSpaceToMeshSpace;
|
||||
|
||||
// Correction applied to all bones
|
||||
FTransform GlobalBoneCorrection;
|
||||
|
||||
// Correction applied per bone
|
||||
TStaticArray<FTransform, static_cast<uint8>(EOculusXRBoneID::COUNT)> LocalBoneCorrections;
|
||||
|
||||
// Target skeleton's bone name per bone id
|
||||
TStaticArray<FName, static_cast<uint8>(EOculusXRBoneID::COUNT)> BoneNames;
|
||||
|
||||
// Latest bone container serial number
|
||||
uint16 LastBoneContainerSerialNumber;
|
||||
|
||||
// Compact pose indices per bone id
|
||||
TStaticArray<FCompactPoseBoneIndex, static_cast<uint8>(EOculusXRBoneID::COUNT)> LastSkeletonBoneRemapping{ InPlace, FCompactPoseBoneIndex(INDEX_NONE) };
|
||||
|
||||
// Recalculate skeleton dependent mappings
|
||||
void OnBoneContainerChanged(const FBoneContainer& BoneContainer);
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Animation/AnimTypes.h"
|
||||
#include "LiveLinkRetargetAsset.h"
|
||||
#include "Containers/StaticArray.h"
|
||||
#include "OculusXRMovementTypes.h"
|
||||
#include "Misc/EngineVersionComparison.h"
|
||||
|
||||
#include "OculusXRLiveLinkRetargetFaceAsset.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRAnimCurveMapping
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
FOculusXRAnimCurveMapping(){};
|
||||
|
||||
FOculusXRAnimCurveMapping(const std::initializer_list<FName> CurveNamesList)
|
||||
: CurveNames(CurveNamesList)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Skeleton's animation curve names
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
TArray<FName> CurveNames;
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, meta = (DisplayName = "MetaXR MovementSDK LiveLink retarget face asset"), ClassGroup = OculusXRHMD)
|
||||
class OCULUSXRMOVEMENT_API UOculusXRLiveLinkRetargetFaceAsset : public ULiveLinkRetargetAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void Initialize() override;
|
||||
virtual void BuildPoseAndCurveFromBaseData(float DeltaTime, const FLiveLinkBaseStaticData* InBaseStaticData, const FLiveLinkBaseFrameData* InBaseFrameData, FCompactPose& OutPose, FBlendedCurve& OutCurve) override;
|
||||
|
||||
/**
|
||||
* Map face expression to Skeleton's animation curve mapping names.
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, Category = "OculusXR|Movement")
|
||||
TMap<EOculusXRFaceExpression, FOculusXRAnimCurveMapping> CurveRemapping;
|
||||
|
||||
private:
|
||||
// Latest skeleton used to build pose
|
||||
FGuid LastSkeletonGuid;
|
||||
|
||||
// Remapping used for latest used skeleton
|
||||
#if UE_VERSION_OLDER_THAN(5, 3, 0)
|
||||
TStaticArray<TArray<SmartName::UID_Type>, static_cast<uint8>(EOculusXRFaceExpression::COUNT)> RemappingForLastSkeleton;
|
||||
#else
|
||||
TStaticArray<TArray<FName>, static_cast<uint8>(EOculusXRFaceExpression::COUNT)> RemappingForLastSkeleton;
|
||||
#endif
|
||||
|
||||
// Recalculate skeleton dependent mappings
|
||||
void OnSkeletonChanged(const USkeleton* Skeleton);
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/SkinnedMeshComponent.h"
|
||||
|
||||
/*
|
||||
* Struct that allows applying morph targets data to an arbitrary skinned mesh component
|
||||
* instead of relying on the skeletal mesh component.
|
||||
*
|
||||
* Usage - In a tick method of your choosing:
|
||||
* 1) ResetMorphTargetCurves(Component) at the start of the update.
|
||||
* 2) SetMorphTarget(...) as many times as needed based on your data set.
|
||||
* 3) ApplyMorphTargets(Component) at the end of the update to apply the morph targets to the anim runtime.
|
||||
*/
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRMorphTargetsController
|
||||
{
|
||||
public:
|
||||
// Clears active morph targets
|
||||
void ResetMorphTargetCurves(USkinnedMeshComponent* TargetMeshComponent);
|
||||
|
||||
// Will apply morph target data to the underlying runtime skeletal mesh
|
||||
void ApplyMorphTargets(USkinnedMeshComponent* TargetMeshComponent);
|
||||
|
||||
// Sets a specific morph target value
|
||||
void SetMorphTarget(FName MorphTargetName, float Value);
|
||||
|
||||
// Gets a specific morph target value
|
||||
float GetMorphTarget(FName MorphTargetName) const;
|
||||
|
||||
// Clears all morph target curves data
|
||||
void ClearMorphTargets();
|
||||
|
||||
// List of morph targets on this controller
|
||||
TMap<FName, float> MorphTargetCurves;
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRMovementTypes.h"
|
||||
|
||||
namespace XRSpaceFlags
|
||||
{
|
||||
static const uint64 XR_SPACE_LOCATION_ORIENTATION_VALID_BIT = 0x00000001;
|
||||
static const uint64 XR_SPACE_LOCATION_POSITION_VALID_BIT = 0x00000002;
|
||||
static const uint64 XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT = 0x00000004;
|
||||
static const uint64 XR_SPACE_LOCATION_POSITION_TRACKED_BIT = 0x00000008;
|
||||
} // namespace XRSpaceFlags
|
||||
|
||||
struct OCULUSXRMOVEMENT_API OculusXRMovement
|
||||
{
|
||||
static bool GetBodyState(FOculusXRBodyState& outOculusXRBodyState, float WorldToMeters = 100.0f);
|
||||
static bool IsBodyTrackingEnabled();
|
||||
static bool IsBodyTrackingSupported();
|
||||
static bool StartBodyTracking();
|
||||
static bool StopBodyTracking();
|
||||
static bool StartBodyTrackingByJointSet(EOculusXRBodyJointSet jointSet);
|
||||
static bool RequestBodyTrackingFidelity(EOculusXRBodyTrackingFidelity fidelity);
|
||||
static bool ResetBodyTrackingCalibration();
|
||||
static bool SuggestBodyTrackingCalibrationOverride(float height);
|
||||
private:
|
||||
static bool IsFullBodyTrackingEnabled();
|
||||
|
||||
public:
|
||||
static bool GetFaceState(FOculusXRFaceState& outOculusXRFaceState);
|
||||
static bool IsFaceTrackingEnabled();
|
||||
static bool IsFaceTrackingSupported();
|
||||
static bool StartFaceTracking();
|
||||
static bool StopFaceTracking();
|
||||
|
||||
static bool GetEyeGazesState(FOculusXREyeGazesState& outOculusXREyeGazesState, float WorldToMeters = 100.0f);
|
||||
static bool IsEyeTrackingEnabled();
|
||||
static bool IsEyeTrackingSupported();
|
||||
static bool StartEyeTracking();
|
||||
static bool StopEyeTracking();
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRMovementTypes.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
|
||||
#include "OculusXRMovementFunctionLibrary.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class OCULUSXRMOVEMENT_API UOculusXRMovementFunctionLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool TryGetBodyState(FOculusXRBodyState& outBodyState, float WorldToMeters = 100.0f);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool IsBodyTrackingEnabled();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool IsBodyTrackingSupported();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool RequestBodyTrackingFidelity(EOculusXRBodyTrackingFidelity fidelity);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool ResetBodyTrackingCalibration();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool SuggestBodyTrackingCalibrationOverride(float height);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool StartBodyTrackingByJointSet(EOculusXRBodyJointSet jointSet);
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (DeprecatedFunction, DeprecationMessage = "StartBodyTracking is deprecated, use StartBodyTrackingByJointSet."), Category = "OculusXR|Body")
|
||||
static bool StartBodyTracking();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Body")
|
||||
static bool StopBodyTracking();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Face")
|
||||
static bool TryGetFaceState(FOculusXRFaceState& outFaceState);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Face")
|
||||
static bool IsFaceTrackingEnabled();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Face")
|
||||
static bool IsFaceTrackingSupported();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Face")
|
||||
static bool StartFaceTracking();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Face")
|
||||
static bool StopFaceTracking();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Eyes")
|
||||
static bool TryGetEyeGazesState(FOculusXREyeGazesState& outEyeGazesState, float WorldToMeters = 100.0f);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Eyes")
|
||||
static bool IsEyeTrackingEnabled();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Eyes")
|
||||
static bool IsEyeTrackingSupported();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Eyes")
|
||||
static bool StartEyeTracking();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "OculusXR|Eyes")
|
||||
static bool StopEyeTracking();
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace OculusXRUtility
|
||||
{
|
||||
template <typename T>
|
||||
T* FindComponentByName(AActor* Actor, const FName& ComponentName)
|
||||
{
|
||||
if (IsValid(Actor) && (ComponentName != NAME_None))
|
||||
{
|
||||
TArray<T*> ComponentsOfType;
|
||||
Actor->GetComponents<T>(ComponentsOfType);
|
||||
T** FoundComponent = ComponentsOfType.FindByPredicate([Name = ComponentName.ToString()](T* Component) { return Component->GetName().Equals(Name); });
|
||||
|
||||
if (FoundComponent != nullptr)
|
||||
{
|
||||
return *FoundComponent;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace OculusXRUtility
|
||||
@@ -0,0 +1,336 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "OculusXRMovementTypes.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EOculusXRBodyJointSet : uint8
|
||||
{
|
||||
UpperBody = 0,
|
||||
FullBody = 1
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EOculusXRBodyTrackingFidelity : uint8
|
||||
{
|
||||
Unset = 0 UMETA(Hidden),
|
||||
Low = 1,
|
||||
High = 2,
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EOculusXRBoneID : uint8
|
||||
{
|
||||
BodyRoot = 0,
|
||||
BodyHips = 1,
|
||||
BodySpineLower = 2,
|
||||
BodySpineMiddle = 3,
|
||||
BodySpineUpper = 4,
|
||||
BodyChest = 5,
|
||||
BodyNeck = 6,
|
||||
BodyHead = 7,
|
||||
BodyLeftShoulder = 8,
|
||||
BodyLeftScapula = 9,
|
||||
BodyLeftArmUpper = 10,
|
||||
BodyLeftArmLower = 11,
|
||||
BodyLeftHandWristTwist = 12,
|
||||
BodyRightShoulder = 13,
|
||||
BodyRightScapula = 14,
|
||||
BodyRightArmUpper = 15,
|
||||
BodyRightArmLower = 16,
|
||||
BodyRightHandWristTwist = 17,
|
||||
BodyLeftHandPalm = 18,
|
||||
BodyLeftHandWrist = 19,
|
||||
BodyLeftHandThumbMetacarpal = 20,
|
||||
BodyLeftHandThumbProximal = 21,
|
||||
BodyLeftHandThumbDistal = 22,
|
||||
BodyLeftHandThumbTip = 23,
|
||||
BodyLeftHandIndexMetacarpal = 24,
|
||||
BodyLeftHandIndexProximal = 25,
|
||||
BodyLeftHandIndexIntermediate = 26,
|
||||
BodyLeftHandIndexDistal = 27,
|
||||
BodyLeftHandIndexTip = 28,
|
||||
BodyLeftHandMiddleMetacarpal = 29,
|
||||
BodyLeftHandMiddleProximal = 30,
|
||||
BodyLeftHandMiddleIntermediate = 31,
|
||||
BodyLeftHandMiddleDistal = 32,
|
||||
BodyLeftHandMiddleTip = 33,
|
||||
BodyLeftHandRingMetacarpal = 34,
|
||||
BodyLeftHandRingProximal = 35,
|
||||
BodyLeftHandRingIntermediate = 36,
|
||||
BodyLeftHandRingDistal = 37,
|
||||
BodyLeftHandRingTip = 38,
|
||||
BodyLeftHandLittleMetacarpal = 39,
|
||||
BodyLeftHandLittleProximal = 40,
|
||||
BodyLeftHandLittleIntermediate = 41,
|
||||
BodyLeftHandLittleDistal = 42,
|
||||
BodyLeftHandLittleTip = 43,
|
||||
BodyRightHandPalm = 44,
|
||||
BodyRightHandWrist = 45,
|
||||
BodyRightHandThumbMetacarpal = 46,
|
||||
BodyRightHandThumbProximal = 47,
|
||||
BodyRightHandThumbDistal = 48,
|
||||
BodyRightHandThumbTip = 49,
|
||||
BodyRightHandIndexMetacarpal = 50,
|
||||
BodyRightHandIndexProximal = 51,
|
||||
BodyRightHandIndexIntermediate = 52,
|
||||
BodyRightHandIndexDistal = 53,
|
||||
BodyRightHandIndexTip = 54,
|
||||
BodyRightHandMiddleMetacarpal = 55,
|
||||
BodyRightHandMiddleProximal = 56,
|
||||
BodyRightHandMiddleIntermediate = 57,
|
||||
BodyRightHandMiddleDistal = 58,
|
||||
BodyRightHandMiddleTip = 59,
|
||||
BodyRightHandRingMetacarpal = 60,
|
||||
BodyRightHandRingProximal = 61,
|
||||
BodyRightHandRingIntermediate = 62,
|
||||
BodyRightHandRingDistal = 63,
|
||||
BodyRightHandRingTip = 64,
|
||||
BodyRightHandLittleMetacarpal = 65,
|
||||
BodyRightHandLittleProximal = 66,
|
||||
BodyRightHandLittleIntermediate = 67,
|
||||
BodyRightHandLittleDistal = 68,
|
||||
BodyRightHandLittleTip = 69,
|
||||
BodyLeftUpperLeg = 70,
|
||||
BodyLeftLowerLeg = 71,
|
||||
BodyLeftFootAnkleTwist = 72,
|
||||
BodyLeftFootAnkle = 73,
|
||||
BodyLeftFootSubtalar = 74,
|
||||
BodyLeftFootTransverse = 75,
|
||||
BodyLeftFootBall = 76,
|
||||
BodyRightUpperLeg = 77,
|
||||
BodyRightLowerLeg = 78,
|
||||
BodyRightFootAnkleTwist = 79,
|
||||
BodyRightFootAnkle = 80,
|
||||
BodyRightFootSubtalar = 81,
|
||||
BodyRightFootTransverse = 82,
|
||||
BodyRightFootBall = 83,
|
||||
COUNT = 84 UMETA(Hidden),
|
||||
None = 255 UMETA(Hidden),
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRBodyJoint
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FOculusXRBodyJoint();
|
||||
|
||||
uint64 LocationFlags;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
bool bIsValid;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
FRotator Orientation;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
FVector Position;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRBodyState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FOculusXRBodyState();
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
bool IsActive;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
float Confidence;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
int SkeletonChangedCount;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
float Time;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TArray<FOculusXRBodyJoint> Joints;
|
||||
};
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EFaceTrackingDataSource : uint8
|
||||
{
|
||||
Visual = 0 UMETA(DisplayName = "Visual"),
|
||||
Audio = 1 UMETA(DisplayName = "Audio"),
|
||||
MAX = 2 UMETA(Hidden),
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EOculusXRFaceExpression : uint8
|
||||
{
|
||||
// Removed invalid to make this supported as a uint8 enum class
|
||||
BrowLowererL = 0,
|
||||
BrowLowererR = 1,
|
||||
CheekPuffL = 2,
|
||||
CheekPuffR = 3,
|
||||
CheekRaiserL = 4,
|
||||
CheekRaiserR = 5,
|
||||
CheekSuckL = 6,
|
||||
CheekSuckR = 7,
|
||||
ChinRaiserB = 8,
|
||||
ChinRaiserT = 9,
|
||||
DimplerL = 10,
|
||||
DimplerR = 11,
|
||||
EyesClosedL = 12,
|
||||
EyesClosedR = 13,
|
||||
EyesLookDownL = 14,
|
||||
EyesLookDownR = 15,
|
||||
EyesLookLeftL = 16,
|
||||
EyesLookLeftR = 17,
|
||||
EyesLookRightL = 18,
|
||||
EyesLookRightR = 19,
|
||||
EyesLookUpL = 20,
|
||||
EyesLookUpR = 21,
|
||||
InnerBrowRaiserL = 22,
|
||||
InnerBrowRaiserR = 23,
|
||||
JawDrop = 24,
|
||||
JawSidewaysLeft = 25,
|
||||
JawSidewaysRight = 26,
|
||||
JawThrust = 27,
|
||||
LidTightenerL = 28,
|
||||
LidTightenerR = 29,
|
||||
LipCornerDepressorL = 30,
|
||||
LipCornerDepressorR = 31,
|
||||
LipCornerPullerL = 32,
|
||||
LipCornerPullerR = 33,
|
||||
LipFunnelerLB = 34,
|
||||
LipFunnelerLT = 35,
|
||||
LipFunnelerRB = 36,
|
||||
LipFunnelerRT = 37,
|
||||
LipPressorL = 38,
|
||||
LipPressorR = 39,
|
||||
LipPuckerL = 40,
|
||||
LipPuckerR = 41,
|
||||
LipStretcherL = 42,
|
||||
LipStretcherR = 43,
|
||||
LipSuckLB = 44,
|
||||
LipSuckLT = 45,
|
||||
LipSuckRB = 46,
|
||||
LipSuckRT = 47,
|
||||
LipTightenerL = 48,
|
||||
LipTightenerR = 49,
|
||||
LipsToward = 50,
|
||||
LowerLipDepressorL = 51,
|
||||
LowerLipDepressorR = 52,
|
||||
MouthLeft = 53,
|
||||
MouthRight = 54,
|
||||
NoseWrinklerL = 55,
|
||||
NoseWrinklerR = 56,
|
||||
OuterBrowRaiserL = 57,
|
||||
OuterBrowRaiserR = 58,
|
||||
UpperLidRaiserL = 59,
|
||||
UpperLidRaiserR = 60,
|
||||
UpperLipRaiserL = 61,
|
||||
UpperLipRaiserR = 62,
|
||||
TongueTipInterdental = 63,
|
||||
TongueTipAlveolar = 64,
|
||||
TongueFrontDorsalPalate = 65,
|
||||
TongueMidDorsalPalate = 66,
|
||||
TongueBackDorsalVelar = 67,
|
||||
TongueOut = 68,
|
||||
TongueRetreat = 69,
|
||||
COUNT = 70 UMETA(Hidden),
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EOculusXRFaceConfidence : uint8
|
||||
{
|
||||
Lower = 0,
|
||||
Upper = 1,
|
||||
COUNT = 2,
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRFaceState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FOculusXRFaceState();
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TArray<float> ExpressionWeights;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TArray<float> ExpressionWeightConfidences;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
bool bIsValid;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
bool bIsEyeFollowingBlendshapesValid;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
float Time;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
EFaceTrackingDataSource DataSource;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct OCULUSXRMOVEMENT_API FOculusXRFaceExpressionModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FOculusXRFaceExpressionModifier();
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
TArray<EOculusXRFaceExpression> FaceExpressions;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
float MinValue;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
float MaxValue;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "OculusXR|Movement")
|
||||
float Multiplier;
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EOculusXREye : uint8
|
||||
{
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
COUNT = 2,
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct OCULUSXRMOVEMENT_API FOculusXREyeGazeState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FOculusXREyeGazeState();
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
FRotator Orientation;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
FVector Position;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
float Confidence;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
bool bIsValid;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct OCULUSXRMOVEMENT_API FOculusXREyeGazesState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FOculusXREyeGazesState();
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
TArray<FOculusXREyeGazeState> EyeGazes;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Movement")
|
||||
float Time;
|
||||
};
|
||||
Reference in New Issue
Block a user