From 8eee5e59e13dc5af430d3c662e8f3c81a6afe2b2 Mon Sep 17 00:00:00 2001 From: Lutz Date: Sun, 3 May 2020 10:35:07 +0000 Subject: [PATCH] the SC actually outputs a quaternion, so a fourth value has to be read to handle it properly. also the structure representing the orientation is now a four-vector details about quaternions are rather painful but never the less interesting! https://en.wikipedia.org/wiki/Quaternion cheers --- steamcontroller.h | 15 +++++++-------- steamcontroller_state.c | 9 +++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/steamcontroller.h b/steamcontroller.h index 673164f..c96578e 100644 --- a/steamcontroller.h +++ b/steamcontroller.h @@ -26,6 +26,8 @@ typedef struct { int16_t x, y; } SteamControllerAxisPair; /** 3 coordinates representing a vector in three dimensional space relative to the controller. */ typedef struct { int16_t x, y, z; } SteamControllerVector; +/** 4 coordinates representing a (unit) quaternion in three dimensional space. */ +typedef struct { int16_t w, x, y, z; } SteamControllerQuaternion; #define STEAMCONTROLLER_BUTTON_RT (1<<0) /**< Right trigger fully pressed. */ #define STEAMCONTROLLER_BUTTON_LT (1<<1) /**< Left trigger fully pressed. */ @@ -71,14 +73,11 @@ typedef struct { SteamControllerAxisPair stick; /**< Stick position. */ /** - * Contains some kind of orientation vector? - * When rotating the controller around one axis 360 degrees, the value for that - * axis becomes negative. One further rotation and it becomes positive againg. - * This is probably the imaginary parts of a unit quaternion representing the - * controller orientation in space. - * @todo Figure this out. + * Contains a unit orientation representing the controler's orientation in the world + * that is: the quaternion rotates coordinates from the controller's local coordinate frame to a globally fixed coordinate frame + * FYI, the controller's x-axis points to the right, y to the front and z points upwards */ - SteamControllerVector orientation; + SteamControllerQuaternion orientation; /** * Current acceleration of the controller. @@ -116,7 +115,7 @@ typedef struct { SteamControllerAxisPair leftXY; SteamControllerAxisPair rightXY; - SteamControllerVector orientation; + SteamControllerQuaternion orientation; SteamControllerVector acceleration; SteamControllerVector angularVelocity; } SteamControllerUpdateEvent; diff --git a/steamcontroller_state.c b/steamcontroller_state.c index 1efc2f0..8535046 100644 --- a/steamcontroller_state.c +++ b/steamcontroller_state.c @@ -64,7 +64,7 @@ uint8_t SCAPI SteamController_ReadEvent(const SteamControllerDevice *pDevice, St 0x0018 00 00 00 00 4 bytes Padding? 0x001c xx xx yy yy zz zz 3 sshorts Acceleration along X,Y,Z axes. 0x0022 xx xx yy yy zz zz 3 sshorts Angular velocity (gyro) along X,Y,Z axes. - 0x0028 xx xx yy yy zz zz 3 sshorts Orientation vector. + 0x0028 ww xx xx yy yy zz zz 4 sshorts Orientation quaternion. */ pEvent->update.timeStamp = eventData[0x04] | (eventData[0x05] << 8) | (eventData[0x06] << 16) | (eventData[0x07] << 24); pEvent->update.buttons = eventData[0x08] | (eventData[0x09] << 8) | (eventData[0x0a] << 16); @@ -86,9 +86,10 @@ uint8_t SCAPI SteamController_ReadEvent(const SteamControllerDevice *pDevice, St pEvent->update.angularVelocity.y = eventData[0x24] | (eventData[0x25] << 8); pEvent->update.angularVelocity.z = eventData[0x26] | (eventData[0x27] << 8); - pEvent->update.orientation.x = eventData[0x28] | (eventData[0x29] << 8); - pEvent->update.orientation.y = eventData[0x2a] | (eventData[0x2b] << 8); - pEvent->update.orientation.z = eventData[0x2c] | (eventData[0x2d] << 8); + pEvent->update.orientation.w = eventData[0x28] | (eventData[0x29] << 8); + pEvent->update.orientation.x = eventData[0x2a] | (eventData[0x2b] << 8); + pEvent->update.orientation.y = eventData[0x2c] | (eventData[0x2d] << 8); + pEvent->update.orientation.z = eventData[0x2e] | (eventData[0x2f] << 8); break; case STEAMCONTROLLER_EVENT_BATTERY: