mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
102 lines
3 KiB
C++
102 lines
3 KiB
C++
#pragma once
|
|
|
|
#ifdef HAVE_OPENCV
|
|
constexpr bool g_ps_move_tracking_supported = true;
|
|
#else
|
|
constexpr bool g_ps_move_tracking_supported = false;
|
|
#endif
|
|
|
|
struct ps_move_info
|
|
{
|
|
bool valid = false;
|
|
f32 radius = 0.0f;
|
|
f32 distance = 0.0f;
|
|
u32 x_pos = 0;
|
|
u32 y_pos = 0;
|
|
u32 x_max = 0;
|
|
u32 y_max = 0;
|
|
};
|
|
|
|
template <bool DiagnosticsEnabled = false>
|
|
class ps_move_tracker
|
|
{
|
|
public:
|
|
ps_move_tracker();
|
|
virtual ~ps_move_tracker();
|
|
|
|
void set_image_data(const void* buf, u64 size, u32 width, u32 height, s32 format);
|
|
|
|
void init_workers();
|
|
void process_image();
|
|
void convert_image(s32 output_format);
|
|
void process_hues();
|
|
void process_contours(ps_move_info& info, u32 index);
|
|
|
|
void set_active(u32 index, bool active);
|
|
void set_hue(u32 index, u16 hue);
|
|
void set_hue_threshold(u32 index, u16 threshold);
|
|
void set_saturation_threshold(u32 index, u16 threshold);
|
|
|
|
void set_min_radius(f32 radius) { m_min_radius = radius; }
|
|
void set_max_radius(f32 radius) { m_max_radius = radius; }
|
|
void set_filter_small_contours(bool enabled = false) { m_filter_small_contours = enabled; }
|
|
void set_show_all_contours(bool enabled = false) { m_show_all_contours = enabled; }
|
|
void set_draw_contours(bool enabled = false) { m_draw_contours = enabled; }
|
|
void set_draw_overlays(bool enabled = false) { m_draw_overlays = enabled; }
|
|
|
|
const std::array<ps_move_info, CELL_GEM_MAX_NUM>& info() { return m_info; }
|
|
const std::array<u32, 360>& hues() { return m_hues; }
|
|
const std::vector<u8>& rgba() { return m_image_rgba; }
|
|
const std::vector<u8>& rgba_contours() { return m_image_rgba_contours; }
|
|
const std::vector<u8>& hsv() { return m_image_hsv; }
|
|
const std::vector<u8>& gray() { return m_image_gray; }
|
|
const std::vector<u8>& binary(u32 index) { return ::at32(m_image_binary, index); }
|
|
|
|
static std::tuple<u8, u8, u8> hsv_to_rgb(u16 hue, float saturation, float value);
|
|
static std::tuple<s16, float, float> rgb_to_hsv(float r, float g, float b);
|
|
|
|
private:
|
|
struct ps_move_config
|
|
{
|
|
bool active = false;
|
|
|
|
u16 hue = 0;
|
|
u16 hue_threshold = 0;
|
|
u16 saturation_threshold_u8 = 0;
|
|
|
|
s16 min_hue = 0;
|
|
s16 max_hue = 0;
|
|
f32 saturation_threshold = 0.0f;
|
|
|
|
void calculate_values();
|
|
};
|
|
|
|
u32 m_width = 0;
|
|
u32 m_height = 0;
|
|
s32 m_format = 0;
|
|
f32 m_min_radius = 0.0f;
|
|
f32 m_max_radius = 1.0f;
|
|
|
|
bool m_filter_small_contours = true;
|
|
bool m_show_all_contours = false;
|
|
bool m_draw_contours = false;
|
|
bool m_draw_overlays = false;
|
|
|
|
std::vector<u8> m_image_data;
|
|
std::vector<u8> m_image_rgba;
|
|
std::vector<u8> m_image_rgba_contours;
|
|
std::vector<u8> m_image_hsv;
|
|
std::vector<u8> m_image_gray;
|
|
|
|
std::array<std::vector<u8>, CELL_GEM_MAX_NUM> m_image_hue_filtered{};
|
|
std::array<std::vector<u8>, CELL_GEM_MAX_NUM> m_image_binary{};
|
|
|
|
std::array<u32, 360> m_hues{};
|
|
std::array<ps_move_info, CELL_GEM_MAX_NUM> m_info{};
|
|
std::array<ps_move_config, CELL_GEM_MAX_NUM> m_config{};
|
|
|
|
std::array<std::unique_ptr<named_thread<std::function<void()>>>, CELL_GEM_MAX_NUM> m_workers{};
|
|
std::array<atomic_t<u32>, CELL_GEM_MAX_NUM> m_wake_up_workers{};
|
|
std::array<atomic_t<u32>, CELL_GEM_MAX_NUM> m_workers_finished{};
|
|
};
|