Compare commits

...
14 Commits
Author SHA1 Message Date
Mamadou Babaei f0db0b0846 bump the plugin version to v1.9.2 2023-11-03 18:35:09 +01:00
Mamadou Babaei 5e1cb6a637 fix a bug where released actor is going to be null whenever the OnActorReleased event fires 2023-11-03 18:35:08 +01:00
Mamadou Babaei eca69677b1 restructure the planned features completion status 2023-11-03 18:35:08 +01:00
Mamadou Babaei fbe415c7ae update the list of planned features and their completion status 2023-11-03 18:35:08 +01:00
Mamadou Babaei 0b052356ee update the list of planned features and their completion status 2023-11-03 18:35:07 +01:00
Mamadou Babaei 42316edb95 update the list of planned features and their completion status 2023-11-03 18:35:07 +01:00
Mamadou Babaei 932bdb26d4 add a list of planned features and their completion status to the main readme file 2023-11-03 18:35:07 +01:00
Mamadou Babaei 4fe5281cd8 bump the plugin version to v1.9.1 2023-10-11 17:02:50 +02:00
Mamadou Babaei dcbe1015f8 add the missing unreal header that defines ENGINE_*_VERSION macros in order to pass epic store builds for ue 5.3 2023-10-11 17:02:49 +02:00
Mamadou Babaei 6ebee2aa2f bump the plugin version to v1.9.0 2023-10-10 17:29:53 +02:00
Mamadou Babaei 7c8f26e978 change the ufunction specifier for sgpawn blueprint implementable events to blueprint native event in order to allow overrides from c++ as well 2023-10-10 17:29:53 +02:00
Mamadou Babaei bf234d720b add a missing release note fix for v1.8.0 to the changelog file 2023-10-10 17:29:52 +02:00
Mamadou Babaei 702fdf19fa bump the plugin version to v1.8.0 2023-10-10 16:12:51 +02:00
Mamadou Babaei 0364f67ae2 This single commit inroduces the following changes:
- Introduced new SGPawn events: OnActorGrabbed, OnActorReleased, OnActorBeginTouch, and OnActorEndTouch.
- Exposed OnGrabStateUpdated, OnTouchStateUpdated, OnActorGrabbed, OnActorReleased, OnActorBeginTouch, and OnActorEndTouch events to Blueprint as BlueprintImplementableEvent.

