diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2022-10-09 03:28:43 -0500 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2022-10-11 14:57:04 -0500 |
| commit | 3939b32ed6158b700cbbb79d0bad7ef62f563c8b (patch) | |
| tree | 962395ba67a744da2c32a58851675c42266dab23 /Source/Core | |
| parent | a056a1366f458754aee61b67f05f61f34c826353 (diff) | |
WiimoteEmu: Improve simulated IR point size accuracy.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/HW/WiimoteEmu/Camera.cpp | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp index 854c9e8577..fb79f12702 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp @@ -75,19 +75,24 @@ CameraLogic::GetCameraPoints(const Common::Matrix44& transform, Common::Vec2 fie const auto point = camera_view * Vec4(v, 1.0); // Check if LED is behind camera. - if (point.z > 0) - { - // FYI: Casting down vs. rounding seems to produce more symmetrical output. - const auto x = s32((1 - point.x / point.w) * CAMERA_RES_X / 2); - const auto y = s32((1 - point.y / point.w) * CAMERA_RES_Y / 2); + if (point.z < 0) + return CameraPoint(); - const auto point_size = std::lround(MAX_POINT_SIZE / point.w / 2); + // FYI: truncating vs. rounding seems to produce more symmetrical cursor positioning. + const auto x = s32((1 - point.x / point.w) * CAMERA_RES_X / 2); + const auto y = s32((1 - point.y / point.w) * CAMERA_RES_Y / 2); - if (x >= 0 && y >= 0 && x < CAMERA_RES_X && y < CAMERA_RES_Y) - return CameraPoint({u16(x), u16(y)}, u8(point_size)); - } + // Check if LED is outside of view. + if (x < 0 || y < 0 || x >= CAMERA_RES_X || y >= CAMERA_RES_Y) + return CameraPoint(); + + // Curve fit from data using an official WM+ and sensor bar at middle "sensitivity". + // Point sizes at minimum and maximum sensitivity differ by around 0.5 (not implemented). + const auto point_size = 2.37f * std::pow(point.z, -0.778f); + + const auto clamped_point_size = std::clamp<s32>(std::lround(point_size), 1, MAX_POINT_SIZE); - return CameraPoint(); + return CameraPoint({u16(x), u16(y)}, u8(clamped_point_size)); }); return camera_points; |
