~bl4ckb0ne/wxrc

983be67b2d89303a021485ac18178b85f0bbc9a7 — Simon Zeni 1 year, 9 months ago 73c3f7d
wxrc/input: improve input init, fix bug and more verbose output
3 files changed, 58 insertions(+), 97 deletions(-)

M wxrc/controller.c
M wxrc/hand-tracking.c
M wxrc/input.c
M wxrc/controller.c => wxrc/controller.c +45 -2
@@ 22,11 22,54 @@ static const struct wlr_pointer_impl pointer_impl = {
	.name = "xr-pointer",
};

static bool
grip_active(struct wxrc_input *input, XrHandEXT hand)
{
	XrPath path = {0};
	if (hand == XR_HAND_LEFT_EXT) {
		path = input->paths[0];
	} else if (hand == XR_HAND_RIGHT_EXT) {
		path = input->paths[1];
	} else {
		// unreachable
		abort();
	}

	XrActionStateGetInfo grip_info = {
		.type = XR_TYPE_ACTION_STATE_GET_INFO,
		.next = NULL,
		.action = input->grip.action,
		.subactionPath = path,
	};

	XrActionStatePose grip_state = {
		.type = XR_TYPE_ACTION_STATE_POSE,
		.next = NULL,
	};

	struct wxrc_server *server = input->server;
	XrResult r = xrGetActionStatePose(server->session, &grip_info, &grip_state);
	if (XR_FAILED(r)) {
		char buf[XR_MAX_PATH_LENGTH] = {0};
		uint32_t len;
		xrPathToString(server->instance, path, XR_MAX_PATH_LENGTH, &len, buf);

		wxrc_xr_log(r, "failed to get grip pose state for path %s", buf);
		return false;
	}

	return grip_state.isActive == XR_TRUE;
}

