brilliantsole 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/build/brilliantsole.cjs +5957 -0
  4. package/build/brilliantsole.cjs.map +1 -0
  5. package/build/brilliantsole.js +5448 -0
  6. package/build/brilliantsole.js.map +1 -0
  7. package/build/brilliantsole.ls.js +4872 -0
  8. package/build/brilliantsole.ls.js.map +1 -0
  9. package/build/brilliantsole.min.js +6 -0
  10. package/build/brilliantsole.min.js.map +1 -0
  11. package/build/brilliantsole.module.d.ts +908 -0
  12. package/build/brilliantsole.module.js +5412 -0
  13. package/build/brilliantsole.module.js.map +1 -0
  14. package/build/brilliantsole.module.min.d.ts +908 -0
  15. package/build/brilliantsole.module.min.js +6 -0
  16. package/build/brilliantsole.module.min.js.map +1 -0
  17. package/build/brilliantsole.node.module.d.ts +908 -0
  18. package/build/brilliantsole.node.module.js +5906 -0
  19. package/build/brilliantsole.node.module.js.map +1 -0
  20. package/build/dts/BS.d.ts +25 -0
  21. package/build/dts/Device.d.ts +136 -0
  22. package/build/dts/DeviceInformationManager.d.ts +56 -0
  23. package/build/dts/DeviceManager.d.ts +67 -0
  24. package/build/dts/FileTransferManager.d.ts +84 -0
  25. package/build/dts/FirmwareManager.d.ts +71 -0
  26. package/build/dts/InformationManager.d.ts +66 -0
  27. package/build/dts/TfliteManager.d.ts +92 -0
  28. package/build/dts/connection/BaseConnectionManager.d.ts +59 -0
  29. package/build/dts/connection/ClientConnectionManager.d.ts +23 -0
  30. package/build/dts/connection/WebSocketClientConnectionManager.d.ts +23 -0
  31. package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +10 -0
  32. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +42 -0
  33. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +20 -0
  34. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +14 -0
  35. package/build/dts/connection/webSocket/ClientConnectionManager.d.ts +23 -0
  36. package/build/dts/connection/webSocket/WebSocketClientConnectionManager.d.ts +23 -0
  37. package/build/dts/devicePair/DevicePair.d.ts +60 -0
  38. package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +25 -0
  39. package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +33 -0
  40. package/build/dts/scanner/BaseScanner.d.ts +66 -0
  41. package/build/dts/scanner/NobleScanner.d.ts +17 -0
  42. package/build/dts/scanner/Scanner.d.ts +3 -0
  43. package/build/dts/sensor/BarometerSensorDataManager.d.ts +16 -0
  44. package/build/dts/sensor/MotionSensorDataManager.d.ts +69 -0
  45. package/build/dts/sensor/PressureSensorDataManager.d.ts +36 -0
  46. package/build/dts/sensor/SensorConfigurationManager.d.ts +44 -0
  47. package/build/dts/sensor/SensorDataManager.d.ts +40 -0
  48. package/build/dts/server/BaseClient.d.ts +85 -0
  49. package/build/dts/server/BaseServer.d.ts +48 -0
  50. package/build/dts/server/ServerUtils.d.ts +23 -0
  51. package/build/dts/server/udp/UDPServer.d.ts +11 -0
  52. package/build/dts/server/udp/UDPUtils.d.ts +9 -0
  53. package/build/dts/server/websocket/WebSocketClient.d.ts +17 -0
  54. package/build/dts/server/websocket/WebSocketServer.d.ts +13 -0
  55. package/build/dts/server/websocket/WebSocketUtils.d.ts +9 -0
  56. package/build/dts/utils/ArrayBufferUtils.d.ts +7 -0
  57. package/build/dts/utils/ArrayUtils.d.ts +2 -0
  58. package/build/dts/utils/CenterOfPressureHelper.d.ts +15 -0
  59. package/build/dts/utils/Console.d.ts +34 -0
  60. package/build/dts/utils/EventDispatcher.d.ts +50 -0
  61. package/build/dts/utils/EventUtils.d.ts +6 -0
  62. package/build/dts/utils/MathUtils.d.ts +21 -0
  63. package/build/dts/utils/ParseUtils.d.ts +5 -0
  64. package/build/dts/utils/RangeHelper.d.ts +8 -0
  65. package/build/dts/utils/Text.d.ts +6 -0
  66. package/build/dts/utils/Timer.d.ts +14 -0
  67. package/build/dts/utils/TypeScriptUtils.d.ts +19 -0
  68. package/build/dts/utils/cbor.d.ts +6 -0
  69. package/build/dts/utils/checksum.d.ts +3 -0
  70. package/build/dts/utils/environment.d.ts +13 -0
  71. package/build/dts/utils/mcumgr.d.ts +88 -0
  72. package/build/dts/utils/stringUtils.d.ts +2 -0
  73. package/build/dts/vibration/VibrationManager.d.ts +45 -0
  74. package/build/dts/vibration/VibrationWaveformEffects.d.ts +2 -0
  75. package/build/index.d.ts +908 -0
  76. package/build/index.node.d.ts +908 -0
  77. package/examples/3d/index.html +109 -0
  78. package/examples/3d/scene.html +57 -0
  79. package/examples/3d/script.js +419 -0
  80. package/examples/balance/index.html +138 -0
  81. package/examples/balance/script.js +243 -0
  82. package/examples/basic/index.html +327 -0
  83. package/examples/basic/script.js +1093 -0
  84. package/examples/center-of-pressure/index.html +132 -0
  85. package/examples/center-of-pressure/script.js +207 -0
  86. package/examples/device-pair/index.html +72 -0
  87. package/examples/device-pair/script.js +187 -0
  88. package/examples/edge-impulse/index.html +94 -0
  89. package/examples/edge-impulse/script.js +1033 -0
  90. package/examples/graph/index.html +83 -0
  91. package/examples/graph/script.js +469 -0
  92. package/examples/machine-learning/index.html +366 -0
  93. package/examples/machine-learning/script.js +1774 -0
  94. package/examples/pressure/index.html +145 -0
  95. package/examples/pressure/script.js +201 -0
  96. package/examples/recording/index.html +187 -0
  97. package/examples/recording/script.js +736 -0
  98. package/examples/server/index.html +266 -0
  99. package/examples/server/script.js +925 -0
  100. package/examples/utils/aframe/fingertip-button-component.js +201 -0
  101. package/examples/utils/aframe/fingertip-collider-target-component.js +102 -0
  102. package/examples/utils/aframe/fingertip-colliders-component.js +147 -0
  103. package/examples/utils/three/three.module.min.js +24846 -0
  104. package/examples/webxr/index.html +221 -0
  105. package/examples/webxr/script.js +1127 -0
  106. package/package.json +83 -0
  107. package/src/BS.ts +68 -0
  108. package/src/Device.ts +734 -0
  109. package/src/DeviceInformationManager.ts +146 -0
  110. package/src/DeviceManager.ts +354 -0
  111. package/src/FileTransferManager.ts +452 -0
  112. package/src/FirmwareManager.ts +357 -0
  113. package/src/InformationManager.ts +283 -0
  114. package/src/TfliteManager.ts +450 -0
  115. package/src/connection/BaseConnectionManager.ts +255 -0
  116. package/src/connection/ClientConnectionManager.ts +120 -0
  117. package/src/connection/bluetooth/BluetoothConnectionManager.ts +34 -0
  118. package/src/connection/bluetooth/NobleConnectionManager.ts +302 -0
  119. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +269 -0
  120. package/src/connection/bluetooth/bluetoothUUIDs.ts +218 -0
  121. package/src/devicePair/DevicePair.ts +253 -0
  122. package/src/devicePair/DevicePairPressureSensorDataManager.ts +82 -0
  123. package/src/devicePair/DevicePairSensorDataManager.ts +90 -0
  124. package/src/scanner/BaseScanner.ts +189 -0
  125. package/src/scanner/NobleScanner.ts +195 -0
  126. package/src/scanner/Scanner.ts +16 -0
  127. package/src/sensor/BarometerSensorDataManager.ts +41 -0
  128. package/src/sensor/MotionSensorDataManager.ts +151 -0
  129. package/src/sensor/PressureSensorDataManager.ts +112 -0
  130. package/src/sensor/SensorConfigurationManager.ts +177 -0
  131. package/src/sensor/SensorDataManager.ts +166 -0
  132. package/src/server/BaseClient.ts +368 -0
  133. package/src/server/BaseServer.ts +344 -0
  134. package/src/server/ServerUtils.ts +93 -0
  135. package/src/server/udp/UDPServer.ts +229 -0
  136. package/src/server/udp/UDPUtils.ts +20 -0
  137. package/src/server/websocket/WebSocketClient.ts +179 -0
  138. package/src/server/websocket/WebSocketServer.ts +184 -0
  139. package/src/server/websocket/WebSocketUtils.ts +20 -0
  140. package/src/utils/ArrayBufferUtils.ts +88 -0
  141. package/src/utils/ArrayUtils.ts +15 -0
  142. package/src/utils/CenterOfPressureHelper.ts +39 -0
  143. package/src/utils/Console.ts +156 -0
  144. package/src/utils/EventDispatcher.ts +153 -0
  145. package/src/utils/EventUtils.ts +41 -0
  146. package/src/utils/MathUtils.ts +53 -0
  147. package/src/utils/ParseUtils.ts +46 -0
  148. package/src/utils/RangeHelper.ts +38 -0
  149. package/src/utils/Text.ts +30 -0
  150. package/src/utils/Timer.ts +72 -0
  151. package/src/utils/TypeScriptUtils.ts +22 -0
  152. package/src/utils/cbor.js +429 -0
  153. package/src/utils/checksum.ts +41 -0
  154. package/src/utils/environment.ts +46 -0
  155. package/src/utils/mcumgr.js +444 -0
  156. package/src/utils/stringUtils.ts +11 -0
  157. package/src/vibration/VibrationManager.ts +308 -0
  158. package/src/vibration/VibrationWaveformEffects.ts +128 -0
