Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c56af0e1f
|
||
|
|
9cbdf5cea7
|
||
|
|
032422de1c
|
||
|
|
0f89d1c4dd
|
||
|
|
8d289c0f2f
|
||
|
|
62a2dd44f0
|
||
|
|
c3001c588c
|
||
|
|
f3b21fecfa
|
||
|
|
94e1b9ffcb
|
||
|
|
01078b6cd6
|
||
|
|
a62f615036
|
||
|
|
5213282f25
|
||
|
|
58712b48ad
|
||
|
|
1684a40c20
|
||
|
|
cbcb6abaee
|
||
|
|
1ff21f70c7
|
||
|
|
3020fcdd7a
|
||
|
|
d3467ac7f2
|
||
|
|
4a212edbca
|
||
|
|
5ebcb583f6
|
||
|
|
9b99399641
|
||
|
|
691fd43cd1
|
||
|
|
716ce49ca7
|
||
|
|
f4a368a61c
|
||
|
|
22c97d2d77
|
||
|
|
e89643f8d0
|
||
|
|
24eb573007
|
||
|
|
3b29f54622
|
||
|
|
61e4aa2e6a
|
||
|
|
0dccac6432
|
||
|
|
12bfcfe80d
|
||
|
|
407d4ea14c
|
||
|
|
1dff735623
|
||
|
|
1834ea5d5c
|
||
|
|
29d2aad490
|
||
|
|
82f354e340
|
||
|
|
d4b06e062e
|
||
|
|
4a005a85b0
|
||
|
|
919e7f17dd
|
||
|
|
31cb7ee20b
|
||
|
|
ae268ebde7
|
||
|
|
220ddf28a6
|
||
|
|
091b0ade32
|
||
|
|
b0c32ccad4
|
||
|
|
838b5fe557
|
||
|
|
78735026c2
|
||
|
|
e1ced44a69
|
||
|
|
f92e870c56
|
||
|
|
a4941d4d7d
|
||
|
|
4a72839ece
|
||
|
|
1a89f202c5
|
||
|
|
f1b14c7673
|
||
|
|
a35e706283
|
||
|
|
708fce2f0c
|
||
|
|
9116e4a234
|
||
|
|
9ee7e3f0df
|
||
|
|
4a03aedb3c
|
||
|
|
1eadfd249b
|
||
|
|
d2a1583217
|
||
|
|
786c7d8380
|
||
|
|
53a70569bd
|
||
|
|
4f01d61640
|
||
|
|
a0bd230c73
|
||
|
|
81eb3bb90c
|
||
|
|
8253ec277d
|
||
|
|
9598c772fc
|
||
|
|
01eed66701
|
||
|
|
9ae0b1ea2f
|
||
|
|
a6baab575c
|
||
|
|
79c31ecf50
|
||
|
|
d80697ee72
|
||
|
|
50f76c7a0d
|
||
|
|
846dac5a88
|
||
|
|
c314920d89
|
||
|
|
55405672f8
|
||
|
|
f2656f1bea
|
||
|
|
eead79b8f5
|
||
|
|
5ae86cbf66
|
||
|
|
5902aafff0
|
||
|
|
4e591d6290
|
||
|
|
46f885fa5a
|
||
|
|
51190d6ead
|
||
|
|
96fb9c3c8e
|
||
|
|
9bde1878ed
|
||
|
|
7c271d30ce
|
||
|
|
d61183a960
|
||
|
|
caa0bf259a
|
||
|
|
e9a6fc3df0
|
||
|
|
bdfb75920b
|
||
|
|
2e5ba17d89
|
||
|
|
25dca3f8f3
|
||
|
|
b4cdbec91a
|
||
|
|
58ca6a5bca
|
||
|
|
f29c428b16
|
||
|
|
759c94bcbf
|
||
|
|
4393af7317
|
||
|
|
a31b14d48c
|
||
|
|
854ce6a198
|
||
|
|
e0e743b63d
|
||
|
|
e32453dfef
|
||
|
|
d57d3ffa4a
|
||
|
|
8194072025
|
||
|
|
cf7fba949d
|
||
|
|
0dd745bbe6
|
||
|
|
0ca24adee3
|
||
|
|
b947685598
|
||
|
|
11534229f4
|
||
|
|
77d7b4eb23
|
||
|
|
25e8fd2d07
|
||
|
|
dafc7c0ad6
|
||
|
|
2b818dd11b
|
||
|
|
cf115e2782
|
||
|
|
f709be4935
|
||
|
|
a0f3b84aab
|
||
|
|
de83672ef1
|
||
|
|
a465321f9d
|
||
|
|
392fcd4932
|
||
|
|
8a1e9ff300
|
||
|
|
fd257711c2
|
||
|
|
ff59e7f712
|
||
|
|
06b27847cb
|
||
|
|
94301a321c
|
||
|
|
0ea98272a9
|
||
|
|
14a43e0630
|
||
|
|
a7f4a83850
|
||
|
|
9101d2061a
|
||
|
|
3e025f3e47
|
||
|
|
2ba5c0f2fc
|
||
|
|
66e60ff18a
|
||
|
|
25f8ef6393
|
||
|
|
e30ca2c9ed
|
||
|
|
adcfa63415
|
||
|
|
02cb09d504
|
||
|
|
89a9200413
|
||
|
|
e50a65ca92
|
||
|
|
955bb69cf9
|
||
|
|
3335ee2ec3
|
||
|
|
b0113a908e
|
||
|
|
50971e6051
|
||
|
|
78bb5adff6
|
||
|
|
95fb454576
|
||
|
|
c0d4a50f76
|
||
|
|
092f4a1327
|
||
|
|
5bbb51b0fe
|
||
|
|
6006a22c06
|
||
|
|
ffdb3657d6
|
||
|
|
f5b93b45ed
|
||
|
|
08e8eec206
|
||
|
|
b47de02afe
|
||
|
|
e58522bfd1
|
||
|
|
a3827277b1
|
||
|
|
5c6f9ad18b
|
||
|
|
f3845ef65f
|
||
|
|
1c7b1891f7
|
||
|
|
54bda06bdc
|
||
|
|
f9dbc1f11e
|
||
|
|
16df85607d
|
||
|
|
7ec9e80c3a
|
||
|
|
0f514a2f95
|
||
|
|
14ebc3327b
|
||
|
|
3b6a2341fa
|
||
|
|
fb5babc0f1
|
||
|
|
4db4bf397a
|
||
|
|
6ef49c204c
|
||
|
|
2785c1ae38
|
||
|
|
756abf819d
|
||
|
|
7bfb6c1517
|
||
|
|
f916999716
|
||
|
|
672209ab03
|
||
|
|
e215d7192f
|
||
|
|
9ea20a2bc8
|
||
|
|
fae227db6c
|
||
|
|
4d18afb9d6
|
||
|
|
f9bc33f2fd
|
||
|
|
ae46cb6240
|
||
|
|
225f2d3d30
|
||
|
|
acd955f815
|
||
|
|
a07f54dea8
|
||
|
|
729e10681b
|
||
|
|
3289fadcde
|
||
|
|
d958ae6382
|
||
|
|
c8ca169f3b
|
||
|
|
c391c0a794
|
||
|
|
4a3ca10802
|
||
|
|
5bf4e8264f
|
||
|
|
cb388efd30
|
||
|
|
2d2b43d4ad
|
||
|
|
bb3452ce7c
|
||
|
|
fbcf503351
|
||
|
|
88832fd6bd
|
||
|
|
f25259c556
|
||
|
|
ce1a342b28
|
||
|
|
18b0ea9eea
|
||
|
|
49bd844c1c
|
||
|
|
8c15c54077
|
||
|
|
2312b75c85
|
||
|
|
696d77f629
|
||
|
|
3ffbd72def
|
||
|
|
29e3458cd1
|
||
|
|
344027b781
|
||
|
|
8e86d9f656
|
||
|
|
37b30cd099
|
||
|
|
45b1c36cf7
|
||
|
|
340503b61d
|
||
|
|
6b076bb5fb
|
||
|
|
f5050ac081
|
||
|
|
1ab4410c21
|
||
|
|
b683aa22af
|
||
|
|
aac0bb8a05
|
||
|
|
4903e11dee
|
||
|
|
b3b0639e72
|
||
|
|
ae43aead8c
|
||
|
|
4f08fe0286
|
||
|
|
4b28a863f0
|
||
|
|
ed0cfe18c3
|
||
|
|
85e4ddaac5
|
||
|
|
4225eeaaf6
|
||
|
|
2477c97588
|
+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
|
||||||
!ThirdParty/**/*
|
!Source/ThirdParty/**/*
|
||||||
|
|||||||
@@ -5,6 +5,83 @@ 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.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.
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+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 - 2022 SenseGlove
|
Copyright (c) 2020 - 2023 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,26 +6,29 @@ This repository relies on Git LFS for storing binary blobs (e.g. third-party lib
|
|||||||
|
|
||||||
## Platform Support Matrix
|
## Platform Support Matrix
|
||||||
|
|
||||||
| | **Windows<br>(MSVC 2017)** | **Windows<br>(MSVC 2019)** | **Windows<br>(MSVC 2022)** | **Linux<br>(Native Toolchain)** | **macOS** | **Oculus Mobile<br>(Android NDK r21b)** |
|
| | **Windows (MSVC 2017)** | **Windows (MSVC 2019)** | **Windows (MSVC 2022)** | **Linux (Native Toolchain)** | **macOS** | **Oculus Mobile (Android NDK)** |
|
||||||
|----------|:--------------------------:|:--------------------------:|:--------------------------:|:-------------------------------:|:---------:|:---------------------------------------:|
|
|:--------:|:-----------------------:|:-----------------------:|:-----------------------:|:----------------------------:|:---------:|:-------------------------------:|
|
||||||
| **4.22** | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
| **4.22** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
||||||
| **4.23** | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
| **4.23** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
||||||
| **4.24** | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
| **4.24** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
||||||
| **4.25** | ✅ | ✅ | ❌ | ✅ | ❌ | ❓ |
|
| **4.25** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
||||||
| **4.26** | ✅ | ✅ | ❌ | ✅ | ❌ | ❓ |
|
| **4.26** | ⚠️ v1.0.x | ⚠️ v1.0.x | ❌ | ⚠️ v1.0.x | ❌ | ❌ |
|
||||||
| **4.27** | ✅ | ✅ | ✅ | ✅ | ❌ | ❓ |
|
| **4.27** | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ❌ | ✅ v1.2.x (r21e) |
|
||||||
| **5.0** | ❌ | ✅ | ✅ | ✅ | ❌ | ❓ |
|
| **5.0** | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ❌ | ✅ v1.2.x (r21e) |
|
||||||
| **5.1** | ❌ | ✅ | ✅ | ✅ | ❌ | ❓ |
|
| **5.1** | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ❌ | ✅ v1.2.x (r25b) |
|
||||||
|
| **5.2** | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ✅ v1.2.x | ❌ | ✅ v1.2.x (r25b) |
|
||||||
|
|
||||||
* <code>✅</code> Supported
|
* <code>✅</code> Supported
|
||||||
* <code>❌</code> Not Supported
|
* <code>⚠️</code> Not supported by the latest release and might be lacking features
|
||||||
* <code>❓</code> Unknown or Untested
|
* <code>❌</code> Not supported at all
|
||||||
|
* <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 r21b by Epic Games.
|
* Oculus support is only provided through the recommended Android NDK versions by Epic Games.
|
||||||
* 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.
|
* The Unreal Engine 4.27+ support is provided for Android/Oculus development.
|
||||||
|
* [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
|
||||||
@@ -61,6 +64,8 @@ Source
|
|||||||
│
|
│
|
||||||
├── 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++)
|
||||||
@@ -75,19 +80,27 @@ Source
|
|||||||
│
|
│
|
||||||
├── 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)
|
||||||
|
│
|
||||||
├── 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)
|
||||||
│
|
│
|
||||||
├── SenseGloveTypes (exposes various enums from the backend libraries)
|
├── SenseGloveSettings (the plugin's settings manager)
|
||||||
|
│
|
||||||
|
├── 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)
|
||||||
│ │
|
│ │
|
||||||
@@ -102,52 +115,90 @@ Source
|
|||||||
│ └── 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)
|
||||||
│ │
|
│ │
|
||||||
|
|||||||
+55
-2
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"FileVersion": 3,
|
"FileVersion": 3,
|
||||||
"Version": 1,
|
"Version": 1,
|
||||||
"VersionName": "1.0.4",
|
"VersionName": "1.2.1",
|
||||||
"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.25.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,6 +25,17 @@
|
|||||||
"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"
|
||||||
]
|
]
|
||||||
@@ -34,6 +45,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -43,6 +55,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -52,6 +65,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -61,6 +75,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -70,6 +85,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -79,6 +95,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -88,6 +105,17 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
|
"Linux",
|
||||||
|
"Win64"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "SenseGloveCoreTypes",
|
||||||
|
"Type": "Runtime",
|
||||||
|
"LoadingPhase": "PreDefault",
|
||||||
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -106,6 +134,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -115,6 +144,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -124,6 +154,27 @@
|
|||||||
"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"
|
||||||
]
|
]
|
||||||
@@ -133,6 +184,7 @@
|
|||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "PreDefault",
|
"LoadingPhase": "PreDefault",
|
||||||
"WhitelistPlatforms": [
|
"WhitelistPlatforms": [
|
||||||
|
"Android",
|
||||||
"Linux",
|
"Linux",
|
||||||
"Win64"
|
"Win64"
|
||||||
]
|
]
|
||||||
@@ -142,6 +194,7 @@
|
|||||||
"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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,686 @@
|
|||||||
|
/**
|
||||||
|
* @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 "SGConnect/SGConnect.h"
|
||||||
|
#include "SGCore/SGDeviceList.h"
|
||||||
|
#include "SGCore/SGHandPose.h"
|
||||||
|
#include "SGCore/SGHapticGlove.h"
|
||||||
|
#include "SGCore/SGHapticGloveHandProfiles.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;
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Super::SetSkeletalMesh(nullptr, true);
|
||||||
|
|
||||||
|
bBackendInitialized = false;
|
||||||
|
Glove = 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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::FImplDeleter::operator()(const FImpl* P) const
|
||||||
|
{
|
||||||
|
delete P;
|
||||||
|
}
|
||||||
@@ -0,0 +1,776 @@
|
|||||||
|
/**
|
||||||
|
* @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 "DrawDebugHelpers.h"
|
||||||
|
#include "Engine/SkeletalMesh.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
#include "UObject/ConstructorHelpers.h"
|
||||||
|
|
||||||
|
#include "SGConnect/SGConnect.h"
|
||||||
|
#include "SGCore/SGDeviceList.h"
|
||||||
|
#include "SGCore/SGHapticGlove.h"
|
||||||
|
#include "SGCore/SGHapticGloveHandProfiles.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;
|
||||||
|
bDrawDebugWristTrackerGizmo = false;
|
||||||
|
TrackingHardware = ESGPositionalTrackingHardware::None;
|
||||||
|
TrackingHardwareLocationOffset = FVector::ZeroVector;
|
||||||
|
TrackingHardwareLocationOffset = FVector::ZeroVector;
|
||||||
|
|
||||||
|
bOverridePluginWristTrackingDebugSettings = false;
|
||||||
|
bDrawDebugWristTrackerGizmo = false;
|
||||||
|
DebugWristTrackerGizmoLength = 1.0f;
|
||||||
|
DebugWristTrackerGizmoXAxisColor = FColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
DebugWristTrackerGizmoYAxisColor = FColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
DebugWristTrackerGizmoZAxisColor = FColor(0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
bDebugWristTrackerGizmoPersistentLines = false;
|
||||||
|
DebugWristTrackerGizmoLifeTimeModifier = 1.1f;
|
||||||
|
DebugWristTrackerGizmoDepthPriority = 0;
|
||||||
|
DebugWristTrackerGizmoThickness = 1.0f;
|
||||||
|
|
||||||
|
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::GetDrawDebugWristTrackerGizmo() const
|
||||||
|
{
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return !!bDrawDebugWristTrackerGizmo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDrawDebugWristTrackerGizmo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDrawDebugWristTrackerGizmo(const bool bInDrawDebugWristTrackerGizmo)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT( "Setting bDrawDebugWristTrackerGizmo is only permitted when bOverridePluginWristTrackingDebugSettings is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
bDrawDebugWristTrackerGizmo = bInDrawDebugWristTrackerGizmo;
|
||||||
|
}
|
||||||
|
|
||||||
|
float USGWristTrackerComponent::GetDebugWristTrackerGizmoLength() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting DebugWristTrackerGizmoLength is only permitted when bDrawDebugWristTrackerGizmo is enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return DebugWristTrackerGizmoLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoLength(const float InDebugWristTrackerGizmoLength)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoLength is only permitted when bOverridePluginWristTrackingDebugSettings is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoLength is only permitted when bDrawDebugWristTrackerGizmo is enabled!"));
|
||||||
|
|
||||||
|
DebugWristTrackerGizmoLength = InDebugWristTrackerGizmoLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FColor& USGWristTrackerComponent::GetDebugWristTrackerGizmoXAxisColor() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting DebugWristTrackerGizmoXAxisColor is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return DebugWristTrackerGizmoXAxisColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoXAxisColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoXAxisColor(
|
||||||
|
const FColor& InDebugWristTrackerGizmoXAxisColor)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoXAxisColor is only permitted when bOverridePluginWristTrackingDebugSettings"
|
||||||
|
" is enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoXAxisColor is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
DebugWristTrackerGizmoXAxisColor = InDebugWristTrackerGizmoXAxisColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FColor& USGWristTrackerComponent::GetDebugWristTrackerGizmoYAxisColor() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting DebugWristTrackerGizmoYAxisColor is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return DebugWristTrackerGizmoYAxisColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoYAxisColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoYAxisColor(
|
||||||
|
const FColor& InDebugWristTrackerGizmoYAxisColor)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoYAxisColor is only permitted when bOverridePluginWristTrackingDebugSettings"
|
||||||
|
" is enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoYAxisColor is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
DebugWristTrackerGizmoYAxisColor = InDebugWristTrackerGizmoYAxisColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FColor& USGWristTrackerComponent::GetDebugWristTrackerGizmoZAxisColor() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting DebugWristTrackerGizmoZAxisColor is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return DebugWristTrackerGizmoZAxisColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoZAxisColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoZAxisColor(
|
||||||
|
const FColor& InDebugWristTrackerGizmoZAxisColor)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoZAxisColor is only permitted when bOverridePluginWristTrackingDebugSettings"
|
||||||
|
" is enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoZAxisColor is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
DebugWristTrackerGizmoZAxisColor = InDebugWristTrackerGizmoZAxisColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USGWristTrackerComponent::GetDebugWristTrackerGizmoPersistentLines() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting bDebugWristTrackerGizmoPersistentLines is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return !!bDebugWristTrackerGizmoPersistentLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoPersistentLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoPersistentLines(
|
||||||
|
const bool bInDebugWristTrackerGizmoPersistentLines)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoPersistentLines is only permitted when"
|
||||||
|
" bOverridePluginWristTrackingDebugSettings is enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting bDebugWristTrackerGizmoPersistentLines is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
bDebugWristTrackerGizmoPersistentLines = bInDebugWristTrackerGizmoPersistentLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
float USGWristTrackerComponent::GetDebugWristTrackerGizmoLifeTimeModifier() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting DebugWristTrackerGizmoLifeTimeModifier is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return DebugWristTrackerGizmoLifeTimeModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoLifeTimeModifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoLifeTimeModifier(
|
||||||
|
const float InDebugWristTrackerGizmoLifeTimeModifier)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoLifetimeModifier is only permitted when"
|
||||||
|
" bOverridePluginWristTrackingDebugSettings is enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoLifeTimeModifier is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
DebugWristTrackerGizmoLifeTimeModifier = InDebugWristTrackerGizmoLifeTimeModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 USGWristTrackerComponent::GetDebugWristTrackerGizmoDepthPriority() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting DebugWristTrackerGizmoDepthPriority is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return DebugWristTrackerGizmoDepthPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoDepthPriority();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoDepthPriority(const uint8 InDebugWristTrackerGizmoDepthPriority)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoDepthPriority is only permitted when"
|
||||||
|
" bOverridePluginWristTrackingDebugSettings is enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoDepthPriority is only permitted when bDrawDebugWristTrackerGizmo is"
|
||||||
|
" enabled!"));
|
||||||
|
|
||||||
|
DebugWristTrackerGizmoDepthPriority = InDebugWristTrackerGizmoDepthPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
float USGWristTrackerComponent::GetDebugWristTrackerGizmoThickness() const
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Getting DebugWristTrackerGizmoThickness is only permitted when bDrawDebugWristTrackerGizmo is enabled!"));
|
||||||
|
|
||||||
|
if (OverridesPluginWristTrackingDebugSettings())
|
||||||
|
{
|
||||||
|
return DebugWristTrackerGizmoThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
return USGSettings::GetInstance()->GetDebugWristTrackerGizmoThickness();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::SetDebugWristTrackerGizmoThickness(float InDebugWristTrackerGizmoThickness)
|
||||||
|
{
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
OverridesPluginWristTrackingDebugSettings(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoDepthThickness is only permitted when"
|
||||||
|
" bOverridePluginWristTrackingDebugSettings is enabled!"));
|
||||||
|
|
||||||
|
ensureAlwaysMsgf(
|
||||||
|
GetDrawDebugWristTrackerGizmo(),
|
||||||
|
TEXT("Setting DebugWristTrackerGizmoThickness is only permitted when bDrawDebugWristTrackerGizmo is enabled!"));
|
||||||
|
|
||||||
|
DebugWristTrackerGizmoThickness = InDebugWristTrackerGizmoThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 (GetDrawDebugWristTrackerGizmo())
|
||||||
|
{
|
||||||
|
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 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 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->GetRelativeLocation()};
|
||||||
|
FRotator TrackerRotation{Owner->GetRelativeRotation()};
|
||||||
|
|
||||||
|
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->GetRelativeLocation()};
|
||||||
|
const FRotator& Rotation{Owner->GetRelativeRotation()};
|
||||||
|
const float Length = Owner->GetDebugWristTrackerGizmoLength();
|
||||||
|
const bool bPersistentLines = Owner->GetDebugWristTrackerGizmoPersistentLines();
|
||||||
|
const float LifeTime = UGameplayStatics::GetWorldDeltaSeconds(World)
|
||||||
|
* Owner->GetDebugWristTrackerGizmoLifeTimeModifier();
|
||||||
|
const float DepthPriority = Owner->GetDebugWristTrackerGizmoDepthPriority();
|
||||||
|
const float Thickness = Owner->GetDebugWristTrackerGizmoThickness();
|
||||||
|
const FColor& XAxisColor{Owner->GetDebugWristTrackerGizmoXAxisColor()};
|
||||||
|
const FColor& YAxisColor{Owner->GetDebugWristTrackerGizmoYAxisColor()};
|
||||||
|
const FColor& ZAxisColor{Owner->GetDebugWristTrackerGizmoZAxisColor()};
|
||||||
|
|
||||||
|
const FVector XAxisLineEnd(Location + Rotation.RotateVector(FVector(Length, 0.0f, 0.0f)));
|
||||||
|
DrawDebugLine(World, Location, XAxisLineEnd, XAxisColor, bPersistentLines, LifeTime, DepthPriority, Thickness);
|
||||||
|
|
||||||
|
const FVector YAxisLineEnd(Location + Rotation.RotateVector(FVector{0.0f, Length, 0.0f}));
|
||||||
|
DrawDebugLine(World, Location, YAxisLineEnd, YAxisColor, bPersistentLines, LifeTime, DepthPriority, Thickness);
|
||||||
|
|
||||||
|
const FVector ZAxisLineEnd{Location + Rotation.RotateVector(FVector{0.0f, 0.0f, Length})};
|
||||||
|
DrawDebugLine(World, Location, ZAxisLineEnd, ZAxisColor, bPersistentLines, LifeTime, DepthPriority, Thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USGWristTrackerComponent::FImplDeleter::operator()(const FImpl* P) const
|
||||||
|
{
|
||||||
|
delete P;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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->SetRelativeLocation(Location);
|
||||||
|
});
|
||||||
|
|
||||||
|
WristTrackerLeft->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void
|
||||||
|
{
|
||||||
|
HandLeft->SetRelativeRotation(Rotation);
|
||||||
|
});
|
||||||
|
|
||||||
|
WristTrackerRight->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void
|
||||||
|
{
|
||||||
|
HandRight->SetRelativeLocation(Location);
|
||||||
|
});
|
||||||
|
|
||||||
|
WristTrackerRight->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void
|
||||||
|
{
|
||||||
|
HandRight->SetRelativeRotation(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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
* @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->SetRelativeLocation(Location);
|
||||||
|
});
|
||||||
|
|
||||||
|
WristTracker->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void
|
||||||
|
{
|
||||||
|
VirtualHand->SetRelativeRotation(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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
};
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
};
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
* @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 "SGVirtualHandComponent.generated.h"
|
||||||
|
|
||||||
|
class USkeletalMesh;
|
||||||
|
|
||||||
|
class USGHandPose;
|
||||||
|
class USGHapticGlove;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UPROPERTY(Transient)
|
||||||
|
uint8 bBackendInitialized : 1;
|
||||||
|
|
||||||
|
UPROPERTY(Transient)
|
||||||
|
USGHapticGlove* Glove;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
};
|
||||||
@@ -0,0 +1,311 @@
|
|||||||
|
/**
|
||||||
|
* @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 "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 bDrawDebugWristTrackerGizmo : 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
float DebugWristTrackerGizmoLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
FColor DebugWristTrackerGizmoXAxisColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
FColor DebugWristTrackerGizmoYAxisColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
FColor DebugWristTrackerGizmoZAxisColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
uint8 bDebugWristTrackerGizmoPersistentLines : 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
float DebugWristTrackerGizmoLifeTimeModifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
uint8 DebugWristTrackerGizmoDepthPriority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid only if bDrawDebugWristTrackerGizmo is enabled.
|
||||||
|
*/
|
||||||
|
UPROPERTY(Config, EditAnywhere, Category = "Override Plugin Settings",
|
||||||
|
meta=(EditCondition="bOverridePluginWristTrackingDebugSettings && bDrawDebugWristTrackerGizmo",
|
||||||
|
EditConditionHides))
|
||||||
|
float DebugWristTrackerGizmoThickness;
|
||||||
|
|
||||||
|
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 GetDrawDebugWristTrackerGizmo() const;
|
||||||
|
void SetDrawDebugWristTrackerGizmo(bool bInDrawDebugWristTrackerGizmo);
|
||||||
|
|
||||||
|
float GetDebugWristTrackerGizmoLength() const;
|
||||||
|
void SetDebugWristTrackerGizmoLength(float InDebugWristTrackerGizmoLength);
|
||||||
|
|
||||||
|
const FColor& GetDebugWristTrackerGizmoXAxisColor() const;
|
||||||
|
void SetDebugWristTrackerGizmoXAxisColor(const FColor& InDebugWristTrackerGizmoXAxisColor);
|
||||||
|
|
||||||
|
const FColor& GetDebugWristTrackerGizmoYAxisColor() const;
|
||||||
|
void SetDebugWristTrackerGizmoYAxisColor(const FColor& InDebugWristTrackerGizmoYAxisColor);
|
||||||
|
|
||||||
|
const FColor& GetDebugWristTrackerGizmoZAxisColor() const;
|
||||||
|
void SetDebugWristTrackerGizmoZAxisColor(const FColor& InDebugWristTrackerGizmoZAxisColor);
|
||||||
|
|
||||||
|
bool GetDebugWristTrackerGizmoPersistentLines() const;
|
||||||
|
void SetDebugWristTrackerGizmoPersistentLines(bool bInDebugWristTrackerGizmoPersistentLines);
|
||||||
|
|
||||||
|
float GetDebugWristTrackerGizmoLifeTimeModifier() const;
|
||||||
|
void SetDebugWristTrackerGizmoLifeTimeModifier(float InDebugWristTrackerGizmoLifeTimeModifier);
|
||||||
|
|
||||||
|
uint8 GetDebugWristTrackerGizmoDepthPriority() const;
|
||||||
|
void SetDebugWristTrackerGizmoDepthPriority(uint8 InDebugWristTrackerGizmoDepthPriority);
|
||||||
|
|
||||||
|
float GetDebugWristTrackerGizmoThickness() const;
|
||||||
|
void SetDebugWristTrackerGizmoThickness(float InDebugWristTrackerGizmoThickness);
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @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()
|
||||||
|
};
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
};
|
||||||
+13
-6
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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
|
||||||
@@ -35,8 +35,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L )
|
#include "GameFramework/PlayerController.h"
|
||||||
#define SG_CPP17 1
|
|
||||||
#else /* ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L ) */
|
#include "SGPlayerController.generated.h"
|
||||||
#define SG_CPP17 0
|
|
||||||
#endif /* ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L ) */
|
UCLASS(Config=Game, BlueprintType, Blueprintable)
|
||||||
|
class SENSEGLOVE_API ASGPlayerController : public APlayerController
|
||||||
|
{
|
||||||
|
GENERATED_UCLASS_BODY()
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void SetupInputComponent() override;
|
||||||
|
};
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* @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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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,11 +52,14 @@ public class SenseGlove : ModuleRules
|
|||||||
PrivateDependencyModuleNames.AddRange(
|
PrivateDependencyModuleNames.AddRange(
|
||||||
new string[]
|
new string[]
|
||||||
{
|
{
|
||||||
|
"AnimGraphRuntime",
|
||||||
"CoreUObject",
|
"CoreUObject",
|
||||||
"Engine",
|
"Engine",
|
||||||
|
"HeadMountedDisplay",
|
||||||
"SenseGloveConnect",
|
"SenseGloveConnect",
|
||||||
"SenseGloveCore",
|
"SenseGloveCore",
|
||||||
"SenseGloveLog",
|
"SenseGloveLog",
|
||||||
|
"SenseGloveSettings",
|
||||||
"SenseGloveTypes",
|
"SenseGloveTypes",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* @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)
|
||||||
+4
-2
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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
|
||||||
@@ -33,4 +33,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "SGTypes/SGConnectTypes.h"
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
+37
-30
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* (The MIT License)
|
* (The MIT License)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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
|
||||||
@@ -33,36 +33,43 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#include "SenseGloveAndroidModule.h"
|
||||||
|
|
||||||
#include "Containers/UnrealString.h"
|
#include "SGAndroid/SGConnectJNI.h"
|
||||||
#include "Misc/AssertionMacros.h"
|
#include "SGAndroid/SGCoreJNI.h"
|
||||||
#include "Templates/UnrealTemplate.h"
|
#include "SGLog/SGLog.h"
|
||||||
#include "UObject/Class.h"
|
|
||||||
#include "UObject/Object.h"
|
|
||||||
#include "UObject/Package.h"
|
|
||||||
#include "UObject/ObjectMacros.h"
|
|
||||||
|
|
||||||
class SENSEGLOVEUTILS_API SGEnumUtils
|
#define LOCTEXT_NAMESPACE "FSenseGloveAndroidModule"
|
||||||
|
|
||||||
|
void FSenseGloveAndroidModule::StartupModule()
|
||||||
{
|
{
|
||||||
public:
|
SGLOG("Starting up SenseGloveAndroid module...");
|
||||||
template<typename E>
|
|
||||||
static FORCEINLINE FString ValueToName(const FString& Enum, const E Value)
|
|
||||||
{
|
|
||||||
const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Enum, true);
|
|
||||||
if (!ensureAlwaysMsgf(EnumPtr, TEXT("No such enum exists!"))) {
|
|
||||||
return FString("None");
|
|
||||||
}
|
|
||||||
return EnumPtr->GetNameByValue(StaticCast<int64>(Value)).ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename E>
|
#if PLATFORM_ANDROID
|
||||||
static FORCEINLINE E NameToValue(const FString& Enum, const FString& Name)
|
const int32 R1 = FSGConnectJNI::Initialize();
|
||||||
{
|
const int32 R2 = FSGCoreJNI::Initialize();
|
||||||
UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Enum, true);
|
|
||||||
if (!ensureAlwaysMsgf(EnumPtr, TEXT("No such enum exists!"))) {
|
ensureAlwaysMsgf(R1 == 0,
|
||||||
return StaticCast<E>(0);
|
TEXT("Failed to initialize the SGConnect JNI bridge to SGConnect for Android! Status Code: %d"), R1);
|
||||||
}
|
|
||||||
return StaticCast<E>(EnumPtr->GetValueByName(FName(*Name)));
|
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
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* @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
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* @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 "SGConnectJNI.generated.h"
|
||||||
|
|
||||||
|
USTRUCT()
|
||||||
|
struct SENSEGLOVEANDROID_API FSGConnectJNI
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
static int32 Initialize();
|
||||||
|
};
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* @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();
|
||||||
|
};
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* @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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
<?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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* @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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* @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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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 - 2022 SenseGlove
|
* Copyright (c) 2020 - 2023 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