VR: Reset pose offsets when changing base pose

The offsets are applied after toggling positional tracking off, so that
the view does not jump at that moment. But when changing the base pose,
keeping that offset doesn't make sense. Especially with landmarks, which
are supposed to give precise positions/rotations to jump to. For that
part the VR Scene Inspection Add-on will need a little adjustment
though.

Also exposes an explicit function to the Python API to reset the
offsets, to be used by the Add-on.

This is mostly untested since I don't have access to an HMD currently.
This commit is contained in:
Julian Eisel 2020-04-28 23:16:29 +02:00
parent c57e4418bb
commit 0cfd2d6f4b
Notes: blender-bot 2023-02-14 08:40:26 +01:00
Referenced by issue #71347, Virtual Reality - Milestone 1 - Scene Inspection
4 changed files with 42 additions and 1 deletions

View File

@ -45,6 +45,16 @@ static bool rna_XrSessionState_is_running(bContext *C)
# endif
}
static void rna_XrSessionState_reset_to_base_pose(bContext *C)
{
# ifdef WITH_XR_OPENXR
wmWindowManager *wm = CTX_wm_manager(C);
WM_xr_session_base_pose_reset(&wm->xr);
# else
UNUSED_VARS(C);
# endif
}
# ifdef WITH_XR_OPENXR
static wmXrData *rna_XrSessionState_wm_xr_data_get(PointerRNA *ptr)
{
@ -197,6 +207,12 @@ static void rna_def_xr_session_state(BlenderRNA *brna)
parm = RNA_def_boolean(func, "result", 0, "Result", "");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "reset_to_base_pose", "rna_XrSessionState_reset_to_base_pose");
RNA_def_function_ui_description(func, "Force resetting of position and rotation deltas");
RNA_def_function_flag(func, FUNC_NO_SELF);
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
prop = RNA_def_property(srna, "viewer_pose_location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_array(prop, 3);
RNA_def_property_float_funcs(prop, "rna_XrSessionState_viewer_pose_location_get", NULL, NULL);

View File

@ -872,6 +872,7 @@ void WM_generic_user_data_free(struct wmGenericUserData *user_data);
bool WM_xr_session_exists(const wmXrData *xr);
bool WM_xr_session_is_ready(const wmXrData *xr);
struct wmXrSessionState *WM_xr_session_state_handle_get(const wmXrData *xr);
void WM_xr_session_base_pose_reset(wmXrData *xr);
bool WM_xr_session_state_viewer_pose_location_get(const wmXrData *xr, float r_location[3]);
bool WM_xr_session_state_viewer_pose_rotation_get(const wmXrData *xr, float r_rotation[4]);
bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,

View File

@ -34,11 +34,16 @@ typedef struct wmXrSessionState {
float viewer_viewmat[4][4];
float focal_len;
/** Copy of XrSessionSettings.base_pose_ data to detect changes that need
* resetting to base pose. */
char prev_base_pose_type; /* eXRSessionBasePoseType */
Object *prev_base_pose_object;
/** Copy of XrSessionSettings.flag created on the last draw call, stored to detect changes. */
int prev_settings_flag;
/** Copy of wmXrDrawData.eye_position_ofs. */
float prev_eye_position_ofs[3];
bool force_reset_to_base_pose;
bool is_view_data_set;
} wmXrSessionState;

View File

@ -95,6 +95,11 @@ bool WM_xr_session_exists(const wmXrData *xr)
return xr->runtime && xr->runtime->context && xr->runtime->session_state.is_started;
}
void WM_xr_session_base_pose_reset(wmXrData *xr)
{
xr->runtime->session_state.force_reset_to_base_pose = true;
}
/**
* Check if the session is running, according to the OpenXR definition.
*/
@ -154,6 +159,17 @@ static void wm_xr_session_draw_data_populate(wmXrData *xr_data,
wm_xr_session_base_pose_calc(r_draw_data->scene, settings, &r_draw_data->base_pose);
}
static bool wm_xr_session_draw_data_needs_reset_to_base_pose(const wmXrSessionState *state,
const XrSessionSettings *settings)
{
if (state->force_reset_to_base_pose) {
return true;
}
return ((settings->flag & XR_SESSION_USE_POSITION_TRACKING) == 0) &&
((state->prev_base_pose_type != settings->base_pose_type) ||
(state->prev_base_pose_object != settings->base_pose_object));
}
void wm_xr_session_draw_data_update(const wmXrSessionState *state,
const XrSessionSettings *settings,
const GHOST_XrDrawViewInfo *draw_view,
@ -166,7 +182,8 @@ void wm_xr_session_draw_data_update(const wmXrSessionState *state,
/* Set the eye position offset, it's used to offset the base pose when changing positional
* tracking. */
if (!state->is_view_data_set) {
if (!state->is_view_data_set ||
wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) {
/* Always use the exact base pose with no offset when starting the session. */
copy_v3_fl(draw_data->eye_position_ofs, 0.0f);
}
@ -223,6 +240,8 @@ void wm_xr_session_state_update(const XrSessionSettings *settings,
copy_v3_v3(state->prev_eye_position_ofs, draw_data->eye_position_ofs);
state->prev_settings_flag = settings->flag;
state->prev_base_pose_type = settings->base_pose_type;
state->prev_base_pose_object = settings->base_pose_object;
state->is_view_data_set = true;
}