From 1e3ce85e8127e32b3bf5a19a0cc50c9a1b287c12 Mon Sep 17 00:00:00 2001 From: Shreyas Minocha Date: Sat, 18 Jan 2025 20:38:18 -0500 Subject: [PATCH 1/2] Add GAN V4 gyroscope support PoC --- src/js/hardware/gancube.js | 28 ++++++++++++++++++++++++++++ src/js/timer/giiker.js | 4 ++++ src/js/twisty/twisty.js | 2 ++ 3 files changed, 34 insertions(+) diff --git a/src/js/hardware/gancube.js b/src/js/hardware/gancube.js index f2e5b292..de790ba9 100644 --- a/src/js/hardware/gancube.js +++ b/src/js/hardware/gancube.js @@ -1040,6 +1040,34 @@ execMain(function() { giikerutil.log('[gancube]', 'v4 battery level', batteryLevel); giikerutil.updateBattery([batteryLevel, deviceName + '*']); } else if (mode == 0xEC) { // gyro + var zero = parseInt(value.slice(0, 16), 2) / 16_384; + var one = parseInt(value.slice(16, 32), 2) / 16_384; + var two = parseInt(value.slice(32, 48), 2) / 16_384; + var three = parseInt(value.slice(48, 64), 2) / 16_384; + + var quaterX = two; + var quaterY = one; + var quaterZ = three; + var quaterW = zero; + + // var wSquared = 1 - (quaterX * quaterX + quaterY * quaterY + quaterZ * quaterZ); + // var quaterW = wSquared > 0 ? Math.sqrt(wSquared) : 0; + + var angleSpeedX = parseInt(value.slice(64, 68), 2); + var angleSpeedY = parseInt(value.slice(68, 72), 2); + var angleSpeedZ = parseInt(value.slice(72, 76), 2); + + var axisX = parseInt(value.slice(76, 97), 2) / 16_384; + var axisY = parseInt(value.slice(97, 118), 2) / 16_384; + var axisZ = parseInt(value.slice(118, 139), 2) / 16_384; + var angle = parseInt(value.slice(139, 160), 2) / 16_384; + + window.puzzleObj.twisty._3d.useQuaternion = true; + + var newQuat = new THREE.Quaternion(quaterX, quaterY, quaterZ, quaterW).normalize(); + window.puzzleObj.twisty._3d.quaternion = newQuat; + + window.puzzleObj.twistyScene.render() } else { giikerutil.log('[gancube]', 'v4 received unknown event', mode, value); } diff --git a/src/js/timer/giiker.js b/src/js/timer/giiker.js index f594eb7f..a42db3ce 100644 --- a/src/js/timer/giiker.js +++ b/src/js/timer/giiker.js @@ -44,6 +44,10 @@ execMain(function(timer) { curVRCCubie.selfMoveStr(puzzleObj.move2str(preScramble[i])); } puzzleObj.applyMoves(preScramble); // process pre scramble (cube orientation) + + // temporary hack + window.puzzleObj = puzzleObj; + var targetOri = kernel.getProp('giiOri'); targetOri = targetOri == 'auto' ? -1 : ~~targetOri; setOri(targetOri); diff --git a/src/js/twisty/twisty.js b/src/js/twisty/twisty.js index 6a68699e..21729e0c 100644 --- a/src/js/twisty/twisty.js +++ b/src/js/twisty/twisty.js @@ -399,6 +399,8 @@ window.twistyjs = (function() { moveCameraDelta(deltaTheta, 0); } + this.render = render; + function render() { renderer.render(scene, camera); } From 3424c02f5fe5a5bac1a3a3e75867c5c0fef46273 Mon Sep 17 00:00:00 2001 From: Shreyas Minocha Date: Sat, 18 Jan 2025 22:09:08 -0500 Subject: [PATCH 2/2] Fix gyroscope data parsing Thanks to https://github.com/afedotov/gan-web-bluetooth --- src/js/hardware/gancube.js | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/js/hardware/gancube.js b/src/js/hardware/gancube.js index de790ba9..949e9759 100644 --- a/src/js/hardware/gancube.js +++ b/src/js/hardware/gancube.js @@ -1040,27 +1040,19 @@ execMain(function() { giikerutil.log('[gancube]', 'v4 battery level', batteryLevel); giikerutil.updateBattery([batteryLevel, deviceName + '*']); } else if (mode == 0xEC) { // gyro - var zero = parseInt(value.slice(0, 16), 2) / 16_384; - var one = parseInt(value.slice(16, 32), 2) / 16_384; - var two = parseInt(value.slice(32, 48), 2) / 16_384; - var three = parseInt(value.slice(48, 64), 2) / 16_384; - - var quaterX = two; - var quaterY = one; - var quaterZ = three; - var quaterW = zero; - - // var wSquared = 1 - (quaterX * quaterX + quaterY * quaterY + quaterZ * quaterZ); - // var quaterW = wSquared > 0 ? Math.sqrt(wSquared) : 0; - - var angleSpeedX = parseInt(value.slice(64, 68), 2); - var angleSpeedY = parseInt(value.slice(68, 72), 2); - var angleSpeedZ = parseInt(value.slice(72, 76), 2); - - var axisX = parseInt(value.slice(76, 97), 2) / 16_384; - var axisY = parseInt(value.slice(97, 118), 2) / 16_384; - var axisZ = parseInt(value.slice(118, 139), 2) / 16_384; - var angle = parseInt(value.slice(139, 160), 2) / 16_384; + var zero = parseInt(value.slice(16, 32), 2); + var one = parseInt(value.slice(32, 48), 2); + var two = parseInt(value.slice(48, 64), 2); + var three = parseInt(value.slice(64, 80), 2); + + var quaterW = (1 - (zero >> 15) * 2) * (zero & 0x7FFF) / 0x7FFF; + var quaterX = (1 - (one >> 15) * 2) * (one & 0x7FFF) / 0x7FFF; + var quaterY = (1 - (two >> 15) * 2) * (two & 0x7FFF) / 0x7FFF; + var quaterZ = (1 - (three >> 15) * 2) * (three & 0x7FFF) / 0x7FFF; + + var angleSpeedX = parseInt(value.slice(80, 84), 2); + var angleSpeedY = parseInt(value.slice(84, 88), 2); + var angleSpeedZ = parseInt(value.slice(88, 92), 2); window.puzzleObj.twisty._3d.useQuaternion = true;