- Fix a bug where the OnTouchStateUpdated event is mistakenly triggered instead of the OnGrabStateUpdated when the right thumb fingertip grab collider overlaps with a grabbable actor.
2023-10-10 16:12:50 +02:00
7 changed files with 270 additions and 41 deletions
+39 -1
View File
@@ -5,6 +5,44 @@ 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).
## [1.9.2] - 2023-11-03
# Added
- Added a list of planned features and their completion status to the main README file.
### Fixed
- A bug where released actor is going to be NULL whenever the OnActorReleased event fires.
## [1.9.1] - 2023-10-11
### Fixed
- Add the missing Unreal Engine C++ header to files that rely on the ENGINE\_\*\_VERSION macros in order to fix the Epic Store build failures on UE 5.3.
## [1.9.0] - 2023-10-10
### Changed
- The BlueprintImplementableEvent UFUNCTION specifier for the OnGrabStateUpdated, OnTouchStateUpdated, OnActorGrabbed, OnActorReleased, OnActorBeginTouch, and OnActorEndTouch events have been changed to BlueprintNativeEvent in order to allow them to be implemented from the child C++ classes as well. This won't break any existing Blueprint code that relies on the previous BlueprintImplementableEvent signature.
### Fixed
- Add a missing release note entry for the v1.8.0 release to the changelog file.
## [1.8.0] - 2023-10-10
### Added
- Introduced new SGPawn events: OnActorGrabbed, OnActorReleased, OnActorBeginTouch, and OnActorEndTouch.
- Exposed OnGrabStateUpdated, OnTouchStateUpdated, OnActorGrabbed, OnActorReleased, OnActorBeginTouch, and OnActorEndTouch events to Blueprint as BlueprintImplementableEvent.
### Fixed
- Fix a bug where the OnTouchStateUpdated event is mistakenly triggered instead of the OnGrabStateUpdated when the right thumb fingertip grab collider overlaps with a grabbable actor.
- Fix the DECLARE_EVENT macro signature for OnGrabStateUpdated and OnTouchStateUpdated events.
## [1.7.0] - 2023-09-14
### Added
@@ -322,4 +360,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.
- Initial public release of the SenseGlove haptic API for Unreal Engine with support for Microsoft Windows and GNU/Linux.
+50 -4
View File
@@ -15,9 +15,9 @@ This repository relies on Git LFS for storing binary blobs (e.g. third-party lib
| **4.26** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ | ❌ | ⚠️ v1.0.4 |
| **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 |
| **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.1** | ❌ | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x (r25b) | ✅ v1.7.0 | ✅ v1.7.0 |
| **5.2** | ❌ | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x (r25b) | ✅ v1.7.0 | ✅ v1.7.0 |
| **5.3** | ❌ | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x | ✅ v1.7.x (r25b) | ✅ v1.7.0 | ✅ v1.7.0 |
| **5.1** | ❌ | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x (r25b) | ✅ v1.9.1 | ✅ v1.9.1 |
| **5.2** | ❌ | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x (r25b) | ✅ v1.9.1 | ✅ v1.9.1 |
| **5.3** | ❌ | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x | ✅ v1.9.x (r25b) | ✅ v1.9.2 | ✅ v1.9.2 |
* <code>✅</code> Supported
* <code>⚠️</code> Not supported by the latest release and might be lacking features
@@ -53,6 +53,52 @@ The following modules are intended to be used by the C++ users of this plugin:
Please note that modules postfixed with **Impl** are intended for interal use and are discouraged to be used by the users of the API. The modules postfixed with **Kismet** are exposing the functionality of the equivalent modules to Blueprints. For other modules descriptions, please see [the Directory Structure section](#directory-structure).
## Planned Features Completion Status
### Implemented as of v1.9.2
- [X] Full SenseGlove low-level core API access through Unreal C++.
- [X] Full SenseGlove low-level core API access through Blueprint.
- [X] DK 1 Support.
- [X] Nova 1 Support.
- [X] Support for Microsoft Windows as a development platform.
- [X] Support for GNU/Linux as a development platform.
- [X] Support for Microsoft Windows as a deployment platform.
- [X] Support for GNU/Linux x64 as a deployment platform.
- [X] Support for GNU/Linux AArch64 as a deployment platform.
- [X] Support for Android as a deployment platform.
- [X] Support for Oculus Quest 2 and Oculus Quest Pro.
- [X] Support for HTC VIVE Pro and HTC VIVE Focus 3.
- [X] Support for HTC VIVE Trackers and HTC VIVE Wrist Trackers.
- [X] On-device calibration for Android without the need for SenseCom.
- [X] Haptic feedback including force feedback, buzz, and thumper commands.
- [X] A customizable Grab component that could be added to any actor.
- [X] A customizable Touch component that could be added to any actor.
- [X] Ability to grab, release, and throw objects around.
- [X] Separation of the real and virtual hand rendering.
- [X] An out-of-the-box customizable SGPawn with the ability to be extended in C++ and Blueprint.
- [X] Easy wrist/hand tracking debugging using the SenseGlove Debug module.
- [X] A generic Settings module with the ability to override settings.
- [X] C++/Blueprint interaction events such as OnGrabStateUpdated, OnTouchStateUpdated, OnActorGrabbed, OnActorReleased, OnActorBeginTouch, and OnActorEndTouch.
### Upcoming features planned for the v2.0.0 release
- [ ] A default hand mesh rigged with the standard SenseGlove default hand pose.
- [ ] Hand tracking compatible with OpenXR (or other generic hand tracking format).
- [ ] Nova 2 Support.
### Planned features long-term
- [ ] Get tracking input from sources other than a SenseGlove device.
- [ ] Be able to assign behaviors to different objects (meshes) in the scene (e.g. Slider, Hinge, basic Grabables, etc).
- [ ] Make it so developers can define or extend their own behavior(s) to an object through Code / Blueprints (e.g. I want a car door that is like a slider, but follows a path rather than a straight line).
- [ ] Make the hand(s) able to push around physics-driven objects (for as much as their behaviors allow) (in backlog).
- [ ] Be able to grab objects with up to 2 hands (and move them around with both hands at the same time in a way that seems realistic).
- [ ] Ensure that our virtual hands (and the objects they hold) do not phase through other physics objects (e.g. walls and tables).
- [ ] Allow other scripts to force a grab and/or release to occur (for example, when you place it apart at the designated location, it gets removed from your hand and snaps into place).
- [ ] Have some form of weight simulation by making certain objects harder to push, lowering manipulation speed, or making objects only moveable with two hands.
- [ ] (Optional) Make it so the fingers of your virtual hands do not clip inside the meshes you are holding (certain people see this as an indicator of how fast the Force-Feedback activates - but it's basically just rendering).
## Directory Structure
```
@@ -239,4 +285,4 @@ The SenseGlove plug-in for Unreal Engine is licensed under the terms of the [MIT
### Third-Party Licenses
Please note that while the SenseGlove plug-in for Unreal Engine is made available under the [MIT License](LICENSE.md), it utilizes a few third-party libraries with permissive free licenses as well, in order to power various components. For a list of these libraries and their own respective open-source licenses take a look at [LICENSE-THIRD-PARTY.md](LICENSE-THIRD-PARTY.md), please.
Please note that while the SenseGlove plug-in for Unreal Engine is made available under the [MIT License](LICENSE.md), it utilizes a few third-party libraries with permissive free licenses as well, in order to power various components. For a list of these libraries and their own respective open-source licenses take a look at [LICENSE-THIRD-PARTY.md](LICENSE-THIRD-PARTY.md), please.
+1 -1
View File
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.7.0",
"VersionName": "1.9.1",
"FriendlyName": "SenseGlove",
"Description": "Integrating the SenseGlove haptic controller into Unreal Engine",
"Category": "Virtual Reality",
@@ -44,9 +44,9 @@
#include "Engine/SkeletalMesh.h"
#include "Math/Rotator.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGLog/SGLog.h"
#include "SenseGlove/Components/SGVirtualHandComponent.h"
#include "SGLog/SGLog.h"
FSGVirtualHandAnimInstanceProxy::FSGVirtualHandAnimInstanceProxy()
: FAnimInstanceProxy()
@@ -39,6 +39,7 @@
#include "Components/PrimitiveComponent.h"
#include "Components/SphereComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "Runtime/Launch/Resources/Version.h"
#include "UObject/UObjectGlobals.h"
#include "SenseGlove/Components/SGGrabComponent.h"
@@ -145,6 +146,13 @@ struct ASGPawn::FImpl
void RecordHandVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const;
void Release(FSGGrabState& GrabState) const;
void TriggerGrabStateUpdatedEvent(const FSGGrabState& GrabState) const;
void TriggerTouchStateUpdatedEvent(const FSGTouchState& TouchState) const;
void TriggerActorGrabbedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const;
void TriggerActorReleasedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const;
void TriggerBeginTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const;
void TriggerEndTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const;
};
ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
@@ -606,6 +614,30 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
RightHandTouchState = FSGTouchState(HandRight, nullptr, nullptr, nullptr, nullptr, nullptr);
}
void ASGPawn::OnGrabStateUpdated_Implementation(const FSGGrabState& GrabState)
{
}
void ASGPawn::OnTouchStateUpdated_Implementation(const FSGTouchState& TouchState)
{
}
void ASGPawn::OnActorGrabbed_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor)
{
}
void ASGPawn::OnActorReleased_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor)
{
}
void ASGPawn::OnActorBeginTouch_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor)
{
}
void ASGPawn::OnActorEndTouch_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor)
{
}
void ASGPawn::BeginPlay()
{
Super::BeginPlay();
@@ -781,7 +813,7 @@ void ASGPawn::OnLeftThumbFingertipGrabColliderOverlapBegins(
if (USGGrabComponent::IsGrabbable(OtherActor))
{
LeftHandGrabState.ActorThumbCanGrab = OtherActor;
GrabStateUpdatedEvent.Broadcast(LeftHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState);
}
}
@@ -798,7 +830,7 @@ void ASGPawn::OnLeftThumbFingertipGrabColliderOverlapEnds(
if (LeftHandGrabState.ActorThumbCanGrab == OtherActor)
{
LeftHandGrabState.ActorThumbCanGrab = nullptr;
GrabStateUpdatedEvent.Broadcast(LeftHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState);
}
}
@@ -819,7 +851,7 @@ void ASGPawn::OnLeftIndexFingertipGrabColliderOverlapBegins(
if (USGGrabComponent::IsGrabbable(OtherActor))
{
LeftHandGrabState.ActorIndexCanGrab = OtherActor;
GrabStateUpdatedEvent.Broadcast(LeftHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState);
}
}
@@ -836,7 +868,7 @@ void ASGPawn::OnLeftIndexFingertipGrabColliderOverlapEnds(
if (LeftHandGrabState.ActorIndexCanGrab == OtherActor)
{
LeftHandGrabState.ActorIndexCanGrab = nullptr;
GrabStateUpdatedEvent.Broadcast(LeftHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState);
}
}
@@ -857,7 +889,7 @@ void ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapBegins(
if (USGGrabComponent::IsGrabbable(OtherActor))
{
LeftHandGrabState.ActorMiddleCanGrab = OtherActor;
GrabStateUpdatedEvent.Broadcast(LeftHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState);
}
}
@@ -874,7 +906,7 @@ void ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapEnds(
if (LeftHandGrabState.ActorMiddleCanGrab == OtherActor)
{
LeftHandGrabState.ActorMiddleCanGrab = nullptr;
GrabStateUpdatedEvent.Broadcast(LeftHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState);
}
}
@@ -895,7 +927,8 @@ void ASGPawn::OnLeftThumbFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
LeftHandTouchState.ActorThumbTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -912,7 +945,8 @@ void ASGPawn::OnLeftThumbFingertipTouchColliderOverlapEnds(
if (LeftHandTouchState.ActorThumbTouching == OtherActor)
{
LeftHandTouchState.ActorThumbTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -933,7 +967,8 @@ void ASGPawn::OnLeftIndexFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
LeftHandTouchState.ActorIndexTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -950,7 +985,8 @@ void ASGPawn::OnLeftIndexFingertipTouchColliderOverlapEnds(
if (LeftHandTouchState.ActorIndexTouching == OtherActor)
{
LeftHandTouchState.ActorIndexTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -971,7 +1007,8 @@ void ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
LeftHandTouchState.ActorMiddleTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -988,7 +1025,8 @@ void ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapEnds(
if (LeftHandTouchState.ActorMiddleTouching == OtherActor)
{
LeftHandTouchState.ActorMiddleTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -1009,7 +1047,8 @@ void ASGPawn::OnLeftRingFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
LeftHandTouchState.ActorRingTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -1026,7 +1065,8 @@ void ASGPawn::OnLeftRingFingertipTouchColliderOverlapEnds(
if (LeftHandTouchState.ActorRingTouching == OtherActor)
{
LeftHandTouchState.ActorRingTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -1047,7 +1087,8 @@ void ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
LeftHandTouchState.ActorPinkyTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -1064,7 +1105,8 @@ void ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapEnds(
if (LeftHandTouchState.ActorPinkyTouching == OtherActor)
{
LeftHandTouchState.ActorPinkyTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState);
Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor);
}
}
@@ -1085,7 +1127,7 @@ void ASGPawn::OnRightThumbFingertipGrabColliderOverlapBegins(
if (USGGrabComponent::IsGrabbable(OtherActor))
{
RightHandGrabState.ActorThumbCanGrab = OtherActor;
TouchStateUpdatedEvent.Broadcast(LeftHandTouchState);
Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState);
}
}
@@ -1102,7 +1144,7 @@ void ASGPawn::OnRightThumbFingertipGrabColliderOverlapEnds(
if (RightHandGrabState.ActorThumbCanGrab == OtherActor)
{
RightHandGrabState.ActorThumbCanGrab = nullptr;
GrabStateUpdatedEvent.Broadcast(RightHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState);
}
}
@@ -1123,7 +1165,7 @@ void ASGPawn::OnRightIndexFingertipGrabColliderOverlapBegins(
if (USGGrabComponent::IsGrabbable(OtherActor))
{
RightHandGrabState.ActorIndexCanGrab = OtherActor;
GrabStateUpdatedEvent.Broadcast(RightHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState);
}
}
@@ -1140,7 +1182,7 @@ void ASGPawn::OnRightIndexFingertipGrabColliderOverlapEnds(
if (RightHandGrabState.ActorThumbCanGrab == OtherActor)
{
RightHandGrabState.ActorIndexCanGrab = nullptr;
GrabStateUpdatedEvent.Broadcast(RightHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState);
}
}
@@ -1161,7 +1203,7 @@ void ASGPawn::OnRightMiddleFingertipGrabColliderOverlapBegins(
if (USGGrabComponent::IsGrabbable(OtherActor))
{
RightHandGrabState.ActorMiddleCanGrab = OtherActor;
GrabStateUpdatedEvent.Broadcast(RightHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState);
}
}
@@ -1178,7 +1220,7 @@ void ASGPawn::OnRightMiddleFingertipGrabColliderOverlapEnds(
if (RightHandGrabState.ActorMiddleCanGrab == OtherActor)
{
RightHandGrabState.ActorMiddleCanGrab = nullptr;
GrabStateUpdatedEvent.Broadcast(RightHandGrabState);
Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState);
}
}
@@ -1199,7 +1241,8 @@ void ASGPawn::OnRightThumbFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
RightHandTouchState.ActorThumbTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1216,7 +1259,8 @@ void ASGPawn::OnRightThumbFingertipTouchColliderOverlapEnds(
if (RightHandTouchState.ActorThumbTouching == OtherActor)
{
RightHandTouchState.ActorThumbTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1237,7 +1281,8 @@ void ASGPawn::OnRightIndexFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
RightHandTouchState.ActorIndexTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1254,7 +1299,8 @@ void ASGPawn::OnRightIndexFingertipTouchColliderOverlapEnds(
if (RightHandTouchState.ActorIndexTouching == OtherActor)
{
RightHandTouchState.ActorIndexTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1275,7 +1321,8 @@ void ASGPawn::OnRightMiddleFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
RightHandTouchState.ActorMiddleTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1292,7 +1339,8 @@ void ASGPawn::OnRightMiddleFingertipTouchColliderOverlapEnds(
if (RightHandTouchState.ActorMiddleTouching == OtherActor)
{
RightHandTouchState.ActorMiddleTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1313,7 +1361,8 @@ void ASGPawn::OnRightRingFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
RightHandTouchState.ActorRingTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1330,7 +1379,8 @@ void ASGPawn::OnRightRingFingertipTouchColliderOverlapEnds(
if (RightHandTouchState.ActorRingTouching == OtherActor)
{
RightHandTouchState.ActorRingTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1351,7 +1401,8 @@ void ASGPawn::OnRightPinkyFingertipTouchColliderOverlapBegins(
if (USGTouchComponent::IsTouchable(OtherActor))
{
RightHandTouchState.ActorPinkyTouching = OtherActor;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1368,7 +1419,8 @@ void ASGPawn::OnRightPinkyFingertipTouchColliderOverlapEnds(
if (RightHandTouchState.ActorPinkyTouching == OtherActor)
{
RightHandTouchState.ActorPinkyTouching = nullptr;
TouchStateUpdatedEvent.Broadcast(RightHandTouchState);
Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState);
Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor);
}
}
@@ -1471,6 +1523,8 @@ void ASGPawn::Grab(USGVirtualHandComponent* Hand, AActor* Actor)
Pimpl->SetLeftHandGrabbedActor(Actor);
}
#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 2 */
Pimpl->TriggerActorGrabbedEvent(Hand, Actor);
}
void ASGPawn::ReleaseLeft()
@@ -1923,9 +1977,47 @@ void ASGPawn::FImpl::Release(FSGGrabState& GrabState) const
ApplyHandVelocityToGrabbedActor(GrabState);
TriggerActorReleasedEvent(GrabState.Hand, GrabState.GrabbedActor);
SetGrabbedActor(GrabState, nullptr);
}
void ASGPawn::FImpl::TriggerGrabStateUpdatedEvent(const FSGGrabState& GrabState) const
{
Owner->GrabStateUpdatedEvent.Broadcast(GrabState);
Owner->OnGrabStateUpdated(GrabState);
}
void ASGPawn::FImpl::TriggerTouchStateUpdatedEvent(const FSGTouchState& TouchState) const
{
Owner->TouchStateUpdatedEvent.Broadcast(TouchState);
Owner->OnTouchStateUpdated(TouchState);
}
void ASGPawn::FImpl::TriggerActorGrabbedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const
{
Owner->ActorGrabbedEvent.Broadcast(Hand, Actor);
Owner->OnActorGrabbed(Hand, Actor);
}
void ASGPawn::FImpl::TriggerActorReleasedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const
{
Owner->ActorReleasedEvent.Broadcast(Hand, Actor);
Owner->OnActorReleased(Hand, Actor);
}
void ASGPawn::FImpl::TriggerBeginTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const
{
Owner->ActorBeginTouchEvent.Broadcast(Hand, Actor);
Owner->OnActorBeginTouch(Hand, Actor);
}
void ASGPawn::FImpl::TriggerEndTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const
{
Owner->ActorEndTouchEvent.Broadcast(Hand, Actor);
Owner->OnActorEndTouch(Hand, Actor);
}
ASGPawn::FImpl::~FImpl() = default;
void ASGPawn::FImplDeleter::operator()(const FImpl* P) const
@@ -35,6 +35,8 @@
#include "SenseGlove/GameFramework/SGPlayerController.h"
#include "Runtime/Launch/Resources/Version.h"
#if ENGINE_MAJOR_VERSION > 5 || ( ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2 )
#include "Engine/TimerHandle.h"
#else /* ENGINE_MAJOR_VERSION > 5 || ( ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2 ) */
@@ -58,23 +58,55 @@ class SENSEGLOVE_API ASGPawn : public APawn
GENERATED_UCLASS_BODY()
public:
DECLARE_EVENT_OneParam(ASGVirtualHandActor, FGrabStateUpdatedEvent, const FSGGrabState& GrabState);
DECLARE_EVENT_OneParam(ASGPawn, FGrabStateUpdatedEvent, const FSGGrabState& GrabState);
FGrabStateUpdatedEvent& OnGrabStateUpdated()
{
return GrabStateUpdatedEvent;
};
DECLARE_EVENT_OneParam(ASGVirtualHandActor, FTouchStateUpdatedEvent, const FSGTouchState& TouchState)
DECLARE_EVENT_OneParam(ASGPawn, FTouchStateUpdatedEvent, const FSGTouchState& TouchState)
FTouchStateUpdatedEvent& OnTouchStateUpdated()
{
return TouchStateUpdatedEvent;
};
DECLARE_EVENT_TwoParams(ASGPawn, FActorGrabbedEvent, const USGVirtualHandComponent* Hand, const AActor* Actor);
FActorGrabbedEvent& OnGrabbed()
{
return ActorGrabbedEvent;
};
DECLARE_EVENT_TwoParams(ASGPawn, FActorReleasedEvent, const USGVirtualHandComponent* Hand, const AActor* Actor);
FActorReleasedEvent& OnReleased()
{
return ActorReleasedEvent;
};
DECLARE_EVENT_TwoParams(ASGPawn, FActorBeginTouchEvent, const USGVirtualHandComponent* Hand, const AActor* Actor);
FActorBeginTouchEvent& OnActorBeginTouch()
{
return ActorBeginTouchEvent;
};
DECLARE_EVENT_TwoParams(ASGPawn, FActorEndTouchEvent, const USGVirtualHandComponent* Hand, const AActor* Actor);
FActorEndTouchEvent& OnActorEndTouch()
{
return ActorEndTouchEvent;
};
private:
FGrabStateUpdatedEvent GrabStateUpdatedEvent;
FTouchStateUpdatedEvent TouchStateUpdatedEvent;
FActorGrabbedEvent ActorGrabbedEvent;
FActorReleasedEvent ActorReleasedEvent;
FActorBeginTouchEvent ActorBeginTouchEvent;
FActorEndTouchEvent ActorEndTouchEvent;
private:
struct FImpl;
@@ -182,6 +214,25 @@ private:
UPROPERTY(Transient)
TArray<const AActor*> RightHandOverlappedActors;
protected:
UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn")
void OnGrabStateUpdated(const FSGGrabState& GrabState);
UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn")
void OnTouchStateUpdated(const FSGTouchState& TouchState);
UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn")
void OnActorGrabbed(const USGVirtualHandComponent* Hand, const AActor* Actor);
UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn")
void OnActorReleased(const USGVirtualHandComponent* Hand, const AActor* Actor);
UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn")
void OnActorBeginTouch(const USGVirtualHandComponent* Hand, const AActor* Actor);
UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn")
void OnActorEndTouch(const USGVirtualHandComponent* Hand, const AActor* Actor);
public:
FORCEINLINE UCameraComponent* GetCamera() const
{