struct wxrc_controller *
wxrc_controller_create(struct wxrc_input *input, XrHandEXT hand)
{
	wlr_log(WLR_DEBUG, "creating controller for %s hand",
		wxrc_xr_hand_str(hand));
	if (!grip_active(input, hand)) {
		wlr_log(WLR_INFO, "controller %s is inactive", wxrc_xr_hand_str(hand));
		return NULL;
	}

	wlr_log(WLR_INFO, "creating controller for %s", wxrc_xr_hand_str(hand));

	struct wxrc_controller *controller =
			calloc(1, sizeof(struct wxrc_controller));

M wxrc/hand-tracking.c => wxrc/hand-tracking.c +1 -1
@@ 33,7 33,7 @@ wxrc_hand_tracking_create(struct wxrc_input *input, XrHandEXT hand)
		}
	}

	wlr_log(WLR_DEBUG, "creating hand tracking for %s",
	wlr_log(WLR_INFO, "creating hand tracking for %s",
		wxrc_xr_hand_str(hand));

	struct wxrc_hand_tracking *tracking =

M wxrc/input.c => wxrc/input.c +12 -94
@@ 145,7 145,7 @@ add_action(struct wxrc_action *action, struct binding *binding,
	if (action->type == XR_ACTION_TYPE_VECTOR2F_INPUT) {
		snprintf(binding->paths[0], PATH_MAX, "/user/hand/left/input/%s",
			name);
		snprintf(binding->paths[1], PATH_MAX, "/user/hand/left/input/%s",
		snprintf(binding->paths[1], PATH_MAX, "/user/hand/right/input/%s",
			name);
	} else if (action->type == XR_ACTION_TYPE_VIBRATION_OUTPUT) {
		snprintf(binding->paths[0], PATH_MAX, "/user/hand/left/output/haptic");


@@ 153,11 153,10 @@ add_action(struct wxrc_action *action, struct binding *binding,
	} else {
		snprintf(binding->paths[0], PATH_MAX, "/user/hand/left/input/%s/%s",
			name, type);
		snprintf(binding->paths[1], PATH_MAX, "/user/hand/left/input/%s/%s",
		snprintf(binding->paths[1], PATH_MAX, "/user/hand/right/input/%s/%s",
			name, type);
	}


	return true;
}



@@ 290,98 289,10 @@ input_sync_actions(struct wxrc_input *input)
	return true;
}

static bool
input_init(struct wxrc_input *input, XrHandEXT hand)
{
	struct wxrc_server *server = input->server;

	const char *name = NULL;
	XrPath path = {0};
	if (hand == XR_HAND_LEFT_EXT) {
		name = "left";
		path = input->paths[0];
	} else if (hand == XR_HAND_RIGHT_EXT) {
		name = "right";
		path = input->paths[1];
	}

	XrActionStateGetInfo grip_info = {
		.type = XR_TYPE_ACTION_STATE_GET_INFO,
		.next = NULL,
		.action = input->grip.action,
		.subactionPath = path,
	};

	XrActionStatePose grip_state = {
		.type = XR_TYPE_ACTION_STATE_POSE,
		.next = NULL,
	};

	XrResult r = xrGetActionStatePose(server->session, &grip_info, &grip_state);
	if (XR_FAILED(r)) {
		wxrc_xr_log(r, "failed to get %s grip pose state", name);
		return false;
	}

	if (grip_state.isActive == XR_TRUE) {
		/* TODO handle monado hotplug */
		if (hand == XR_HAND_LEFT_EXT) {
			input->left.controller = wxrc_controller_create(input, hand);
			if (input->left.controller == NULL) {
				wlr_log(WLR_ERROR, "failed to create left hand controller");
				return false;
			}
		} else if (hand == XR_HAND_RIGHT_EXT) {
			input->right.controller = wxrc_controller_create(input, hand);
			if (input->right.controller == NULL) {
				wlr_log(WLR_ERROR, "failed to create right hand controller");
				return false;
			}
		}
	} else {
		wlr_log(WLR_DEBUG, "%s controller is not active", name);
	}

	XrSystemHandTrackingPropertiesEXT hand_tracking_props = {
		.type = XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT,
		.next = NULL,
	};

	XrSystemProperties props = {
		.type = XR_TYPE_SYSTEM_PROPERTIES,
		.next = &hand_tracking_props,
	};

	r = xrGetSystemProperties(server->instance, server->system_id, &props);
	if (XR_FAILED(r)) {
		wxrc_xr_log(r, "failed to get system properties");
		return false;
	}

	if (hand_tracking_props.supportsHandTracking) {
		wlr_log(WLR_DEBUG, "creating hand tracking");
		if (hand == XR_HAND_LEFT_EXT) {
			input->left.hand = wxrc_hand_tracking_create(input, hand);
			if (input->left.hand == NULL) {
				wlr_log(WLR_ERROR, "failed to create left hand tracking");
				return false;
			}
		} else if (hand == XR_HAND_RIGHT_EXT) {
			input->right.hand = wxrc_hand_tracking_create(input, hand);
			if (input->right.hand == NULL) {
				wlr_log(WLR_ERROR, "failed to create right hand tracking");
				return false;
			}
		}
	}

	return true;
}

bool
wxrc_input_init(struct wxrc_input *input)
{
	wlr_log(WLR_DEBUG, "initializing OpenXR input");
	wlr_log(WLR_INFO, "initializing OpenXR input");

	struct wxrc_server *server = input->server;
	if (server->state != XR_SESSION_STATE_FOCUSED) {


@@ 406,8 317,15 @@ wxrc_input_init(struct wxrc_input *input)
		return false;
	}

	return input_init(input, XR_HAND_LEFT_EXT)
		&& input_init(input, XR_HAND_RIGHT_EXT);
	input->left.controller = wxrc_controller_create(input, XR_HAND_LEFT_EXT);
	input->right.controller = wxrc_controller_create(input, XR_HAND_RIGHT_EXT);

	if (wxrc_xr_has_hand_tracking(server->instance, server->system_id)) {
		input->left.hand = wxrc_hand_tracking_create(input, XR_HAND_LEFT_EXT);
		input->right.hand = wxrc_hand_tracking_create(input, XR_HAND_RIGHT_EXT);
	}

	return true;
}

bool