bump the SenseGlove Unreal Engine Plugin to v2.1.4
This commit is contained in:
+102
-82
@@ -6,56 +6,56 @@ Taking a closer look at the `FXRMotionControllerData` declaration inside the Unr
|
|||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
struct FXRMotionControllerData
|
struct FXRMotionControllerData
|
||||||
{
|
{
|
||||||
GENERATED_USTRUCT_BODY();
|
GENERATED_USTRUCT_BODY();
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
bool bValid = false;
|
bool bValid = false;
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FName DeviceName;
|
FName DeviceName;
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FGuid ApplicationInstanceID;
|
FGuid ApplicationInstanceID;
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
EXRVisualType DeviceVisualType = EXRVisualType::Controller;
|
EXRVisualType DeviceVisualType = EXRVisualType::Controller;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
EControllerHand HandIndex = EControllerHand::Left;
|
EControllerHand HandIndex = EControllerHand::Left;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
ETrackingStatus TrackingStatus = ETrackingStatus::NotTracked;
|
ETrackingStatus TrackingStatus = ETrackingStatus::NotTracked;
|
||||||
|
|
||||||
// Vector representing an object being held in the player's hand
|
// Vector representing an object being held in the player's hand
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FVector GripPosition = FVector(0.0f);
|
FVector GripPosition = FVector(0.0f);
|
||||||
// Quaternion representing an object being held in the player's hand
|
// Quaternion representing an object being held in the player's hand
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FQuat GripRotation = FQuat(EForceInit::ForceInitToZero);
|
FQuat GripRotation = FQuat(EForceInit::ForceInitToZero);
|
||||||
|
|
||||||
// For handheld controllers, gives a vector for pointing at objects
|
// For handheld controllers, gives a vector for pointing at objects
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FVector AimPosition = FVector(0.0f);
|
FVector AimPosition = FVector(0.0f);
|
||||||
// For handheld controllers, gives a quaternion for pointing at objects
|
// For handheld controllers, gives a quaternion for pointing at objects
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FQuat AimRotation = FQuat(EForceInit::ForceInitToZero);
|
FQuat AimRotation = FQuat(EForceInit::ForceInitToZero);
|
||||||
|
|
||||||
// For handheld controllers, gives a vector for representing the hand
|
// For handheld controllers, gives a vector for representing the hand
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FVector PalmPosition = FVector(0.0f);
|
FVector PalmPosition = FVector(0.0f);
|
||||||
// For handheld controllers, gives a quaternion for representing the hand
|
// For handheld controllers, gives a quaternion for representing the hand
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
FQuat PalmRotation = FQuat(EForceInit::ForceInitToZero);
|
FQuat PalmRotation = FQuat(EForceInit::ForceInitToZero);
|
||||||
|
|
||||||
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
|
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
TArray<FVector> HandKeyPositions;
|
TArray<FVector> HandKeyPositions;
|
||||||
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
|
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
TArray<FQuat> HandKeyRotations;
|
TArray<FQuat> HandKeyRotations;
|
||||||
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
|
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
TArray<float> HandKeyRadii;
|
TArray<float> HandKeyRadii;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
UPROPERTY(BlueprintReadOnly, Category = "XR")
|
||||||
bool bIsGrasped = false;
|
bool bIsGrasped = false;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -71,68 +71,88 @@ But, fear not, we've got you covered!
|
|||||||
|
|
||||||
### Structure Members of FXRMotionControllerData
|
### Structure Members of FXRMotionControllerData
|
||||||
|
|
||||||
1. **bValid**
|
- **bValid**
|
||||||
- **Description**: A boolean flag indicating whether the data is valid or not.
|
- **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.
|
- **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`
|
- **Type**: `FName`
|
||||||
- **Description**: The name of the device.
|
- **Description**: The name of the device.
|
||||||
- **Usage**: Identifies which motion controller device the data is coming from, useful when multiple devices are in use.
|
- **Usage**: Identifies which motion controller device the data is coming from, useful when multiple devices are in use.
|
||||||
|
|
||||||
3. **ApplicationInstanceID**
|
- **ApplicationInstanceID**
|
||||||
- **Type**: `FString`
|
- **Type**: `FString`
|
||||||
- **Description**: A unique identifier for the application instance.
|
- **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.
|
- **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`
|
- **Type**: `EXRTrackingStatus`
|
||||||
- **Description**: Enum indicating the tracking status of the motion controller.
|
- **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.
|
- **Usage**: Shows whether the controller is being tracked accurately, with possible statuses like `Tracked`, `NotTracked`, etc.
|
||||||
|
|
||||||
5. **GripPosition**
|
- **GripPosition**
|
||||||
- **Type**: `FVector`
|
- **Type**: `FVector`
|
||||||
- **Description**: The position of the grip in world coordinates.
|
- **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.
|
- **Usage**: Provides the 3D coordinates of the controller's grip, essential for positioning the virtual representation of the controller.
|
||||||
|
|
||||||
6. **GripRotation**
|
- **GripRotation**
|
||||||
- **Type**: `FQuat`
|
- **Type**: `FQuat`
|
||||||
- **Description**: The rotation of the grip in world coordinates.
|
- **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.
|
- **Usage**: Provides the orientation of the controller's grip, allowing for accurate rotation and alignment in the virtual space.
|
||||||
|
|
||||||
7. **AimPosition**
|
- **AimPosition**
|
||||||
- **Type**: `FVector`
|
- **Type**: `FVector`
|
||||||
- **Description**: The position of the aim point in world coordinates.
|
- **Description**: The position of the aim point in world coordinates.
|
||||||
- **Usage**: Specifies where the controller is aiming, useful for aiming or pointing actions.
|
- **Usage**: Specifies where the controller is aiming, useful for aiming or pointing actions.
|
||||||
|
|
||||||
8. **AimRotation**
|
- **AimRotation**
|
||||||
- **Type**: `FQuat`
|
- **Type**: `FQuat`
|
||||||
- **Description**: The rotation of the aim point in world coordinates.
|
- **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.
|
- **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<FVector>`
|
- **Type**: `TArray<FVector>`
|
||||||
- **Description**: An array of vectors representing key positions of the hand.
|
- **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.
|
- **Usage**: Provides detailed positions of key points on the hand, useful for precise hand tracking and interaction.
|
||||||
|
|
||||||
10. **HandKeyRotations**
|
- **HandKeyRotations**
|
||||||
- **Type**: `TArray<FQuat>`
|
- **Type**: `TArray<FQuat>`
|
||||||
- **Description**: An array of quaternions representing key rotations of the hand.
|
- **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.
|
- **Usage**: Complements the hand key positions with rotational data, ensuring accurate representation of hand movements.
|
||||||
|
|
||||||
11. **HandKeyRadii**
|
- **HandKeyRadii**
|
||||||
- **Type**: `TArray<float>`
|
- **Type**: `TArray<float>`
|
||||||
- **Description**: An array of floats representing the radii of key points of the hand.
|
- **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.
|
- **Usage**: Gives the size of the hand key points, aiding in collision detection and interaction fidelity.
|
||||||
|
|
||||||
12. **bIsGrasped**
|
- **bIsGrasped**
|
||||||
- **Type**: `bool`
|
- **Type**: `bool`
|
||||||
- **Description**: A boolean indicating whether the controller is currently grasping an object.
|
- **Description**: A boolean indicating whether the controller is currently grasping an object.
|
||||||
- **Usage**: Determines if the user is holding something, affecting interactions and animations.
|
- **Usage**: Determines if the user is holding something, affecting interactions and animations.
|
||||||
|
|
||||||
### Organization of FXRMotionControllerData
|
### 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
|
### 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)
|
UENUM(BlueprintType)
|
||||||
enum class EHandKeypoint : uint8
|
enum class EHandKeypoint : uint8
|
||||||
{
|
{
|
||||||
Palm,
|
Palm,
|
||||||
Wrist,
|
Wrist,
|
||||||
ThumbMetacarpal,
|
ThumbMetacarpal,
|
||||||
ThumbProximal,
|
ThumbProximal,
|
||||||
ThumbDistal,
|
ThumbDistal,
|
||||||
ThumbTip,
|
ThumbTip,
|
||||||
IndexMetacarpal,
|
IndexMetacarpal,
|
||||||
IndexProximal,
|
IndexProximal,
|
||||||
IndexIntermediate,
|
IndexIntermediate,
|
||||||
IndexDistal,
|
IndexDistal,
|
||||||
IndexTip,
|
IndexTip,
|
||||||
MiddleMetacarpal,
|
MiddleMetacarpal,
|
||||||
MiddleProximal,
|
MiddleProximal,
|
||||||
MiddleIntermediate,
|
MiddleIntermediate,
|
||||||
MiddleDistal,
|
MiddleDistal,
|
||||||
MiddleTip,
|
MiddleTip,
|
||||||
RingMetacarpal,
|
RingMetacarpal,
|
||||||
RingProximal,
|
RingProximal,
|
||||||
RingIntermediate,
|
RingIntermediate,
|
||||||
RingDistal,
|
RingDistal,
|
||||||
RingTip,
|
RingTip,
|
||||||
LittleMetacarpal,
|
LittleMetacarpal,
|
||||||
LittleProximal,
|
LittleProximal,
|
||||||
LittleIntermediate,
|
LittleIntermediate,
|
||||||
LittleDistal,
|
LittleDistal,
|
||||||
LittleTip
|
LittleTip
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32 EHandKeypointCount = static_cast<int32>(EHandKeypoint::LittleTip) + 1;
|
const int32 EHandKeypointCount = static_cast<int32>(EHandKeypoint::LittleTip) + 1;
|
||||||
@@ -217,7 +237,7 @@ So, getting the any joint's position or rotation is as easy as casting the enum
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that MotionControllerData.HandKeyPositions has the rotation data
|
// Ensure that MotionControllerData.HandKeyRotations has the rotation data
|
||||||
// for 26 joints!
|
// for 26 joints!
|
||||||
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num()
|
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num()
|
||||||
== EHandKeypointCount,
|
== EHandKeypointCount,
|
||||||
|
|||||||
+1
-1
@@ -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.
|
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.
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
+115
-115
@@ -47,30 +47,30 @@ using UnrealBuildTool;
|
|||||||
|
|
||||||
public class VirtualHandCpp : ModuleRules
|
public class VirtualHandCpp : ModuleRules
|
||||||
{
|
{
|
||||||
public VirtualHandCpp(ReadOnlyTargetRules Target) : base(Target)
|
public VirtualHandCpp(ReadOnlyTargetRules Target) : base(Target)
|
||||||
{
|
{
|
||||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
|
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
|
||||||
|
|
||||||
PrivateDependencyModuleNames.AddRange(new string[]
|
PrivateDependencyModuleNames.AddRange(new string[]
|
||||||
{
|
{
|
||||||
"InputDevice",
|
"InputDevice",
|
||||||
"OpenXRHMD",
|
"OpenXRHMD",
|
||||||
"SenseGloveBuildHacks",
|
"SenseGloveBuildHacks",
|
||||||
"SenseGloveDebug",
|
"SenseGloveDebug",
|
||||||
"SenseGloveSettings",
|
"SenseGloveSettings",
|
||||||
"SenseGloveTracking"
|
"SenseGloveTracking"
|
||||||
});
|
});
|
||||||
|
|
||||||
// Uncomment if you are using Slate UI
|
// Uncomment if you are using Slate UI
|
||||||
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
|
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
|
||||||
|
|
||||||
// Uncomment if you are using online features
|
// Uncomment if you are using online features
|
||||||
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
|
// 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()
|
UCLASS()
|
||||||
class VIRTUALHANDCPP_API ADebugPawn : public APawn
|
class VIRTUALHANDCPP_API ADebugPawn : public APawn
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The virtual hand drawing settings.
|
// The virtual hand drawing settings.
|
||||||
UPROPERTY(EditDefaultsOnly, Category="DebugPawn",
|
UPROPERTY(EditDefaultsOnly, Category="DebugPawn",
|
||||||
meta=(AllowPrivateAccess="false"))
|
meta=(AllowPrivateAccess="false"))
|
||||||
FSGDebugGizmoSettings HandDrawingSettings;
|
FSGDebugGizmoSettings HandDrawingSettings;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Sets default values for this pawn's properties
|
// Sets default values for this pawn's properties
|
||||||
ADebugPawn();
|
ADebugPawn();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Called when the game starts or when spawned
|
// Called when the game starts or when spawned
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Called every frame
|
// Called every frame
|
||||||
virtual void Tick(float DeltaTime) override;
|
virtual void Tick(float DeltaTime) override;
|
||||||
|
|
||||||
// Called to bind functionality to input
|
// Called to bind functionality to input
|
||||||
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The method responsible for drawing a virtual hand.
|
// The method responsible for drawing a virtual hand.
|
||||||
void DrawHand(EControllerHand Hand) const;
|
void DrawHand(EControllerHand Hand) const;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -137,116 +137,116 @@ private:
|
|||||||
// Sets default values
|
// Sets default values
|
||||||
ADebugPawn::ADebugPawn()
|
ADebugPawn::ADebugPawn()
|
||||||
{
|
{
|
||||||
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
// 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;
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
|
|
||||||
// Set the default virtual hand drawing settings.
|
// Set the default virtual hand drawing settings.
|
||||||
HandDrawingSettings = FSGDebugGizmoSettings{
|
HandDrawingSettings = FSGDebugGizmoSettings{
|
||||||
1.0f,
|
1.0f,
|
||||||
FColor{255, 0, 0, 255},
|
FColor{255, 0, 0, 255},
|
||||||
FColor{0, 255, 0, 255},
|
FColor{0, 255, 0, 255},
|
||||||
FColor{0, 0, 255, 255},
|
FColor{0, 0, 255, 255},
|
||||||
false,
|
false,
|
||||||
1.1f,
|
1.1f,
|
||||||
0,
|
0,
|
||||||
0.2f,
|
0.2f,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the game starts or when spawned
|
// Called when the game starts or when spawned
|
||||||
void ADebugPawn::BeginPlay()
|
void ADebugPawn::BeginPlay()
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame
|
// Called every frame
|
||||||
void ADebugPawn::Tick(float DeltaTime)
|
void ADebugPawn::Tick(float DeltaTime)
|
||||||
{
|
{
|
||||||
Super::Tick(DeltaTime);
|
Super::Tick(DeltaTime);
|
||||||
|
|
||||||
// Attempt at drawing the left/right virtual hands every frame.
|
// Attempt at drawing the left/right virtual hands every frame.
|
||||||
DrawHand(EControllerHand::Left);
|
DrawHand(EControllerHand::Left);
|
||||||
DrawHand(EControllerHand::Right);
|
DrawHand(EControllerHand::Right);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to bind functionality to input
|
// Called to bind functionality to input
|
||||||
void ADebugPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
void ADebugPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
||||||
{
|
{
|
||||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADebugPawn::DrawHand(const EControllerHand Hand) const
|
void ADebugPawn::DrawHand(const EControllerHand Hand) const
|
||||||
{
|
{
|
||||||
// Get the world and cache it, if it's null we return early.
|
// Get the world and cache it, if it's null we return early.
|
||||||
UWorld* World{GetWorld()};
|
UWorld* World{GetWorld()};
|
||||||
if (!IsValid(World))
|
if (!IsValid(World))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FXRMotionControllerData MotionControllerData;
|
FXRMotionControllerData MotionControllerData;
|
||||||
const bool bGotMotionControllerData = FSGXRTracker::GetMotionControllerData(
|
const bool bGotMotionControllerData = FSGXRTracker::GetMotionControllerData(
|
||||||
World, Hand, MotionControllerData);
|
World, Hand, MotionControllerData);
|
||||||
|
|
||||||
// Return if the struct data is invalid!
|
// Return if the struct data is invalid!
|
||||||
if (!bGotMotionControllerData || !MotionControllerData.bValid)
|
if (!bGotMotionControllerData || !MotionControllerData.bValid)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return if the device is not being tracked!
|
// Return if the device is not being tracked!
|
||||||
if (MotionControllerData.TrackingStatus == ETrackingStatus::NotTracked)
|
if (MotionControllerData.TrackingStatus == ETrackingStatus::NotTracked)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that MotionControllerData.DeviceVisualType is a hand!
|
// Ensure that MotionControllerData.DeviceVisualType is a hand!
|
||||||
if (!ensureAlwaysMsgf(MotionControllerData.DeviceVisualType
|
if (!ensureAlwaysMsgf(MotionControllerData.DeviceVisualType
|
||||||
== EXRVisualType::Hand,
|
== EXRVisualType::Hand,
|
||||||
TEXT("Invalid DeviceVisualType type!")))
|
TEXT("Invalid DeviceVisualType type!")))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that MotionControllerData.HandKeyPositions has the position data
|
// Ensure that MotionControllerData.HandKeyPositions has the position data
|
||||||
// for 26 joints!
|
// for 26 joints!
|
||||||
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num()
|
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num()
|
||||||
== EHandKeypointCount,
|
== EHandKeypointCount,
|
||||||
TEXT("Invalid HandKeyPositions count!")))
|
TEXT("Invalid HandKeyPositions count!")))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that MotionControllerData.HandKeyPositions has the rotation data
|
// Ensure that MotionControllerData.HandKeyRotations has the rotation data
|
||||||
// for 26 joints!
|
// for 26 joints!
|
||||||
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num()
|
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num()
|
||||||
== EHandKeypointCount,
|
== EHandKeypointCount,
|
||||||
TEXT("Invalid HandKeyRotations count!")))
|
TEXT("Invalid HandKeyRotations count!")))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over the hand joint positions and rotations!
|
// Iterate over the hand joint positions and rotations!
|
||||||
for (int32 JointIndex = 0; JointIndex < EHandKeypointCount; ++JointIndex)
|
for (int32 JointIndex = 0; JointIndex < EHandKeypointCount; ++JointIndex)
|
||||||
{
|
{
|
||||||
const FVector& JointPosition{
|
const FVector& JointPosition{
|
||||||
MotionControllerData.HandKeyPositions[JointIndex]
|
MotionControllerData.HandKeyPositions[JointIndex]
|
||||||
};
|
};
|
||||||
const FQuat& JointRotation{
|
const FQuat& JointRotation{
|
||||||
MotionControllerData.HandKeyRotations[JointIndex]
|
MotionControllerData.HandKeyRotations[JointIndex]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw a single joint's gizmo!
|
// Draw a single joint's gizmo!
|
||||||
// Please note that we could alternatively:
|
// Please note that we could alternatively:
|
||||||
// Use FSGDebugCube::Draw() to draw a cube.
|
// Use FSGDebugCube::Draw() to draw a cube.
|
||||||
// Or use the FSGDebugVirtualHand::Draw() method and pass the
|
// Or use the FSGDebugVirtualHand::Draw() method and pass the
|
||||||
// MotionControllerData directly to draw the virtual hand
|
// MotionControllerData directly to draw the virtual hand
|
||||||
// all at once without iterating the joints. But, that's not
|
// all at once without iterating the joints. But, that's not
|
||||||
// goal of this tutorial.
|
// goal of this tutorial.
|
||||||
FSGDebugGizmo::Draw(World, JointPosition, JointRotation, HandDrawingSettings);
|
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.
|
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.
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -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/),
|
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).
|
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
|
## [2.1.3] - 2024-10-11
|
||||||
|
|
||||||
|
This bugfix release centers on adding initial support for the upcoming Unreal Engine `5.5`.
|
||||||
|
|
||||||
### Added
|
### 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.
|
- 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
|
### Added
|
||||||
|
|
||||||
- Initial public release of the SenseGlove haptic API for Unreal Engine with support for Microsoft Windows and GNU/Linux.
|
- Initial public release of the SenseGlove haptic API for Unreal Engine with support for Microsoft Windows and GNU/Linux.
|
||||||
|
|||||||
@@ -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** |
|
| | **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.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.3 |
|
| **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.3 |
|
| **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.3 |
|
| **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.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 |
|
| **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 |
|
| **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 |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"FileVersion": 3,
|
"FileVersion": 3,
|
||||||
"Version": 1,
|
"Version": 1,
|
||||||
"VersionName": "2.1.3",
|
"VersionName": "2.1.4",
|
||||||
"FriendlyName": "SenseGlove",
|
"FriendlyName": "SenseGlove",
|
||||||
"Description": "Integrating the SenseGlove haptic controller into Unreal Engine",
|
"Description": "Integrating the SenseGlove haptic controller into Unreal Engine",
|
||||||
"Category": "Virtual Reality",
|
"Category": "Virtual Reality",
|
||||||
|
|||||||
Reference in New Issue
Block a user