Compare commits

...

2 Commits

Author SHA1 Message Date
Megamouse
729826ec40 cellGem: fix HUE_NOT_SET 2024-11-29 05:39:11 +01:00
Megamouse
a8b0c0be07 cellGem: calculate distance from sphere to camera 2024-11-29 05:39:11 +01:00
3 changed files with 28 additions and 18 deletions

View File

@ -232,7 +232,7 @@ public:
u8 rumble = 0; // Rumble intensity
gem_color sphere_rgb = {}; // RGB color of the sphere LED
u32 hue = 0; // Tracking hue of the motion controller
f32 distance{1500.0f}; // Distance from the camera in mm
f32 distance_mm{1500.0f}; // Distance from the camera in mm
f32 radius{10.0f}; // Radius of the sphere in camera pixels
bool radius_valid = true; // If the radius and distance of the sphere was computed.
@ -817,7 +817,7 @@ public:
{
// Only set new radius and distance if the radius is valid
controller.radius = info.radius;
controller.distance = info.distance;
controller.distance_mm = info.distance_mm;
}
}
}
@ -894,8 +894,8 @@ static inline void pos_to_gem_image_state(u32 gem_num, const gem_config::gem_con
gem_image_state->v = image_y;
// Projected camera coordinates in mm
gem_image_state->projectionx = camera_x / controller.distance;
gem_image_state->projectiony = camera_y / controller.distance;
gem_image_state->projectionx = camera_x / controller.distance_mm;
gem_image_state->projectiony = camera_y / controller.distance_mm;
if (g_cfg.io.show_move_cursor)
{
@ -929,7 +929,7 @@ static inline void pos_to_gem_state(u32 gem_num, const gem_config::gem_controlle
// World coordinates in mm
gem_state->pos[0] = camera_x;
gem_state->pos[1] = camera_y;
gem_state->pos[2] = static_cast<f32>(controller.distance);
gem_state->pos[2] = controller.distance_mm;
gem_state->pos[3] = 0.f;
gem_state->quat[0] = 320.f - image_x;
@ -939,7 +939,7 @@ static inline void pos_to_gem_state(u32 gem_num, const gem_config::gem_controlle
// TODO: calculate handle position based on our world coordinate and the angles
gem_state->handle_pos[0] = camera_x;
gem_state->handle_pos[1] = camera_y;
gem_state->handle_pos[2] = static_cast<f32>(controller.distance + 10);
gem_state->handle_pos[2] = controller.distance_mm + 10.0f;
gem_state->handle_pos[3] = 0.f;
if (g_cfg.io.show_move_cursor)
@ -1800,7 +1800,7 @@ error_code cellGemGetImageState(u32 gem_num, vm::ptr<CellGemImageState> gem_imag
gem_image_state->frame_timestamp = shared_data.frame_timestamp_us.load();
gem_image_state->timestamp = gem_image_state->frame_timestamp + 10;
gem_image_state->r = controller.radius; // Radius in camera pixels
gem_image_state->distance = controller.distance; // 1.5 meters away from camera
gem_image_state->distance = controller.distance_mm;
gem_image_state->visible = gem.is_controller_ready(gem_num);
gem_image_state->r_valid = controller.radius_valid;
@ -2644,6 +2644,7 @@ error_code cellGemTrackHues(vm::cptr<u32> req_hues, vm::ptr<u32> res_hues)
{
gem.controllers[i].enabled_tracking = true;
gem.controllers[i].enabled_LED = true;
gem.controllers[i].hue_set = true;
// TODO: set hue based on tracker data
@ -2673,6 +2674,7 @@ error_code cellGemTrackHues(vm::cptr<u32> req_hues, vm::ptr<u32> res_hues)
{
gem.controllers[i].enabled_tracking = false;
gem.controllers[i].enabled_LED = false;
gem.controllers[i].hue_set = false;
if (res_hues)
{
@ -2688,6 +2690,7 @@ error_code cellGemTrackHues(vm::cptr<u32> req_hues, vm::ptr<u32> res_hues)
gem.controllers[i].enabled_tracking = true;
gem.controllers[i].enabled_LED = true;
gem.controllers[i].hue_set = true;
gem.controllers[i].hue = req_hues[i];
// TODO: set hue of tracker
@ -2697,8 +2700,6 @@ error_code cellGemTrackHues(vm::cptr<u32> req_hues, vm::ptr<u32> res_hues)
res_hues[i] = gem.controllers[i].hue;
}
}
gem.controllers[i].hue_set = true;
}
return CELL_OK;

View File

@ -408,9 +408,18 @@ void ps_move_tracker<DiagnosticsEnabled>::process_contours(ps_move_info& info, u
if (best_index == umax)
return;
// Calculate distance from sphere to camera
const f32 sphere_radius_pixels = radii[best_index];
constexpr f32 focal_length_mm = 3.5f; // Based on common webcam specs
constexpr f32 sensor_width_mm = 3.6f; // Based on common webcam specs
const f32 image_width_pixels = static_cast<float>(width);
const f32 focal_length_pixels = (focal_length_mm * image_width_pixels) / sensor_width_mm;
const f32 distance_mm = (focal_length_pixels * CELL_GEM_SPHERE_RADIUS_MM) / sphere_radius_pixels;
// Set results
info.valid = true;
info.distance = 1500.0f;
info.radius = radii[best_index];
info.distance_mm = distance_mm;
info.radius = sphere_radius_pixels;
info.x_pos = std::clamp(static_cast<u32>(centers[best_index].x), 0u, width);
info.y_pos = std::clamp(static_cast<u32>(centers[best_index].y), 0u, height);

View File

@ -8,13 +8,13 @@
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;
bool valid = false; // The tracking result
f32 radius = 0.0f; // Radius of the sphere in pixels
f32 distance_mm = 0.0f; // Distance from sphere to camera in mm
u32 x_pos = 0; // X position in pixels
u32 y_pos = 0; // Y position in pixels
u32 x_max = 0; // Maximum X position in pixels
u32 y_max = 0; // Maximum Y position in pixels
};
template <bool DiagnosticsEnabled = false>