mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-03 12:28:07 +00:00
gui: Add gui for tracking overrides
This commit is contained in:
parent
5e4c62c8aa
commit
de169bf575
src/xrt
state_trackers/gui
targets/gui
|
@ -15,6 +15,7 @@ set(GUI_SOURCE_FILES
|
|||
gui_scene_main_menu.c
|
||||
gui_scene_remote.c
|
||||
gui_scene_video.c
|
||||
gui_scene_tracking_overrides.c
|
||||
../../../external/imgui/imgui/cimgui.cpp
|
||||
../../../external/imgui/imgui/cimgui.h
|
||||
../../../external/imgui/imgui/cimplot.cpp
|
||||
|
|
|
@ -197,6 +197,14 @@ gui_scene_main_menu(struct gui_program *p);
|
|||
void
|
||||
gui_scene_select_video_calibrate(struct gui_program *p);
|
||||
|
||||
/*!
|
||||
* Shows a UI that lets you set up tracking overrides.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
void
|
||||
gui_scene_tracking_overrides(struct gui_program *p);
|
||||
|
||||
/*!
|
||||
* Regular debug UI.
|
||||
*
|
||||
|
|
|
@ -34,6 +34,12 @@ scene_render(struct gui_scene *scene, struct gui_program *p)
|
|||
gui_scene_select_video_calibrate(p);
|
||||
}
|
||||
|
||||
if (igButton("Tracking Overrides", button_dims)) {
|
||||
gui_scene_delete_me(p, scene);
|
||||
|
||||
gui_scene_tracking_overrides(p);
|
||||
}
|
||||
|
||||
if (igButton("Debug Test", button_dims)) {
|
||||
gui_scene_delete_me(p, scene);
|
||||
|
||||
|
|
314
src/xrt/state_trackers/gui/gui_scene_tracking_overrides.c
Normal file
314
src/xrt/state_trackers/gui/gui_scene_tracking_overrides.c
Normal file
|
@ -0,0 +1,314 @@
|
|||
// Copyright 2021, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief A very small scene that lets the user configure tracking overrides.
|
||||
* @author Christoph Haag <christoph.haag@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup gui
|
||||
*/
|
||||
|
||||
#include "util/u_misc.h"
|
||||
#include "util/u_format.h"
|
||||
|
||||
#include "util/u_config_json.h"
|
||||
|
||||
#include "math/m_api.h"
|
||||
|
||||
#include "xrt/xrt_prober.h"
|
||||
#include "xrt/xrt_settings.h"
|
||||
|
||||
#include "gui_common.h"
|
||||
#include "gui_imgui.h"
|
||||
|
||||
struct gui_tracking_overrides
|
||||
{
|
||||
struct gui_scene base;
|
||||
|
||||
int editing_override;
|
||||
|
||||
bool add_one;
|
||||
int add_target;
|
||||
int add_tracker;
|
||||
|
||||
struct u_config_json config;
|
||||
|
||||
struct xrt_pose reset_offset;
|
||||
|
||||
size_t num_overrides;
|
||||
struct xrt_tracking_override overrides[XRT_MAX_TRACKING_OVERRIDES];
|
||||
};
|
||||
|
||||
static ImVec2 button_dims = {256 + 64, 0};
|
||||
|
||||
/*
|
||||
*
|
||||
* Internal functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#define NAME_LENGTH XRT_DEVICE_NAME_LEN * 2 + 5
|
||||
|
||||
static void
|
||||
make_name(struct xrt_device *xdev, char *buf)
|
||||
{
|
||||
snprintf(buf, NAME_LENGTH, "%s | %s", xdev->str, xdev->serial);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_draggable_vec3_f32(const char *name, struct xrt_vec3 *v, const struct xrt_vec3 *reset)
|
||||
{
|
||||
float min = -256.0f;
|
||||
float max = 256.0f;
|
||||
char tmp[256];
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s.reset", name);
|
||||
|
||||
if (igArrowButton(tmp, ImGuiDir_Left)) {
|
||||
*v = *reset;
|
||||
}
|
||||
|
||||
igSameLine(0, 3);
|
||||
igDragFloat3(name, (float *)v, 0.005f, min, max, "%+f", 1.0f);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_draggable_quat(const char *name, struct xrt_quat *q, const struct xrt_quat *reset)
|
||||
{
|
||||
float min = -1.0f;
|
||||
float max = 1.0f;
|
||||
|
||||
char tmp[256];
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s.reset", name);
|
||||
|
||||
if (igArrowButton(tmp, ImGuiDir_Left)) {
|
||||
*q = *reset;
|
||||
}
|
||||
|
||||
igSameLine(0, 3);
|
||||
igDragFloat4(name, (float *)q, 0.005f, min, max, "%+f", 1.0f);
|
||||
|
||||
// Avoid invalid
|
||||
if (q->x == 0.0f && q->y == 0.0f && q->z == 0.0f && q->w == 0.0f) {
|
||||
q->w = 1.0f;
|
||||
}
|
||||
|
||||
// And make sure it's a unit rotation.
|
||||
math_quat_normalize(q);
|
||||
}
|
||||
|
||||
static bool
|
||||
get_indices(struct gui_program *p,
|
||||
struct gui_tracking_overrides *ts,
|
||||
struct xrt_tracking_override *override,
|
||||
int *out_target,
|
||||
int *out_tracker)
|
||||
{
|
||||
bool has_target = false;
|
||||
bool has_tracker = false;
|
||||
|
||||
for (int i = 0; i < NUM_XDEVS; i++) {
|
||||
if (!p->xdevs[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(p->xdevs[i]->serial, override->target_device_serial) == 0) {
|
||||
has_target = true;
|
||||
*out_target = i;
|
||||
}
|
||||
|
||||
if (strcmp(p->xdevs[i]->serial, override->tracker_device_serial) == 0) {
|
||||
has_tracker = true;
|
||||
*out_tracker = i;
|
||||
}
|
||||
}
|
||||
|
||||
return has_tracker && has_target;
|
||||
}
|
||||
|
||||
static struct xrt_pose identity = {.position = {.x = 0, .y = 0, .z = 0},
|
||||
.orientation = {.x = 0, .y = 0, .z = 0, .w = 1}};
|
||||
|
||||
static void
|
||||
add_one(struct gui_program *p, struct gui_tracking_overrides *ts)
|
||||
{
|
||||
igBegin("Target Device", NULL, 0);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (!p->xdevs[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char buf[NAME_LENGTH];
|
||||
make_name(p->xdevs[i], buf);
|
||||
|
||||
bool selected = ts->add_target == i;
|
||||
if (igCheckbox(buf, &selected)) {
|
||||
ts->add_target = i;
|
||||
}
|
||||
}
|
||||
igEnd();
|
||||
|
||||
igBegin("Tracker Device", NULL, 0);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (!p->xdevs[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char buf[NAME_LENGTH];
|
||||
make_name(p->xdevs[i], buf);
|
||||
|
||||
bool selected = ts->add_tracker == i;
|
||||
if (igCheckbox(buf, &selected)) {
|
||||
ts->add_tracker = i;
|
||||
}
|
||||
}
|
||||
igEnd();
|
||||
|
||||
if (ts->add_target >= 0 && ts->add_tracker >= 0 && ts->add_target != ts->add_tracker) {
|
||||
struct xrt_tracking_override *o = &ts->overrides[ts->num_overrides];
|
||||
o->input_name = XRT_INPUT_GENERIC_TRACKER_POSE;
|
||||
strncpy(o->target_device_serial, p->xdevs[ts->add_target]->serial, XRT_DEVICE_NAME_LEN);
|
||||
strncpy(o->tracker_device_serial, p->xdevs[ts->add_tracker]->serial, XRT_DEVICE_NAME_LEN);
|
||||
o->offset = identity;
|
||||
|
||||
ts->num_overrides += 1;
|
||||
|
||||
ts->add_target = -1;
|
||||
ts->add_tracker = -1;
|
||||
|
||||
ts->add_one = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scene_render(struct gui_scene *scene, struct gui_program *p)
|
||||
{
|
||||
struct gui_tracking_overrides *ts = (struct gui_tracking_overrides *)scene;
|
||||
|
||||
if (ts->editing_override >= 0) {
|
||||
struct xrt_tracking_override *o = &ts->overrides[ts->editing_override];
|
||||
|
||||
igBegin("Tracker Device Offset", NULL, 0);
|
||||
int target, tracker;
|
||||
if (get_indices(p, ts, o, &target, &tracker)) {
|
||||
igText("Editing %s [%s] <- %s [%s]", p->xdevs[target]->str, o->target_device_serial,
|
||||
p->xdevs[tracker]->str, o->tracker_device_serial);
|
||||
} else {
|
||||
igText("Editing unconnected %s <- %s", o->target_device_serial, o->tracker_device_serial);
|
||||
}
|
||||
handle_draggable_vec3_f32("Position", &o->offset.position, &ts->reset_offset.position);
|
||||
handle_draggable_quat("Orientation", &o->offset.orientation, &ts->reset_offset.orientation);
|
||||
igEnd();
|
||||
}
|
||||
|
||||
if (ts->add_one) {
|
||||
add_one(p, ts);
|
||||
}
|
||||
|
||||
igBegin("Tracking Overrides", NULL, 0);
|
||||
|
||||
igText("Existing Overrides");
|
||||
for (size_t i = 0; i < ts->num_overrides; i++) {
|
||||
// make the delete buttons work
|
||||
igPushIDInt(i);
|
||||
|
||||
igSeparator();
|
||||
|
||||
bool checked = ts->editing_override == (int)i;
|
||||
|
||||
const int len = XRT_DEVICE_NAME_LEN * 2 + 10;
|
||||
char buf[len];
|
||||
snprintf(buf, len, "%s <- %s", ts->overrides[i].target_device_serial,
|
||||
ts->overrides[i].tracker_device_serial);
|
||||
if (igCheckbox(buf, &checked)) {
|
||||
ts->editing_override = i;
|
||||
ts->reset_offset = ts->overrides[i].offset;
|
||||
}
|
||||
if (igButton("Delete this one", button_dims)) {
|
||||
for (size_t j = i; j < ts->num_overrides - 1; j++) {
|
||||
ts->overrides[j] = ts->overrides[j + 1];
|
||||
}
|
||||
ts->num_overrides--;
|
||||
if (ts->editing_override >= (int)i) {
|
||||
ts->editing_override -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
igSeparator();
|
||||
|
||||
igPopID();
|
||||
}
|
||||
|
||||
igSeparator();
|
||||
|
||||
if (igButton("Add one", button_dims)) {
|
||||
if (ts->num_overrides < XRT_MAX_TRACKING_OVERRIDES) {
|
||||
ts->add_one = true;
|
||||
}
|
||||
}
|
||||
|
||||
igSeparator();
|
||||
|
||||
if (igButton("Save", button_dims)) {
|
||||
gui_scene_delete_me(p, scene);
|
||||
}
|
||||
|
||||
if (igButton("Exit", button_dims)) {
|
||||
gui_scene_delete_me(p, scene);
|
||||
}
|
||||
|
||||
igEnd();
|
||||
}
|
||||
|
||||
static void
|
||||
scene_destroy(struct gui_scene *scene, struct gui_program *p)
|
||||
{
|
||||
// struct tracking_overrides *ts = (struct tracking_overrides *)scene;
|
||||
|
||||
free(scene);
|
||||
}
|
||||
|
||||
static struct gui_tracking_overrides *
|
||||
create(struct gui_program *p)
|
||||
{
|
||||
struct gui_tracking_overrides *ts = U_TYPED_CALLOC(struct gui_tracking_overrides);
|
||||
|
||||
ts->base.render = scene_render;
|
||||
ts->base.destroy = scene_destroy;
|
||||
|
||||
ts->editing_override = -1;
|
||||
ts->add_one = false;
|
||||
ts->add_target = -1;
|
||||
ts->add_tracker = -1;
|
||||
|
||||
u_config_json_open_or_create_main_file(&ts->config);
|
||||
u_config_json_get_tracking_overrides(&ts->config, ts->overrides, &ts->num_overrides);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 'Exported' functions.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
gui_scene_tracking_overrides(struct gui_program *p)
|
||||
{
|
||||
if (p->xp == NULL) {
|
||||
// No prober, nothing to create.
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have created a prober select devices now.
|
||||
if (p->xp != NULL) {
|
||||
gui_prober_select(p);
|
||||
}
|
||||
|
||||
struct gui_tracking_overrides *ts = create(p);
|
||||
|
||||
gui_scene_push_front(p, &ts->base);
|
||||
}
|
|
@ -12,6 +12,7 @@ gui_sources = [
|
|||
'gui_scene_main_menu.c',
|
||||
'gui_scene_remote.c',
|
||||
'gui_scene_video.c',
|
||||
'gui_scene_tracking_overrides.c',
|
||||
'../../../external/imgui/imgui/cimgui.cpp',
|
||||
'../../../external/imgui/imgui/cimgui.h',
|
||||
'../../../external/imgui/imgui/cimplot.cpp',
|
||||
|
|
|
@ -39,6 +39,8 @@ main(int argc, char **argv)
|
|||
gui_scene_debug(&p.base);
|
||||
} else if (argc >= 2 && strcmp("calibrate", argv[1]) == 0) {
|
||||
gui_scene_select_video_calibrate(&p.base);
|
||||
} else if (argc >= 2 && strcmp("tracking_overrides", argv[1]) == 0) {
|
||||
gui_scene_tracking_overrides(&p.base);
|
||||
} else if (argc >= 2 && strcmp("remote", argv[1]) == 0) {
|
||||
gui_scene_remote(&p.base);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue