@@ -101,8 +101,9 @@ static SDL_FPoint ProjectVec3ToRect(const Vector3 *v, const SDL_FRect *rect)
101
101
float fovScaleX = fovScaleY * aspect ;
102
102
103
103
float relZ = cameraZ - v -> z ;
104
- if (relZ < 0.01f )
104
+ if (relZ < 0.01f ) {
105
105
relZ = 0.01f ; /* Prevent division by 0 or negative depth */
106
+ }
106
107
107
108
float ndc_x = (v -> x / relZ ) / fovScaleX ;
108
109
float ndc_y = (v -> y / relZ ) / fovScaleY ;
@@ -207,6 +208,39 @@ void DrawGyroDebugCircle(SDL_Renderer *renderer, const Quaternion *orientation,
207
208
SDL_SetRenderDrawColor (renderer , r , g , b , a );
208
209
}
209
210
211
+
212
+ void DrawGyroDebugAxes (SDL_Renderer * renderer , const Quaternion * orientation , const SDL_FRect * bounds )
213
+ {
214
+ /* Store current color */
215
+ Uint8 r , g , b , a ;
216
+ SDL_GetRenderDrawColor (renderer , & r , & g , & b , & a );
217
+
218
+ Vector3 origin = { 0.0f , 0.0f , 0.0f };
219
+
220
+ Vector3 right = { 1.0f , 0.0f , 0.0f };
221
+ Vector3 up = { 0.0f , 1.0f , 0.0f };
222
+ Vector3 back = { 0.0f , 0.0f , 1.0f };
223
+
224
+ Vector3 world_right = RotateVectorByQuaternion (& right , orientation );
225
+ Vector3 world_up = RotateVectorByQuaternion (& up , orientation );
226
+ Vector3 world_back = RotateVectorByQuaternion (& back , orientation );
227
+
228
+ SDL_FPoint origin_screen = ProjectVec3ToRect (& origin , bounds );
229
+ SDL_FPoint right_screen = ProjectVec3ToRect (& world_right , bounds );
230
+ SDL_FPoint up_screen = ProjectVec3ToRect (& world_up , bounds );
231
+ SDL_FPoint back_screen = ProjectVec3ToRect (& world_back , bounds );
232
+
233
+ SDL_SetRenderDrawColor (renderer , GYRO_COLOR_RED );
234
+ SDL_RenderLine (renderer , origin_screen .x , origin_screen .y , right_screen .x , right_screen .y );
235
+ SDL_SetRenderDrawColor (renderer , GYRO_COLOR_GREEN );
236
+ SDL_RenderLine (renderer , origin_screen .x , origin_screen .y , up_screen .x , up_screen .y );
237
+ SDL_SetRenderDrawColor (renderer , GYRO_COLOR_BLUE );
238
+ SDL_RenderLine (renderer , origin_screen .x , origin_screen .y , back_screen .x , back_screen .y );
239
+
240
+ /* Restore current color */
241
+ SDL_SetRenderDrawColor (renderer , r , g , b , a );
242
+ }
243
+
210
244
void DrawAccelerometerDebugArrow (SDL_Renderer * renderer , const Quaternion * gyro_quaternion , const float * accel_data , const SDL_FRect * bounds )
211
245
{
212
246
/* Store current color */
@@ -990,6 +1024,8 @@ struct GyroDisplay
990
1024
/* This part displays extra info from the IMUstate in order to figure out actual polling rates. */
991
1025
float gyro_drift_solution [3 ];
992
1026
int reported_sensor_rate_hz ; /*hz - comes from HIDsdl implementation. Could be fixed, platform time, or true sensor time*/
1027
+ Uint64 next_reported_sensor_time ; /* SDL ticks used to throttle the display */
1028
+
993
1029
int estimated_sensor_rate_hz ; /*hz - our estimation of the actual polling rate by observing packets received*/
994
1030
float euler_displacement_angles [3 ]; /* pitch, yaw, roll */
995
1031
Quaternion gyro_quaternion ; /* Rotation since startup/reset, comprised of each gyro speed packet times sensor delta time. */
@@ -1009,7 +1045,8 @@ GyroDisplay *CreateGyroDisplay(SDL_Renderer *renderer)
1009
1045
SDL_zeroa (ctx -> gyro_drift_solution );
1010
1046
Quaternion quat_identity = { 0.0f , 0.0f , 0.0f , 1.0f };
1011
1047
ctx -> gyro_quaternion = quat_identity ;
1012
-
1048
+ ctx -> reported_sensor_rate_hz = 0 ;
1049
+ ctx -> next_reported_sensor_time = 0 ;
1013
1050
ctx -> reset_gyro_button = CreateGamepadButton (renderer , "Reset View" );
1014
1051
ctx -> calibrate_gyro_button = CreateGamepadButton (renderer , "Recalibrate Drift" );
1015
1052
}
@@ -1024,7 +1061,6 @@ void SetGyroDisplayArea(GyroDisplay *ctx, const SDL_FRect *area)
1024
1061
}
1025
1062
1026
1063
SDL_copyp (& ctx -> area , area );
1027
-
1028
1064
/* Place the reset button to the bottom right of the gyro display area.*/
1029
1065
SDL_FRect reset_button_area ;
1030
1066
reset_button_area .w = SDL_max (MINIMUM_BUTTON_WIDTH , GetGamepadButtonLabelWidth (ctx -> reset_gyro_button ) + 2 * BUTTON_PADDING );
@@ -1340,12 +1376,17 @@ void SetGamepadDisplayIMUValues(GyroDisplay *ctx, float *gyro_drift_solution, fl
1340
1376
return ;
1341
1377
}
1342
1378
1343
- SDL_memcpy (ctx -> gyro_drift_solution , gyro_drift_solution , sizeof (ctx -> gyro_drift_solution ));
1344
- ctx -> estimated_sensor_rate_hz = estimated_sensor_rate_hz ;
1345
-
1346
- if (reported_senor_rate_hz != 0 )
1347
- ctx -> reported_sensor_rate_hz = reported_senor_rate_hz ;
1379
+ const int SENSOR_UPDATE_INTERVAL_MS = 100 ;
1380
+ Uint64 now = SDL_GetTicks ();
1381
+ if (now > ctx -> next_reported_sensor_time ) {
1382
+ ctx -> estimated_sensor_rate_hz = estimated_sensor_rate_hz ;
1383
+ if (reported_senor_rate_hz != 0 ) {
1384
+ ctx -> reported_sensor_rate_hz = reported_senor_rate_hz ;
1385
+ }
1386
+ ctx -> next_reported_sensor_time = now + SENSOR_UPDATE_INTERVAL_MS ;
1387
+ }
1348
1388
1389
+ SDL_memcpy (ctx -> gyro_drift_solution , gyro_drift_solution , sizeof (ctx -> gyro_drift_solution ));
1349
1390
SDL_memcpy (ctx -> euler_displacement_angles , euler_displacement_angles , sizeof (ctx -> euler_displacement_angles ));
1350
1391
ctx -> gyro_quaternion = * gyro_quaternion ;
1351
1392
ctx -> drift_calibration_progress_frac = drift_calibration_progress_frac ;
@@ -1637,7 +1678,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
1637
1678
SDLTest_DrawString (ctx -> renderer , x + center - SDL_strlen (text ) * FONT_CHARACTER_SIZE , y , text );
1638
1679
SDL_snprintf (text , sizeof (text ), "[%.2f,%.2f,%.2f]%s/s" , ctx -> gyro_data [0 ] * RAD_TO_DEG , ctx -> gyro_data [1 ] * RAD_TO_DEG , ctx -> gyro_data [2 ] * RAD_TO_DEG , DEGREE_UTF8 );
1639
1680
SDLTest_DrawString (ctx -> renderer , x + center + 2.0f , y , text );
1640
-
1681
+
1641
1682
1642
1683
/* Display the testcontroller tool's evaluation of drift. This is also useful to get an average rate of turn in calibrated turntable tests. */
1643
1684
if (ctx -> gyro_drift_correction_data [0 ] != 0.0f && ctx -> gyro_drift_correction_data [2 ] != 0.0f && ctx -> gyro_drift_correction_data [2 ] != 0.0f )
@@ -1648,10 +1689,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
1648
1689
SDL_snprintf (text , sizeof (text ), "[%.2f,%.2f,%.2f]%s/s" , ctx -> gyro_drift_correction_data [0 ] * RAD_TO_DEG , ctx -> gyro_drift_correction_data [1 ] * RAD_TO_DEG , ctx -> gyro_drift_correction_data [2 ] * RAD_TO_DEG , DEGREE_UTF8 );
1649
1690
SDLTest_DrawString (ctx -> renderer , x + center + 2.0f , y , text );
1650
1691
}
1651
-
1652
1692
}
1653
-
1654
-
1655
1693
}
1656
1694
}
1657
1695
SDL_free (mapping );
@@ -1797,7 +1835,6 @@ void RenderGyroDriftCalibrationButton(GyroDisplay *ctx, GamepadDisplay *gamepad_
1797
1835
1798
1836
/* Set the color based on the drift calibration progress fraction */
1799
1837
SDL_SetRenderDrawColor (ctx -> renderer , GYRO_COLOR_GREEN ); /* red when too much noise, green when low noise*/
1800
-
1801
1838
/* Now draw the bars with the filled, then empty rectangles */
1802
1839
SDL_RenderFillRect (ctx -> renderer , & progress_bar_fill ); /* draw the filled rectangle*/
1803
1840
SDL_SetRenderDrawColor (ctx -> renderer , 100 , 100 , 100 , 255 ); /* gray box*/
@@ -1823,20 +1860,26 @@ float RenderEulerReadout(GyroDisplay *ctx, GamepadDisplay *gamepad_display )
1823
1860
const float new_line_height = gamepad_display -> button_height + 2.0f ;
1824
1861
float log_gyro_euler_text_x = gyro_calibrate_button_rect .x ;
1825
1862
1863
+ Uint8 r , g , b , a ;
1864
+ SDL_GetRenderDrawColor (ctx -> renderer , & r , & g , & b , & a );
1826
1865
/* Pitch Readout */
1866
+ SDL_SetRenderDrawColor (ctx -> renderer , GYRO_COLOR_RED );
1827
1867
SDL_snprintf (text , sizeof (text ), "Pitch: %6.2f%s" , ctx -> euler_displacement_angles [0 ], DEGREE_UTF8 );
1828
1868
SDLTest_DrawString (ctx -> renderer , log_gyro_euler_text_x + 2.0f , log_y , text );
1829
1869
1830
1870
/* Yaw Readout */
1871
+ SDL_SetRenderDrawColor (ctx -> renderer , GYRO_COLOR_GREEN );
1831
1872
log_y += new_line_height ;
1832
1873
SDL_snprintf (text , sizeof (text ), " Yaw: %6.2f%s" , ctx -> euler_displacement_angles [1 ], DEGREE_UTF8 );
1833
1874
SDLTest_DrawString (ctx -> renderer , log_gyro_euler_text_x + 2.0f , log_y , text );
1834
1875
1835
1876
/* Roll Readout */
1877
+ SDL_SetRenderDrawColor (ctx -> renderer , GYRO_COLOR_BLUE );
1836
1878
log_y += new_line_height ;
1837
1879
SDL_snprintf (text , sizeof (text ), " Roll: %6.2f%s" , ctx -> euler_displacement_angles [2 ], DEGREE_UTF8 );
1838
1880
SDLTest_DrawString (ctx -> renderer , log_gyro_euler_text_x + 2.0f , log_y , text );
1839
1881
1882
+ SDL_SetRenderDrawColor (ctx -> renderer , r , g , b , a );
1840
1883
return log_y + new_line_height ; /* Return the next y position for further rendering */
1841
1884
}
1842
1885
@@ -1859,6 +1902,9 @@ void RenderGyroGizmo(GyroDisplay *ctx, SDL_Gamepad *gamepad, float top)
1859
1902
/* Draw the rotated cube */
1860
1903
DrawGyroDebugCube (ctx -> renderer , & ctx -> gyro_quaternion , & gizmoRect );
1861
1904
1905
+ /* Draw positive axes */
1906
+ DrawGyroDebugAxes (ctx -> renderer , & ctx -> gyro_quaternion , & gizmoRect );
1907
+
1862
1908
/* Overlay the XYZ circles */
1863
1909
DrawGyroDebugCircle (ctx -> renderer , & ctx -> gyro_quaternion , & gizmoRect );
1864
1910
@@ -1906,7 +1952,6 @@ void RenderGyroDisplay(GyroDisplay *ctx, GamepadDisplay *gamepadElements, SDL_Ga
1906
1952
if (bHasCachedDriftSolution ) {
1907
1953
float bottom = RenderEulerReadout (ctx , gamepadElements );
1908
1954
RenderGyroGizmo (ctx , gamepad , bottom );
1909
-
1910
1955
}
1911
1956
SDL_SetRenderDrawColor (ctx -> renderer , r , g , b , a );
1912
1957
}
0 commit comments