diff options
Diffstat (limited to 'source/blender/windowmanager/xr/intern/wm_xr_session.c')
-rw-r--r-- | source/blender/windowmanager/xr/intern/wm_xr_session.c | 101 |
1 files changed, 69 insertions, 32 deletions
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c index e9ff38c5a92..c564f74b771 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_session.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c @@ -41,8 +41,8 @@ #include "wm_window.h" #include "wm_xr_intern.h" -wmSurface *g_xr_surface = NULL; -CLG_LogRef LOG = {"wm.xr"}; +static wmSurface *g_xr_surface = NULL; +static CLG_LogRef LOG = {"wm.xr"}; /* -------------------------------------------------------------------- */ @@ -159,6 +159,13 @@ 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); } +typedef enum wmXrSessionStateEvent { + SESSION_STATE_EVENT_NONE = 0, + SESSION_STATE_EVENT_START, + SESSION_STATE_EVENT_RESET_TO_BASE_POSE, + SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE, +} wmXrSessionStateEvent; + static bool wm_xr_session_draw_data_needs_reset_to_base_pose(const wmXrSessionState *state, const XrSessionSettings *settings) { @@ -170,36 +177,64 @@ static bool wm_xr_session_draw_data_needs_reset_to_base_pose(const wmXrSessionSt (state->prev_base_pose_object != settings->base_pose_object)); } +static wmXrSessionStateEvent wm_xr_session_state_to_event(const wmXrSessionState *state, + const XrSessionSettings *settings) +{ + if (!state->is_view_data_set) { + return SESSION_STATE_EVENT_START; + } + else if (wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) { + return SESSION_STATE_EVENT_RESET_TO_BASE_POSE; + } + else { + const bool position_tracking_toggled = ((state->prev_settings_flag & + XR_SESSION_USE_POSITION_TRACKING) != + (settings->flag & XR_SESSION_USE_POSITION_TRACKING)); + if (position_tracking_toggled) { + return SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE; + } + } + + return SESSION_STATE_EVENT_NONE; +} + void wm_xr_session_draw_data_update(const wmXrSessionState *state, const XrSessionSettings *settings, const GHOST_XrDrawViewInfo *draw_view, wmXrDrawData *draw_data) { - const bool position_tracking_toggled = ((state->prev_settings_flag & - XR_SESSION_USE_POSITION_TRACKING) != - (settings->flag & XR_SESSION_USE_POSITION_TRACKING)); - const bool use_position_tracking = settings->flag & XR_SESSION_USE_POSITION_TRACKING; + const wmXrSessionStateEvent event = wm_xr_session_state_to_event(state, settings); + const bool use_position_tracking = (settings->flag & XR_SESSION_USE_POSITION_TRACKING); - /* Set the eye position offset, it's used to offset the base pose when changing positional - * tracking. */ - 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); - } - else if (position_tracking_toggled) { - if (use_position_tracking) { + switch (event) { + case SESSION_STATE_EVENT_START: + /* Always use the exact base pose with no offset when starting the session. */ copy_v3_fl(draw_data->eye_position_ofs, 0.0f); - } - else { - /* Store the current local offset (local pose) so that we can apply that to the eyes. This - * way the eyes stay exactly where they are when disabling positional tracking. */ - copy_v3_v3(draw_data->eye_position_ofs, draw_view->local_pose.position); - } - } - else if (!use_position_tracking) { - /* Keep previous offset when positional tracking is disabled. */ - copy_v3_v3(draw_data->eye_position_ofs, state->prev_eye_position_ofs); + break; + /* This should be triggered by the VR add-on if a landmark changes. */ + case SESSION_STATE_EVENT_RESET_TO_BASE_POSE: + if (use_position_tracking) { + /* Switch exactly to base pose, so use eye offset to cancel out current position delta. */ + copy_v3_v3(draw_data->eye_position_ofs, draw_view->local_pose.position); + } + else { + copy_v3_fl(draw_data->eye_position_ofs, 0.0f); + } + break; + case SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE: + if (use_position_tracking) { + /* Keep the current position, and let the user move from there. */ + copy_v3_v3(draw_data->eye_position_ofs, state->prev_eye_position_ofs); + } + else { + /* Back to the exact base-pose position. */ + copy_v3_fl(draw_data->eye_position_ofs, 0.0f); + } + break; + case SESSION_STATE_EVENT_NONE: + /* Keep previous offset when positional tracking is disabled. */ + copy_v3_v3(draw_data->eye_position_ofs, state->prev_eye_position_ofs); + break; } } @@ -243,6 +278,8 @@ void wm_xr_session_state_update(const XrSessionSettings *settings, state->prev_base_pose_type = settings->base_pose_type; state->prev_base_pose_object = settings->base_pose_object; state->is_view_data_set = true; + /* Assume this was already done through wm_xr_session_draw_data_update(). */ + state->force_reset_to_base_pose = false; } wmXrSessionState *WM_xr_session_state_handle_get(const wmXrData *xr) @@ -299,9 +336,9 @@ bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr, /** * \brief Call Ghost-XR to draw a frame * - * Draw callback for the XR-session surface. It's expected to be called on each main loop iteration - * and tells Ghost-XR to submit a new frame by drawing its views. Note that for drawing each view, - * #wm_xr_draw_view() will be called through Ghost-XR (see GHOST_XrDrawViewFunc()). + * Draw callback for the XR-session surface. It's expected to be called on each main loop + * iteration and tells Ghost-XR to submit a new frame by drawing its views. Note that for drawing + * each view, #wm_xr_draw_view() will be called through Ghost-XR (see GHOST_XrDrawViewFunc()). */ static void wm_xr_session_surface_draw(bContext *C) { @@ -315,12 +352,9 @@ static void wm_xr_session_surface_draw(bContext *C) wm_xr_session_draw_data_populate( &wm->xr, CTX_data_scene(C), CTX_data_ensure_evaluated_depsgraph(C), &draw_data); - DRW_xr_drawing_begin(); - GHOST_XrSessionDrawViews(wm->xr.runtime->context, &draw_data); GPU_offscreen_unbind(surface_data->offscreen, false); - DRW_xr_drawing_end(); } bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data, @@ -343,7 +377,7 @@ bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data, } if (!(surface_data->offscreen = GPU_offscreen_create( - draw_view->width, draw_view->height, 0, true, false, err_out))) { + draw_view->width, draw_view->height, true, false, err_out))) { failure = true; } @@ -391,6 +425,9 @@ static wmSurface *wm_xr_session_surface_create(void) surface->draw = wm_xr_session_surface_draw; surface->free_data = wm_xr_session_surface_free_data; + surface->activate = DRW_xr_drawing_begin; + surface->deactivate = DRW_xr_drawing_end; + surface->ghost_ctx = DRW_xr_opengl_context_get(); surface->gpu_ctx = DRW_xr_gpu_context_get(); |