Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/xr/intern/wm_xr_session.c
| Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | static void wm_xr_session_create_cb(void) | ||||
| wmXrData *xr_data = &wm->xr; | wmXrData *xr_data = &wm->xr; | ||||
| /* Get action set data from Python. */ | /* Get action set data from Python. */ | ||||
| BKE_callback_exec_null(bmain, BKE_CB_EVT_XR_SESSION_START_PRE); | BKE_callback_exec_null(bmain, BKE_CB_EVT_XR_SESSION_START_PRE); | ||||
| wm_xr_session_actions_init(xr_data); | wm_xr_session_actions_init(xr_data); | ||||
| } | } | ||||
| static void wm_xr_session_controller_data_free(wmXrSessionState *state) | |||||
| { | |||||
| BLI_freelistN(&state->controllers); | |||||
| } | |||||
| static void wm_xr_session_data_free(wmXrSessionState *state) | |||||
| { | |||||
| wm_xr_session_controller_data_free(state); | |||||
| } | |||||
| static void wm_xr_session_exit_cb(void *customdata) | static void wm_xr_session_exit_cb(void *customdata) | ||||
| { | { | ||||
| wmXrData *xr_data = customdata; | wmXrData *xr_data = customdata; | ||||
| xr_data->runtime->session_state.is_started = false; | xr_data->runtime->session_state.is_started = false; | ||||
| if (xr_data->runtime->exit_fn) { | if (xr_data->runtime->exit_fn) { | ||||
| xr_data->runtime->exit_fn(xr_data); | xr_data->runtime->exit_fn(xr_data); | ||||
| } | } | ||||
| /* Free the entire runtime data (including session state and context), to play safe. */ | /* Free the entire runtime data (including session state and context), to play safe. */ | ||||
| wm_xr_session_data_free(&xr_data->runtime->session_state); | |||||
| wm_xr_runtime_data_free(&xr_data->runtime); | wm_xr_runtime_data_free(&xr_data->runtime); | ||||
| } | } | ||||
| static void wm_xr_session_begin_info_create(wmXrData *xr_data, | static void wm_xr_session_begin_info_create(wmXrData *xr_data, | ||||
| GHOST_XrSessionBeginInfo *r_begin_info) | GHOST_XrSessionBeginInfo *r_begin_info) | ||||
| { | { | ||||
| /* Callback for when the session is created. This is needed to create and bind OpenXR actions | /* Callback for when the session is created. This is needed to create and bind OpenXR actions | ||||
| * after the session is created but before it is started. */ | * after the session is created but before it is started. */ | ||||
| ▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Lines | void wm_xr_session_state_update(const XrSessionSettings *settings, | ||||
| if (!use_absolute_tracking) { | if (!use_absolute_tracking) { | ||||
| viewer_pose.position[0] -= draw_data->eye_position_ofs[0]; | viewer_pose.position[0] -= draw_data->eye_position_ofs[0]; | ||||
| viewer_pose.position[1] += draw_data->eye_position_ofs[2]; | viewer_pose.position[1] += draw_data->eye_position_ofs[2]; | ||||
| viewer_pose.position[2] -= draw_data->eye_position_ofs[1]; | viewer_pose.position[2] -= draw_data->eye_position_ofs[1]; | ||||
| } | } | ||||
| copy_v3_v3(state->viewer_pose.position, viewer_pose.position); | copy_v3_v3(state->viewer_pose.position, viewer_pose.position); | ||||
| copy_qt_qt(state->viewer_pose.orientation_quat, viewer_pose.orientation_quat); | copy_qt_qt(state->viewer_pose.orientation_quat, viewer_pose.orientation_quat); | ||||
| wm_xr_pose_to_viewmat(&viewer_pose, state->viewer_viewmat); | wm_xr_pose_to_imat(&viewer_pose, state->viewer_viewmat); | ||||
| /* No idea why, but multiplying by two seems to make it match the VR view more. */ | /* No idea why, but multiplying by two seems to make it match the VR view more. */ | ||||
| state->focal_len = 2.0f * | state->focal_len = 2.0f * | ||||
| fov_to_focallength(draw_view->fov.angle_right - draw_view->fov.angle_left, | fov_to_focallength(draw_view->fov.angle_right - draw_view->fov.angle_left, | ||||
| DEFAULT_SENSOR_WIDTH); | DEFAULT_SENSOR_WIDTH); | ||||
| copy_v3_v3(state->prev_eye_position_ofs, draw_data->eye_position_ofs); | copy_v3_v3(state->prev_eye_position_ofs, draw_data->eye_position_ofs); | ||||
| memcpy(&state->prev_base_pose, &draw_data->base_pose, sizeof(state->prev_base_pose)); | memcpy(&state->prev_base_pose, &draw_data->base_pose, sizeof(state->prev_base_pose)); | ||||
| memcpy(&state->prev_local_pose, &draw_view->local_pose, sizeof(state->prev_local_pose)); | memcpy(&state->prev_local_pose, &draw_view->local_pose, sizeof(state->prev_local_pose)); | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr, | ||||
| } | } | ||||
| copy_m4_m4(r_viewmat, xr->runtime->session_state.viewer_viewmat); | copy_m4_m4(r_viewmat, xr->runtime->session_state.viewer_viewmat); | ||||
| *r_focal_len = xr->runtime->session_state.focal_len; | *r_focal_len = xr->runtime->session_state.focal_len; | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool WM_xr_session_state_controller_pose_location_get(const wmXrData *xr, | bool WM_xr_session_state_controller_grip_location_get(const wmXrData *xr, | ||||
| unsigned int subaction_idx, | unsigned int subaction_idx, | ||||
| float r_location[3]) | float r_location[3]) | ||||
| { | { | ||||
| if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set || | if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set || | ||||
| subaction_idx >= ARRAY_SIZE(xr->runtime->session_state.controllers)) { | (subaction_idx >= BLI_listbase_count(&xr->runtime->session_state.controllers))) { | ||||
| zero_v3(r_location); | zero_v3(r_location); | ||||
| return false; | return false; | ||||
| } | } | ||||
| copy_v3_v3(r_location, xr->runtime->session_state.controllers[subaction_idx].pose.position); | const wmXrController *controller = BLI_findlink(&xr->runtime->session_state.controllers, | ||||
| subaction_idx); | |||||
| BLI_assert(controller); | |||||
| copy_v3_v3(r_location, controller->grip_pose.position); | |||||
| return true; | return true; | ||||
| } | } | ||||
| bool WM_xr_session_state_controller_pose_rotation_get(const wmXrData *xr, | bool WM_xr_session_state_controller_grip_rotation_get(const wmXrData *xr, | ||||
| unsigned int subaction_idx, | unsigned int subaction_idx, | ||||
| float r_rotation[4]) | float r_rotation[4]) | ||||
| { | { | ||||
| if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set || | if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set || | ||||
| subaction_idx >= ARRAY_SIZE(xr->runtime->session_state.controllers)) { | (subaction_idx >= BLI_listbase_count(&xr->runtime->session_state.controllers))) { | ||||
| unit_qt(r_rotation); | unit_qt(r_rotation); | ||||
| return false; | return false; | ||||
| } | } | ||||
| copy_v4_v4(r_rotation, | const wmXrController *controller = BLI_findlink(&xr->runtime->session_state.controllers, | ||||
| xr->runtime->session_state.controllers[subaction_idx].pose.orientation_quat); | subaction_idx); | ||||
| BLI_assert(controller); | |||||
| copy_qt_qt(r_rotation, controller->grip_pose.orientation_quat); | |||||
| return true; | |||||
| } | |||||
| bool WM_xr_session_state_controller_aim_location_get(const wmXrData *xr, | |||||
| unsigned int subaction_idx, | |||||
| float r_location[3]) | |||||
| { | |||||
| if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set || | |||||
| (subaction_idx >= BLI_listbase_count(&xr->runtime->session_state.controllers))) { | |||||
| zero_v3(r_location); | |||||
| return false; | |||||
| } | |||||
| const wmXrController *controller = BLI_findlink(&xr->runtime->session_state.controllers, | |||||
| subaction_idx); | |||||
| BLI_assert(controller); | |||||
| copy_v3_v3(r_location, controller->aim_pose.position); | |||||
| return true; | |||||
| } | |||||
| bool WM_xr_session_state_controller_aim_rotation_get(const wmXrData *xr, | |||||
| unsigned int subaction_idx, | |||||
| float r_rotation[4]) | |||||
| { | |||||
| if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set || | |||||
| (subaction_idx >= BLI_listbase_count(&xr->runtime->session_state.controllers))) { | |||||
| unit_qt(r_rotation); | |||||
| return false; | |||||
| } | |||||
| const wmXrController *controller = BLI_findlink(&xr->runtime->session_state.controllers, | |||||
| subaction_idx); | |||||
| BLI_assert(controller); | |||||
| copy_qt_qt(r_rotation, controller->aim_pose.orientation_quat); | |||||
| return true; | return true; | ||||
| } | } | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name XR-Session Actions | /** \name XR-Session Actions | ||||
| * | * | ||||
| * XR action processing and event dispatching. | * XR action processing and event dispatching. | ||||
| * | * | ||||
| * \{ */ | * \{ */ | ||||
| void wm_xr_session_actions_init(wmXrData *xr) | void wm_xr_session_actions_init(wmXrData *xr) | ||||
| { | { | ||||
| if (!xr->runtime) { | if (!xr->runtime) { | ||||
| return; | return; | ||||
| } | } | ||||
| GHOST_XrAttachActionSets(xr->runtime->context); | GHOST_XrAttachActionSets(xr->runtime->context); | ||||
| } | } | ||||
| static void wm_xr_session_controller_mats_update(const XrSessionSettings *settings, | static void wm_xr_session_controller_pose_calc(const GHOST_XrPose *raw_pose, | ||||
| const wmXrAction *controller_pose_action, | const float view_ofs[3], | ||||
| const float base_mat[4][4], | |||||
| GHOST_XrPose *r_pose, | |||||
| float r_mat[4][4]) | |||||
| { | |||||
| float m[4][4]; | |||||
| /* Calculate controller matrix in world space. */ | |||||
| wm_xr_pose_to_mat(raw_pose, m); | |||||
| /* Apply eye position and base pose offsets. */ | |||||
| sub_v3_v3(m[3], view_ofs); | |||||
| mul_m4_m4m4(r_mat, base_mat, m); | |||||
| /* Save final pose. */ | |||||
| mat4_to_loc_quat(r_pose->position, r_pose->orientation_quat, r_mat); | |||||
| } | |||||
| static void wm_xr_session_controller_data_update(const XrSessionSettings *settings, | |||||
| const wmXrAction *grip_action, | |||||
| const wmXrAction *aim_action, | |||||
| wmXrSessionState *state) | wmXrSessionState *state) | ||||
| { | { | ||||
| const unsigned int count = (unsigned int)min_ii( | BLI_assert(grip_action->count_subaction_paths == aim_action->count_subaction_paths); | ||||
| (int)controller_pose_action->count_subaction_paths, (int)ARRAY_SIZE(state->controllers)); | BLI_assert(grip_action->count_subaction_paths == BLI_listbase_count(&state->controllers)); | ||||
| float view_ofs[3]; | unsigned int subaction_idx = 0; | ||||
| float base_inv[4][4]; | float view_ofs[3], base_mat[4][4]; | ||||
| float tmp[4][4]; | |||||
| if ((settings->flag & XR_SESSION_USE_POSITION_TRACKING) == 0) { | if ((settings->flag & XR_SESSION_USE_POSITION_TRACKING) == 0) { | ||||
| copy_v3_v3(view_ofs, state->prev_local_pose.position); | copy_v3_v3(view_ofs, state->prev_local_pose.position); | ||||
| } | } | ||||
| else { | else { | ||||
| zero_v3(view_ofs); | zero_v3(view_ofs); | ||||
| } | } | ||||
| if ((settings->flag & XR_SESSION_USE_ABSOLUTE_TRACKING) == 0) { | if ((settings->flag & XR_SESSION_USE_ABSOLUTE_TRACKING) == 0) { | ||||
| add_v3_v3(view_ofs, state->prev_eye_position_ofs); | add_v3_v3(view_ofs, state->prev_eye_position_ofs); | ||||
| } | } | ||||
| wm_xr_pose_to_viewmat(&state->prev_base_pose, base_inv); | wm_xr_pose_to_mat(&state->prev_base_pose, base_mat); | ||||
| invert_m4(base_inv); | |||||
| for (unsigned int i = 0; i < count; ++i) { | LISTBASE_FOREACH_INDEX (wmXrController *, controller, &state->controllers, subaction_idx) { | ||||
| wmXrControllerData *controller = &state->controllers[i]; | wm_xr_session_controller_pose_calc(&((GHOST_XrPose *)grip_action->states)[subaction_idx], | ||||
| view_ofs, | |||||
| /* Calculate controller matrix in world space. */ | base_mat, | ||||
| wm_xr_controller_pose_to_mat(&((GHOST_XrPose *)controller_pose_action->states)[i], tmp); | &controller->grip_pose, | ||||
| controller->grip_mat); | |||||
| /* Apply eye position and base pose offsets. */ | wm_xr_session_controller_pose_calc(&((GHOST_XrPose *)aim_action->states)[subaction_idx], | ||||
| sub_v3_v3(tmp[3], view_ofs); | view_ofs, | ||||
| mul_m4_m4m4(controller->mat, base_inv, tmp); | base_mat, | ||||
| &controller->aim_pose, | |||||
| /* Save final pose. */ | controller->aim_mat); | ||||
| mat4_to_loc_quat( | |||||
| controller->pose.position, controller->pose.orientation_quat, controller->mat); | |||||
| } | } | ||||
| } | } | ||||
| void wm_xr_session_actions_update(wmXrData *xr) | void wm_xr_session_actions_update(wmXrData *xr) | ||||
| { | { | ||||
| if (!xr->runtime) { | if (!xr->runtime) { | ||||
| return; | return; | ||||
| } | } | ||||
| GHOST_XrContextHandle xr_context = xr->runtime->context; | GHOST_XrContextHandle xr_context = xr->runtime->context; | ||||
| wmXrSessionState *state = &xr->runtime->session_state; | wmXrSessionState *state = &xr->runtime->session_state; | ||||
| wmXrActionSet *active_action_set = state->active_action_set; | wmXrActionSet *active_action_set = state->active_action_set; | ||||
| int ret = GHOST_XrSyncActions(xr_context, active_action_set ? active_action_set->name : NULL); | int ret = GHOST_XrSyncActions(xr_context, active_action_set ? active_action_set->name : NULL); | ||||
| if (!ret) { | if (!ret) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Only update controller mats for active action set. */ | /* Only update controller data for active action set. */ | ||||
| if (active_action_set) { | if (active_action_set) { | ||||
| if (active_action_set->controller_pose_action) { | if (active_action_set->controller_grip_action && active_action_set->controller_aim_action) { | ||||
| wm_xr_session_controller_mats_update( | wm_xr_session_controller_data_update(&xr->session_settings, | ||||
| &xr->session_settings, active_action_set->controller_pose_action, state); | active_action_set->controller_grip_action, | ||||
| active_action_set->controller_aim_action, | |||||
| state); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void wm_xr_session_controller_data_populate(const wmXrAction *controller_pose_action, wmXrData *xr) | void wm_xr_session_controller_data_populate(const wmXrAction *grip_action, | ||||
| const wmXrAction *aim_action, | |||||
| wmXrData *xr) | |||||
| { | { | ||||
| UNUSED_VARS(aim_action); /* Only used for asserts. */ | |||||
| wmXrSessionState *state = &xr->runtime->session_state; | wmXrSessionState *state = &xr->runtime->session_state; | ||||
| ListBase *controllers = &state->controllers; | |||||
| BLI_assert(grip_action->count_subaction_paths == aim_action->count_subaction_paths); | |||||
| const unsigned int count = grip_action->count_subaction_paths; | |||||
| const unsigned int count = (unsigned int)min_ii( | wm_xr_session_controller_data_free(state); | ||||
| (int)ARRAY_SIZE(state->controllers), (int)controller_pose_action->count_subaction_paths); | |||||
| for (unsigned int i = 0; i < count; ++i) { | for (unsigned int i = 0; i < count; ++i) { | ||||
| wmXrControllerData *c = &state->controllers[i]; | wmXrController *controller = MEM_callocN(sizeof(*controller), __func__); | ||||
| strcpy(c->subaction_path, controller_pose_action->subaction_paths[i]); | |||||
| memset(&c->pose, 0, sizeof(c->pose)); | BLI_assert(STREQ(grip_action->subaction_paths[i], aim_action->subaction_paths[i])); | ||||
| zero_m4(c->mat); | strcpy(controller->subaction_path, grip_action->subaction_paths[i]); | ||||
| BLI_addtail(controllers, controller); | |||||
Severin: There are no `next` & `prev` pointers in `wmXrController`, so you can't use that in a list like… | |||||
Done Inline ActionsThanks for catching this. Added the next, prev pointers to wmXrController struct. muxed-reality: Thanks for catching this. Added the `next`, `prev` pointers to `wmXrController` struct. | |||||
| } | } | ||||
| } | } | ||||
| void wm_xr_session_controller_data_clear(wmXrSessionState *state) | void wm_xr_session_controller_data_clear(wmXrSessionState *state) | ||||
| { | { | ||||
| memset(state->controllers, 0, sizeof(state->controllers)); | wm_xr_session_controller_data_free(state); | ||||
| } | } | ||||
| /** \} */ /* XR-Session Actions */ | /** \} */ /* XR-Session Actions */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name XR-Session Surface | /** \name XR-Session Surface | ||||
| * | * | ||||
| * A wmSurface is used to manage drawing of the VR viewport. It's created and destroyed with the | * A wmSurface is used to manage drawing of the VR viewport. It's created and destroyed with the | ||||
| ▲ Show 20 Lines • Show All 156 Lines • Show Last 20 Lines | |||||
There are no next & prev pointers in wmXrController, so you can't use that in a list like this. Either add those or use LinkData.