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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/include/ED_screen.h6
-rw-r--r--source/blender/editors/screen/area.c62
-rw-r--r--source/blender/editors/screen/screen_edit.c19
-rw-r--r--source/blender/editors/screen/screen_intern.h1
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/WM_types.h31
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c92
-rw-r--r--source/blender/windowmanager/wm_event_system.h7
-rw-r--r--source/blender/windowmanager/wm_event_types.h4
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr.c17
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_intern.h12
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_session.c35
12 files changed, 268 insertions, 19 deletions
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 60ef3e740c6..0de6907e677 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -178,6 +178,12 @@ void ED_area_update_region_sizes(struct wmWindowManager *wm,
struct wmWindow *win,
struct ScrArea *area);
bool ED_area_has_shared_border(struct ScrArea *a, struct ScrArea *b);
+ScrArea *ED_area_offscreen_create(struct wmWindowManager *wm,
+ struct wmWindow *win,
+ eSpace_Type space_type);
+void ED_area_offscreen_free(struct wmWindowManager *wm,
+ struct wmWindow *win,
+ struct ScrArea *area);
ScrArea *ED_screen_areas_iter_first(const struct wmWindow *win, const bScreen *screen);
ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 833c9accf95..d5456482d67 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -2001,6 +2001,68 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
}
}
+static void area_offscreen_init(wmWindowManager *wm, ScrArea *area)
+{
+ area->type = BKE_spacetype_from_id(area->spacetype);
+
+ if (area->type == NULL) {
+ area->spacetype = SPACE_VIEW3D;
+ area->type = BKE_spacetype_from_id(area->spacetype);
+ }
+
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ region->type = BKE_regiontype_from_id_or_first(area->type, region->regiontype);
+ }
+}
+
+ScrArea *ED_area_offscreen_create(wmWindowManager *wm, wmWindow *win, eSpace_Type space_type)
+{
+ ScrArea *area = MEM_callocN(sizeof(*area), __func__);
+ area->spacetype = space_type;
+
+ screen_area_spacelink_add(WM_window_get_active_scene(win), area, space_type);
+ area_offscreen_init(wm, area);
+
+ return area;
+}
+
+static void area_offscreen_exit(wmWindowManager *wm, wmWindow *win, ScrArea *area)
+{
+ if (area->type && area->type->exit) {
+ area->type->exit(wm, area);
+ }
+
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ if (region->type && region->type->exit) {
+ region->type->exit(wm, region);
+ }
+
+ WM_event_modal_handler_region_replace(win, region, NULL);
+ WM_draw_region_free(region, true);
+
+ MEM_SAFE_FREE(region->headerstr);
+
+ if (region->regiontimer) {
+ WM_event_remove_timer(wm, win, region->regiontimer);
+ region->regiontimer = NULL;
+ }
+
+ if (wm->message_bus) {
+ WM_msgbus_clear_by_owner(wm->message_bus, region);
+ }
+ }
+
+ WM_event_modal_handler_area_replace(win, area, NULL);
+}
+
+void ED_area_offscreen_free(wmWindowManager *wm, wmWindow *win, ScrArea *area)
+{
+ area_offscreen_exit(wm, win, area);
+
+ BKE_screen_area_free(area);
+ MEM_freeN(area);
+}
+
static void region_update_rect(ARegion *region)
{
region->winx = BLI_rcti_size_x(&region->winrct) + 1;
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 1c068fdd6e4..02b1e002d86 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -574,6 +574,17 @@ bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area)
return screen_area_join_ex(C, screen, sa2, area, true);
}
+void screen_area_spacelink_add(Scene *scene, ScrArea *area, eSpace_Type space_type)
+{
+ SpaceType *stype = BKE_spacetype_from_id(space_type);
+ SpaceLink *slink = stype->create(area, scene);
+
+ area->regionbase = slink->regionbase;
+
+ BLI_addhead(&area->spacedata, slink);
+ BLI_listbase_clear(&slink->regionbase);
+}
+
/* ****************** EXPORTED API TO OTHER MODULES *************************** */
/* screen sets cursor based on active region */
@@ -1023,13 +1034,7 @@ static void screen_global_area_refresh(wmWindow *win,
}
else {
area = screen_area_create_with_geometry(&win->global_areas, rect, space_type);
- SpaceType *stype = BKE_spacetype_from_id(space_type);
- SpaceLink *slink = stype->create(area, WM_window_get_active_scene(win));
-
- area->regionbase = slink->regionbase;
-
- BLI_addhead(&area->spacedata, slink);
- BLI_listbase_clear(&slink->regionbase);
+ screen_area_spacelink_add(WM_window_get_active_scene(win), area, space_type);
/* Data specific to global areas. */
area->global = MEM_callocN(sizeof(*area->global), __func__);
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 04ee62b1631..47229e5e2b5 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -94,6 +94,7 @@ eScreenDir area_getorientation(ScrArea *sa_a, ScrArea *sa_b);
void area_getoffsets(
ScrArea *sa_a, ScrArea *sa_b, const eScreenDir dir, int *r_offset1, int *r_offset2);
bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area);
+void screen_area_spacelink_add(struct Scene *scene, ScrArea *area, eSpace_Type space_type);
struct AZone *ED_area_actionzone_find_xy(ScrArea *area, const int xy[2]);
/* screen_geometry.c */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index ebb0f803acf..b79f5762955 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -989,6 +989,7 @@ bool WM_region_use_viewport(struct ScrArea *area, struct ARegion *region);
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);
+struct ScrArea *WM_xr_session_area_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]);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 7f52bef3203..14a69d9c435 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -120,6 +120,7 @@ struct wmWindowManager;
#include "BLI_compiler_attrs.h"
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
+#include "DNA_xr_types.h"
#include "RNA_types.h"
/* exported types for WM */
@@ -721,6 +722,36 @@ typedef struct wmXrActionState {
};
int type; /* eXrActionType */
} wmXrActionState;
+
+typedef struct wmXrActionData {
+ /** Action set name. */
+ char action_set[64];
+ /** Action name. */
+ char action[64];
+ /** Type. */
+ eXrActionType type;
+ /** State. Set appropriately based on type. */
+ float state[2];
+ /** State of the other subaction path for bimanual actions. */
+ float state_other[2];
+
+ /** Input threshold for float/vector2f actions. */
+ float float_threshold;
+
+ /** Controller aim pose corresponding to the action's subaction path. */
+ float controller_loc[3];
+ float controller_rot[4];
+ /** Controller aim pose of the other subaction path for bimanual actions. */
+ float controller_loc_other[3];
+ float controller_rot_other[4];
+
+ /** Operator. */
+ struct wmOperatorType *ot;
+ struct IDProperty *op_properties;
+
+ /** Whether bimanual interaction is occuring. */
+ bool bimanual;
+} wmXrActionData;
#endif
/** Timer flags. */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index cc0a13e96af..c92208c4818 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -3461,6 +3461,70 @@ static void wm_event_free_and_remove_from_queue_if_valid(wmEvent *event)
* Handle events for all windows, run from the #WM_main event loop.
* \{ */
+#ifdef WITH_XR_OPENXR
+/**
+ * Special handling for XR events.
+ *
+ * Although XR events are added to regular window queues, they are handled in an "offscreen area"
+ * context that is owned entirely by XR runtime data and not tied to a window.
+ */
+static void wm_event_handle_xrevent(bContext *C,
+ wmWindowManager *wm,
+ wmWindow *win,
+ wmEvent *event)
+{
+ ScrArea *area = WM_xr_session_area_get(&wm->xr);
+ if (!area) {
+ return;
+ }
+ BLI_assert(area->spacetype == SPACE_VIEW3D && area->spacedata.first);
+
+ /* Find a valid region for XR operator execution and modal handling. */
+ ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+ if (!region) {
+ return;
+ }
+ BLI_assert(WM_region_use_viewport(area, region)); /* For operators using GPU-based selection. */
+
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+
+ int action = wm_handlers_do(C, event, &win->modalhandlers);
+
+ if ((action & WM_HANDLER_BREAK) == 0) {
+ wmXrActionData *actiondata = event->customdata;
+ if (actiondata->ot->modal && event->val == KM_RELEASE) {
+ /* Don't execute modal operators on release. */
+ }
+ else {
+ PointerRNA properties = {.type = actiondata->ot->srna, .data = actiondata->op_properties};
+ if (actiondata->ot->invoke) {
+ /* Invoke operator, either executing operator or transferring responsibility to window
+ * modal handlers. */
+ wm_operator_invoke(C,
+ actiondata->ot,
+ event,
+ actiondata->op_properties ? &properties : NULL,
+ NULL,
+ false,
+ false);
+ }
+ else {
+ /* Execute operator. */
+ wmOperator *op = wm_operator_create(
+ wm, actiondata->ot, actiondata->op_properties ? &properties : NULL, NULL);
+ if ((WM_operator_call(C, op) & OPERATOR_HANDLED) == 0) {
+ WM_operator_free(op);
+ }
+ }
+ }
+ }
+
+ CTX_wm_region_set(C, NULL);
+ CTX_wm_area_set(C, NULL);
+}
+#endif /* WITH_XR_OPENXR */
+
/* Called in main loop. */
/* Goes over entire hierarchy: events -> window -> screen -> area -> region. */
void wm_event_do_handlers(bContext *C)
@@ -3558,6 +3622,16 @@ void wm_event_do_handlers(bContext *C)
CTX_wm_window_set(C, win);
+#ifdef WITH_XR_OPENXR
+ if (event->type == EVT_XR_ACTION) {
+ wm_event_handle_xrevent(C, wm, win, event);
+ BLI_remlink(&win->event_queue, event);
+ wm_event_free(event);
+ /* Skip mouse event handling below, which is unnecessary for XR events. */
+ continue;
+ }
+#endif
+
/* Clear tool-tip on mouse move. */
if (screen->tool_tip && screen->tool_tip->exit_on_event) {
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
@@ -5110,6 +5184,24 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
#endif
}
+#ifdef WITH_XR_OPENXR
+void wm_event_add_xrevent(wmWindow *win, wmXrActionData *actiondata, short val)
+{
+ BLI_assert(val == KM_PRESS || val == KM_RELEASE);
+
+ wmEvent event = {
+ .type = EVT_XR_ACTION,
+ .val = val,
+ .is_repeat = false,
+ .custom = EVT_DATA_XR,
+ .customdata = actiondata,
+ .customdatafree = 1,
+ };
+
+ wm_event_add(win, &event);
+}
+#endif /* WITH_XR_OPENXR */
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 787c840de8a..d1eb10787e2 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -33,6 +33,10 @@ struct ARegion;
struct GHOST_TabletData;
struct ScrArea;
+#ifdef WITH_XR_OPENXR
+struct wmXrActionData;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -147,6 +151,9 @@ void wm_event_free_handler(wmEventHandler *handler);
void wm_event_do_handlers(bContext *C);
void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void *customdata);
+#ifdef WITH_XR_OPENXR
+void wm_event_add_xrevent(wmWindow *win, struct wmXrActionData *actiondata, short val);
+#endif
void wm_event_do_depsgraph(bContext *C, bool is_after_open_file);
void wm_event_do_refresh_wm_and_depsgraph(bContext *C);
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 905c57d901a..c175c211db6 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -34,6 +34,7 @@ enum {
EVT_DATA_TIMER = 2,
EVT_DATA_DRAGDROP = 3,
EVT_DATA_NDOF_MOTION = 4,
+ EVT_DATA_XR = 5,
};
/* tablet active, matches GHOST_TTabletMode */
@@ -341,6 +342,9 @@ enum {
/* could become gizmo callback */
EVT_GIZMO_UPDATE = 0x5025, /* 20517 */
+
+ /* XR events: 0x503x */
+ EVT_XR_ACTION = 0x5030, /* 20528 */
/* ********** End of Blender internal events. ********** */
};
diff --git a/source/blender/windowmanager/xr/intern/wm_xr.c b/source/blender/windowmanager/xr/intern/wm_xr.c
index 8891840cb75..36bd03ed3ea 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr.c
@@ -24,19 +24,22 @@
#include "BKE_global.h"
#include "BKE_idprop.h"
+#include "BKE_main.h"
#include "BKE_report.h"
+#include "DEG_depsgraph.h"
+
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
-#include "DEG_depsgraph.h"
-
-#include "MEM_guardedalloc.h"
+#include "ED_screen.h"
#include "GHOST_C-api.h"
#include "GPU_platform.h"
+#include "MEM_guardedalloc.h"
+
#include "WM_api.h"
#include "wm_surface.h"
@@ -137,7 +140,7 @@ bool wm_xr_events_handle(wmWindowManager *wm)
/* Process OpenXR action events. */
if (WM_xr_session_is_ready(&wm->xr)) {
- wm_xr_session_actions_update(&wm->xr);
+ wm_xr_session_actions_update(wm);
}
/* wm_window_process_events() uses the return value to determine if it can put the main thread
@@ -172,6 +175,12 @@ void wm_xr_runtime_data_free(wmXrRuntimeData **runtime)
* first call, see comment above. */
(*runtime)->context = NULL;
+ if ((*runtime)->area) {
+ wmWindowManager *wm = G_MAIN->wm.first;
+ wmWindow *win = wm_xr_session_root_window_or_fallback_get(wm, (*runtime));
+ ED_area_offscreen_free(wm, win, (*runtime)->area);
+ (*runtime)->area = NULL;
+ }
wm_xr_session_data_free(&(*runtime)->session_state);
WM_xr_actionmaps_clear(*runtime);
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_intern.h b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
index fc54e261f79..ee495755ac6 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_intern.h
+++ b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
@@ -67,6 +67,9 @@ typedef struct wmXrRuntimeData {
* be an invalid reference, i.e. the window may have been closed. */
wmWindow *session_root_win;
+ /** Offscreen area used for XR events. */
+ struct ScrArea *area;
+
/** Although this struct is internal, RNA gets a handle to this for state information queries. */
wmXrSessionState session_state;
wmXrSessionExitFn exit_fn;
@@ -172,10 +175,14 @@ typedef struct wmXrActionSet {
ListBase active_haptic_actions;
} wmXrActionSet;
+/* wm_xr.c */
wmXrRuntimeData *wm_xr_runtime_data_create(void);
void wm_xr_runtime_data_free(wmXrRuntimeData **runtime);
-void wm_xr_session_data_free(wmXrSessionState *state);
+/* wm_xr_session.c */
+void wm_xr_session_data_free(wmXrSessionState *state);
+wmWindow *wm_xr_session_root_window_or_fallback_get(const wmWindowManager *wm,
+ const wmXrRuntimeData *runtime_data);
void wm_xr_session_draw_data_update(const wmXrSessionState *state,
const XrSessionSettings *settings,
const GHOST_XrDrawViewInfo *draw_view,
@@ -190,12 +197,13 @@ void *wm_xr_session_gpu_binding_context_create(void);
void wm_xr_session_gpu_binding_context_destroy(GHOST_ContextHandle context);
void wm_xr_session_actions_init(wmXrData *xr);
-void wm_xr_session_actions_update(wmXrData *xr);
+void wm_xr_session_actions_update(wmWindowManager *wm);
void wm_xr_session_controller_data_populate(const wmXrAction *grip_action,
const wmXrAction *aim_action,
wmXrData *xr);
void wm_xr_session_controller_data_clear(wmXrSessionState *state);
+/* wm_xr_draw.c */
void wm_xr_pose_to_mat(const GHOST_XrPose *pose, float r_mat[4][4]);
void wm_xr_pose_to_imat(const GHOST_XrPose *pose, float r_imat[4][4]);
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata);
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index 88bf3ff453c..1e8cda30121 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -30,9 +30,12 @@
#include "DEG_depsgraph.h"
#include "DNA_camera_types.h"
+#include "DNA_space_types.h"
#include "DRW_engine.h"
+#include "ED_screen.h"
+
#include "GHOST_C-api.h"
#include "GPU_viewport.h"
@@ -111,6 +114,7 @@ void wm_xr_session_toggle(wmWindowManager *wm,
if (WM_xr_session_exists(xr_data)) {
GHOST_XrSessionEnd(xr_data->runtime->context);
+ xr_data->runtime->session_state.is_started = false;
}
else {
GHOST_XrSessionBeginInfo begin_info;
@@ -197,8 +201,8 @@ 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 wmWindow *wm_xr_session_root_window_or_fallback_get(const wmWindowManager *wm,
- const wmXrRuntimeData *runtime_data)
+wmWindow *wm_xr_session_root_window_or_fallback_get(const wmWindowManager *wm,
+ const wmXrRuntimeData *runtime_data)
{
if (runtime_data->session_root_win &&
BLI_findindex(&wm->windows, runtime_data->session_root_win) != -1) {
@@ -373,6 +377,11 @@ wmXrSessionState *WM_xr_session_state_handle_get(const wmXrData *xr)
return xr->runtime ? &xr->runtime->session_state : NULL;
}
+ScrArea *WM_xr_session_area_get(const wmXrData *xr)
+{
+ return xr->runtime ? xr->runtime->area : NULL;
+}
+
bool WM_xr_session_state_viewer_pose_location_get(const wmXrData *xr, float r_location[3])
{
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
@@ -550,8 +559,9 @@ static void wm_xr_session_controller_data_update(const XrSessionSettings *settin
}
}
-void wm_xr_session_actions_update(wmXrData *xr)
+void wm_xr_session_actions_update(wmWindowManager *wm)
{
+ wmXrData *xr = &wm->xr;
if (!xr->runtime) {
return;
}
@@ -565,14 +575,27 @@ void wm_xr_session_actions_update(wmXrData *xr)
return;
}
- /* Only update controller data for active action set. */
+ /* Only update controller data and dispatch events for active action set. */
if (active_action_set) {
+ const XrSessionSettings *settings = &xr->session_settings;
+ wmWindow *win = wm_xr_session_root_window_or_fallback_get(wm, xr->runtime);
+
if (active_action_set->controller_grip_action && active_action_set->controller_aim_action) {
- wm_xr_session_controller_data_update(&xr->session_settings,
+ wm_xr_session_controller_data_update(settings,
active_action_set->controller_grip_action,
active_action_set->controller_aim_action,
state);
}
+
+ if (win) {
+ /* Ensure an XR area exists for events. */
+ if (!xr->runtime->area) {
+ xr->runtime->area = ED_area_offscreen_create(wm, win, SPACE_VIEW3D);
+ }
+
+ /* Implemented in D10944. */
+ // wm_xr_session_events_dispatch(xr, settings, xr_context, active_action_set, state, win);
+ }
}
}
@@ -628,7 +651,7 @@ static void wm_xr_session_surface_draw(bContext *C)
Main *bmain = CTX_data_main(C);
wmXrDrawData draw_data;
- if (!GHOST_XrSessionIsRunning(wm->xr.runtime->context)) {
+ if (!WM_xr_session_is_ready(&wm->xr)) {
return;
}