@@ -0,0 +1,109 @@
1
+ <html>
2
+ <head>
3
+ <title>3D | BrilliantSole JavaScript SDK</title>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
5
+ <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
6
+ <!-- <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script> -->
7
+ <script src="https://aframe.io/releases/1.6.0/aframe.min.js"></script>
8
+ <!-- required to get aframe-orbit-controls-component to work -->
9
+ <script>
10
+ THREE.Quaternion.prototype.inverse = THREE.Quaternion.prototype.invert;
11
+ THREE.Math = THREE.MathUtils;
12
+ </script>
13
+ <!-- https://github.com/tizzle/aframe-orbit-controls-component -->
14
+ <script src="https://cdn.rawgit.com/tizzle/aframe-orbit-controls-component/v0.1.14/dist/aframe-orbit-controls-component.min.js"></script>
15
+ <script type="module" src="./script.js"></script>
16
+ </head>
17
+
18
+ <style>
19
+ #insoles {
20
+ display: flex;
21
+ flex-direction: row;
22
+ height: 100%;
23
+ gap: 2rem;
24
+ }
25
+ .insole {
26
+ position: relative;
27
+ height: 100%;
28
+ min-width: 700px;
29
+ }
30
+
31
+ .scene {
32
+ width: 100%;
33
+ height: 100%;
34
+ margin: auto;
35
+ border-radius: 2rem;
36
+ overflow: hidden;
37
+ border: solid black;
38
+ box-sizing: border-box;
39
+ }
40
+
41
+ .scene iframe {
42
+ width: 100%;
43
+ height: 100%;
44
+ border: none;
45
+ }
46
+ </style>
47
+
48
+ <body>
49
+ <nav>
50
+ <a href="../../">home</a>
51
+ </nav>
52
+
53
+ <h1>3D | BrilliantSole JavaScript SDK</h1>
54
+
55
+ <button id="toggleServerConnection">connect to server</button>
56
+
57
+ <div>
58
+ <h2>available devices</h2>
59
+ <div id="availableDevices">
60
+ <template id="availableDeviceTemplate">
61
+ <div class="availableDevice">
62
+ <ul>
63
+ <li><b>name: </b> <span class="name"></span></li>
64
+ <li><b>type: </b> <span class="type"></span></li>
65
+ <li><button class="toggleConnection">connect</button></li>
66
+ </ul>
67
+ </div>
68
+ </template>
69
+ </div>
70
+ </div>
71
+
72
+ <p>
73
+ <button id="addDevice">add device</button>
74
+ </p>
75
+
76
+ <div id="insoles"></div>
77
+
78
+ <template id="insoleTemplate">
79
+ <div class="insole">
80
+ <p>
81
+ <button class="toggleConnection" disabled>disconnect</button>
82
+ <br />
83
+ <select class="orientation" disabled>
84
+ <optgroup label="orientation">
85
+ <option value="none">no orientation</option>
86
+ <option>gameRotation</option>
87
+ <option>rotation</option>
88
+ <option>orientation</option>
89
+ <option>gyroscope</option>
90
+ </optgroup>
91
+ </select>
92
+ <button disabled class="resetOrientation">reset orientation</button>
93
+ <br />
94
+ <select class="position" disabled>
95
+ <optgroup label="position">
96
+ <option value="none">no position</option>
97
+ <option>acceleration</option>
98
+ <option>gravity</option>
99
+ <option>linearAcceleration</option>
100
+ </optgroup>
101
+ </select>
102
+ </p>
103
+ <div class="scene">
104
+ <iframe src="./scene.html"></iframe>
105
+ </div>
106
+ </div>
107
+ </template>
108
+ </body>
109
+ </html>
@@ -0,0 +1,57 @@
1
+ <html>
2
+ <head>
3
+ <title>3D iframe | BrilliantSole JavaScript SDK</title>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
5
+ <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
6
+ <!-- <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script> -->
7
+ <script src="https://aframe.io/releases/1.6.0/aframe.min.js"></script>
8
+ <!-- required to get aframe-orbit-controls-component to work -->
9
+ <script>
10
+ THREE.Quaternion.prototype.inverse = THREE.Quaternion.prototype.invert;
11
+ THREE.Math = THREE.MathUtils;
12
+ </script>
13
+ <!-- https://github.com/tizzle/aframe-orbit-controls-component -->
14
+ <script src="https://cdn.rawgit.com/tizzle/aframe-orbit-controls-component/v0.1.14/dist/aframe-orbit-controls-component.min.js"></script>
15
+ </head>
16
+
17
+ <body>
18
+ <a-scene
19
+ embedded
20
+ xr-mode-ui="enabled: false;"
21
+ device-orientation-permission-ui="enabled: false"
22
+ renderer="colorManagement: true;"
23
+ >
24
+ <a-assets>
25
+ <a-asset-item id="leftInsole" src="../../assets/3d/leftInsole.glb"></a-asset-item>
26
+ <a-asset-item id="rightInsole" src="../../assets/3d/rightInsole.glb"></a-asset-item>
27
+ </a-assets>
28
+ <a-light type="directional" position="2 2 -2" target=".target"></a-light>
29
+ <a-light type="directional" position="-2 2 2" target=".target"></a-light>
30
+ <a-light type="directional" position="2 -2 2" target=".target"></a-light>
31
+
32
+ <a-camera
33
+ class="camera"
34
+ camera="fov: 50; zoom: 3.2;"
35
+ position="0 1 0"
36
+ orbit-controls="
37
+ enableZoom: true;
38
+ autoRotate: false;
39
+ target: .target;
40
+ enableDamping: true;
41
+ dampingFactor: 0.125;
42
+ rotateSpeed:0.25;
43
+ minDistance:0.75;
44
+ maxDistance:2;
45
+ "
46
+ ></a-camera>
47
+
48
+ <a-entity class="target">
49
+ <a-entity class="rotation">
50
+ <a-entity class="position" position="0 0 0.005">
51
+ <a-entity class="insole" gltf-model="#rightInsole" visible="true"></a-entity>
52
+ </a-entity>
53
+ </a-entity>
54
+ </a-entity>
55
+ </a-scene>
56
+ </body>
57
+ </html>
@@ -0,0 +1,419 @@
1
+ import * as BS from "../../build/brilliantsole.module.js";
2
+ window.BS = BS;
3
+ console.log({ BS });
4
+ //BS.setAllConsoleLevelFlags({ log: false });
5
+
6
+ /** @typedef {import("../utils/three/three.module.min").Vector3} TVector3 */
7
+ /** @typedef {import("../utils/three/three.module.min").Quaternion} TQuaternion */
8
+ /** @typedef {import("../utils/three/three.module.min").Euler} TEuler */
9
+
10
+ // GET DEVICES
11
+
12
+ /** @type {HTMLTemplateElement} */
13
+ const availableDeviceTemplate = document.getElementById("availableDeviceTemplate");
14
+ const availableDevicesContainer = document.getElementById("availableDevices");
15
+ /** @param {BS.Device[]} availableDevices */
16
+ function onAvailableDevices(availableDevices) {
17
+ availableDevicesContainer.innerHTML = "";
18
+ if (availableDevices.length == 0) {
19
+ availableDevicesContainer.innerText = "no devices available";
20
+ } else {
21
+ availableDevices.forEach((availableDevice) => {
22
+ let availableDeviceContainer = availableDeviceTemplate.content.cloneNode(true).querySelector(".availableDevice");
23
+ availableDeviceContainer.querySelector(".name").innerText = availableDevice.name;
24
+ availableDeviceContainer.querySelector(".type").innerText = availableDevice.type;
25
+
26
+ /** @type {HTMLButtonElement} */
27
+ const toggleConnectionButton = availableDeviceContainer.querySelector(".toggleConnection");
28
+ toggleConnectionButton.addEventListener("click", () => {
29
+ availableDevice.toggleConnection();
30
+ });
31
+ const onConnectionStatusUpdate = () => {
32
+ switch (availableDevice.connectionStatus) {
33
+ case "connected":
34
+ case "notConnected":
35
+ toggleConnectionButton.disabled = false;
36
+ toggleConnectionButton.innerText = availableDevice.isConnected ? "disconnect" : "connect";
37
+ break;
38
+ case "connecting":
39
+ case "disconnecting":
40
+ toggleConnectionButton.disabled = true;
41
+ toggleConnectionButton.innerText = availableDevice.connectionStatus;
42
+ break;
43
+ }
44
+ };
45
+ availableDevice.addEventListener("connectionStatus", () => onConnectionStatusUpdate());
46
+ onConnectionStatusUpdate();
47
+ availableDevicesContainer.appendChild(availableDeviceContainer);
48
+ });
49
+ }
50
+ }
51
+ async function getDevices() {
52
+ const availableDevices = await BS.DeviceManager.GetDevices();
53
+ if (!availableDevices) {
54
+ return;
55
+ }
56
+ onAvailableDevices(availableDevices);
57
+ }
58
+
59
+ BS.DeviceManager.AddEventListener("availableDevices", (event) => {
60
+ const devices = event.message.availableDevices;
61
+ onAvailableDevices(devices);
62
+ });
63
+ getDevices();
64
+
65
+ // ADD DEVICE
66
+
67
+ /** @type {HTMLButtonElement} */
68
+ const addDeviceButton = document.getElementById("addDevice");
69
+ addDeviceButton.addEventListener("click", () => {
70
+ BS.Device.Connect();
71
+ });
72
+
73
+ const devicePair = BS.DevicePair.shared;
74
+ devicePair.addEventListener("isConnected", () => {
75
+ addDeviceButton.disabled = devicePair.isConnected;
76
+ });
77
+
78
+ // 3D VISUALIZATION
79
+
80
+ const insolesContainer = document.getElementById("insoles");
81
+ /** @type {HTMLTemplateElement} */
82
+ const insoleTemplate = document.getElementById("insoleTemplate");
83
+
84
+ window.sensorRate = 20;
85
+ window.interpolationSmoothing = 0.4;
86
+ window.positionScalar = 0.4;
87
+
88
+ devicePair.sides.forEach((side) => {
89
+ /** @type {HTMLElement} */
90
+ const insoleContainer = insoleTemplate.content.cloneNode(true).querySelector(".insole");
91
+ insoleContainer.classList.add(side);
92
+ insoleContainer.dataset.side = side;
93
+ /** @type {HTMLIFrameElement} */
94
+ const iframe = insoleContainer.querySelector("iframe");
95
+ iframe.addEventListener("load", () => {
96
+ onIFrameLoaded(insoleContainer);
97
+ });
98
+ insolesContainer.appendChild(insoleContainer);
99
+ });
100
+
101
+ /** @param {HTMLElement} insoleContainer */
102
+ function onIFrameLoaded(insoleContainer) {
103
+ const side = insoleContainer.dataset.side;
104
+ /** @type {HTMLIFrameElement} */
105
+ const iframe = insoleContainer.querySelector("iframe");
106
+ const scene = iframe.contentDocument.querySelector("a-scene");
107
+ const targetEntity = scene.querySelector(".target");
108
+ const targetPositionEntity = targetEntity.querySelector(".position");
109
+ const targetRotationEntity = targetEntity.querySelector(".rotation");
110
+ const insoleEntity = targetEntity.querySelector(".insole");
111
+ insoleEntity.setAttribute("gltf-model", `#${side}Insole`);
112
+ scene.addEventListener("loaded", () => {
113
+ if (side == "right") {
114
+ //insoleEntity.object3D.scale.x = -1;
115
+ }
116
+ });
117
+
118
+ /** @type {HTMLButtonElement} */
119
+ const toggleConnectionButton = insoleContainer.querySelector(".toggleConnection");
120
+ toggleConnectionButton.addEventListener("click", () => {
121
+ devicePair[side].toggleConnection();
122
+ });
123
+ devicePair.addEventListener("deviceIsConnected", (event) => {
124
+ /** @type {BS.Device} */
125
+ const device = event.message.device;
126
+ if (device.insoleSide != side) {
127
+ return;
128
+ }
129
+
130
+ if (device.isConnected) {
131
+ toggleConnectionButton.disabled = false;
132
+ }
133
+ toggleConnectionButton.innerText = device.isConnected ? "disconnect" : "reconnect";
134
+ });
135
+
136
+ devicePair.addEventListener("deviceConnectionStatus", (event) => {
137
+ /** @type {BS.Device} */
138
+ const device = event.message.device;
139
+ if (device.insoleSide != side) {
140
+ return;
141
+ }
142
+
143
+ switch (device.connectionStatus) {
144
+ case "connected":
145
+ case "notConnected":
146
+ toggleConnectionButton.disabled = false;
147
+ toggleConnectionButton.innerText = device.isConnected ? "disconnect" : "reconnect";
148
+ break;
149
+ case "connecting":
150
+ case "disconnecting":
151
+ toggleConnectionButton.disabled = true;
152
+ toggleConnectionButton.innerText = device.connectionStatus;
153
+ break;
154
+ }
155
+ });
156
+
157
+ /** @type {HTMLSelectElement} */
158
+ const orientationSelect = insoleContainer.querySelector(".orientation");
159
+ orientationSelect.addEventListener("input", () => {
160
+ /** @type {BS.SensorConfiguration} */
161
+ const configuration = { gameRotation: 0, rotation: 0, gyroscope: 0, orientation: 0 };
162
+
163
+ switch (orientationSelect.value) {
164
+ case "none":
165
+ break;
166
+ case "gameRotation":
167
+ configuration.gameRotation = sensorRate;
168
+ break;
169
+ case "rotation":
170
+ configuration.rotation = sensorRate;
171
+ break;
172
+ case "orientation":
173
+ configuration.orientation = sensorRate;
174
+ break;
175
+ case "gyroscope":
176
+ configuration.gyroscope = sensorRate;
177
+ break;
178
+ default:
179
+ console.error(`uncaught orientationSelect value "${orientationSelect.value}"`);
180
+ break;
181
+ }
182
+
183
+ devicePair[side].setSensorConfiguration(configuration);
184
+ });
185
+
186
+ /** @type {HTMLButtonElement} */
187
+ const resetOrientationButton = insoleContainer.querySelector(".resetOrientation");
188
+ resetOrientationButton.addEventListener("click", () => {
189
+ resetOrientation();
190
+ });
191
+ devicePair.addEventListener("deviceIsConnected", (event) => {
192
+ const device = event.message.device;
193
+ if (device.insoleSide != side) {
194
+ return;
195
+ }
196
+
197
+ resetOrientationButton.disabled = !device.isConnected;
198
+ });
199
+
200
+ /** @type {HTMLSelectElement} */
201
+ const positionSelect = insoleContainer.querySelector(".position");
202
+ positionSelect.addEventListener("input", () => {
203
+ /** @type {BS.SensorConfiguration} */
204
+ const configuration = { acceleration: 0, gravity: 0, linearAcceleration: 0 };
205
+
206
+ switch (positionSelect.value) {
207
+ case "none":
208
+ break;
209
+ case "acceleration":
210
+ configuration.acceleration = sensorRate;
211
+ break;
212
+ case "gravity":
213
+ configuration.gravity = sensorRate;
214
+ break;
215
+ case "linearAcceleration":
216
+ configuration.linearAcceleration = sensorRate;
217
+ break;
218
+ default:
219
+ console.error(`uncaught positionSelect value "${positionSelect.value}"`);
220
+ break;
221
+ }
222
+
223
+ console.log({ configuration });
224
+
225
+ devicePair[side].setSensorConfiguration(configuration);
226
+ });
227
+ devicePair.addEventListener("deviceIsConnected", (event) => {
228
+ const device = event.message.device;
229
+ if (device.insoleSide != side) {
230
+ return;
231
+ }
232
+
233
+ orientationSelect.disabled = !device.isConnected;
234
+ positionSelect.disabled = !device.isConnected;
235
+ });
236
+
237
+ devicePair.addEventListener("deviceGetSensorConfiguration", (event) => {
238
+ const device = event.message.device;
239
+ if (device.insoleSide != side) {
240
+ return;
241
+ }
242
+
243
+ let newOrientationSelectValue = "none";
244
+ let newPositionSelectValue = "none";
245
+
246
+ for (const key in device.sensorConfiguration) {
247
+ /** @type {BS.SensorType} */
248
+ const sensorType = key;
249
+ if (device.sensorConfiguration[sensorType] > 0) {
250
+ switch (sensorType) {
251
+ case "gameRotation":
252
+ case "rotation":
253
+ case "orientation":
254
+ case "gyroscope":
255
+ newOrientationSelectValue = sensorType;
256
+ break;
257
+ case "acceleration":
258
+ case "gravity":
259
+ case "linearAcceleration":
260
+ newPositionSelectValue = sensorType;
261
+ break;
262
+ }
263
+ }
264
+ }
265
+
266
+ orientationSelect.value = newOrientationSelectValue;
267
+ positionSelect.value = newPositionSelectValue;
268
+ });
269
+
270
+ /** @type {TVector3} */
271
+ const _position = new THREE.Vector3();
272
+
273
+ /** @param {BS.Vector3} position */
274
+ const updatePosition = (position) => {
275
+ _position.copy(position).multiplyScalar(window.positionScalar);
276
+ targetPositionEntity.object3D.position.lerp(_position, window.interpolationSmoothing);
277
+ };
278
+
279
+ devicePair.addEventListener("deviceAcceleration", (event) => {
280
+ const device = event.message.device;
281
+ if (device.insoleSide != side) {
282
+ return;
283
+ }
284
+ /** @type {BS.Vector3} */
285
+ const acceleration = event.message.acceleration;
286
+ updatePosition(acceleration);
287
+ });
288
+ devicePair.addEventListener("deviceGravity", (event) => {
289
+ const device = event.message.device;
290
+ if (device.insoleSide != side) {
291
+ return;
292
+ }
293
+
294
+ /** @type {BS.Vector3} */
295
+ const gravity = event.message.gravity;
296
+ updatePosition(gravity);
297
+ });
298
+ devicePair.addEventListener("deviceLinearAcceleration", (event) => {
299
+ const device = event.message.device;
300
+ if (device.insoleSide != side) {
301
+ return;
302
+ }
303
+
304
+ /** @type {BS.Vector3} */
305
+ const linearAcceleration = event.message.linearAcceleration;
306
+ updatePosition(linearAcceleration);
307
+ });
308
+
309
+ /** @type {TQuaternion} */
310
+ const offsetQuaternion = new THREE.Quaternion();
311
+ const resetOrientation = () => {
312
+ offsetQuaternion.copy(_quaternion).invert();
313
+ };
314
+
315
+ /** @type {TQuaternion} */
316
+ const _quaternion = new THREE.Quaternion();
317
+ /** @type {TQuaternion} */
318
+ const targetQuaternion = new THREE.Quaternion();
319
+ /**
320
+ * @param {BS.Quaternion} quaternion
321
+ * @param {boolean} applyOffset
322
+ */
323
+ const updateQuaternion = (quaternion, applyOffset = false) => {
324
+ _quaternion.copy(quaternion);
325
+ targetQuaternion.copy(_quaternion);
326
+ if (applyOffset) {
327
+ targetQuaternion.premultiply(offsetQuaternion);
328
+ }
329
+ targetRotationEntity.object3D.quaternion.slerp(targetQuaternion, window.interpolationSmoothing);
330
+ };
331
+ devicePair.addEventListener("deviceGameRotation", (event) => {
332
+ const device = event.message.device;
333
+ if (device.insoleSide != side) {
334
+ return;
335
+ }
336
+
337
+ /** @type {BS.Quaternion} */
338
+ const gameRotation = event.message.gameRotation;
339
+ //permuteQuaternion(gameRotation);
340
+ updateQuaternion(gameRotation, true);
341
+ });
342
+ devicePair.addEventListener("deviceRotation", (event) => {
343
+ const device = event.message.device;
344
+ if (device.insoleSide != side) {
345
+ return;
346
+ }
347
+
348
+ /** @type {BS.Quaternion} */
349
+ const rotation = event.message.rotation;
350
+ //permuteQuaternion(rotation);
351
+ updateQuaternion(rotation, true);
352
+ });
353
+
354
+ /** @type {TVector3} */
355
+ const orientationVector3 = new THREE.Vector3();
356
+ /** @type {TEuler} */
357
+ const orientationEuler = new THREE.Euler(0, 0, 0, "YXZ");
358
+ /** @type {TQuaternion} */
359
+ const orientationQuaternion = new THREE.Quaternion();
360
+ devicePair.addEventListener("deviceOrientation", (event) => {
361
+ const device = event.message.device;
362
+ if (device.insoleSide != side) {
363
+ return;
364
+ }
365
+
366
+ /** @type {BS.Euler} */
367
+ const orientation = event.message.orientation;
368
+ orientationVector3.set(orientation.pitch, orientation.heading, orientation.roll).multiplyScalar(Math.PI / 180);
369
+ orientationEuler.setFromVector3(orientationVector3);
370
+ orientationQuaternion.setFromEuler(orientationEuler);
371
+ updateQuaternion(orientationQuaternion);
372
+ });
373
+
374
+ /** @type {TVector3} */
375
+ const gyroscopeVector3 = new THREE.Vector3();
376
+ /** @type {TEuler} */
377
+ const gyroscopeEuler = new THREE.Euler();
378
+ /** @type {TQuaternion} */
379
+ const gyroscopeQuaternion = new THREE.Quaternion();
380
+ devicePair.addEventListener("deviceGyroscope", (event) => {
381
+ const device = event.message.device;
382
+ if (device.insoleSide != side) {
383
+ return;
384
+ }
385
+
386
+ /** @type {BS.Vector3} */
387
+ const gyroscope = event.message.gyroscope;
388
+ gyroscopeVector3.copy(gyroscope).multiplyScalar(Math.PI / 180);
389
+ gyroscopeEuler.setFromVector3(gyroscopeVector3);
390
+ gyroscopeQuaternion.setFromEuler(gyroscopeEuler);
391
+ updateQuaternion(gyroscopeQuaternion);
392
+ });
393
+ }
394
+
395
+ // SERVER
396
+
397
+ const websocketClient = new BS.WebSocketClient();
398
+ /** @type {HTMLButtonElement} */
399
+ const toggleServerConnectionButton = document.getElementById("toggleServerConnection");
400
+ toggleServerConnectionButton.addEventListener("click", () => {
401
+ websocketClient.toggleConnection();
402
+ });
403
+ websocketClient.addEventListener("isConnected", () => {
404
+ toggleServerConnectionButton.innerText = websocketClient.isConnected ? "disconnect from server" : "connect to server";
405
+ });
406
+ websocketClient.addEventListener("connectionStatus", () => {
407
+ let disabled;
408
+ switch (websocketClient.connectionStatus) {
409
+ case "notConnected":
410
+ case "connected":
411
+ disabled = false;
412
+ break;
413
+ case "connecting":
414
+ case "disconnecting":
415
+ disabled = true;
416
+ break;
417
+ }
418
+ toggleServerConnectionButton.disabled = disabled;
419
+ });