From 45e41e60d9014738b90220425d3dd55be8516c05 Mon Sep 17 00:00:00 2001 From: Mamadou Babaei Date: Tue, 22 Oct 2024 07:33:34 +0200 Subject: [PATCH] bump the SenseGlove Unreal Engine Plugin to v2.1.4 --- .../README.md | 184 +++++++------- .../blueprint.md | 2 +- .../consuming-fxrmotioncontrollerdata/cpp.md | 230 +++++++++--------- .../Handbook/src/appendix/changelog.md | 13 +- .../src/appendix/platform-support-matrix.md | 8 +- Plugins/SenseGlove/SenseGlove.uplugin | 2 +- 6 files changed, 235 insertions(+), 204 deletions(-) diff --git a/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/README.md b/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/README.md index 5af42d7..1cba97f 100644 --- a/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/README.md +++ b/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/README.md @@ -6,56 +6,56 @@ Taking a closer look at the `FXRMotionControllerData` declaration inside the Unr USTRUCT(BlueprintType) struct FXRMotionControllerData { - GENERATED_USTRUCT_BODY(); + GENERATED_USTRUCT_BODY(); - UPROPERTY(BlueprintReadOnly, Category = "XR") - bool bValid = false; - UPROPERTY(BlueprintReadOnly, Category = "XR") - FName DeviceName; - UPROPERTY(BlueprintReadOnly, Category = "XR") - FGuid ApplicationInstanceID; - UPROPERTY(BlueprintReadOnly, Category = "XR") - EXRVisualType DeviceVisualType = EXRVisualType::Controller; + UPROPERTY(BlueprintReadOnly, Category = "XR") + bool bValid = false; + UPROPERTY(BlueprintReadOnly, Category = "XR") + FName DeviceName; + UPROPERTY(BlueprintReadOnly, Category = "XR") + FGuid ApplicationInstanceID; + UPROPERTY(BlueprintReadOnly, Category = "XR") + EXRVisualType DeviceVisualType = EXRVisualType::Controller; - UPROPERTY(BlueprintReadOnly, Category = "XR") - EControllerHand HandIndex = EControllerHand::Left; + UPROPERTY(BlueprintReadOnly, Category = "XR") + EControllerHand HandIndex = EControllerHand::Left; - UPROPERTY(BlueprintReadOnly, Category = "XR") - ETrackingStatus TrackingStatus = ETrackingStatus::NotTracked; + UPROPERTY(BlueprintReadOnly, Category = "XR") + ETrackingStatus TrackingStatus = ETrackingStatus::NotTracked; - // Vector representing an object being held in the player's hand - UPROPERTY(BlueprintReadOnly, Category = "XR") - FVector GripPosition = FVector(0.0f); - // Quaternion representing an object being held in the player's hand - UPROPERTY(BlueprintReadOnly, Category = "XR") - FQuat GripRotation = FQuat(EForceInit::ForceInitToZero); + // Vector representing an object being held in the player's hand + UPROPERTY(BlueprintReadOnly, Category = "XR") + FVector GripPosition = FVector(0.0f); + // Quaternion representing an object being held in the player's hand + UPROPERTY(BlueprintReadOnly, Category = "XR") + FQuat GripRotation = FQuat(EForceInit::ForceInitToZero); - // For handheld controllers, gives a vector for pointing at objects - UPROPERTY(BlueprintReadOnly, Category = "XR") - FVector AimPosition = FVector(0.0f); - // For handheld controllers, gives a quaternion for pointing at objects - UPROPERTY(BlueprintReadOnly, Category = "XR") - FQuat AimRotation = FQuat(EForceInit::ForceInitToZero); + // For handheld controllers, gives a vector for pointing at objects + UPROPERTY(BlueprintReadOnly, Category = "XR") + FVector AimPosition = FVector(0.0f); + // For handheld controllers, gives a quaternion for pointing at objects + UPROPERTY(BlueprintReadOnly, Category = "XR") + FQuat AimRotation = FQuat(EForceInit::ForceInitToZero); - // For handheld controllers, gives a vector for representing the hand - UPROPERTY(BlueprintReadOnly, Category = "XR") - FVector PalmPosition = FVector(0.0f); - // For handheld controllers, gives a quaternion for representing the hand - UPROPERTY(BlueprintReadOnly, Category = "XR") - FQuat PalmRotation = FQuat(EForceInit::ForceInitToZero); + // For handheld controllers, gives a vector for representing the hand + UPROPERTY(BlueprintReadOnly, Category = "XR") + FVector PalmPosition = FVector(0.0f); + // For handheld controllers, gives a quaternion for representing the hand + UPROPERTY(BlueprintReadOnly, Category = "XR") + FQuat PalmRotation = FQuat(EForceInit::ForceInitToZero); - // The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc). - UPROPERTY(BlueprintReadOnly, Category = "XR") - TArray HandKeyPositions; - // The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc). - UPROPERTY(BlueprintReadOnly, Category = "XR") - TArray HandKeyRotations; - // The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc). - UPROPERTY(BlueprintReadOnly, Category = "XR") - TArray HandKeyRadii; + // The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc). + UPROPERTY(BlueprintReadOnly, Category = "XR") + TArray HandKeyPositions; + // The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc). + UPROPERTY(BlueprintReadOnly, Category = "XR") + TArray HandKeyRotations; + // The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc). + UPROPERTY(BlueprintReadOnly, Category = "XR") + TArray HandKeyRadii; - UPROPERTY(BlueprintReadOnly, Category = "XR") - bool bIsGrasped = false; + UPROPERTY(BlueprintReadOnly, Category = "XR") + bool bIsGrasped = false; }; ``` @@ -71,68 +71,88 @@ But, fear not, we've got you covered! ### Structure Members of FXRMotionControllerData -1. **bValid** +- **bValid** - **Description**: A boolean flag indicating whether the data is valid or not. - **Usage**: This is used to check if the motion controller data is correctly initialized and can be used for further processing. -2. **DeviceName** +- **DeviceName** - **Type**: `FName` - **Description**: The name of the device. - **Usage**: Identifies which motion controller device the data is coming from, useful when multiple devices are in use. -3. **ApplicationInstanceID** +- **ApplicationInstanceID** - **Type**: `FString` - **Description**: A unique identifier for the application instance. - **Usage**: Helps in differentiating data from different instances of an application, ensuring the correct instance processes the data. -4. **TrackingStatus** +- **DeviceVisualType** + - **Type**: `EXRVisualType` + - **Description**: Enum specifying the visual type of the device (e.g., controller, hand). + - **Usage**: Used to differentiate between various motion controller devices or hand-tracking representations for rendering and interaction purposes. + +- **HandIndex** + - **Type**: `EControllerHand` + - **Description**: Enum indicating which hand is being tracked (left or right). + - **Usage**: Helps identify whether the motion data pertains to the left or right hand, essential for hand-specific actions or interactions. + +- **TrackingStatus** - **Type**: `EXRTrackingStatus` - **Description**: Enum indicating the tracking status of the motion controller. - **Usage**: Shows whether the controller is being tracked accurately, with possible statuses like `Tracked`, `NotTracked`, etc. -5. **GripPosition** +- **GripPosition** - **Type**: `FVector` - **Description**: The position of the grip in world coordinates. - **Usage**: Provides the 3D coordinates of the controller's grip, essential for positioning the virtual representation of the controller. -6. **GripRotation** +- **GripRotation** - **Type**: `FQuat` - **Description**: The rotation of the grip in world coordinates. - **Usage**: Provides the orientation of the controller's grip, allowing for accurate rotation and alignment in the virtual space. -7. **AimPosition** +- **AimPosition** - **Type**: `FVector` - **Description**: The position of the aim point in world coordinates. - **Usage**: Specifies where the controller is aiming, useful for aiming or pointing actions. -8. **AimRotation** +- **AimRotation** - **Type**: `FQuat` - **Description**: The rotation of the aim point in world coordinates. - **Usage**: Determines the orientation of the aim direction, important for actions like shooting or selecting objects in VR. -9. **HandKeyPositions** +- **PalmPosition** + - **Type**: `FVector` + - **Description**: The position of the palm in world coordinates. + - **Usage**: Provides the 3D location of the palm, important for determining hand gestures or interactions in VR. + +- **PalmRotation** + - **Type**: `FQuat` + - **Description**: The rotation of the palm in world coordinates. + - **Usage**: Defines the orientation of the palm, crucial for hand-based interaction accuracy and realism in VR experiences. + +- **HandKeyPositions** - **Type**: `TArray` - **Description**: An array of vectors representing key positions of the hand. - **Usage**: Provides detailed positions of key points on the hand, useful for precise hand tracking and interaction. -10. **HandKeyRotations** +- **HandKeyRotations** - **Type**: `TArray` - **Description**: An array of quaternions representing key rotations of the hand. - **Usage**: Complements the hand key positions with rotational data, ensuring accurate representation of hand movements. -11. **HandKeyRadii** +- **HandKeyRadii** - **Type**: `TArray` - **Description**: An array of floats representing the radii of key points of the hand. - **Usage**: Gives the size of the hand key points, aiding in collision detection and interaction fidelity. -12. **bIsGrasped** +- **bIsGrasped** - **Type**: `bool` - **Description**: A boolean indicating whether the controller is currently grasping an object. - **Usage**: Determines if the user is holding something, affecting interactions and animations. ### Organization of FXRMotionControllerData -The structure is organized to encapsulate all relevant data needed for motion controller tracking in a coherent and accessible manner. Boolean flags `bValid` and `bIsGrasped` provide quick checks on the state of the controller data. Identifiers `DeviceName` and `ApplicationInstanceID` ensure the correct association of data. Positional and rotational data `GripPosition`, `GripRotation`, `AimPosition`, and `AimRotation` offer precise tracking of the controller's movement. Arrays `HandKeyPositions`, `HandKeyRotations`, and `HandKeyRadii` allow detailed hand tracking, which is critical for immersive VR experiences. Lastly, the tracking status `TrackingStatus` informs the system of the reliability of the data being processed and whether the motion controller is actively being tracked or it's inactive at the moment. +The structure is organized to encapsulate all relevant data needed for hand and motion controller tracking in a coherent and accessible manner. Boolean flags `bValid` and `bIsGrasped` provide quick checks on the state of the controller data. Identifiers `DeviceName` and `ApplicationInstanceID` ensure the correct association of data. Positional and rotational data `GripPosition`, `GripRotation`, `AimPosition`, and `AimRotation` offer precise tracking of the controller's movement. Arrays `HandKeyPositions`, `HandKeyRotations`, and `HandKeyRadii` allow detailed hand tracking, which is critical for immersive VR experiences. Lastly, the tracking status `TrackingStatus` informs the system of the reliability of the data being processed and whether the motion controller is actively being tracked or it's inactive at the moment. ### Processing the Data for Drawing and Animating a Virtual Hand @@ -150,32 +170,32 @@ Unreal Engine also provides an enum called `EHandKeypoint` naming the 26 joints, UENUM(BlueprintType) enum class EHandKeypoint : uint8 { - Palm, - Wrist, - ThumbMetacarpal, - ThumbProximal, - ThumbDistal, - ThumbTip, - IndexMetacarpal, - IndexProximal, - IndexIntermediate, - IndexDistal, - IndexTip, - MiddleMetacarpal, - MiddleProximal, - MiddleIntermediate, - MiddleDistal, - MiddleTip, - RingMetacarpal, - RingProximal, - RingIntermediate, - RingDistal, - RingTip, - LittleMetacarpal, - LittleProximal, - LittleIntermediate, - LittleDistal, - LittleTip + Palm, + Wrist, + ThumbMetacarpal, + ThumbProximal, + ThumbDistal, + ThumbTip, + IndexMetacarpal, + IndexProximal, + IndexIntermediate, + IndexDistal, + IndexTip, + MiddleMetacarpal, + MiddleProximal, + MiddleIntermediate, + MiddleDistal, + MiddleTip, + RingMetacarpal, + RingProximal, + RingIntermediate, + RingDistal, + RingTip, + LittleMetacarpal, + LittleProximal, + LittleIntermediate, + LittleDistal, + LittleTip }; const int32 EHandKeypointCount = static_cast(EHandKeypoint::LittleTip) + 1; @@ -217,7 +237,7 @@ So, getting the any joint's position or rotation is as easy as casting the enum return; } - // Ensure that MotionControllerData.HandKeyPositions has the rotation data + // Ensure that MotionControllerData.HandKeyRotations has the rotation data // for 26 joints! if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num() == EHandKeypointCount, diff --git a/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/blueprint.md b/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/blueprint.md index 7ef8acf..4f9bfc9 100644 --- a/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/blueprint.md +++ b/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/blueprint.md @@ -48,4 +48,4 @@ Before continuing this section, please ensure you've studied the [Consuming FXRM 13. Now, go back to the `VRTemplateMap` and use the VR Preview button to run the game. If everything's done correctly, you should be able to see the virtual hands inside your VR simulation. -![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands") \ No newline at end of file +![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands") diff --git a/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/cpp.md b/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/cpp.md index e283b31..b1d05a0 100644 --- a/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/cpp.md +++ b/Plugins/SenseGlove/Handbook/src/advanced-topics/openxr/consuming-fxrmotioncontrollerdata/cpp.md @@ -47,30 +47,30 @@ using UnrealBuildTool; public class VirtualHandCpp : ModuleRules { - public VirtualHandCpp(ReadOnlyTargetRules Target) : base(Target) - { - PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; - - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); + public VirtualHandCpp(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); - PrivateDependencyModuleNames.AddRange(new string[] - { - "InputDevice", - "OpenXRHMD", - "SenseGloveBuildHacks", - "SenseGloveDebug", - "SenseGloveSettings", - "SenseGloveTracking" - }); + PrivateDependencyModuleNames.AddRange(new string[] + { + "InputDevice", + "OpenXRHMD", + "SenseGloveBuildHacks", + "SenseGloveDebug", + "SenseGloveSettings", + "SenseGloveTracking" + }); - // Uncomment if you are using Slate UI - // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); - - // Uncomment if you are using online features - // PrivateDependencyModuleNames.Add("OnlineSubsystem"); + // Uncomment if you are using Slate UI + // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); + + // Uncomment if you are using online features + // PrivateDependencyModuleNames.Add("OnlineSubsystem"); - // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true - } + // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true + } } ``` @@ -93,32 +93,32 @@ public class VirtualHandCpp : ModuleRules UCLASS() class VIRTUALHANDCPP_API ADebugPawn : public APawn { - GENERATED_BODY() + GENERATED_BODY() private: - // The virtual hand drawing settings. - UPROPERTY(EditDefaultsOnly, Category="DebugPawn", - meta=(AllowPrivateAccess="false")) - FSGDebugGizmoSettings HandDrawingSettings; + // The virtual hand drawing settings. + UPROPERTY(EditDefaultsOnly, Category="DebugPawn", + meta=(AllowPrivateAccess="false")) + FSGDebugGizmoSettings HandDrawingSettings; public: - // Sets default values for this pawn's properties - ADebugPawn(); + // Sets default values for this pawn's properties + ADebugPawn(); protected: - // Called when the game starts or when spawned - virtual void BeginPlay() override; + // Called when the game starts or when spawned + virtual void BeginPlay() override; public: - // Called every frame - virtual void Tick(float DeltaTime) override; + // Called every frame + virtual void Tick(float DeltaTime) override; - // Called to bind functionality to input - virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; + // Called to bind functionality to input + virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; private: - // The method responsible for drawing a virtual hand. - void DrawHand(EControllerHand Hand) const; + // The method responsible for drawing a virtual hand. + void DrawHand(EControllerHand Hand) const; }; ``` @@ -137,116 +137,116 @@ private: // Sets default values ADebugPawn::ADebugPawn() { - // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. - PrimaryActorTick.bCanEverTick = true; + // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; - // Set the default virtual hand drawing settings. - HandDrawingSettings = FSGDebugGizmoSettings{ - 1.0f, - FColor{255, 0, 0, 255}, - FColor{0, 255, 0, 255}, - FColor{0, 0, 255, 255}, - false, - 1.1f, - 0, - 0.2f, - }; + // Set the default virtual hand drawing settings. + HandDrawingSettings = FSGDebugGizmoSettings{ + 1.0f, + FColor{255, 0, 0, 255}, + FColor{0, 255, 0, 255}, + FColor{0, 0, 255, 255}, + false, + 1.1f, + 0, + 0.2f, + }; } // Called when the game starts or when spawned void ADebugPawn::BeginPlay() { - Super::BeginPlay(); + Super::BeginPlay(); } // Called every frame void ADebugPawn::Tick(float DeltaTime) { - Super::Tick(DeltaTime); + Super::Tick(DeltaTime); - // Attempt at drawing the left/right virtual hands every frame. - DrawHand(EControllerHand::Left); - DrawHand(EControllerHand::Right); + // Attempt at drawing the left/right virtual hands every frame. + DrawHand(EControllerHand::Left); + DrawHand(EControllerHand::Right); } // Called to bind functionality to input void ADebugPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { - Super::SetupPlayerInputComponent(PlayerInputComponent); + Super::SetupPlayerInputComponent(PlayerInputComponent); } void ADebugPawn::DrawHand(const EControllerHand Hand) const { - // Get the world and cache it, if it's null we return early. - UWorld* World{GetWorld()}; - if (!IsValid(World)) - { - return; - } + // Get the world and cache it, if it's null we return early. + UWorld* World{GetWorld()}; + if (!IsValid(World)) + { + return; + } - FXRMotionControllerData MotionControllerData; - const bool bGotMotionControllerData = FSGXRTracker::GetMotionControllerData( - World, Hand, MotionControllerData); + FXRMotionControllerData MotionControllerData; + const bool bGotMotionControllerData = FSGXRTracker::GetMotionControllerData( + World, Hand, MotionControllerData); - // Return if the struct data is invalid! - if (!bGotMotionControllerData || !MotionControllerData.bValid) - { - return; - } + // Return if the struct data is invalid! + if (!bGotMotionControllerData || !MotionControllerData.bValid) + { + return; + } - // Return if the device is not being tracked! - if (MotionControllerData.TrackingStatus == ETrackingStatus::NotTracked) - { - return; - } + // Return if the device is not being tracked! + if (MotionControllerData.TrackingStatus == ETrackingStatus::NotTracked) + { + return; + } - // Ensure that MotionControllerData.DeviceVisualType is a hand! - if (!ensureAlwaysMsgf(MotionControllerData.DeviceVisualType - == EXRVisualType::Hand, - TEXT("Invalid DeviceVisualType type!"))) - { - } + // Ensure that MotionControllerData.DeviceVisualType is a hand! + if (!ensureAlwaysMsgf(MotionControllerData.DeviceVisualType + == EXRVisualType::Hand, + TEXT("Invalid DeviceVisualType type!"))) + { + } - // Ensure that MotionControllerData.HandKeyPositions has the position data - // for 26 joints! - if (!ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num() - == EHandKeypointCount, - TEXT("Invalid HandKeyPositions count!"))) - { - return; - } + // Ensure that MotionControllerData.HandKeyPositions has the position data + // for 26 joints! + if (!ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num() + == EHandKeypointCount, + TEXT("Invalid HandKeyPositions count!"))) + { + return; + } - // Ensure that MotionControllerData.HandKeyPositions has the rotation data - // for 26 joints! - if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num() - == EHandKeypointCount, - TEXT("Invalid HandKeyRotations count!"))) - { - return; - } + // Ensure that MotionControllerData.HandKeyRotations has the rotation data + // for 26 joints! + if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num() + == EHandKeypointCount, + TEXT("Invalid HandKeyRotations count!"))) + { + return; + } - // Iterate over the hand joint positions and rotations! - for (int32 JointIndex = 0; JointIndex < EHandKeypointCount; ++JointIndex) - { - const FVector& JointPosition{ - MotionControllerData.HandKeyPositions[JointIndex] - }; - const FQuat& JointRotation{ - MotionControllerData.HandKeyRotations[JointIndex] - }; + // Iterate over the hand joint positions and rotations! + for (int32 JointIndex = 0; JointIndex < EHandKeypointCount; ++JointIndex) + { + const FVector& JointPosition{ + MotionControllerData.HandKeyPositions[JointIndex] + }; + const FQuat& JointRotation{ + MotionControllerData.HandKeyRotations[JointIndex] + }; - // Draw a single joint's gizmo! - // Please note that we could alternatively: - // Use FSGDebugCube::Draw() to draw a cube. - // Or use the FSGDebugVirtualHand::Draw() method and pass the - // MotionControllerData directly to draw the virtual hand - // all at once without iterating the joints. But, that's not - // goal of this tutorial. - FSGDebugGizmo::Draw(World, JointPosition, JointRotation, HandDrawingSettings); - } + // Draw a single joint's gizmo! + // Please note that we could alternatively: + // Use FSGDebugCube::Draw() to draw a cube. + // Or use the FSGDebugVirtualHand::Draw() method and pass the + // MotionControllerData directly to draw the virtual hand + // all at once without iterating the joints. But, that's not + // goal of this tutorial. + FSGDebugGizmo::Draw(World, JointPosition, JointRotation, HandDrawingSettings); + } } ``` 15. Now, rebuild the source code and go back to the `VRTemplateMap`, then use the VR Preview button to run the game. If everything's done correctly, you should be able to see the virtual hands inside your VR simulation. -![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands") \ No newline at end of file +![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands") diff --git a/Plugins/SenseGlove/Handbook/src/appendix/changelog.md b/Plugins/SenseGlove/Handbook/src/appendix/changelog.md index bc1df1f..35ed4de 100644 --- a/Plugins/SenseGlove/Handbook/src/appendix/changelog.md +++ b/Plugins/SenseGlove/Handbook/src/appendix/changelog.md @@ -5,8 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.1.4] - 2024-10-22 + +This is a bugfix release that delivers some documentation fixes. + +### Documentation + +- Updated the documentation on consuming the `FXRMotionControllerData` struct. +- Additional minor documentation fixes and improvements that may not be listed here. + ## [2.1.3] - 2024-10-11 +This bugfix release centers on adding initial support for the upcoming Unreal Engine `5.5`. + ### Added - Added initial support for the upcoming Unreal Engine `5.5` release. Please note that, while the plugin is functional, a few adjustments are still required to address deprecation warnings. Specifically, the `FXRMotionControllerData` struct needs to be replaced with the newly introduced `FXRMotionControllerState` and `FXRHandTrackingState` structs, along with adjustments to adhere to the new hand-tracking API changes. @@ -722,4 +733,4 @@ This is a minor release focusing on adherence to the Unreal Engine Marketplace G ### Added -- Initial public release of the SenseGlove haptic API for Unreal Engine with support for Microsoft Windows and GNU/Linux. \ No newline at end of file +- Initial public release of the SenseGlove haptic API for Unreal Engine with support for Microsoft Windows and GNU/Linux. diff --git a/Plugins/SenseGlove/Handbook/src/appendix/platform-support-matrix.md b/Plugins/SenseGlove/Handbook/src/appendix/platform-support-matrix.md index 3a6ea4a..daedb59 100644 --- a/Plugins/SenseGlove/Handbook/src/appendix/platform-support-matrix.md +++ b/Plugins/SenseGlove/Handbook/src/appendix/platform-support-matrix.md @@ -2,10 +2,10 @@ | | **Windows (MSVC 2017)** | **Windows (MSVC 2019)** | **Windows (MSVC 2022)** | **Linux x86-64 (Native Toolchain)** | **Linux AArch64 (Native Toolchain)** | **Meta Quest Stand-alone (Android NDK)** | **HTC VIVE Stand-alone (Android NDK)** | **UE Marketplace Version** | **Azure DevOps Version** | |:--------:|:-----------------------:|:-----------------------:|:-----------------------:|:-----------------------------------:|:------------------------------------:|:----------------------------------------:|:--------------------------------------:|:--------------------------:|:------------------------:| -| **5.5** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ❌ | ✅ v2.1.3 | -| **5.4** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.3 | -| **5.3** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.3 | -| **5.2** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.3 | +| **5.5** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ❌ | ✅ v2.1.4 | +| **5.4** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.4 | +| **5.3** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.4 | +| **5.2** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.4 | | **5.1** | ❌ | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x (r25b) | ❓ | ⚠️ v2.0.1 | ⚠️ v2.0.2 | | **5.0** | ❌ | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x (r21e) | ❓ | ⚠️ v1.6.1 | ⚠️ v1.6.1 | | **4.27** | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x (r21e) | ❓ | ⚠️ v1.3.1 | ⚠️ v1.4.3 | diff --git a/Plugins/SenseGlove/SenseGlove.uplugin b/Plugins/SenseGlove/SenseGlove.uplugin index 67dfdb8..7d4b704 100644 --- a/Plugins/SenseGlove/SenseGlove.uplugin +++ b/Plugins/SenseGlove/SenseGlove.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "2.1.3", + "VersionName": "2.1.4", "FriendlyName": "SenseGlove", "Description": "Integrating the SenseGlove haptic controller into Unreal Engine", "Category": "Virtual Reality",