Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/xr/intern/wm_xr_session.c')
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_session.c101
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();