Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d515c87613
|
||
|
|
68210423a5
|
||
|
|
a953f197ae
|
||
|
|
248919b080
|
||
|
|
dcea66c48c
|
||
|
|
c953e3afac
|
||
|
|
f0e0b30685
|
||
|
|
005eb48232
|
||
|
|
208ce5f96a
|
||
|
|
d85252c69f
|
||
|
|
da570f30c2
|
||
|
|
48a62f7aee
|
||
|
|
aac0d9d348
|
||
|
|
f9f93fd301
|
||
|
|
26078b6cf6
|
||
|
|
324861820c
|
||
|
|
f5d38f0975
|
||
|
|
4e86707676
|
||
|
|
8c652038b5
|
||
|
|
c63e5af789
|
||
|
|
bd9e3f0f3c
|
||
|
|
51388d14f9
|
||
|
|
585e8fb9d0
|
||
|
|
9d897c7f08
|
||
|
|
ab0abee814
|
||
|
|
8701964cc6
|
||
|
|
29b468bdc5
|
||
|
|
1cee88159b
|
||
|
|
f41ff82013
|
||
|
|
73d87cb94a
|
||
|
|
cee6d98636
|
||
|
|
15eaa1650b
|
||
|
|
eedac54709
|
||
|
|
dcf82891f1
|
||
|
|
0527b7e727
|
||
|
|
25b3bdef58
|
||
|
|
6a5ee47681
|
||
|
|
ba578eec6b
|
||
|
|
115ee6b915
|
||
|
|
179ad610f0
|
||
|
|
a1b79aba1f
|
||
|
|
2156f793cc
|
||
|
|
3a2c558df8
|
||
|
|
796242627b
|
||
|
|
c65f968678
|
||
|
|
0af8eb3c51
|
||
|
|
fe3515f6f2
|
||
|
|
a0d009c7de
|
||
|
|
637479655b
|
||
|
|
0d8fcf75d3
|
||
|
|
e72d052799
|
+1
-1
@@ -124,4 +124,4 @@ DerivedDataCache/*
|
|||||||
.ignore
|
.ignore
|
||||||
|
|
||||||
# Do not ignore anything inside the ThirdParty directory at all
|
# Do not ignore anything inside the ThirdParty directory at all
|
||||||
!Source/ThirdParty/**/*
|
!ThirdParty/**/*
|
||||||
|
|||||||
+1
-105
@@ -5,110 +5,6 @@ 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).
|
||||||
|
|
||||||
## [v1.3.1] - 2023-04-28
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix RunUAT build issues caused by missing headers.
|
|
||||||
|
|
||||||
## [v1.3.0] - 2023-04-28
|
|
||||||
|
|
||||||
This release breaks ABI/API compatibility with the previous versions in addition to breaking coordinates systems conversions between Unreal Engine and the SenseGlove libraries.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- A new generic SenseGlove Debug module.
|
|
||||||
- A debug virtual hand.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix the wrist tracker miscalculations for the Quest 2 controllers (other headsets might needs fixing as well, in that case future releases will address that).
|
|
||||||
- Minor code improvement and fixes.
|
|
||||||
- Minor documentation fixes.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Breaking API/ABI changes in the Settings and the main SenseGlove module due to some settings refactoring.
|
|
||||||
- Breaking changes in the SenseGlove/Unreal coordinates systems conversions due to underlying changes in the SenseGlove Core Libraries.
|
|
||||||
- SenseGlove libraries have been updated to v2.6.0-aac3d56.
|
|
||||||
|
|
||||||
## [v1.2.1] - 2023-03-30
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix RunUAT build issues with Android.
|
|
||||||
|
|
||||||
## [v1.2.0] - 2023-03-28
|
|
||||||
|
|
||||||
This release breaks ABI/API compatibility with the previous versions.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Android / Oculus on-device glove calibration.
|
|
||||||
- Introduced the animated Virtual Hand Model (as a set of virtual hand and wrist tracker components and an actor) with in-editor animation availability.
|
|
||||||
- Introduced SGPawn, SGPlayerController, SGGameModeBase, etc classes.
|
|
||||||
- Added an internal SenseGloveCoreTypes module in order to share common SenseGloveCore types between various modules.
|
|
||||||
- Segregated Android binaries for NDK r21e (UE 4.27 and 5.0) and r25b (UE 5.1, 5.2).
|
|
||||||
- Fully functional and stable Linux development support.
|
|
||||||
- Fully functional and stable Unreal Engine 5.2 preview support has been added.
|
|
||||||
- Added a Plugin's settings manager and two new modules SenseGloveSettings and SenseGloveSettingsKismet.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- SenseGlove libraries have been updated to the Linux-aware version: v2.5.0-8069342.
|
|
||||||
- API has changed to use degrees instead of radians.
|
|
||||||
- SGCoordinates utility class name has been changed to SGAngles and now the plugin API uses degrees in contrast of SenseGlove libraries by default.
|
|
||||||
- Migrate common nested array types into the SenseGloveTypes module from the SenseGloveCore module.
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
- Removed a few thousands lines of archaic pre-public-release dead code.
|
|
||||||
- Dropped Android NDK r21b binaries used by the older engine versions.
|
|
||||||
- Purged the dead code for dropped engine versions by v1.1.1 (4.22, 4.23, 4.24, 4.25, and 4.26) that carried over to the current version.
|
|
||||||
- Removed redundant SGConnectImpl/SGPlatform.
|
|
||||||
- Removed redundant SGTypes/SGConnectTypes.
|
|
||||||
|
|
||||||
### Known Issues
|
|
||||||
|
|
||||||
- Wrist Tracker's offsets are a bit off (e.g. on Quest 2), scheduled to be fixed in the next patch release.
|
|
||||||
|
|
||||||
## [1.1.1] - 2023-02-07
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Initial support for the upcoming Unreal Engine 5.2.
|
|
||||||
- Add support for Android armeabi-v7a with neon, x86-64, and x86 builds in addition to arm64-v8a.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix various Android build issues.
|
|
||||||
- Some minor fixes and improvements.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Bump SenseGlove libraries to v2.1.2-95ec6e7.
|
|
||||||
|
|
||||||
## [1.1.0] - 2023-02-03
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Whitelist Android as a target platform.
|
|
||||||
- Introduce Android support.
|
|
||||||
- Add third-pary library SGConnect for Android v1.1.0.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix Android build issues caused by the log module.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- SGConnect and SGCore libraries have been updated to v2.1.1-0569c74.
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
- Removed the enum utils class due to ANY_PACKAGE deprecation warnings in Unreal Engine 5.1.
|
|
||||||
- Support for older versions of the Engine (namely, 4.22, 4.23, 4.24, 4.25, and 4.26) has been dropped.
|
|
||||||
|
|
||||||
## [1.0.4] - 2022-12-02
|
## [1.0.4] - 2022-12-02
|
||||||
|
|
||||||
This is a minor release focusing mostly on adherence to the Unreal Engine Marketplace Guidelines based on the feedback from Epic Games.
|
This is a minor release focusing mostly on adherence to the Unreal Engine Marketplace Guidelines based on the feedback from Epic Games.
|
||||||
@@ -160,4 +56,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.
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ The SenseGlove plug-in for Unreal Engine is licensed under the terms of the MIT
|
|||||||
```
|
```
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2020 - 2023 SenseGlove
|
Copyright (c) 2020 - 2022 SenseGlove
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -6,29 +6,26 @@ This repository relies on Git LFS for storing binary blobs (e.g. third-party lib
|
|||||||
|
|
||||||
## Platform Support Matrix
|
## Platform Support Matrix
|
||||||
|
|
||||||
| | **Windows (MSVC 2017)** | **Windows (MSVC 2019)** | **Windows (MSVC 2022)** | **Linux (Native Toolchain)** | **macOS** | **Oculus Mobile (Android NDK)** |
|
| | **Windows<br>(MSVC 2017)** | **Windows<br>(MSVC 2019)** | **Windows<br>(MSVC 2022)** | **Linux<br>(Native Toolchain)** | **macOS** | **Oculus Mobile<br>(Android NDK r21b)** |
|
||||||
|:--------:|:-----------------------:|:-----------------------:|:-----------------------:|:----------------------------:|:---------:|:-------------------------------:|
|
|----------|:--------------------------:|:--------------------------:|:--------------------------:|:-------------------------------:|:---------:|:---------------------------------------:|
|
||||||
| **4.22** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
| **4.22** | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
||||||
| **4.23** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
| **4.23** | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
||||||
| **4.24** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
| **4.24** | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
||||||
| **4.25** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
| **4.25** | ✅ | ✅ | ❌ | ✅ | ❌ | ❓ |
|
||||||
| **4.26** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
| **4.26** | ✅ | ✅ | ❌ | ✅ | ❌ | ❓ |
|
||||||
| **4.27** | ✅ v1.3.x | ✅ v1.3.x | ✅ v1.3.x | ✅ v1.3.x | ❌ | ✅ v1.3.x (r21e) |
|
| **4.27** | ✅ | ✅ | ✅ | ✅ | ❌ | ❓ |
|
||||||
| **5.0** | ❌ | ✅ v1.3.x | ✅ v1.3.x | ✅ v1.3.x | ❌ | ✅ v1.3.x (r21e) |
|
| **5.0** | ❌ | ✅ | ✅ | ✅ | ❌ | ❓ |
|
||||||
| **5.1** | ❌ | ✅ v1.3.x | ✅ v1.3.x | ✅ v1.3.x | ❌ | ✅ v1.3.x (r25b) |
|
| **5.1** | ❌ | ✅ | ✅ | ✅ | ❌ | ❓ |
|
||||||
| **5.2** | ❌ | ✅ v1.3.x | ✅ v1.3.x | ✅ v1.3.x | ❌ | ✅ v1.3.x (r25b) |
|
|
||||||
|
|
||||||
* <code>✅</code> Supported
|
* <code>✅</code> Supported
|
||||||
* <code>⚠️</code> Not supported by the latest release and might be lacking features
|
* <code>❌</code> Not Supported
|
||||||
* <code>❌</code> Not supported at all
|
* <code>❓</code> Unknown or Untested
|
||||||
* <code>❓</code> Unknown or untested
|
|
||||||
|
|
||||||
Remarks:
|
Remarks:
|
||||||
* Microsoft Visual Studio 2022 is not supported by Unreal Engine 4.22 through 4.26.
|
* Microsoft Visual Studio 2022 is not supported by Unreal Engine 4.22 through 4.26.
|
||||||
* All third-party libraries on Windows built against Windows SDK 10.0.
|
* All third-party libraries on Windows built against Windows SDK 10.0.
|
||||||
* Oculus support is only provided through the recommended Android NDK versions by Epic Games.
|
* Oculus support is only provided through the recommended Android NDK r21b by Epic Games.
|
||||||
* The Unreal Engine 4.27+ support is provided for Android/Oculus development.
|
* Supporting Unreal Engine 4.22 through 4.24 for Oculus development is a huge challenge due to limited Android NDK support (r14b to r18b); firstly, because of uncomplete C++11 standard library support, and second, as a result of a known bug in Unreal Engine, which falsely detects NDK r18b as unsupported r18c. Thus, only Unreal Engine 4.25+ support is provided for Android/Oculus development. Third, [wjwwood/serial](https://github.com/wjwwood/serial) requires Android NDK API Level 28+ in order to be built successfully, thus some older NDKs such as r14b, which is the recommended NDK by Epic Games for 4.22 to 4.24 cannot build the serial library.
|
||||||
* [wjwwood/serial](https://github.com/wjwwood/serial) requires Android NDK API Level 28+ in order to be built successfully, thus some older NDKs such as r14b.
|
|
||||||
* All third-party libraries target Android NDK API Level 29, thus any project relying on the plug-in should be build with the same NDK API Level.
|
* All third-party libraries target Android NDK API Level 29, thus any project relying on the plug-in should be build with the same NDK API Level.
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
@@ -54,7 +51,7 @@ Please note that modules postfixed with **Impl** are intended for interal use an
|
|||||||
## Directory Structure
|
## Directory Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
/
|
Source
|
||||||
│
|
│
|
||||||
├── Config
|
├── Config
|
||||||
│
|
│
|
||||||
@@ -64,8 +61,6 @@ Please note that modules postfixed with **Impl** are intended for interal use an
|
|||||||
│
|
│
|
||||||
├── SenseGlove (the UE-specific high-level API)
|
├── SenseGlove (the UE-specific high-level API)
|
||||||
│
|
│
|
||||||
├── SenseGloveAndroid (the Android-specific module)
|
|
||||||
│
|
|
||||||
├── SenseGloveBuildHacks (uses Exceptions and RTTI, internally used for compiler-specific build hacks)
|
├── SenseGloveBuildHacks (uses Exceptions and RTTI, internally used for compiler-specific build hacks)
|
||||||
│
|
│
|
||||||
├── SenseGloveConnect (exposes part of the SGConnect low-level API to C++)
|
├── SenseGloveConnect (exposes part of the SGConnect low-level API to C++)
|
||||||
@@ -80,29 +75,19 @@ Please note that modules postfixed with **Impl** are intended for interal use an
|
|||||||
│
|
│
|
||||||
├── SenseGloveCoreKismet (SGCoreCpp functionality exposed to Blueprints)
|
├── SenseGloveCoreKismet (SGCoreCpp functionality exposed to Blueprints)
|
||||||
│
|
│
|
||||||
├── SenseGloveCoreTypes (exposes special public types from the SenseGloveCore module in order to be shared by with other modules)
|
|
||||||
│
|
|
||||||
├── SenseGloveDebug (a utility debug module)
|
|
||||||
│
|
|
||||||
├── SenseGloveEditor (the Editor module)
|
├── SenseGloveEditor (the Editor module)
|
||||||
│
|
│
|
||||||
├── SenseGloveInterop (internally used for interoperability between RTTI disabled/enabled modules)
|
├── SenseGloveInterop (internally used for interoperability between RTTI disabled/enabled modules)
|
||||||
│
|
│
|
||||||
├── SenseGloveKismet (exposes Blueprints-specific functionality from the SenseGlove module)
|
├── SenseGloveKismet(exposes Blueprints-specific functionality from the SenseGlove module)
|
||||||
│
|
│
|
||||||
├── SenseGloveLog (the internal log module)
|
├── SenseGloveLog (the internal log module)
|
||||||
│
|
│
|
||||||
├── SenseGloveSettings (the plugin's settings manager)
|
├── SenseGloveTypes (exposes various enums from the backend libraries)
|
||||||
│
|
|
||||||
├── SenseGloveSettingsKismet (exposes Blueprints-specific functionality from the SenseGloveSettings module)
|
|
||||||
│
|
|
||||||
├── SenseGloveTypes (exposes various enums from the backend libraries and also types from the SenseGlove module)
|
|
||||||
│
|
│
|
||||||
├── SenseGloveUtils (the internal utility module)
|
├── SenseGloveUtils (the internal utility module)
|
||||||
│
|
│
|
||||||
└── ThirdParty (3rd-party dependencies)
|
└── ThirdParty (3rd-party dependencies)
|
||||||
│
|
|
||||||
├── android (.jar file Java libraries for Android)
|
|
||||||
│
|
│
|
||||||
├── include (header files)
|
├── include (header files)
|
||||||
│ │
|
│ │
|
||||||
@@ -117,90 +102,52 @@ Please note that modules postfixed with **Impl** are intended for interal use an
|
|||||||
│ └── serial
|
│ └── serial
|
||||||
│
|
│
|
||||||
└── lib (platform-specific pre-built binary dependencies)
|
└── lib (platform-specific pre-built binary dependencies)
|
||||||
│
|
|
||||||
├── android
|
|
||||||
│ │
|
|
||||||
│ ├── r21e (Android NDK r21e dependencies for UE 4.27 and 5.0)
|
|
||||||
│ │ │
|
|
||||||
│ │ │
|
|
||||||
│ │ ├── arm64 (64-bit Arm variant of Android)
|
|
||||||
│ │ │ │
|
|
||||||
│ │ │ ├── debug
|
|
||||||
│ │ │ │
|
|
||||||
│ │ │ └── release
|
|
||||||
│ │ │
|
|
||||||
│ │ ├── armv7 (32-bit ARM variant of Android)
|
|
||||||
│ │ │ │
|
|
||||||
│ │ │ ├── debug
|
|
||||||
│ │ │ │
|
|
||||||
│ │ │ └── release
|
|
||||||
│ │ │
|
|
||||||
│ │ ├── x64 (64-bit x86-64 variant of Android)
|
|
||||||
│ │ │ │
|
|
||||||
│ │ │ ├── debug
|
|
||||||
│ │ │ │
|
|
||||||
│ │ │ └── release
|
|
||||||
│ │ │
|
|
||||||
│ │ └── x86 (32-bit x86 variant of Android)
|
|
||||||
│ │ │
|
|
||||||
│ │ ├── debug
|
|
||||||
│ │ │
|
|
||||||
│ │ └── release
|
|
||||||
│ │
|
|
||||||
│ └── r25b (Android NDK r21b dependencies for UE 5.1)
|
|
||||||
│ │
|
|
||||||
│ │
|
|
||||||
│ ├── arm64 (64-bit Arm variant of Android)
|
|
||||||
│ │ │
|
|
||||||
│ │ ├── debug
|
|
||||||
│ │ │
|
|
||||||
│ │ └── release
|
|
||||||
│ │
|
|
||||||
│ ├── armv7 (32-bit ARM variant of Android)
|
|
||||||
│ │ │
|
|
||||||
│ │ ├── debug
|
|
||||||
│ │ │
|
|
||||||
│ │ └── release
|
|
||||||
│ │
|
|
||||||
│ ├── x64 (64-bit x86-64 variant of Android)
|
|
||||||
│ │ │
|
|
||||||
│ │ ├── debug
|
|
||||||
│ │ │
|
|
||||||
│ │ └── release
|
|
||||||
│ │
|
|
||||||
│ └── x86 (32-bit x86 variant of Android)
|
|
||||||
│ │
|
|
||||||
│ ├── debug
|
|
||||||
│ │
|
|
||||||
│ └── release
|
|
||||||
│
|
│
|
||||||
├── linux
|
├── linux
|
||||||
│ │
|
│ │
|
||||||
|
│ ├── v13 (UE 4.22 Linux dependencies)
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── debug
|
||||||
|
│ │ │
|
||||||
|
│ │ └── release
|
||||||
|
│ │
|
||||||
|
│ ├── v15 (UE 4.23 and 4.24 Linux dependencies)
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── debug
|
||||||
|
│ │ │
|
||||||
|
│ │ └── release
|
||||||
|
│ │
|
||||||
|
│ ├── v16 (UE 4.25 Linux dependencies)
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── debug
|
||||||
|
│ │ │
|
||||||
|
│ │ └── release
|
||||||
|
│ │
|
||||||
|
│ ├── v17 (UE 4.26 Linux dependencies)
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── debug
|
||||||
|
│ │ │
|
||||||
|
│ │ └── release
|
||||||
|
│ │
|
||||||
│ ├── v19 (UE 4.27 Linux dependencies)
|
│ ├── v19 (UE 4.27 Linux dependencies)
|
||||||
│ │ │
|
│ │ │
|
||||||
│ │ ├── debug
|
│ │ ├── debug
|
||||||
│ │ │
|
│ │ │
|
||||||
│ │ └── release
|
│ │ └── release
|
||||||
│ │
|
│ │
|
||||||
│ ├── v20 (UE 5.0 and 5.1 Linux dependencies)
|
│ └── v20 (UE 5.0 and 5.1 Linux dependencies)
|
||||||
│ │ │
|
|
||||||
│ │ ├── debug
|
|
||||||
│ │ │
|
|
||||||
│ │ └── release
|
|
||||||
│ │
|
|
||||||
│ └── v21 (UE 5.2 Linux dependencies)
|
|
||||||
│ │
|
│ │
|
||||||
│ ├── debug
|
│ ├── debug
|
||||||
│ │
|
│ │
|
||||||
│ └── release
|
│ └── release
|
||||||
│
|
│
|
||||||
|
├── oculus
|
||||||
|
│ │
|
||||||
|
│ ├── debug
|
||||||
|
│ │
|
||||||
|
│ └── release
|
||||||
|
│
|
||||||
└── win64
|
└── win64
|
||||||
│
|
|
||||||
├── msvc141 (Microsoft Visual Studio 2017 dependencies)
|
|
||||||
│ │
|
|
||||||
│ ├── debug
|
|
||||||
│ │
|
|
||||||
│ └── release
|
|
||||||
│
|
│
|
||||||
├── msvc142 (Microsoft Visual Studio 2019 dependencies)
|
├── msvc142 (Microsoft Visual Studio 2019 dependencies)
|
||||||
│ │
|
│ │
|
||||||
@@ -223,4 +170,4 @@ The SenseGlove plug-in for Unreal Engine is licensed under the terms of the [MIT
|
|||||||
|
|
||||||
### Third-Party Licenses
|
### 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.
|
||||||
|
|||||||
+2
-65
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"FileVersion": 3,
|
"FileVersion": 3,
|
||||||
"Version": 1,
|
"Version": 1,
|
||||||
"VersionName": "1.3.1",
|
"VersionName": "1.0.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",
|
||||||
@@ -10,12 +10,12 @@
|
|||||||
"DocsURL": "https://senseglove.gitlab.io/unreal-blueprint-docs/",
|
"DocsURL": "https://senseglove.gitlab.io/unreal-blueprint-docs/",
|
||||||
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/5e1d408f517b4966a269ec1035de0b9e",
|
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/5e1d408f517b4966a269ec1035de0b9e",
|
||||||
"SupportURL": "https://www.senseglove.com/support/",
|
"SupportURL": "https://www.senseglove.com/support/",
|
||||||
|
"EngineVersion": "4.26.0",
|
||||||
"CanContainContent": true,
|
"CanContainContent": true,
|
||||||
"IsBetaVersion": false,
|
"IsBetaVersion": false,
|
||||||
"IsExperimentalVersion": false,
|
"IsExperimentalVersion": false,
|
||||||
"Installed": false,
|
"Installed": false,
|
||||||
"SupportedTargetPlatforms": [
|
"SupportedTargetPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
],
|
],
|
||||||
@@ -25,17 +25,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "Default",
|
"LoadingPhase": "Default",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
|
||||||
"Win64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "SenseGloveAndroid",
|
|
||||||
"Type": "Runtime",
|
|
||||||
"LoadingPhase": "PreDefault",
|
|
||||||
"WhitelistPlatforms": [
|
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -45,7 +34,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -55,7 +43,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -65,7 +52,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -75,7 +61,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -85,7 +70,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -95,7 +79,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -105,27 +88,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
|
||||||
"Win64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "SenseGloveCoreTypes",
|
|
||||||
"Type": "Runtime",
|
|
||||||
"LoadingPhase": "PreDefault",
|
|
||||||
"WhitelistPlatforms": [
|
|
||||||
"Android",
|
|
||||||
"Linux",
|
|
||||||
"Win64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "SenseGloveDebug",
|
|
||||||
"Type": "Runtime",
|
|
||||||
"LoadingPhase": "PreDefault",
|
|
||||||
"WhitelistPlatforms": [
|
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -144,7 +106,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -154,7 +115,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -164,27 +124,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
|
||||||
"Win64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "SenseGloveSettings",
|
|
||||||
"Type": "Runtime",
|
|
||||||
"LoadingPhase": "PreDefault",
|
|
||||||
"WhitelistPlatforms": [
|
|
||||||
"Android",
|
|
||||||
"Linux",
|
|
||||||
"Win64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "SenseGloveSettingsKismet",
|
|
||||||
"Type": "Runtime",
|
|
||||||
"LoadingPhase": "PreDefault",
|
|
||||||
"WhitelistPlatforms": [
|
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -194,7 +133,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -204,7 +142,6 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
"Android",
|
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h"
|
|
||||||
|
|
||||||
USGVirtualHandAnimInstance::USGVirtualHandAnimInstance(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
FSGVirtualHandAnimInstanceProxy* USGVirtualHandAnimInstance::CreateAnimInstanceProxy()
|
|
||||||
{
|
|
||||||
return new FSGVirtualHandAnimInstanceProxy();
|
|
||||||
}
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h"
|
|
||||||
|
|
||||||
#include "BoneContainer.h"
|
|
||||||
#include "BoneControllers/AnimNode_ModifyBone.h"
|
|
||||||
#include "BonePose.h"
|
|
||||||
#include "Containers/Array.h"
|
|
||||||
#include "Containers/Map.h"
|
|
||||||
#include "Containers/UnrealString.h"
|
|
||||||
#include "Engine/SkeletalMesh.h"
|
|
||||||
#include "Math/Rotator.h"
|
|
||||||
#include "Runtime/Launch/Resources/Version.h"
|
|
||||||
#include "SGLog/SGLog.h"
|
|
||||||
|
|
||||||
#include "SenseGlove/Components/SGVirtualHandComponent.h"
|
|
||||||
|
|
||||||
FSGVirtualHandAnimInstanceProxy::FSGVirtualHandAnimInstanceProxy()
|
|
||||||
: FAnimInstanceProxy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
FSGVirtualHandAnimInstanceProxy::FSGVirtualHandAnimInstanceProxy(UAnimInstance* Instance)
|
|
||||||
: FAnimInstanceProxy(Instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void FSGVirtualHandAnimInstanceProxy::PreEvaluateAnimation(UAnimInstance* InAnimInstance)
|
|
||||||
{
|
|
||||||
FAnimInstanceProxy::PreEvaluateAnimation(InAnimInstance);
|
|
||||||
|
|
||||||
if (!IsValid(InAnimInstance))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
USGVirtualHandComponent* VirtualHand{Cast<USGVirtualHandComponent>(GetSkelMeshComponent())};
|
|
||||||
if (!IsValid(VirtualHand))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BonesRotations.Empty();
|
|
||||||
|
|
||||||
if (!VirtualHand->IsGloveConnected())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BonesRotations = VirtualHand->GetFingersBonesRotations();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
|
|
||||||
{
|
|
||||||
USGVirtualHandComponent* VirtualHand{Cast<USGVirtualHandComponent>(GetSkelMeshComponent())};
|
|
||||||
if (!IsValid(VirtualHand) && !VirtualHand->IsGloveConnected())
|
|
||||||
{
|
|
||||||
return FAnimInstanceProxy::Evaluate(Output);
|
|
||||||
}
|
|
||||||
|
|
||||||
const USkeletalMesh* HandMesh{VirtualHand->
|
|
||||||
#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1
|
|
||||||
GetSkeletalMeshAsset()
|
|
||||||
#else /* ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1 */
|
|
||||||
SkeletalMesh
|
|
||||||
#endif /* ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1 */
|
|
||||||
};
|
|
||||||
if (!IsValid(HandMesh))
|
|
||||||
{
|
|
||||||
return FAnimInstanceProxy::Evaluate(Output);
|
|
||||||
}
|
|
||||||
|
|
||||||
const USkeleton* HandSkeleton{HandMesh->GetSkeleton()};
|
|
||||||
if (!IsValid(HandSkeleton))
|
|
||||||
{
|
|
||||||
return FAnimInstanceProxy::Evaluate(Output);
|
|
||||||
}
|
|
||||||
|
|
||||||
FComponentSpacePoseContext PoseContext{Output.AnimInstanceProxy};
|
|
||||||
PoseContext.Pose.InitPose(Output.Pose);
|
|
||||||
|
|
||||||
for (const TTuple<FName, FRotator>& Bone: BonesRotations)
|
|
||||||
{
|
|
||||||
FName BoneName{Bone.Key};
|
|
||||||
FRotator BoneRotation{Bone.Value};
|
|
||||||
|
|
||||||
const int32 BoneIndex = GetRequiredBones().GetPoseBoneIndexForBoneName(BoneName);
|
|
||||||
if (BoneIndex == INDEX_NONE)
|
|
||||||
{
|
|
||||||
SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for '%s' finger bone!"),
|
|
||||||
*BoneName.ToString()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
FBoneReference BoneReference;
|
|
||||||
BoneReference.BoneName = MoveTemp(BoneName);
|
|
||||||
BoneReference.BoneIndex = BoneIndex;
|
|
||||||
BoneReference.bUseSkeletonIndex = true;
|
|
||||||
|
|
||||||
FAnimNode_ModifyBone BoneController;
|
|
||||||
BoneController.BoneToModify = MoveTemp(BoneReference);
|
|
||||||
BoneController.Rotation = MoveTemp(BoneRotation);
|
|
||||||
BoneController.RotationMode = EBoneModificationMode::BMM_Replace;
|
|
||||||
BoneController.RotationSpace = EBoneControlSpace::BCS_ParentBoneSpace;
|
|
||||||
BoneController.ScaleMode = EBoneModificationMode::BMM_Ignore;
|
|
||||||
BoneController.TranslationMode = EBoneModificationMode::BMM_Ignore;
|
|
||||||
|
|
||||||
if (BoneController.IsValidToEvaluate(HandSkeleton, Output.Pose.GetBoneContainer()))
|
|
||||||
{
|
|
||||||
TArray<FBoneTransform> BoneTransforms;
|
|
||||||
BoneController.EvaluateSkeletalControl_AnyThread(PoseContext, BoneTransforms);
|
|
||||||
|
|
||||||
const TArray<FBoneTransform>::SizeType BoneTransformsNum = BoneTransforms.Num();
|
|
||||||
if (BoneTransformsNum > 0)
|
|
||||||
{
|
|
||||||
PoseContext.Pose.LocalBlendCSBoneTransforms(BoneTransforms, 1.0f);
|
|
||||||
PoseContext.Pose.ConvertComponentPosesToLocalPoses(PoseContext.Pose, Output.Pose);
|
|
||||||
|
|
||||||
VirtualHand->MarkRenderStateDirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,736 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/Components/SGVirtualHandComponent.h"
|
|
||||||
|
|
||||||
#include "Animation/Skeleton.h"
|
|
||||||
#include "Components/SkeletalMeshComponent.h"
|
|
||||||
#include "Engine/SkeletalMesh.h"
|
|
||||||
#include "Kismet/GameplayStatics.h"
|
|
||||||
#include "Runtime/Launch/Resources/Version.h"
|
|
||||||
#include "UObject/ConstructorHelpers.h"
|
|
||||||
|
|
||||||
#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h"
|
|
||||||
#include "SenseGlove/Components/SGWristTrackerComponent.h"
|
|
||||||
#include "SGConnect/SGConnect.h"
|
|
||||||
#include "SGCore/SGDeviceList.h"
|
|
||||||
#include "SGCore/SGHandPose.h"
|
|
||||||
#include "SGCore/SGHapticGlove.h"
|
|
||||||
#include "SGCore/SGHapticGloveHandProfiles.h"
|
|
||||||
#include "SGDebug/SGDebugVirtualHand.h"
|
|
||||||
#include "SGLog/SGLog.h"
|
|
||||||
|
|
||||||
struct USGVirtualHandComponent::FImpl
|
|
||||||
{
|
|
||||||
/************************
|
|
||||||
* Static methods
|
|
||||||
************************/
|
|
||||||
|
|
||||||
FORCEINLINE static const FString& GetDefaultLeftHandMeshPath()
|
|
||||||
{
|
|
||||||
static const FString Path{TEXT("SkeletalMesh'/SenseGlove/Meshes/"
|
|
||||||
"SK_SenseGlove_VirtualHand_Left.SK_SenseGlove_VirtualHand_Left'")};
|
|
||||||
return Path;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE static const FString& GetDefaultLeftHandMeshPathOnly()
|
|
||||||
{
|
|
||||||
static const FString Path{TEXT("/SenseGlove/Meshes/"
|
|
||||||
"SK_SenseGlove_VirtualHand_Left.SK_SenseGlove_VirtualHand_Left")};
|
|
||||||
return Path;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE static const FString& GetDefaultRightHandMeshPath()
|
|
||||||
{
|
|
||||||
static const FString Path{TEXT("SkeletalMesh'/SenseGlove/Meshes/"
|
|
||||||
"SK_SenseGlove_VirtualHand_Right.SK_SenseGlove_VirtualHand_Right'")};
|
|
||||||
return Path;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE static const FString& GetDefaultRightHandMeshPathOnly()
|
|
||||||
{
|
|
||||||
static const FString Path{TEXT("/SenseGlove/Meshes/"
|
|
||||||
"SK_SenseGlove_VirtualHand_Right.SK_SenseGlove_VirtualHand_Right")};
|
|
||||||
return Path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Owner object
|
|
||||||
************************/
|
|
||||||
|
|
||||||
USGVirtualHandComponent* Owner;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Constructor / Destructor
|
|
||||||
************************/
|
|
||||||
|
|
||||||
explicit FImpl(USGVirtualHandComponent* InOwner);
|
|
||||||
~FImpl();
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Default copy constructor & copy assignment operator
|
|
||||||
************************/
|
|
||||||
|
|
||||||
FImpl(const FImpl& Rhs) = default;
|
|
||||||
FImpl& operator=(const FImpl& Rhs) = default;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Methods
|
|
||||||
************************/
|
|
||||||
|
|
||||||
bool IsEditor() const;
|
|
||||||
|
|
||||||
FString GetDefaultMeshPath() const;
|
|
||||||
bool IsUsingUserMesh() const;
|
|
||||||
USkeletalMesh* LoadDefaultMesh() const;
|
|
||||||
void SetDefaultMesh() const;
|
|
||||||
|
|
||||||
USkeletalMesh* GetMesh() const;
|
|
||||||
USkeleton* GetSkeleton() const;
|
|
||||||
const FReferenceSkeleton& GetRefSkeleton() const;
|
|
||||||
|
|
||||||
bool InitializeBackend() const;
|
|
||||||
bool UninitializeBackend() const;
|
|
||||||
bool CheckGlove() const;
|
|
||||||
|
|
||||||
void SetVisibility(bool bInVisible) const;
|
|
||||||
|
|
||||||
void DrawDebugVirtualHand() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
const TArray<TArray<FName>>& USGVirtualHandComponent::GetLeftHandFingerBoneNames()
|
|
||||||
{
|
|
||||||
static const TArray<TArray<FName>> BoneNames{
|
|
||||||
{FName(TEXT("thumb_01_l")), FName(TEXT("thumb_02_l")), FName(TEXT("thumb_03_l"))},
|
|
||||||
{FName(TEXT("index_01_l")), FName(TEXT("index_02_l")), FName(TEXT("index_03_l"))},
|
|
||||||
{FName(TEXT("middle_01_l")), FName(TEXT("middle_02_l")), FName(TEXT("middle_03_l"))},
|
|
||||||
{FName(TEXT("ring_01_l")), FName(TEXT("ring_02_l")), FName(TEXT("ring_03_l"))},
|
|
||||||
{FName(TEXT("pinky_01_l")), FName(TEXT("pinky_02_l")), FName(TEXT("pinky_03_l"))},
|
|
||||||
};
|
|
||||||
return BoneNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TArray<TArray<FName>>& USGVirtualHandComponent::GetRightHandFingerBoneNames()
|
|
||||||
{
|
|
||||||
static const TArray<TArray<FName>> BoneNames{
|
|
||||||
{FName(TEXT("thumb_01_r")), FName(TEXT("thumb_02_r")), FName(TEXT("thumb_03_r"))},
|
|
||||||
{FName(TEXT("index_01_r")), FName(TEXT("index_02_r")), FName(TEXT("index_03_r"))},
|
|
||||||
{FName(TEXT("middle_01_r")), FName(TEXT("middle_02_r")), FName(TEXT("middle_03_r"))},
|
|
||||||
{FName(TEXT("ring_01_r")), FName(TEXT("ring_02_r")), FName(TEXT("ring_03_r"))},
|
|
||||||
{FName(TEXT("pinky_01_r")), FName(TEXT("pinky_02_r")), FName(TEXT("pinky_03_r"))},
|
|
||||||
};
|
|
||||||
return BoneNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FName& USGVirtualHandComponent::GetLeftHandFingerBoneName(const int32 Finger, const int32 Joint)
|
|
||||||
{
|
|
||||||
const TArray<TArray<FName>>& BoneNames{GetLeftHandFingerBoneNames()};
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(Finger < BoneNames.Num(), TEXT("Finger index is out of bound!"));
|
|
||||||
ensureAlwaysMsgf(Joint < BoneNames[Finger].Num(), TEXT("Joint index is out of bound!"));
|
|
||||||
|
|
||||||
const FName& BoneName{BoneNames[Finger][Joint]};
|
|
||||||
return BoneName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FName& USGVirtualHandComponent::GetRightHandFingerBoneName(const int32 Finger, const int32 Joint)
|
|
||||||
{
|
|
||||||
const TArray<TArray<FName>>& BoneNames{GetRightHandFingerBoneNames()};
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(Finger < BoneNames.Num(), TEXT("Finger index is out of bound!"));
|
|
||||||
ensureAlwaysMsgf(Joint < BoneNames[Finger].Num(), TEXT("Joint index is out of bound!"));
|
|
||||||
|
|
||||||
const FName& BoneName{BoneNames[Finger][Joint]};
|
|
||||||
return BoneName;
|
|
||||||
}
|
|
||||||
|
|
||||||
USGVirtualHandComponent::USGVirtualHandComponent(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer),
|
|
||||||
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
||||||
{
|
|
||||||
PrimaryComponentTick.bTickEvenWhenPaused = false;
|
|
||||||
PrimaryComponentTick.bCanEverTick = true;
|
|
||||||
PrimaryComponentTick.bStartWithTickEnabled = true;
|
|
||||||
bTickInEditor = true;
|
|
||||||
bNeverNeedsRenderUpdate = false;
|
|
||||||
bAllowConcurrentTick = true;
|
|
||||||
SetUpdateAnimationInEditor(true);
|
|
||||||
|
|
||||||
SetCastShadow(true);
|
|
||||||
SetCastHiddenShadow(false);
|
|
||||||
bCastDynamicShadow = true;
|
|
||||||
SetOnlyOwnerSee(false);
|
|
||||||
SetReceivesDecals(true);
|
|
||||||
SetCanEverAffectNavigation(false);
|
|
||||||
Super::SetCollisionObjectType(ECC_WorldDynamic);
|
|
||||||
Super::SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
|
|
||||||
Super::SetCollisionResponseToAllChannels(ECR_Overlap);
|
|
||||||
Super::SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block);
|
|
||||||
Super::SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Block);
|
|
||||||
Super::SetCollisionResponseToChannel(ECC_Pawn, ECR_Block);
|
|
||||||
Super::SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
|
|
||||||
Super::SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Block);
|
|
||||||
Super::SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
|
|
||||||
Super::SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
|
|
||||||
|
|
||||||
Super::SetAnimClass(USGVirtualHandAnimInstance::StaticClass());
|
|
||||||
|
|
||||||
bRight = true;
|
|
||||||
bHiddenInGameIfNoGloveDetected = false;
|
|
||||||
DebugVirtualHandSettings = FSGDebugVirtualHandSettings{
|
|
||||||
ESGDebugVirtualHandDrawingMode::None,
|
|
||||||
FVector(0.5f, 0.5f, 0.5f),
|
|
||||||
FColor(255, 0, 0, 255),
|
|
||||||
0.1f, 1.0f, 1.0f,
|
|
||||||
FColor(255, 0, 0, 255),
|
|
||||||
FColor(0, 255, 0, 255),
|
|
||||||
FColor(0, 0, 255, 255),
|
|
||||||
false, 1.1f, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
Super::SetSkeletalMesh(nullptr, true);
|
|
||||||
|
|
||||||
bBackendInitialized = false;
|
|
||||||
Glove = nullptr;
|
|
||||||
WristTracker = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::SetRight(const bool bInRight)
|
|
||||||
{
|
|
||||||
bRight = bInRight;
|
|
||||||
|
|
||||||
if (!Pimpl->IsUsingUserMesh())
|
|
||||||
{
|
|
||||||
Pimpl->SetDefaultMesh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::SetAnimClass(UClass* NewClass)
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(Cast<USGVirtualHandAnimInstance>(NewClass),
|
|
||||||
TEXT("The AnimInstance class must be a subclass of USGVirtualHandAnimInstance!"));
|
|
||||||
|
|
||||||
Super::SetAnimClass(NewClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::PostInitProperties()
|
|
||||||
{
|
|
||||||
Super::PostInitProperties();
|
|
||||||
|
|
||||||
if (!Pimpl->IsUsingUserMesh())
|
|
||||||
{
|
|
||||||
Pimpl->SetDefaultMesh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WITH_EDITOR
|
|
||||||
void USGVirtualHandComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
||||||
{
|
|
||||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
|
||||||
|
|
||||||
const FName PropertyName{
|
|
||||||
PropertyChangedEvent.Property
|
|
||||||
? PropertyChangedEvent.Property->GetFName()
|
|
||||||
: NAME_None
|
|
||||||
};
|
|
||||||
if (PropertyName == GET_MEMBER_NAME_CHECKED(USGVirtualHandComponent, bRight))
|
|
||||||
{
|
|
||||||
if (!Pimpl->IsUsingUserMesh())
|
|
||||||
{
|
|
||||||
Pimpl->SetDefaultMesh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WITH_EDITOR */
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::InitializeComponent()
|
|
||||||
{
|
|
||||||
Super::InitializeComponent();
|
|
||||||
|
|
||||||
if (!Pimpl->IsUsingUserMesh())
|
|
||||||
{
|
|
||||||
Pimpl->SetDefaultMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pimpl->InitializeBackend())
|
|
||||||
{
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::UninitializeComponent()
|
|
||||||
{
|
|
||||||
Super::UninitializeComponent();
|
|
||||||
|
|
||||||
(void) Pimpl->UninitializeBackend();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
if (Pimpl->InitializeBackend())
|
|
||||||
{
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|
||||||
{
|
|
||||||
Super::EndPlay(EndPlayReason);
|
|
||||||
|
|
||||||
(void) Pimpl->UninitializeBackend();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::TickComponent(
|
|
||||||
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
||||||
{
|
|
||||||
#if WITH_EDITOR
|
|
||||||
if (Pimpl->IsEditor())
|
|
||||||
{
|
|
||||||
EditorTick(DeltaTime, TickType, ThisTickFunction);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* WITH_EDITOR */
|
|
||||||
|
|
||||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
|
||||||
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
|
|
||||||
if (IsValid(Glove) && DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
|
|
||||||
{
|
|
||||||
Pimpl->DrawDebugVirtualHand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::SetSkeletalMesh(USkeletalMesh* NewMesh, const bool bReinitPose)
|
|
||||||
{
|
|
||||||
if (IsValid(NewMesh))
|
|
||||||
{
|
|
||||||
Super::SetSkeletalMesh(NewMesh, bReinitPose);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Super::SetSkeletalMesh(Pimpl->LoadDefaultMesh(), bReinitPose);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::EditorTick(
|
|
||||||
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
||||||
{
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
|
|
||||||
if (IsValid(Glove) && DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
|
|
||||||
{
|
|
||||||
Pimpl->DrawDebugVirtualHand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGVirtualHandComponent::IsGloveConnected() const
|
|
||||||
{
|
|
||||||
return Pimpl->CheckGlove();
|
|
||||||
}
|
|
||||||
|
|
||||||
USGHandPose* USGVirtualHandComponent::GetHandPose()
|
|
||||||
{
|
|
||||||
USGHandPose* HandPose{nullptr};
|
|
||||||
|
|
||||||
if (IsValid(Glove))
|
|
||||||
{
|
|
||||||
#if ! PLATFORM_ANDROID
|
|
||||||
Glove->GetHandPose(this, HandPose);
|
|
||||||
#else /* ! PLATFORM_ANDROID */
|
|
||||||
const UWorld* World{GetWorld()};
|
|
||||||
const float DeltaTime = UGameplayStatics::GetWorldDeltaSeconds(World);
|
|
||||||
Glove->GetHandPose(this, DeltaTime, HandPose);
|
|
||||||
#endif /* ! PLATFORM_ANDROID */
|
|
||||||
}
|
|
||||||
|
|
||||||
return HandPose;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FName& USGVirtualHandComponent::GetFingerBoneName(const int32 Finger, const int32 Joint) const
|
|
||||||
{
|
|
||||||
const FName& Name{
|
|
||||||
IsRight()
|
|
||||||
? GetRightHandFingerBoneName(Finger, Joint)
|
|
||||||
: GetLeftHandFingerBoneName(Finger, Joint)
|
|
||||||
};
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FTransform& USGVirtualHandComponent::GetFingerBoneRefTransform(const int32 Finger, const int32 Joint) const
|
|
||||||
{
|
|
||||||
const FName& BoneName{GetFingerBoneName(Finger, Joint)};
|
|
||||||
const FReferenceSkeleton& ReferenceSkeleton{Pimpl->GetRefSkeleton()};
|
|
||||||
const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(BoneName);
|
|
||||||
|
|
||||||
if (BoneIndex == INDEX_NONE)
|
|
||||||
{
|
|
||||||
SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for '%s' finger bone!"),
|
|
||||||
*BoneName.ToString()));
|
|
||||||
return FTransform::Identity;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FTransform& BoneTransform{ReferenceSkeleton.GetRefBonePose()[BoneIndex]};
|
|
||||||
return BoneTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
FRotator USGVirtualHandComponent::GetFingerBoneRefRotation(const int32 Finger, const int32 Joint) const
|
|
||||||
{
|
|
||||||
const FTransform BoneTransform{GetFingerBoneRefTransform(Finger, Joint)};
|
|
||||||
FRotator BoneRotation{BoneTransform.GetRotation().Rotator()};
|
|
||||||
return MoveTemp(BoneRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
TMap<FName, FRotator> USGVirtualHandComponent::GetFingersBonesRotations()
|
|
||||||
{
|
|
||||||
TMap<FName, FRotator> Rotations;
|
|
||||||
|
|
||||||
if (!IsGloveConnected())
|
|
||||||
{
|
|
||||||
return MoveTemp(Rotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
const USGHandPose* HandPose = GetHandPose();
|
|
||||||
if (!IsValid(HandPose))
|
|
||||||
{
|
|
||||||
return MoveTemp(Rotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
const TArray<TArray<FVector>> HandAngles{HandPose->GetHandAngles()};
|
|
||||||
|
|
||||||
for (int32 FingerIndex = 0; FingerIndex < HandAngles.Num(); ++FingerIndex)
|
|
||||||
{
|
|
||||||
const TArray<FVector>& FingerJointAngles{HandAngles[FingerIndex]};
|
|
||||||
|
|
||||||
for (int32 JointIndex = 0; JointIndex < FingerJointAngles.Num(); ++JointIndex)
|
|
||||||
{
|
|
||||||
const FVector& JointAngle{FingerJointAngles[JointIndex]};
|
|
||||||
const FQuat JointRotation{FQuat::MakeFromEuler(JointAngle)};
|
|
||||||
|
|
||||||
const FTransform& BoneRefTransform{GetFingerBoneRefTransform(FingerIndex, JointIndex)};
|
|
||||||
|
|
||||||
FQuat NewBoneRotation{BoneRefTransform.GetRotation() * JointRotation};
|
|
||||||
|
|
||||||
FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
|
|
||||||
|
|
||||||
Rotations.Emplace(MoveTemp(BoneName), MoveTemp(NewBoneRotation));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MoveTemp(Rotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
USGVirtualHandComponent::FImpl::FImpl(USGVirtualHandComponent* InOwner)
|
|
||||||
: Owner(InOwner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
USGVirtualHandComponent::FImpl::~FImpl() = default;
|
|
||||||
|
|
||||||
bool USGVirtualHandComponent::FImpl::IsEditor() const
|
|
||||||
{
|
|
||||||
const UWorld* World{Owner->GetWorld()};
|
|
||||||
if (World && (World->WorldType == EWorldType::Editor || World->WorldType == EWorldType::EditorPreview))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString USGVirtualHandComponent::FImpl::GetDefaultMeshPath() const
|
|
||||||
{
|
|
||||||
FString SkeletalMeshPath;
|
|
||||||
|
|
||||||
if (Owner->IsRight())
|
|
||||||
{
|
|
||||||
SkeletalMeshPath = GetDefaultRightHandMeshPath();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SkeletalMeshPath = GetDefaultLeftHandMeshPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
return MoveTemp(SkeletalMeshPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGVirtualHandComponent::FImpl::IsUsingUserMesh() const
|
|
||||||
{
|
|
||||||
const USkeletalMesh* CurrentMesh{GetMesh()};
|
|
||||||
if (!IsValid(CurrentMesh))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FString CurrentMeshPath(CurrentMesh->GetPathName());
|
|
||||||
const FString LeftHandDefaultMeshPath(GetDefaultLeftHandMeshPath());
|
|
||||||
const FString LeftHandDefaultMeshPathOnly(GetDefaultLeftHandMeshPathOnly());
|
|
||||||
const FString RightHandDefaultMeshPath(GetDefaultRightHandMeshPath());
|
|
||||||
const FString RightHandDefaultMeshPathOnly(GetDefaultRightHandMeshPathOnly());
|
|
||||||
if (CurrentMeshPath == LeftHandDefaultMeshPath
|
|
||||||
|| CurrentMeshPath == LeftHandDefaultMeshPathOnly
|
|
||||||
|| CurrentMeshPath == RightHandDefaultMeshPath
|
|
||||||
|| CurrentMeshPath == RightHandDefaultMeshPathOnly)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
USkeletalMesh* USGVirtualHandComponent::FImpl::LoadDefaultMesh() const
|
|
||||||
{
|
|
||||||
const FString DefaultMeshPath{GetDefaultMeshPath()};
|
|
||||||
USkeletalMesh* DefaultMesh{
|
|
||||||
Cast<USkeletalMesh>(StaticLoadObject(USkeletalMesh::StaticClass(), nullptr, *DefaultMeshPath))
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!IsValid(DefaultMesh))
|
|
||||||
{
|
|
||||||
SGLOG_WARNING(FString::Printf(TEXT("Failed to load the default skeletal mesh: '%s'"), *DefaultMeshPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefaultMesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::FImpl::SetDefaultMesh() const
|
|
||||||
{
|
|
||||||
Owner->SetSkeletalMesh(LoadDefaultMesh(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
USkeletalMesh* USGVirtualHandComponent::FImpl::GetMesh() const
|
|
||||||
{
|
|
||||||
return Owner->
|
|
||||||
#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1
|
|
||||||
GetSkeletalMeshAsset()
|
|
||||||
#else /* ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1 */
|
|
||||||
SkeletalMesh
|
|
||||||
#endif /* ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1 */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
USkeleton* USGVirtualHandComponent::FImpl::GetSkeleton() const
|
|
||||||
{
|
|
||||||
USkeletalMesh* Mesh{GetMesh()};
|
|
||||||
ensureAlwaysMsgf(IsValid(Mesh), TEXT("Invalid SkeletalMesh object!"));
|
|
||||||
return Mesh->GetSkeleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
const FReferenceSkeleton& USGVirtualHandComponent::FImpl::GetRefSkeleton() const
|
|
||||||
{
|
|
||||||
const USkeletalMesh* Mesh{GetMesh()};
|
|
||||||
ensureAlwaysMsgf(IsValid(Mesh), TEXT("Invalid SkeletalMesh object!"));
|
|
||||||
return Mesh->GetRefSkeleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGVirtualHandComponent::FImpl::InitializeBackend() const
|
|
||||||
{
|
|
||||||
if (!Owner->bBackendInitialized)
|
|
||||||
{
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
const int32_t Result = FSGConnect::Init();
|
|
||||||
switch (Result)
|
|
||||||
{
|
|
||||||
case -3:
|
|
||||||
SGLOG_ERROR("An Unexpected error occurred. Please try again.");
|
|
||||||
return false;
|
|
||||||
case -2:
|
|
||||||
SGLOG_ERROR("Device Scanning is already running within a different program.");
|
|
||||||
return false;
|
|
||||||
case -1:
|
|
||||||
SGLOG_ERROR("Device Scanning already being initialized (function called twice in short succession).");
|
|
||||||
return false;
|
|
||||||
case 0:
|
|
||||||
// Do not pollute the logs!
|
|
||||||
//SGLOG_ERROR("Device Scanning is already running within this program.");
|
|
||||||
// We must return here in case there are two virtual hand components are present in the scene.
|
|
||||||
return true;
|
|
||||||
case 1:
|
|
||||||
SGLOG("Successfully started up DeviceScanning from the current program.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ensureAlwaysMsgf(false, TEXT("Unhandled Init return status code!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
// Ensure that the device list is empty before doing anything.
|
|
||||||
FSGDeviceList::Dispose();
|
|
||||||
FSGDeviceList::Reinitialize();
|
|
||||||
|
|
||||||
// Load the latest hand profiles.
|
|
||||||
FSGHapticGloveHandProfiles::TryLoadingFromDisk();
|
|
||||||
|
|
||||||
Owner->bBackendInitialized = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGVirtualHandComponent::FImpl::UninitializeBackend() const
|
|
||||||
{
|
|
||||||
// NOTE
|
|
||||||
// In Editor builds we should be avoiding dispose, since stopping the game in PIE mode, causes the virtual-hand
|
|
||||||
// to disappear in the editor as the plugin won't be able to retrieve the glove status anymore.
|
|
||||||
#if ! WITH_EDITOR
|
|
||||||
if (Owner->bBackendInitialized)
|
|
||||||
{
|
|
||||||
FSGDeviceList::Dispose();
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
const int32_t Result = FSGConnect::Dispose();
|
|
||||||
switch (Result)
|
|
||||||
{
|
|
||||||
case -3:
|
|
||||||
SGLOG_ERROR("An Unexpected error occurred. Please try again.");
|
|
||||||
return false;
|
|
||||||
case -2:
|
|
||||||
SGLOG_ERROR("Not allowed to dispose of Device Scanning because this is not the program which started it.");
|
|
||||||
return false;
|
|
||||||
case -1:
|
|
||||||
SGLOG_ERROR("Device Scanning is currently being disposed off. This takes a second or two. (function called twice in short succession).");
|
|
||||||
return false;
|
|
||||||
case 0:
|
|
||||||
SGLOG_ERROR("There is no deviceScanner running from any program, so disposing is skipped.");
|
|
||||||
return false;
|
|
||||||
case 1:
|
|
||||||
SGLOG("Successfully disposed of DeviceScanner resources.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ensureAlwaysMsgf(false, TEXT("Unhandled Dispose return status code!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
Owner->bBackendInitialized = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif /* ! WITH_EDITOR */
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGVirtualHandComponent::FImpl::CheckGlove() const
|
|
||||||
{
|
|
||||||
if (!Owner->bBackendInitialized)
|
|
||||||
{
|
|
||||||
const bool bSucceeded = InitializeBackend();
|
|
||||||
if (!bSucceeded)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool bGloveWasPresent = IsValid(Owner->Glove);
|
|
||||||
const bool bFoundGlove = USGHapticGlove::GetGlove(Owner, Owner->IsRight(), Owner->Glove);
|
|
||||||
|
|
||||||
if (!bFoundGlove && bGloveWasPresent)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR(FString::Printf(TEXT("Could not find a %s glove!"),
|
|
||||||
(Owner->IsRight() ? TEXT("right-handed") : TEXT("left-handed"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool bIsEditor = IsEditor();
|
|
||||||
if (!bIsEditor)
|
|
||||||
{
|
|
||||||
const bool bIsVisible = Owner->IsVisible();
|
|
||||||
if (Owner->bHiddenInGameIfNoGloveDetected)
|
|
||||||
{
|
|
||||||
if (bFoundGlove)
|
|
||||||
{
|
|
||||||
if (!bIsVisible)
|
|
||||||
{
|
|
||||||
SetVisibility(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bIsVisible)
|
|
||||||
{
|
|
||||||
SetVisibility(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!bIsVisible)
|
|
||||||
{
|
|
||||||
SetVisibility(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bFoundGlove;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::FImpl::SetVisibility(const bool bInVisible) const
|
|
||||||
{
|
|
||||||
Owner->SetVisibility(bInVisible, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::FImpl::DrawDebugVirtualHand() const
|
|
||||||
{
|
|
||||||
const UWorld* World{Owner->GetWorld()};
|
|
||||||
|
|
||||||
if (!IsValid(Owner->WristTracker))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FVector& WristLocation{Owner->WristTracker->GetWristLocation()};
|
|
||||||
const FRotator& WristRotation{Owner->WristTracker->GetWristRotation()};
|
|
||||||
|
|
||||||
const USGHandPose* HandPose{Owner->GetHandPose()};
|
|
||||||
if (!IsValid(HandPose))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TArray<TArray<FVector>>& JointPositions{HandPose->GetJointPositions()};
|
|
||||||
const TArray<TArray<FRotator>>& JointRotations{HandPose->GetJointRotations()};
|
|
||||||
|
|
||||||
FSGDebugVirtualHand::Draw(World, WristLocation, WristRotation, JointPositions, JointRotations,
|
|
||||||
Owner->DebugVirtualHandSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGVirtualHandComponent::FImplDeleter::operator()(const FImpl* P) const
|
|
||||||
{
|
|
||||||
delete P;
|
|
||||||
}
|
|
||||||
@@ -1,549 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/Components/SGWristTrackerComponent.h"
|
|
||||||
|
|
||||||
#include "Animation/Skeleton.h"
|
|
||||||
#include "Components/SkeletalMeshComponent.h"
|
|
||||||
#include "Engine/SkeletalMesh.h"
|
|
||||||
#include "UObject/ConstructorHelpers.h"
|
|
||||||
|
|
||||||
#include "SGConnect/SGConnect.h"
|
|
||||||
#include "SGCore/SGDeviceList.h"
|
|
||||||
#include "SGCore/SGHapticGlove.h"
|
|
||||||
#include "SGCore/SGHapticGloveHandProfiles.h"
|
|
||||||
#include "SGDebug/SGDebugGizmo.h"
|
|
||||||
#include "SGLog/SGLog.h"
|
|
||||||
#include "SGSettings/SGSettings.h"
|
|
||||||
|
|
||||||
struct USGWristTrackerComponent::FImpl
|
|
||||||
{
|
|
||||||
/************************
|
|
||||||
* Static methods
|
|
||||||
************************/
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Owner object
|
|
||||||
************************/
|
|
||||||
|
|
||||||
USGWristTrackerComponent* Owner;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Constructor / Destructor
|
|
||||||
************************/
|
|
||||||
|
|
||||||
explicit FImpl(USGWristTrackerComponent* InOwner);
|
|
||||||
~FImpl();
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Default copy constructor & copy assignment operator
|
|
||||||
************************/
|
|
||||||
|
|
||||||
FImpl(const FImpl& Rhs) = default;
|
|
||||||
FImpl& operator=(const FImpl& Rhs) = default;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Methods
|
|
||||||
************************/
|
|
||||||
|
|
||||||
bool IsEditor() const;
|
|
||||||
|
|
||||||
bool InitializeBackend() const;
|
|
||||||
bool UninitializeBackend() const;
|
|
||||||
bool CheckGlove() const;
|
|
||||||
|
|
||||||
void UpdateWristTrackingData() const;
|
|
||||||
void DrawDebugGizmo();
|
|
||||||
};
|
|
||||||
|
|
||||||
USGWristTrackerComponent::USGWristTrackerComponent(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer),
|
|
||||||
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
||||||
{
|
|
||||||
PrimaryComponentTick.bTickEvenWhenPaused = false;
|
|
||||||
PrimaryComponentTick.bCanEverTick = true;
|
|
||||||
PrimaryComponentTick.bStartWithTickEnabled = true;
|
|
||||||
bTickInEditor = true;
|
|
||||||
bNeverNeedsRenderUpdate = true;
|
|
||||||
bAllowConcurrentTick = true;
|
|
||||||
|
|
||||||
SetCastShadow(false);
|
|
||||||
SetCastHiddenShadow(false);
|
|
||||||
bCastDynamicShadow = false;
|
|
||||||
SetOnlyOwnerSee(false);
|
|
||||||
SetReceivesDecals(false);
|
|
||||||
SetCanEverAffectNavigation(false);
|
|
||||||
|
|
||||||
SetRight(true);
|
|
||||||
|
|
||||||
bOverridePluginWristTrackingSettings = false;
|
|
||||||
bDrawWristTrackerDebugGizmo = false;
|
|
||||||
TrackingHardware = ESGPositionalTrackingHardware::None;
|
|
||||||
TrackingHardwareLocationOffset = FVector::ZeroVector;
|
|
||||||
TrackingHardwareLocationOffset = FVector::ZeroVector;
|
|
||||||
|
|
||||||
bOverridePluginWristTrackingDebugSettings = false;
|
|
||||||
bDrawWristTrackerDebugGizmo = false;
|
|
||||||
WristTrackerDebugGizmoSettings = FSGDebugGizmoSettings(
|
|
||||||
4.0f, 1.0f,
|
|
||||||
FColor(255, 0, 0, 255),
|
|
||||||
FColor(0, 255, 0, 255),
|
|
||||||
FColor(0, 0, 255, 255),
|
|
||||||
false, 1.1f, 0
|
|
||||||
);
|
|
||||||
bDrawWristTrackerDebugGizmo = false;
|
|
||||||
|
|
||||||
bBackendInitialized = false;
|
|
||||||
Glove = nullptr;
|
|
||||||
WristLocation = FVector::ZeroVector;
|
|
||||||
WristRotation = FRotator::ZeroRotator;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::SetRight(const bool bRight)
|
|
||||||
{
|
|
||||||
SetTrackingSource(bRight ? EControllerHand::Right : EControllerHand::Left);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESGPositionalTrackingHardware USGWristTrackerComponent::GetTrackingHardware() const
|
|
||||||
{
|
|
||||||
if (OverridesPluginWristTrackingSettings())
|
|
||||||
{
|
|
||||||
return TrackingHardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USGSettings::GetInstance()->GetTrackingHardware();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::SetTrackingHardware(const ESGPositionalTrackingHardware InTrackingHardware)
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
OverridesPluginWristTrackingSettings(),
|
|
||||||
TEXT( "Setting TrackingHardware is only permitted when bOverridePluginWristTrackingSettings is enabled!"));
|
|
||||||
|
|
||||||
TrackingHardware = InTrackingHardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FVector& USGWristTrackerComponent::GetTrackingHardwareLocationOffset() const
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
GetTrackingHardware() == ESGPositionalTrackingHardware::Custom,
|
|
||||||
TEXT( "Getting TrackingHardwareLocationOffset is only permitted when TrackingHardware is set to Custom!"));
|
|
||||||
|
|
||||||
if (OverridesPluginWristTrackingSettings())
|
|
||||||
{
|
|
||||||
return TrackingHardwareLocationOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IsRight()
|
|
||||||
? USGSettings::GetInstance()->GetTrackingHardwareLocationOffsetRightHand()
|
|
||||||
: USGSettings::GetInstance()->GetTrackingHardwareLocationOffsetLeftHand();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::SetTrackingHardwareLocationOffset(const FVector& InTrackingHardwareLocationOffset)
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
OverridesPluginWristTrackingSettings(),
|
|
||||||
TEXT(
|
|
||||||
"Setting TrackingHardwareLocationOffset is only permitted when bOverridePluginWristTrackingSettings is enabled!"
|
|
||||||
));
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
GetTrackingHardware() == ESGPositionalTrackingHardware::Custom,
|
|
||||||
TEXT( "Setting TrackingHardwareLocationOffset is only permitted when TrackingHardware is set to Custom!"));
|
|
||||||
|
|
||||||
TrackingHardwareLocationOffset = InTrackingHardwareLocationOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FRotator& USGWristTrackerComponent::GetTrackingHardwareRotationOffset() const
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
GetTrackingHardware() == ESGPositionalTrackingHardware::Custom,
|
|
||||||
TEXT( "Getting TrackingHardwareRotationOffset is only permitted when TrackingHardware is set to Custom!"));
|
|
||||||
|
|
||||||
if (OverridesPluginWristTrackingSettings())
|
|
||||||
{
|
|
||||||
return TrackingHardwareRotationOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IsRight()
|
|
||||||
? USGSettings::GetInstance()->GetTrackingHardwareRotationOffsetRightHand()
|
|
||||||
: USGSettings::GetInstance()->GetTrackingHardwareRotationOffsetLeftHand();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::SetTrackingHardwareRotationOffset(const FRotator& InTrackingHardwareRotationOffset)
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
OverridesPluginWristTrackingSettings(),
|
|
||||||
TEXT(
|
|
||||||
"Setting TrackingHardwareRotationOffset is only permitted when bOverridePluginWristTrackingSettings is enabled!"
|
|
||||||
));
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
GetTrackingHardware() == ESGPositionalTrackingHardware::Custom,
|
|
||||||
TEXT("Setting TrackingHardwareRotationOffsetRightHand is only permitted when TrackingHardware is set to Custom!"
|
|
||||||
));
|
|
||||||
|
|
||||||
TrackingHardwareRotationOffset = InTrackingHardwareRotationOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGWristTrackerComponent::GetDrawWristTrackerDebugGizmo() const
|
|
||||||
{
|
|
||||||
if (OverridesPluginWristTrackingDebugSettings())
|
|
||||||
{
|
|
||||||
return !!bDrawWristTrackerDebugGizmo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USGSettings::GetInstance()->GetDrawWristTrackerDebugGizmo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::SetDrawWristTrackerDebugGizmo(const bool bInDrawWristTrackerDebugGizmo)
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
OverridesPluginWristTrackingDebugSettings(),
|
|
||||||
TEXT( "Setting bDrawWristTrackerDebugGizmo is only permitted when bOverridePluginWristTrackingDebugSettings is"
|
|
||||||
" enabled!"));
|
|
||||||
|
|
||||||
bDrawWristTrackerDebugGizmo = bInDrawWristTrackerDebugGizmo;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FSGDebugGizmoSettings& USGWristTrackerComponent::GetWristTrackerDebugGizmoSettings() const
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
GetDrawWristTrackerDebugGizmo(),
|
|
||||||
TEXT("Getting WristTrackerDebugGizmoLength is only permitted when bDrawWristTrackerDebugGizmo is enabled!"));
|
|
||||||
|
|
||||||
if (OverridesPluginWristTrackingDebugSettings())
|
|
||||||
{
|
|
||||||
return WristTrackerDebugGizmoSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USGSettings::GetInstance()->GetWristTrackerDebugGizmoSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::SetWristTrackerDebugGizmoSettings(
|
|
||||||
const FSGDebugGizmoSettings& InWristTrackerDebugGizmoSettings)
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
OverridesPluginWristTrackingDebugSettings(),
|
|
||||||
TEXT("Setting WristTrackerDebugGizmoLength is only permitted when bOverridePluginWristTrackingDebugSettings is"
|
|
||||||
" enabled!"));
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
GetDrawWristTrackerDebugGizmo(),
|
|
||||||
TEXT("Setting WristTrackerDebugGizmoLength is only permitted when bDrawWristTrackerDebugGizmo is enabled!"));
|
|
||||||
|
|
||||||
WristTrackerDebugGizmoSettings = InWristTrackerDebugGizmoSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WITH_EDITOR
|
|
||||||
void USGWristTrackerComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
||||||
{
|
|
||||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
|
||||||
|
|
||||||
const FName PropertyName{
|
|
||||||
PropertyChangedEvent.Property
|
|
||||||
? PropertyChangedEvent.Property->GetFName()
|
|
||||||
: NAME_None
|
|
||||||
};
|
|
||||||
|
|
||||||
(void) PropertyName;
|
|
||||||
}
|
|
||||||
#endif /* WITH_EDITOR */
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::InitializeComponent()
|
|
||||||
{
|
|
||||||
Super::InitializeComponent();
|
|
||||||
|
|
||||||
if (Pimpl->InitializeBackend())
|
|
||||||
{
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::UninitializeComponent()
|
|
||||||
{
|
|
||||||
Super::UninitializeComponent();
|
|
||||||
|
|
||||||
(void) Pimpl->UninitializeBackend();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
if (Pimpl->InitializeBackend())
|
|
||||||
{
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|
||||||
{
|
|
||||||
Super::EndPlay(EndPlayReason);
|
|
||||||
|
|
||||||
(void) Pimpl->UninitializeBackend();
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::TickComponent(
|
|
||||||
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
||||||
{
|
|
||||||
#if WITH_EDITOR
|
|
||||||
if (Pimpl->IsEditor())
|
|
||||||
{
|
|
||||||
EditorTick(DeltaTime, TickType, ThisTickFunction);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* WITH_EDITOR */
|
|
||||||
|
|
||||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
|
||||||
|
|
||||||
if (GetDrawWristTrackerDebugGizmo())
|
|
||||||
{
|
|
||||||
Pimpl->DrawDebugGizmo();
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::EditorTick(
|
|
||||||
const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
||||||
{
|
|
||||||
(void) Pimpl->CheckGlove();
|
|
||||||
}
|
|
||||||
|
|
||||||
USGWristTrackerComponent::FImpl::FImpl(USGWristTrackerComponent* InOwner)
|
|
||||||
: Owner(InOwner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
USGWristTrackerComponent::FImpl::~FImpl() = default;
|
|
||||||
|
|
||||||
bool USGWristTrackerComponent::FImpl::IsEditor() const
|
|
||||||
{
|
|
||||||
const UWorld* World{Owner->GetWorld()};
|
|
||||||
if (World && (World->WorldType == EWorldType::Editor || World->WorldType == EWorldType::EditorPreview))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGWristTrackerComponent::FImpl::InitializeBackend() const
|
|
||||||
{
|
|
||||||
if (!Owner->bBackendInitialized)
|
|
||||||
{
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
const int32_t Result = FSGConnect::Init();
|
|
||||||
switch (Result)
|
|
||||||
{
|
|
||||||
case -3:
|
|
||||||
SGLOG_ERROR("An Unexpected error occurred. Please try again.");
|
|
||||||
return false;
|
|
||||||
case -2:
|
|
||||||
SGLOG_ERROR("Device Scanning is already running within a different program.");
|
|
||||||
return false;
|
|
||||||
case -1:
|
|
||||||
SGLOG_ERROR("Device Scanning already being initialized (function called twice in short succession).");
|
|
||||||
return false;
|
|
||||||
case 0:
|
|
||||||
// Do not pollute the logs!
|
|
||||||
//SGLOG_ERROR("Device Scanning is already running within this program.");
|
|
||||||
// We must return here in case two virtual hand components are present in the scene.
|
|
||||||
return true;
|
|
||||||
case 1:
|
|
||||||
SGLOG("Successfully started up DeviceScanning from the current program.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ensureAlwaysMsgf(false, TEXT("Unhandled Init return status code!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
// Ensure that the device list is empty before doing anything.
|
|
||||||
FSGDeviceList::Dispose();
|
|
||||||
FSGDeviceList::Reinitialize();
|
|
||||||
|
|
||||||
// Load the latest hand profiles.
|
|
||||||
FSGHapticGloveHandProfiles::TryLoadingFromDisk();
|
|
||||||
|
|
||||||
Owner->bBackendInitialized = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGWristTrackerComponent::FImpl::UninitializeBackend() const
|
|
||||||
{
|
|
||||||
// NOTE
|
|
||||||
// In Editor builds we should be avoiding dispose, since stopping the game in PIE mode, causes the virtual-hand
|
|
||||||
// to disappear in the editor as the plugin won't be able to retrieve the glove status anymore.
|
|
||||||
#if ! WITH_EDITOR
|
|
||||||
if (Owner->bBackendInitialized)
|
|
||||||
{
|
|
||||||
FSGDeviceList::Dispose();
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
const int32_t Result = FSGConnect::Dispose();
|
|
||||||
switch (Result)
|
|
||||||
{
|
|
||||||
case -3:
|
|
||||||
SGLOG_ERROR("An Unexpected error occurred. Please try again.");
|
|
||||||
return false;
|
|
||||||
case -2:
|
|
||||||
SGLOG_ERROR("Not allowed to dispose of Device Scanning because this is not the program which started it.");
|
|
||||||
return false;
|
|
||||||
case -1:
|
|
||||||
SGLOG_ERROR("Device Scanning is currently being disposed off. This takes a second or two. (function called twice in short succession).");
|
|
||||||
return false;
|
|
||||||
case 0:
|
|
||||||
SGLOG_ERROR("There is no deviceScanner running from any program, so disposing is skipped.");
|
|
||||||
return false;
|
|
||||||
case 1:
|
|
||||||
SGLOG("Successfully disposed of DeviceScanner resources.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ensureAlwaysMsgf(false, TEXT("Unhandled Dispose return status code!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
Owner->bBackendInitialized = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif /* ! WITH_EDITOR */
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USGWristTrackerComponent::FImpl::CheckGlove() const
|
|
||||||
{
|
|
||||||
if (!Owner->bBackendInitialized)
|
|
||||||
{
|
|
||||||
const bool bSucceeded = InitializeBackend();
|
|
||||||
if (!bSucceeded)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool bGloveWasPresent = IsValid(Owner->Glove);
|
|
||||||
const bool bFoundGlove = USGHapticGlove::GetGlove(Owner, Owner->IsRight(), Owner->Glove);
|
|
||||||
|
|
||||||
if (!bFoundGlove && bGloveWasPresent)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR(FString::Printf(TEXT("Could not find a %s glove!"),
|
|
||||||
(Owner->IsRight() ? TEXT("right-handed") : TEXT("left-handed"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bFoundGlove)
|
|
||||||
{
|
|
||||||
UpdateWristTrackingData();
|
|
||||||
}
|
|
||||||
|
|
||||||
return bFoundGlove;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
|
|
||||||
{
|
|
||||||
ensureAlwaysMsgf(Owner->Glove, TEXT("Invalid Glove!"));
|
|
||||||
|
|
||||||
FVector TrackerLocation{Owner->GetComponentLocation()};
|
|
||||||
FRotator TrackerRotation{Owner->GetComponentRotation()};
|
|
||||||
|
|
||||||
ESGPositionalTrackingHardware TrackerHardware = Owner->GetTrackingHardware();
|
|
||||||
if (TrackerHardware == ESGPositionalTrackingHardware::None)
|
|
||||||
{
|
|
||||||
TrackerHardware = ESGPositionalTrackingHardware::Custom;
|
|
||||||
}
|
|
||||||
else if (TrackerHardware == ESGPositionalTrackingHardware::Custom)
|
|
||||||
{
|
|
||||||
TrackerLocation += Owner->GetTrackingHardwareLocationOffset();
|
|
||||||
TrackerRotation += Owner->GetTrackingHardwareRotationOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
FVector NewWristLocation;
|
|
||||||
FRotator NewWristRotation;
|
|
||||||
Owner->Glove->GetWristLocation(TrackerLocation, TrackerRotation, TrackerHardware,
|
|
||||||
NewWristLocation, NewWristRotation);
|
|
||||||
|
|
||||||
const bool bLocationUpdated = !Owner->WristLocation.Equals(NewWristLocation, SMALL_NUMBER);
|
|
||||||
const bool bRotationUpdated = !Owner->WristRotation.Equals(NewWristRotation, SMALL_NUMBER);
|
|
||||||
|
|
||||||
if (bLocationUpdated)
|
|
||||||
{
|
|
||||||
Owner->WristLocation = MoveTemp(NewWristLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bRotationUpdated)
|
|
||||||
{
|
|
||||||
Owner->WristRotation = MoveTemp(NewWristRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bLocationUpdated && Owner->WristLocationChangedEvent.IsBound())
|
|
||||||
{
|
|
||||||
Owner->WristLocationChangedEvent.Broadcast(Owner->WristLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bRotationUpdated && Owner->WristRotationChangedEvent.IsBound())
|
|
||||||
{
|
|
||||||
Owner->WristRotationChangedEvent.Broadcast(Owner->WristRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((bLocationUpdated && bRotationUpdated) && Owner->WristLocationAndRotationChangedEvent.IsBound())
|
|
||||||
{
|
|
||||||
Owner->WristLocationAndRotationChangedEvent.Broadcast(Owner->WristLocation, Owner->WristRotation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::FImpl::DrawDebugGizmo()
|
|
||||||
{
|
|
||||||
const UWorld* World{Owner->GetWorld()};
|
|
||||||
const FVector& Location{Owner->GetComponentLocation()};
|
|
||||||
const FRotator& Rotation{Owner->GetComponentRotation()};
|
|
||||||
const FSGDebugGizmoSettings& DebugGizmoSettings{Owner->GetWristTrackerDebugGizmoSettings()};
|
|
||||||
|
|
||||||
FSGDebugGizmo::Draw(World, Location, Rotation, DebugGizmoSettings);
|
|
||||||
//FSGDebugGizmo::Draw(World, Owner->WristLocation, Owner->WristRotation, DebugGizmoSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void USGWristTrackerComponent::FImplDeleter::operator()(const FImpl* P) const
|
|
||||||
{
|
|
||||||
delete P;
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/GameFramework//SGGameModeBase.h"
|
|
||||||
|
|
||||||
#include "SenseGlove/GameFramework/SGPawn.h"
|
|
||||||
#include "SenseGlove/GameFramework/SGPlayerController.h"
|
|
||||||
|
|
||||||
ASGGameModeBase::ASGGameModeBase(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer)
|
|
||||||
{
|
|
||||||
DefaultPawnClass = ASGPawn::StaticClass();
|
|
||||||
PlayerControllerClass = ASGPlayerController::StaticClass();
|
|
||||||
}
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/GameFramework/SGPawn.h"
|
|
||||||
|
|
||||||
#include "Camera/CameraComponent.h"
|
|
||||||
|
|
||||||
#include "SenseGlove/Components/SGVirtualHandComponent.h"
|
|
||||||
#include "SenseGlove/Components/SGWristTrackerComponent.h"
|
|
||||||
|
|
||||||
struct ASGPawn::FImpl
|
|
||||||
{
|
|
||||||
/************************
|
|
||||||
* Static methods
|
|
||||||
************************/
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Owner object
|
|
||||||
************************/
|
|
||||||
|
|
||||||
ASGPawn* Owner;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Constructor / Destructor
|
|
||||||
************************/
|
|
||||||
|
|
||||||
explicit FImpl(ASGPawn* InOwner);
|
|
||||||
~FImpl();
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Default copy constructor & copy assignment operator
|
|
||||||
************************/
|
|
||||||
|
|
||||||
FImpl(const FImpl& Rhs) = default;
|
|
||||||
FImpl& operator=(const FImpl& Rhs) = default;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Methods
|
|
||||||
************************/
|
|
||||||
};
|
|
||||||
|
|
||||||
ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer),
|
|
||||||
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
||||||
{
|
|
||||||
PrimaryActorTick.bCanEverTick = true;
|
|
||||||
|
|
||||||
SceneRoot = ObjectInitializer.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneRoot"));
|
|
||||||
SetRootComponent(SceneRoot);
|
|
||||||
|
|
||||||
Camera = ObjectInitializer.CreateDefaultSubobject<UCameraComponent>(this, TEXT("Camera"));
|
|
||||||
Camera->SetupAttachment(GetRootComponent());
|
|
||||||
Camera->SetCanEverAffectNavigation(false);
|
|
||||||
|
|
||||||
WristTrackerLeft = ObjectInitializer.CreateDefaultSubobject<USGWristTrackerComponent>(
|
|
||||||
this, TEXT("WristTrackerLeft"));
|
|
||||||
WristTrackerLeft->SetupAttachment(GetRootComponent());
|
|
||||||
WristTrackerLeft->SetRight(false);
|
|
||||||
|
|
||||||
HandLeft = ObjectInitializer.CreateDefaultSubobject<USGVirtualHandComponent>(this, TEXT("HandLeft"));
|
|
||||||
HandLeft->SetupAttachment(GetRootComponent());
|
|
||||||
HandLeft->SetRight(false);
|
|
||||||
HandLeft->SetHiddenIfNoGloveDetected(true);
|
|
||||||
HandLeft->SetRelativeRotation(FRotator{0.0f, -90.0f, 0.0f},
|
|
||||||
false, nullptr, ETeleportType::None);
|
|
||||||
HandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f},
|
|
||||||
false, nullptr, ETeleportType::None);
|
|
||||||
HandLeft->SetWristTracker(WristTrackerLeft);
|
|
||||||
|
|
||||||
WristTrackerRight = ObjectInitializer.CreateDefaultSubobject<USGWristTrackerComponent>(
|
|
||||||
this, TEXT("WristTrackerRight"));
|
|
||||||
WristTrackerRight->SetupAttachment(GetRootComponent());
|
|
||||||
WristTrackerRight->SetRight(true);
|
|
||||||
|
|
||||||
HandRight = ObjectInitializer.CreateDefaultSubobject<USGVirtualHandComponent>(this, TEXT("HandRight"));
|
|
||||||
HandRight->SetupAttachment(GetRootComponent());
|
|
||||||
HandRight->SetRight(true);
|
|
||||||
HandRight->SetHiddenIfNoGloveDetected(true);
|
|
||||||
HandRight->SetRelativeRotation(FRotator{0.0f, -90.0f, 0.0f},
|
|
||||||
false, nullptr, ETeleportType::None);
|
|
||||||
HandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f},
|
|
||||||
false, nullptr, ETeleportType::None);
|
|
||||||
HandRight->SetWristTracker(WristTrackerRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASGPawn::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
WristTrackerLeft->IsLeft() && HandLeft->IsLeft(),
|
|
||||||
TEXT("The left hand and the left wrist do not track the left hand!"));
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
WristTrackerRight->IsRight() && HandRight->IsRight(),
|
|
||||||
TEXT("The right hand and the right wrist do not track the right hand!"));
|
|
||||||
|
|
||||||
WristTrackerLeft->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void
|
|
||||||
{
|
|
||||||
HandLeft->SetWorldLocation(Location);
|
|
||||||
});
|
|
||||||
|
|
||||||
WristTrackerLeft->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void
|
|
||||||
{
|
|
||||||
HandLeft->SetWorldRotation(Rotation);
|
|
||||||
});
|
|
||||||
|
|
||||||
WristTrackerRight->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void
|
|
||||||
{
|
|
||||||
HandRight->SetWorldLocation(Location);
|
|
||||||
});
|
|
||||||
|
|
||||||
WristTrackerRight->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void
|
|
||||||
{
|
|
||||||
HandRight->SetWorldRotation(Rotation);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASGPawn::PreInitializeComponents()
|
|
||||||
{
|
|
||||||
Super::PreInitializeComponents();
|
|
||||||
|
|
||||||
WristTrackerLeft->SetRight(HandLeft->IsRight());
|
|
||||||
WristTrackerRight->SetRight(HandRight->IsRight());
|
|
||||||
}
|
|
||||||
|
|
||||||
ASGPawn::FImpl::FImpl(ASGPawn* InOwner)
|
|
||||||
: Owner(InOwner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ASGPawn::FImpl::~FImpl() = default;
|
|
||||||
|
|
||||||
void ASGPawn::FImplDeleter::operator()(const FImpl* P) const
|
|
||||||
{
|
|
||||||
delete P;
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/GameFramework/SGPlayerController.h"
|
|
||||||
|
|
||||||
ASGPlayerController::ASGPlayerController(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASGPlayerController::SetupInputComponent()
|
|
||||||
{
|
|
||||||
Super::SetupInputComponent();
|
|
||||||
}
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGlove/GameFramework/SGVirtualHandActor.h"
|
|
||||||
|
|
||||||
#include "SenseGlove/Components/SGVirtualHandComponent.h"
|
|
||||||
#include "SenseGlove/Components/SGWristTrackerComponent.h"
|
|
||||||
|
|
||||||
struct ASGVirtualHandActor::FImpl
|
|
||||||
{
|
|
||||||
/************************
|
|
||||||
* Owner object
|
|
||||||
************************/
|
|
||||||
|
|
||||||
ASGVirtualHandActor* Owner;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Constructor / Destructor
|
|
||||||
************************/
|
|
||||||
|
|
||||||
explicit FImpl(ASGVirtualHandActor* InOwner);
|
|
||||||
~FImpl();
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Default copy constructor & copy assignment operator
|
|
||||||
************************/
|
|
||||||
|
|
||||||
FImpl(const FImpl& Rhs) = default;
|
|
||||||
FImpl& operator=(const FImpl& Rhs) = default;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Methods
|
|
||||||
************************/
|
|
||||||
};
|
|
||||||
|
|
||||||
ASGVirtualHandActor::ASGVirtualHandActor(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer),
|
|
||||||
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
||||||
{
|
|
||||||
PrimaryActorTick.bCanEverTick = true;
|
|
||||||
|
|
||||||
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
|
|
||||||
SetRootComponent(SceneRoot);
|
|
||||||
|
|
||||||
VirtualHand = CreateDefaultSubobject<USGVirtualHandComponent>(TEXT("VirtualHand"));
|
|
||||||
VirtualHand->SetupAttachment(RootComponent);
|
|
||||||
VirtualHand->SetRelativeRotation(FRotator{0.0f, -90.0f, 0.0f},
|
|
||||||
false, nullptr, ETeleportType::None);
|
|
||||||
|
|
||||||
WristTracker = CreateDefaultSubobject<USGWristTrackerComponent>(TEXT("WristTracker"));
|
|
||||||
WristTracker->SetupAttachment(RootComponent);
|
|
||||||
|
|
||||||
WristTracker->SetRight(VirtualHand->IsRight());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASGVirtualHandActor::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(
|
|
||||||
(WristTracker->IsLeft() && VirtualHand->IsLeft())
|
|
||||||
|| (WristTracker->IsRight() && VirtualHand->IsRight()),
|
|
||||||
TEXT("The virtual hand component and the wrist tracker component do not track the same hand!"));
|
|
||||||
|
|
||||||
WristTracker->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void
|
|
||||||
{
|
|
||||||
VirtualHand->SetWorldLocation(Location);
|
|
||||||
});
|
|
||||||
|
|
||||||
WristTracker->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void
|
|
||||||
{
|
|
||||||
VirtualHand->SetWorldRotation(Rotation);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASGVirtualHandActor::PreInitializeComponents()
|
|
||||||
{
|
|
||||||
Super::PreInitializeComponents();
|
|
||||||
|
|
||||||
WristTracker->SetRight(VirtualHand->IsRight());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ASGVirtualHandActor::IsLeft() const
|
|
||||||
{
|
|
||||||
return WristTracker->IsLeft() && VirtualHand->IsLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ASGVirtualHandActor::IsRight() const
|
|
||||||
{
|
|
||||||
return WristTracker->IsRight() && VirtualHand->IsRight();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASGVirtualHandActor::SetRight(const bool bRight)
|
|
||||||
{
|
|
||||||
WristTracker->SetRight(bRight);
|
|
||||||
VirtualHand->SetRight(bRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ASGVirtualHandActor::IsGloveConnected() const
|
|
||||||
{
|
|
||||||
return VirtualHand->IsGloveConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
ASGVirtualHandActor::FImpl::FImpl(ASGVirtualHandActor* InOwner)
|
|
||||||
: Owner(InOwner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ASGVirtualHandActor::FImpl::~FImpl() = default;
|
|
||||||
|
|
||||||
void ASGVirtualHandActor::FImplDeleter::operator()(const FImpl* P) const
|
|
||||||
{
|
|
||||||
delete P;
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Animation/AnimInstance.h"
|
|
||||||
|
|
||||||
#include "SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h"
|
|
||||||
|
|
||||||
#include "SGVirtualHandAnimInstance.generated.h"
|
|
||||||
|
|
||||||
UCLASS(Transient, Blueprintable, BlueprintType, meta=(BlueprintThreadSafe), Within=SkeletalMeshComponent)
|
|
||||||
class SENSEGLOVE_API USGVirtualHandAnimInstance : public UAnimInstance
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual FSGVirtualHandAnimInstanceProxy* CreateAnimInstanceProxy() override;
|
|
||||||
};
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Animation/AnimInstanceProxy.h"
|
|
||||||
#include "Templates/UniquePtr.h"
|
|
||||||
#include "UObject/NameTypes.h"
|
|
||||||
|
|
||||||
#include "SGVirtualHandAnimInstanceProxy.generated.h"
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct SENSEGLOVE_API FSGVirtualHandAnimInstanceProxy : public FAnimInstanceProxy
|
|
||||||
{
|
|
||||||
GENERATED_USTRUCT_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
TMap<FName, FRotator> BonesRotations;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FSGVirtualHandAnimInstanceProxy();
|
|
||||||
FSGVirtualHandAnimInstanceProxy(UAnimInstance* Instance);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void PreEvaluateAnimation(UAnimInstance* InAnimInstance) override;
|
|
||||||
|
|
||||||
virtual bool Evaluate(FPoseContext& Output) override;
|
|
||||||
};
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Containers/Array.h"
|
|
||||||
#include "Components/SkeletalMeshComponent.h"
|
|
||||||
#include "Containers/Map.h"
|
|
||||||
#include "GameFramework/Actor.h"
|
|
||||||
#include "Math/Rotator.h"
|
|
||||||
#include "Math/Transform.h"
|
|
||||||
#include "ReferenceSkeleton.h"
|
|
||||||
#include "Templates/UniquePtr.h"
|
|
||||||
#include "UObject/NameTypes.h"
|
|
||||||
|
|
||||||
#include "SGSettings/SGDebugVirtualHandSettings.h"
|
|
||||||
|
|
||||||
#include "SGVirtualHandComponent.generated.h"
|
|
||||||
|
|
||||||
class USkeletalMesh;
|
|
||||||
|
|
||||||
class USGHandPose;
|
|
||||||
class USGHapticGlove;
|
|
||||||
class USGWristTrackerComponent;
|
|
||||||
|
|
||||||
UCLASS(Config=Engine, Blueprintable, ClassGroup=(Rendering, Common), hidecategories=(Object, "Mesh|SkeletalAsset"),
|
|
||||||
editinlinenew, meta=(BlueprintSpawnableComponent))
|
|
||||||
class SENSEGLOVE_API USGVirtualHandComponent : public USkeletalMeshComponent
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const TArray<TArray<FName>>& GetLeftHandFingerBoneNames();
|
|
||||||
static const TArray<TArray<FName>>& GetRightHandFingerBoneNames();
|
|
||||||
|
|
||||||
static const FName& GetLeftHandFingerBoneName(int32 Finger, int32 Joint);
|
|
||||||
static const FName& GetRightHandFingerBoneName(int32 Finger, int32 Joint);
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct FImpl;
|
|
||||||
|
|
||||||
struct FImplDeleter
|
|
||||||
{
|
|
||||||
void operator()(const FImpl* P) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
TUniquePtr<FImpl, FImplDeleter> Pimpl;
|
|
||||||
FImplDeleter PimplDeleter;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
uint8 bRight : 1;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
uint8 bHiddenInGameIfNoGloveDetected : 1;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, Category="SenseGlove",
|
|
||||||
meta=(AllowPrivateAccess="false", EditCondition="bDrawDebugVirtualHand", EditConditionHides))
|
|
||||||
FSGDebugVirtualHandSettings DebugVirtualHandSettings;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY(Transient)
|
|
||||||
uint8 bBackendInitialized : 1;
|
|
||||||
|
|
||||||
UPROPERTY(Transient)
|
|
||||||
USGHapticGlove* Glove;
|
|
||||||
|
|
||||||
UPROPERTY(Transient)
|
|
||||||
USGWristTrackerComponent* WristTracker;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FORCEINLINE bool IsLeft() const
|
|
||||||
{
|
|
||||||
return !IsRight();
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE bool IsRight() const
|
|
||||||
{
|
|
||||||
return !!bRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetRight(const bool bInRight);
|
|
||||||
|
|
||||||
FORCEINLINE bool IsHiddenInGameIfNoGloveDetected() const
|
|
||||||
{
|
|
||||||
return !!bHiddenInGameIfNoGloveDetected;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE void SetHiddenIfNoGloveDetected(const bool bInHiddenIfNoGloveDetected)
|
|
||||||
{
|
|
||||||
bHiddenInGameIfNoGloveDetected = bInHiddenIfNoGloveDetected;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE void SetWristTracker(USGWristTrackerComponent* InWristTracker)
|
|
||||||
{
|
|
||||||
WristTracker = InWristTracker;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void SetAnimClass(class UClass* NewClass) override;
|
|
||||||
|
|
||||||
virtual void PostInitProperties() override;
|
|
||||||
|
|
||||||
#if WITH_EDITOR
|
|
||||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
|
||||||
#endif /* WITH_EDITOR */
|
|
||||||
|
|
||||||
virtual void InitializeComponent() override;
|
|
||||||
|
|
||||||
virtual void UninitializeComponent() override;
|
|
||||||
|
|
||||||
virtual void BeginPlay() override;
|
|
||||||
|
|
||||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
|
||||||
|
|
||||||
virtual void TickComponent(float DeltaTime,
|
|
||||||
enum ELevelTick TickType,
|
|
||||||
FActorComponentTickFunction* ThisTickFunction) override;
|
|
||||||
|
|
||||||
virtual void SetSkeletalMesh(USkeletalMesh* NewMesh, bool bReinitPose = true) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void EditorTick(float DeltaTime,
|
|
||||||
enum ELevelTick TickType,
|
|
||||||
FActorComponentTickFunction* ThisTickFunction);
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool IsGloveConnected() const;
|
|
||||||
USGHandPose* GetHandPose();
|
|
||||||
|
|
||||||
public:
|
|
||||||
const FName& GetFingerBoneName(int32 Finger, int32 Joint) const;
|
|
||||||
const FTransform& GetFingerBoneRefTransform(int32 Finger, int32 Joint) const;
|
|
||||||
|
|
||||||
FRotator GetFingerBoneRefRotation(int32 Finger, int32 Joint) const;
|
|
||||||
TMap<FName, FRotator> GetFingersBonesRotations();
|
|
||||||
};
|
|
||||||
@@ -1,235 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GameFramework/Actor.h"
|
|
||||||
#include "Math/Rotator.h"
|
|
||||||
#include "Math/Vector.h"
|
|
||||||
#include "MotionControllerComponent.h"
|
|
||||||
#include "Templates/UniquePtr.h"
|
|
||||||
|
|
||||||
#include "SGSettings/SGDebugGizmoSettings.h"
|
|
||||||
#include "SGTypes/SGCoreTypes.h"
|
|
||||||
|
|
||||||
#include "SGWristTrackerComponent.generated.h"
|
|
||||||
|
|
||||||
class USGHandPose;
|
|
||||||
class USGHapticGlove;
|
|
||||||
|
|
||||||
UCLASS(Blueprintable, ClassGroup = MotionController, meta = (BlueprintSpawnableComponent))
|
|
||||||
class SENSEGLOVE_API USGWristTrackerComponent : public UMotionControllerComponent
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
DECLARE_EVENT_OneParam(USGWristTrackerComponent, FWristLocationChangedEvent, const FVector&)
|
|
||||||
|
|
||||||
FWristLocationChangedEvent& OnWristLocationChanged()
|
|
||||||
{
|
|
||||||
return WristLocationChangedEvent;
|
|
||||||
};
|
|
||||||
|
|
||||||
DECLARE_EVENT_OneParam(USGWristTrackerComponent, FWristRotationChangedEvent, const FRotator&)
|
|
||||||
|
|
||||||
FWristRotationChangedEvent& OnWristRotationChanged()
|
|
||||||
{
|
|
||||||
return WristRotationChangedEvent;
|
|
||||||
};
|
|
||||||
|
|
||||||
DECLARE_EVENT_TwoParams(USGWristTrackerComponent, FWristLocationAndRotationChangedEvent,
|
|
||||||
const FVector&, const FRotator&)
|
|
||||||
|
|
||||||
FWristLocationAndRotationChangedEvent& OnWristLocationAndRotationChanged()
|
|
||||||
{
|
|
||||||
return WristLocationAndRotationChangedEvent;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
FWristLocationChangedEvent WristLocationChangedEvent;
|
|
||||||
FWristRotationChangedEvent WristRotationChangedEvent;
|
|
||||||
FWristLocationAndRotationChangedEvent WristLocationAndRotationChangedEvent;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct FImpl;
|
|
||||||
|
|
||||||
struct FImplDeleter
|
|
||||||
{
|
|
||||||
void operator()(const FImpl* P) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
TUniquePtr<FImpl, FImplDeleter> Pimpl;
|
|
||||||
FImplDeleter PimplDeleter;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings")
|
|
||||||
uint8 bOverridePluginWristTrackingSettings : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set to Custom, any desired location and rotation can be specified.
|
|
||||||
*/
|
|
||||||
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
|
||||||
meta=(EditCondition="bOverridePluginWristTrackingSettings", EditConditionHides))
|
|
||||||
ESGPositionalTrackingHardware TrackingHardware;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Valid only if TrackingHardware is set to Custom.
|
|
||||||
*/
|
|
||||||
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
|
||||||
meta=(EditCondition=
|
|
||||||
"bOverridePluginWristTrackingSettings && TrackingHardware == ESGPositionalTrackingHardware::Custom",
|
|
||||||
EditConditionHides))
|
|
||||||
FVector TrackingHardwareLocationOffset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Valid only if TrackingHardware is set to Custom.
|
|
||||||
*/
|
|
||||||
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
|
||||||
meta=(EditCondition=
|
|
||||||
"bOverridePluginWristTrackingSettings && TrackingHardware == ESGPositionalTrackingHardware::Custom",
|
|
||||||
EditConditionHides))
|
|
||||||
FRotator TrackingHardwareRotationOffset;
|
|
||||||
|
|
||||||
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings")
|
|
||||||
uint8 bOverridePluginWristTrackingDebugSettings : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If enabled, draws debug Wrist trackers where possible.
|
|
||||||
*/
|
|
||||||
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
|
||||||
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings", EditConditionHides))
|
|
||||||
uint8 bDrawWristTrackerDebugGizmo : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Valid only if bDrawWristTrackerDebugGizmo is enabled.
|
|
||||||
*/
|
|
||||||
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
|
||||||
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawWristTrackerDebugGizmo",
|
|
||||||
EditConditionHides))
|
|
||||||
FSGDebugGizmoSettings WristTrackerDebugGizmoSettings;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY(Transient)
|
|
||||||
uint8 bBackendInitialized : 1;
|
|
||||||
|
|
||||||
UPROPERTY(Transient)
|
|
||||||
USGHapticGlove* Glove;
|
|
||||||
|
|
||||||
UPROPERTY(Transient)
|
|
||||||
FVector WristLocation;
|
|
||||||
|
|
||||||
UPROPERTY(Transient)
|
|
||||||
FRotator WristRotation;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FORCEINLINE bool OverridesPluginWristTrackingSettings() const
|
|
||||||
{
|
|
||||||
return !!bOverridePluginWristTrackingSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE void OverridePluginWristTrackingSettings(const bool bInOverridePluginWristTrackingSettings)
|
|
||||||
{
|
|
||||||
bOverridePluginWristTrackingSettings = bInOverridePluginWristTrackingSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
ESGPositionalTrackingHardware GetTrackingHardware() const;
|
|
||||||
void SetTrackingHardware(ESGPositionalTrackingHardware InTrackingHardware);
|
|
||||||
|
|
||||||
const FVector& GetTrackingHardwareLocationOffset() const;
|
|
||||||
void SetTrackingHardwareLocationOffset(const FVector& InTrackingHardwareLocationOffset);
|
|
||||||
|
|
||||||
const FRotator& GetTrackingHardwareRotationOffset() const;
|
|
||||||
void SetTrackingHardwareRotationOffset(const FRotator& InTrackingHardwareRotationOffset);
|
|
||||||
|
|
||||||
FORCEINLINE bool OverridesPluginWristTrackingDebugSettings() const
|
|
||||||
{
|
|
||||||
return !!bOverridePluginWristTrackingDebugSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE void OverridePluginWristTrackingDebugSettings(const bool bInOverridePluginWristTrackingDebugSettings)
|
|
||||||
{
|
|
||||||
bOverridePluginWristTrackingDebugSettings = bInOverridePluginWristTrackingDebugSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetDrawWristTrackerDebugGizmo() const;
|
|
||||||
void SetDrawWristTrackerDebugGizmo(bool bInDrawWristTrackerDebugGizmo);
|
|
||||||
|
|
||||||
const FSGDebugGizmoSettings& GetWristTrackerDebugGizmoSettings() const;
|
|
||||||
void SetWristTrackerDebugGizmoSettings(const FSGDebugGizmoSettings& InWristTrackerDebugGizmoSettings);
|
|
||||||
|
|
||||||
FORCEINLINE bool IsLeft() const
|
|
||||||
{
|
|
||||||
return GetTrackingSource() == EControllerHand::Left;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE bool IsRight() const
|
|
||||||
{
|
|
||||||
return GetTrackingSource() == EControllerHand::Right;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetRight(const bool bRight);
|
|
||||||
|
|
||||||
FORCEINLINE const FVector& GetWristLocation() const
|
|
||||||
{
|
|
||||||
return WristLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE const FRotator& GetWristRotation() const
|
|
||||||
{
|
|
||||||
return WristRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
#if WITH_EDITOR
|
|
||||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
|
||||||
#endif /* WITH_EDITOR */
|
|
||||||
|
|
||||||
virtual void InitializeComponent() override;
|
|
||||||
|
|
||||||
virtual void UninitializeComponent() override;
|
|
||||||
|
|
||||||
virtual void BeginPlay() override;
|
|
||||||
|
|
||||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
|
||||||
|
|
||||||
virtual void TickComponent(float DeltaTime,
|
|
||||||
enum ELevelTick TickType,
|
|
||||||
FActorComponentTickFunction* ThisTickFunction) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void EditorTick(float DeltaTime,
|
|
||||||
enum ELevelTick TickType,
|
|
||||||
FActorComponentTickFunction* ThisTickFunction);
|
|
||||||
};
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GameFramework/GameModeBase.h"
|
|
||||||
|
|
||||||
#include "SGGameModeBase.generated.h"
|
|
||||||
|
|
||||||
UCLASS(Config=Game, NotPlaceable, BlueprintType, Blueprintable, Transient)
|
|
||||||
class SENSEGLOVE_API ASGGameModeBase : public AGameModeBase
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
};
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GameFramework/Pawn.h"
|
|
||||||
#include "Templates/UniquePtr.h"
|
|
||||||
|
|
||||||
#include "SGPawn.generated.h"
|
|
||||||
|
|
||||||
class UCameraComponent;
|
|
||||||
|
|
||||||
class USGVirtualHandComponent;
|
|
||||||
class USGWristTrackerComponent;
|
|
||||||
|
|
||||||
UCLASS(Config=Game, BlueprintType, Blueprintable)
|
|
||||||
class SENSEGLOVE_API ASGPawn : public APawn
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct FImpl;
|
|
||||||
|
|
||||||
struct FImplDeleter
|
|
||||||
{
|
|
||||||
void operator()(const FImpl* P) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
TUniquePtr<FImpl, FImplDeleter> Pimpl;
|
|
||||||
FImplDeleter PimplDeleter;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USceneComponent* SceneRoot;
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
UCameraComponent* Camera;
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USGWristTrackerComponent* WristTrackerLeft;
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USGWristTrackerComponent* WristTrackerRight;
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USGVirtualHandComponent* HandLeft;
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USGVirtualHandComponent* HandRight;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FORCEINLINE UCameraComponent* GetCamera() const
|
|
||||||
{
|
|
||||||
return Camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE USGWristTrackerComponent* GetWristTrackerLeft() const
|
|
||||||
{
|
|
||||||
return WristTrackerLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE USGWristTrackerComponent* GetWristTrackerRight() const
|
|
||||||
{
|
|
||||||
return WristTrackerRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE USGVirtualHandComponent* GetHandLeft() const
|
|
||||||
{
|
|
||||||
return HandLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE USGVirtualHandComponent* GetHandRight() const
|
|
||||||
{
|
|
||||||
return HandRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void BeginPlay() override;
|
|
||||||
virtual void PreInitializeComponents() override;
|
|
||||||
};
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GameFramework/PlayerController.h"
|
|
||||||
|
|
||||||
#include "SGPlayerController.generated.h"
|
|
||||||
|
|
||||||
UCLASS(Config=Game, BlueprintType, Blueprintable)
|
|
||||||
class SENSEGLOVE_API ASGPlayerController : public APlayerController
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void SetupInputComponent() override;
|
|
||||||
};
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Containers/Array.h"
|
|
||||||
#include "Containers/Map.h"
|
|
||||||
#include "GameFramework/Actor.h"
|
|
||||||
#include "Templates/UniquePtr.h"
|
|
||||||
#include "UObject/NameTypes.h"
|
|
||||||
|
|
||||||
#include "SGVirtualHandActor.generated.h"
|
|
||||||
|
|
||||||
class USkeletalMesh;
|
|
||||||
class USkeleton;
|
|
||||||
class USceneComponent;
|
|
||||||
|
|
||||||
class USGHandPose;
|
|
||||||
class USGVirtualHandComponent;
|
|
||||||
class USGWristTrackerComponent;
|
|
||||||
|
|
||||||
UCLASS(Config=Game, BlueprintType)
|
|
||||||
class SENSEGLOVE_API ASGVirtualHandActor : public AActor
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct FImpl;
|
|
||||||
|
|
||||||
struct FImplDeleter
|
|
||||||
{
|
|
||||||
void operator()(const FImpl* P) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
TUniquePtr<FImpl, FImplDeleter> Pimpl;
|
|
||||||
FImplDeleter PimplDeleter;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USceneComponent* SceneRoot;
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USGWristTrackerComponent* WristTracker;
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
|
|
||||||
USGVirtualHandComponent* VirtualHand;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FORCEINLINE USGWristTrackerComponent* GetWristTracker() const
|
|
||||||
{
|
|
||||||
return WristTracker;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE USGVirtualHandComponent* GetVirtualHand() const
|
|
||||||
{
|
|
||||||
return VirtualHand;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FORCEINLINE void SetMesh(USGVirtualHandComponent* InVirtualHand)
|
|
||||||
{
|
|
||||||
VirtualHand = InVirtualHand;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void BeginPlay() override;
|
|
||||||
virtual void PreInitializeComponents() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool IsLeft() const;
|
|
||||||
bool IsRight() const;
|
|
||||||
void SetRight(bool bRight);
|
|
||||||
|
|
||||||
bool IsGloveConnected() const;
|
|
||||||
};
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -52,15 +52,11 @@ public class SenseGlove : ModuleRules
|
|||||||
PrivateDependencyModuleNames.AddRange(
|
PrivateDependencyModuleNames.AddRange(
|
||||||
new string[]
|
new string[]
|
||||||
{
|
{
|
||||||
"AnimGraphRuntime",
|
|
||||||
"CoreUObject",
|
"CoreUObject",
|
||||||
"Engine",
|
"Engine",
|
||||||
"HeadMountedDisplay",
|
|
||||||
"SenseGloveConnect",
|
"SenseGloveConnect",
|
||||||
"SenseGloveCore",
|
"SenseGloveCore",
|
||||||
"SenseGloveDebug",
|
|
||||||
"SenseGloveLog",
|
"SenseGloveLog",
|
||||||
"SenseGloveSettings",
|
|
||||||
"SenseGloveTypes",
|
"SenseGloveTypes",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SGAndroid/SGConnectJNI.h"
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
#include "Android/AndroidApplication.h"
|
|
||||||
#include "Android/AndroidJava.h"
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
#include "Misc/Paths.h"
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
#include "SGConnectImpl/SGExportedFunctions.h"
|
|
||||||
#include "SGInterop/SGIC_FString.h"
|
|
||||||
#include "SGInterop/SGIC_jclass.h"
|
|
||||||
#include "SGInterop/SGIC_jmethodID.h"
|
|
||||||
#include "SGInterop/SGIC_JNIEnv_Ptr.h"
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
int32 FSGConnectJNI::Initialize()
|
|
||||||
{
|
|
||||||
int32 Result = -999999;
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
static constexpr char SGCONNECT_JAVA_CLASS_NAME[] = "com.senseglove.sgconnect.SGConnect";
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to get the Android JNI environment...");
|
|
||||||
|
|
||||||
JNIEnv* Env = FAndroidApplication::GetJavaEnv();
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!Env)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI environmnet!");
|
|
||||||
return -1999999;
|
|
||||||
}
|
|
||||||
FSGIC_JNIEnv_Ptr InEnvContainer{Env};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android Java class...");
|
|
||||||
|
|
||||||
jclass Class = FAndroidApplication::FindJavaClass(SGCONNECT_JAVA_CLASS_NAME);
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (Env->IsSameObject(Class, nullptr))
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android Java class!");
|
|
||||||
return -2999999;
|
|
||||||
}
|
|
||||||
Class = (jclass)Env->NewGlobalRef(Class);
|
|
||||||
FSGIC_jclass InClassContainer{Class};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'Init'...");
|
|
||||||
|
|
||||||
jmethodID InitMethodID = Env->GetStaticMethodID(Class, "Init", "()I");
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!InitMethodID)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'Init'!");
|
|
||||||
return -3999999;
|
|
||||||
}
|
|
||||||
FSGIC_jmethodID InInitMethodIDContainer{InitMethodID};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'Dispose'...");
|
|
||||||
|
|
||||||
jmethodID DisposeMethodID = Env->GetStaticMethodID(Class, "Dispose", "()I");
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!DisposeMethodID)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'Dispose'!");
|
|
||||||
return -4999999;
|
|
||||||
}
|
|
||||||
FSGIC_jmethodID InDisposeMethodIDContainer{DisposeMethodID};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'GetLibraryVersion'...");
|
|
||||||
|
|
||||||
jmethodID GetLibraryVersionMethodID = Env->GetStaticMethodID(Class, "GetLibraryVersion", "()Ljava/lang/String;");
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!GetLibraryVersionMethodID)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'GetLibraryVersion'!");
|
|
||||||
return -5999999;
|
|
||||||
}
|
|
||||||
FSGIC_jmethodID InGetLibraryVersionMethodIDContainer{GetLibraryVersionMethodID};
|
|
||||||
|
|
||||||
FSGIC_FString ProjectSavedDirContainer{FPaths::ProjectSavedDir()};
|
|
||||||
|
|
||||||
Result = SGConnectImpl_Android_Initialize(&InEnvContainer, &InClassContainer,
|
|
||||||
&InInitMethodIDContainer,
|
|
||||||
&InDisposeMethodIDContainer,
|
|
||||||
&InGetLibraryVersionMethodIDContainer,
|
|
||||||
&ProjectSavedDirContainer);
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SGAndroid/SGCoreJNI.h"
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
#include "Android/AndroidApplication.h"
|
|
||||||
#include "Android/AndroidJava.h"
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
#include "Misc/Paths.h"
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
#include "SGCoreImpl/SGExportedFunctions.h"
|
|
||||||
#include "SGInterop/SGIC_FString.h"
|
|
||||||
#include "SGInterop/SGIC_jclass.h"
|
|
||||||
#include "SGInterop/SGIC_jmethodID.h"
|
|
||||||
#include "SGInterop/SGIC_JNIEnv_Ptr.h"
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
#include "SGLog/SGLog.h"
|
|
||||||
|
|
||||||
int32 FSGCoreJNI::Initialize()
|
|
||||||
{
|
|
||||||
int32 Result = -999999;
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
static constexpr char SGCONNECT_JAVA_CLASS_NAME[] = "com.senseglove.sgconnect.SGConnect";
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to get the Android JNI environment...");
|
|
||||||
|
|
||||||
JNIEnv* Env = FAndroidApplication::GetJavaEnv();
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!Env)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI environmnet!");
|
|
||||||
return -1999999;
|
|
||||||
}
|
|
||||||
FSGIC_JNIEnv_Ptr InEnvContainer{Env};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android Java class...");
|
|
||||||
|
|
||||||
jclass Class = FAndroidApplication::FindJavaClass(SGCONNECT_JAVA_CLASS_NAME);
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (Env->IsSameObject(Class, nullptr))
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android Java class!");
|
|
||||||
return -2999999;
|
|
||||||
}
|
|
||||||
Class = (jclass)Env->NewGlobalRef(Class);
|
|
||||||
FSGIC_jclass InClassContainer{Class};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'ActiveDevices'...");
|
|
||||||
|
|
||||||
jmethodID ActiveDevicesMethodID = Env->GetStaticMethodID(Class, "ActiveDevices", "()I");
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!ActiveDevicesMethodID)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'ActiveDevices'!");
|
|
||||||
return -3999999;
|
|
||||||
}
|
|
||||||
FSGIC_jmethodID InActiveDevicesMethodIDContainer{ActiveDevicesMethodID};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'GetDeviceString'...");
|
|
||||||
|
|
||||||
jmethodID GetDeviceStringMethodID = Env->GetStaticMethodID(Class, "GetDeviceString", "(I)Ljava/lang/String;");
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!GetDeviceStringMethodID)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'GetDeviceString'!");
|
|
||||||
return -4999999;
|
|
||||||
}
|
|
||||||
FSGIC_jmethodID InGetDeviceStringMethodIDContainer{GetDeviceStringMethodID};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'GetSensorString'...");
|
|
||||||
|
|
||||||
jmethodID GetSensorStringMethodID = Env->GetStaticMethodID(Class, "GetSensorString", "(I)Ljava/lang/String;");
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!GetSensorStringMethodID)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'GetSensorString'!");
|
|
||||||
return -5999999;
|
|
||||||
}
|
|
||||||
FSGIC_jmethodID InGetSensorStringMethodIDContainer{GetSensorStringMethodID};
|
|
||||||
|
|
||||||
SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'WriteHaptics'...");
|
|
||||||
|
|
||||||
jmethodID WriteHapticsMethodID = Env->GetStaticMethodID(Class, "WriteHaptics", "(ILjava/lang/String;)I");
|
|
||||||
FAndroidApplication::CheckJavaException();
|
|
||||||
if (!WriteHapticsMethodID)
|
|
||||||
{
|
|
||||||
SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'WriteHaptics'!");
|
|
||||||
return -6999999;
|
|
||||||
}
|
|
||||||
FSGIC_jmethodID InWriteHapticsMethodIDContainer{WriteHapticsMethodID};
|
|
||||||
|
|
||||||
FSGIC_FString ProjectSavedDirContainer{FPaths::ProjectSavedDir()};
|
|
||||||
|
|
||||||
Result = SGCoreImpl_Android_Initialize(&InEnvContainer, &InClassContainer,
|
|
||||||
&InActiveDevicesMethodIDContainer,
|
|
||||||
&InGetDeviceStringMethodIDContainer,
|
|
||||||
&InGetSensorStringMethodIDContainer,
|
|
||||||
&InWriteHapticsMethodIDContainer,
|
|
||||||
&ProjectSavedDirContainer);
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGloveAndroid.h"
|
|
||||||
|
|
||||||
#include "Modules/ModuleManager.h"
|
|
||||||
#include "SenseGloveAndroidModule.h"
|
|
||||||
|
|
||||||
IMPLEMENT_MODULE(FSenseGloveAndroidModule, SenseGloveAndroid)
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SenseGloveAndroidModule.h"
|
|
||||||
|
|
||||||
#include "SGAndroid/SGConnectJNI.h"
|
|
||||||
#include "SGAndroid/SGCoreJNI.h"
|
|
||||||
#include "SGLog/SGLog.h"
|
|
||||||
|
|
||||||
#define LOCTEXT_NAMESPACE "FSenseGloveAndroidModule"
|
|
||||||
|
|
||||||
void FSenseGloveAndroidModule::StartupModule()
|
|
||||||
{
|
|
||||||
SGLOG("Starting up SenseGloveAndroid module...");
|
|
||||||
|
|
||||||
#if PLATFORM_ANDROID
|
|
||||||
const int32 R1 = FSGConnectJNI::Initialize();
|
|
||||||
const int32 R2 = FSGCoreJNI::Initialize();
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(R1 == 0,
|
|
||||||
TEXT("Failed to initialize the SGConnect JNI bridge to SGConnect for Android! Status Code: %d"), R1);
|
|
||||||
|
|
||||||
ensureAlwaysMsgf(R2 == 0,
|
|
||||||
TEXT("Failed to initialize the SGCore JNI bridge to SGConnect for Android! Status Code: %d"), R2);
|
|
||||||
#endif /* PLATFORM_ANDROID */
|
|
||||||
}
|
|
||||||
|
|
||||||
void FSenseGloveAndroidModule::PreUnloadCallback()
|
|
||||||
{
|
|
||||||
SGLOG("Unloading SenseGloveAndroid module...");
|
|
||||||
}
|
|
||||||
|
|
||||||
void FSenseGloveAndroidModule::PostLoadCallback()
|
|
||||||
{
|
|
||||||
SGLOG("Loading SenseGloveAndroid module has succeeded!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void FSenseGloveAndroidModule::ShutdownModule()
|
|
||||||
{
|
|
||||||
SGLOG("Shutting down SenseGloveAndroid module...");
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef LOCTEXT_NAMESPACE
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Modules/ModuleInterface.h"
|
|
||||||
|
|
||||||
#define LOCTEXT_NAMESPACE "SenseGloveAndroid"
|
|
||||||
|
|
||||||
class FSenseGloveAndroidModule : public IModuleInterface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void StartupModule() override;
|
|
||||||
virtual void PreUnloadCallback() override;
|
|
||||||
virtual void PostLoadCallback() override;
|
|
||||||
virtual void ShutdownModule() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef LOCTEXT_NAMESPACE
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "UObject/ObjectMacros.h"
|
|
||||||
|
|
||||||
#include "SGCoreJNI.generated.h"
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct SENSEGLOVEANDROID_API FSGCoreJNI
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
static int32 Initialize();
|
|
||||||
};
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using UnrealBuildTool;
|
|
||||||
|
|
||||||
public class SenseGloveAndroid : ModuleRules
|
|
||||||
{
|
|
||||||
public SenseGloveAndroid(ReadOnlyTargetRules Target) : base(Target)
|
|
||||||
{
|
|
||||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
|
||||||
|
|
||||||
PublicDependencyModuleNames.AddRange(
|
|
||||||
new string[]
|
|
||||||
{
|
|
||||||
"Core",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
PrivateDependencyModuleNames.AddRange(
|
|
||||||
new string[]
|
|
||||||
{
|
|
||||||
"CoreUObject",
|
|
||||||
"Engine",
|
|
||||||
"SenseGloveConnectImpl",
|
|
||||||
"SenseGloveCoreImpl",
|
|
||||||
"SenseGloveInterop",
|
|
||||||
"SenseGloveLog",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Target.Platform == UnrealTargetPlatform.Android)
|
|
||||||
{
|
|
||||||
AdditionalPropertiesForReceipt.Add("AndroidPlugin",
|
|
||||||
Path.Combine(ModuleDirectory, "SenseGloveAndroid_UPL.xml"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
@author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
|
|
||||||
@section LICENSE
|
|
||||||
|
|
||||||
(The MIT License)
|
|
||||||
|
|
||||||
Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- https://docs.unrealengine.com/en-US/SharingAndReleasing/Mobile/UnrealPluginLanguage/index.html -->
|
|
||||||
|
|
||||||
<root xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<init>
|
|
||||||
<log text="SenseGloveAndroid [INIT]: adding properties to the manifest and Gradle"/>
|
|
||||||
<trace enable="true"/>
|
|
||||||
|
|
||||||
<setBool result="bSupportedArch" value="false"/>
|
|
||||||
|
|
||||||
<isArch arch="armeabi-v7a">
|
|
||||||
<setBool result="bSupportedArch" value="false"/>
|
|
||||||
</isArch>
|
|
||||||
|
|
||||||
<isArch arch="arm64-v8a">
|
|
||||||
<setBool result="bSupportedArch" value="true"/>
|
|
||||||
</isArch>
|
|
||||||
|
|
||||||
<isArch arch="x86">
|
|
||||||
<setBool result="bSupportedArch" value="false"/>
|
|
||||||
</isArch>
|
|
||||||
|
|
||||||
<isArch arch="x86_64">
|
|
||||||
<setBool result="bSupportedArch" value="false"/>
|
|
||||||
</isArch>
|
|
||||||
|
|
||||||
<if condition="bSupportedArch">
|
|
||||||
<false>
|
|
||||||
<log text="SenseGloveAndroid [WARN]: this architecture is not supported!"/>
|
|
||||||
</false>
|
|
||||||
</if>
|
|
||||||
</init>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<prebuildCopies>
|
|
||||||
<copyDir src="$S(PluginDir)/Private/Java" dst="$S(BuildDir)/src/com/senseglove/sgconnect" />
|
|
||||||
</prebuildCopies>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<resourceCopies>
|
|
||||||
<isArch arch="arm64-v8a">
|
|
||||||
<if condition="Distribution">
|
|
||||||
<true>
|
|
||||||
<!--
|
|
||||||
<copyFile src="$S(PluginDir)/ThirdParty/lib/oculus/release/somelib.so"
|
|
||||||
dst="$S(BuildDir)/libs/$S(Architecture)/somelib.so" />
|
|
||||||
-->
|
|
||||||
</true>
|
|
||||||
<false>
|
|
||||||
<!--
|
|
||||||
<copyFile src="$S(PluginDir)/ThirdParty/lib/oculus/debug/somelib.so"
|
|
||||||
dst="$S(BuildDir)/libs/$S(Architecture)/somelib.so" />
|
|
||||||
-->
|
|
||||||
</false>
|
|
||||||
</if>
|
|
||||||
</isArch>
|
|
||||||
|
|
||||||
<copyFile src="$S(PluginDir)/../ThirdParty/android/sgconnect.jar" dst="$S(BuildDir)/gradle/app/libs/sgconnect.jar" />
|
|
||||||
</resourceCopies>
|
|
||||||
|
|
||||||
<gradleProperties>
|
|
||||||
<insert>
|
|
||||||
<!--android.useAndroidX=true
|
|
||||||
android.enableJetifier=true-->
|
|
||||||
kapt.incremental.apt=true
|
|
||||||
</insert>
|
|
||||||
</gradleProperties>
|
|
||||||
|
|
||||||
<proguardAdditions>
|
|
||||||
<insert>
|
|
||||||
|
|
||||||
<!-- Disable obfuscation for SenseGlove classes -->
|
|
||||||
-dontwarn com.senseglove.**
|
|
||||||
-keep class com.senseglove.** { *; }
|
|
||||||
-keep interface com.senseglove.** { *; }
|
|
||||||
-keep public class com.senseglove.sgconnect.** { public protected *; }
|
|
||||||
|
|
||||||
<!-- Disable obfuscation for AndroidX classes -->
|
|
||||||
<!---dontwarn androidx.**
|
|
||||||
-keep class androidx.** { *; }
|
|
||||||
-keep interface androidx.** { *; }-->
|
|
||||||
|
|
||||||
</insert>
|
|
||||||
</proguardAdditions>
|
|
||||||
|
|
||||||
<soLoadLibrary>
|
|
||||||
<!--
|
|
||||||
<loadLibrary name="somelib" failmsg="SenseGlove [WARN]: somelib.so library failed to load!" />
|
|
||||||
-->
|
|
||||||
</soLoadLibrary>
|
|
||||||
|
|
||||||
<androidManifestUpdates>
|
|
||||||
|
|
||||||
<!-- For target SDK 31 update the SplashActivity activity -->
|
|
||||||
<loopElements tag="activity">
|
|
||||||
<setStringFromAttribute result="activityName" tag="$" name="android:name"/>
|
|
||||||
<setBoolIsEqual result="bSplashActivity" arg1="$S(activityName)" arg2="com.epicgames.ue4.SplashActivity"/>
|
|
||||||
<if condition="bSplashActivity">
|
|
||||||
<true>
|
|
||||||
<addAttribute tag="$" name="android:exported" value="true"/>
|
|
||||||
</true>
|
|
||||||
</if>
|
|
||||||
</loopElements>
|
|
||||||
|
|
||||||
<addElements tag="application">
|
|
||||||
<!--
|
|
||||||
<addAttribute tag="application" name="android:requestSomeThingHere" value="true"/>
|
|
||||||
-->
|
|
||||||
</addElements>
|
|
||||||
|
|
||||||
<addPermission android:name="android.permission.BLUETOOTH"/>
|
|
||||||
<addPermission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
|
||||||
<addPermission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
|
|
||||||
<addPermission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
|
||||||
|
|
||||||
</androidManifestUpdates>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<AARImports>
|
|
||||||
<insertValue value="repository $S(PluginDir)/../../ThirdParty/android"/>
|
|
||||||
<insertNewline/>
|
|
||||||
<insertValue value="com.senseglove.sgconnect,sgconnect-android,release" />
|
|
||||||
<insertNewline/>
|
|
||||||
</AARImports>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<buildGradleAdditions>
|
|
||||||
<insert>
|
|
||||||
ext {
|
|
||||||
android {
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
minifyEnabled false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation files('libs/sgconnect.jar')
|
|
||||||
}
|
|
||||||
|
|
||||||
</insert>
|
|
||||||
</buildGradleAdditions>
|
|
||||||
|
|
||||||
<baseBuildGradleAdditions>
|
|
||||||
<insert>
|
|
||||||
allprojects {
|
|
||||||
def mappings = [
|
|
||||||
]
|
|
||||||
beforeEvaluate {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</insert>
|
|
||||||
</baseBuildGradleAdditions>
|
|
||||||
|
|
||||||
<buildscriptGradleAdditions>
|
|
||||||
</buildscriptGradleAdditions>
|
|
||||||
|
|
||||||
<gradleCopies>
|
|
||||||
</gradleCopies>
|
|
||||||
|
|
||||||
<buildXmlPropertyAdditions>
|
|
||||||
</buildXmlPropertyAdditions>
|
|
||||||
|
|
||||||
<minimumSDKAPI>
|
|
||||||
</minimumSDKAPI>
|
|
||||||
|
|
||||||
<gameActivityImportAdditions>
|
|
||||||
<insert>
|
|
||||||
import com.senseglove.*;
|
|
||||||
</insert>
|
|
||||||
</gameActivityImportAdditions>
|
|
||||||
</root>
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SGBuildHacks/SGInclude_Connect_Android.h"
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
||||||
*
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* (The MIT License)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "SGBuildHacks/SGInclude_Core_Android.h"
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2023 SenseGlove
|
* Copyright (c) 2020 - 2022 SenseGlove
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user