diff --git a/rpcs3/Input/ps_move_tracker.cpp b/rpcs3/Input/ps_move_tracker.cpp index 062731a052..e72c550338 100644 --- a/rpcs3/Input/ps_move_tracker.cpp +++ b/rpcs3/Input/ps_move_tracker.cpp @@ -444,10 +444,27 @@ void ps_move_tracker::process_contours(ps_move_info& info, u // Set results set_valid(info, index, true); - info.distance_mm = distance_mm; - info.radius = sphere_radius_pixels; - info.x_pos = std::clamp(static_cast(centers[best_index].x), 0u, width); - info.y_pos = std::clamp(static_cast(centers[best_index].y), 0u, height); + + const u32 x_pos = std::clamp(static_cast(centers[best_index].x), 0u, width); + const u32 y_pos = std::clamp(static_cast(centers[best_index].y), 0u, height); + + // Only set new values if the new shape and position are relatively similar to the old ones. + const auto distance_travelled = [](int x1, int y1, int x2, int y2) + { + return std::sqrt(std::pow(x2 - x1, 2) + pow(y2 - y1, 2)); + }; + const bool shape_matches = std::abs(info.radius - sphere_radius_pixels) < (info.radius * 2) && + distance_travelled(info.x_pos, info.y_pos, x_pos, y_pos) < (info.radius * 8); + + if (shape_matches || ++m_shape_fail_count[index] >= 3) + { + info.distance_mm = distance_mm; + info.radius = sphere_radius_pixels; + info.x_pos = x_pos; + info.y_pos = y_pos; + + m_shape_fail_count[index] = 0; // Reset fail count + } if constexpr (!DiagnosticsEnabled) return; diff --git a/rpcs3/Input/ps_move_tracker.h b/rpcs3/Input/ps_move_tracker.h index 00f5155541..5ca91fd893 100644 --- a/rpcs3/Input/ps_move_tracker.h +++ b/rpcs3/Input/ps_move_tracker.h @@ -93,6 +93,7 @@ private: std::array, CELL_GEM_MAX_NUM> m_image_hue_filtered{}; std::array, CELL_GEM_MAX_NUM> m_image_binary{}; std::array m_fail_count{}; + std::array m_shape_fail_count{}; std::array m_hues{}; std::array m_info{};