XR: Customizable Actions

https://developer.blender.org/D13420
This commit is contained in:
Peter Kim 2022-02-20 15:00:10 +09:00
parent 1f79132287
commit 517dc644f1
12 changed files with 271 additions and 234 deletions

View File

@ -2365,6 +2365,7 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C);
void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C);
void uiTemplateInputStatus(uiLayout *layout, struct bContext *C);
void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplateXrActionmapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
bool uiTemplateEventFromKeymapItem(struct uiLayout *layout,
const char *text,

View File

@ -102,5 +102,8 @@ if(WIN32 OR APPLE)
endif()
endif()
if(WITH_XR_OPENXR)
add_definitions(-DWITH_XR_OPENXR)
endif()
blender_add_lib(bf_editor_interface "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@ -6151,6 +6151,44 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
/** \} */
/* -------------------------------------------------------------------- */
/** \name XR Actionmap Template
* \{ */
#ifdef WITH_XR_OPENXR
static void xr_actionmap_item_modified(bContext *UNUSED(C),
void *UNUSED(ami_p),
void *UNUSED(unused))
{
}
#endif
void uiTemplateXrActionmapItemProperties(uiLayout *layout, PointerRNA *ptr)
{
#ifdef WITH_XR_OPENXR
PointerRNA propptr = RNA_pointer_get(ptr, "op_properties");
if (propptr.data) {
uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
WM_operator_properties_sanitize(&propptr, false);
/* Use same template as keymap item properties. */
template_keymap_item_properties(layout, NULL, &propptr);
for (; but; but = but->next) {
if (but->rnaprop) {
UI_but_func_set(but, xr_actionmap_item_modified, ptr->data, NULL);
UI_but_flag_enable(but, UI_BUT_UPDATE_DELAY);
}
}
}
#else
UNUSED_VARS(layout, ptr);
#endif
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Event Icon Template
* \{ */

View File

@ -36,6 +36,11 @@ typedef struct XrSessionSettings {
float clip_start, clip_end;
int flag;
ListBase actionmaps; /* XrActionMap */
short actactionmap;
short selactionmap;
char _pad3[4];
} XrSessionSettings;
typedef enum eXrSessionFlag {
@ -137,7 +142,8 @@ typedef struct XrActionMapBinding {
/** Input threshold/region. */
float float_threshold;
short axis_flag; /* eXrAxisFlag */
char _pad[2];
short sel_component_path;
/** Pose action properties. */
float pose_location[3];
@ -183,8 +189,8 @@ typedef struct XrActionMapItem {
float haptic_frequency;
float haptic_amplitude;
short selbinding;
char _pad3[2];
short sel_user_path;
short sel_binding;
ListBase bindings; /* XrActionMapBinding */
} XrActionMapItem;
@ -197,7 +203,7 @@ typedef struct XrActionMap {
char name[64]; /* MAX_NAME */
ListBase items; /* XrActionMapItem */
short selitem;
short sel_item;
char _pad[6];
} XrActionMap;

View File

@ -1789,6 +1789,11 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_pointer(func, "item", "KeyMapItem", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
func = RNA_def_function(
srna, "template_xr_actionmap_item_properties", "uiTemplateXrActionmapItemProperties");
parm = RNA_def_pointer(func, "item", "XrActionMapItem", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
func = RNA_def_function(srna, "template_component_menu", "uiTemplateComponentMenu");
RNA_def_function_ui_description(func, "Item. Display expanded property in a popup menu");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");

View File

@ -66,6 +66,12 @@ static void rna_XrComponentPath_remove(XrActionMapBinding *amb, PointerRNA *comp
int idx = BLI_findindex(&amb->component_paths, component_path);
if (idx != -1) {
BLI_freelinkN(&amb->component_paths, component_path);
if (idx <= amb->sel_component_path) {
if (--amb->sel_component_path < 0) {
amb->sel_component_path = 0;
}
}
}
RNA_POINTER_INVALIDATE(component_path_ptr);
# else
@ -216,12 +222,11 @@ static void rna_XrActionMapBinding_name_update(Main *bmain, Scene *UNUSED(scene)
{
# ifdef WITH_XR_OPENXR
wmWindowManager *wm = bmain->wm.first;
if (wm && wm->xr.runtime) {
ListBase *actionmaps = WM_xr_actionmaps_get(wm->xr.runtime);
short idx = WM_xr_actionmap_selected_index_get(wm->xr.runtime);
XrActionMap *actionmap = BLI_findlink(actionmaps, idx);
if (wm) {
XrActionMap *actionmap = BLI_findlink(&wm->xr.session_settings.actionmaps,
wm->xr.session_settings.selactionmap);
if (actionmap) {
XrActionMapItem *ami = BLI_findlink(&actionmap->items, actionmap->selitem);
XrActionMapItem *ami = BLI_findlink(&actionmap->items, actionmap->sel_item);
if (ami) {
XrActionMapBinding *amb = ptr->data;
WM_xr_actionmap_binding_ensure_unique(ami, amb);
@ -253,6 +258,12 @@ static void rna_XrUserPath_remove(XrActionMapItem *ami, PointerRNA *user_path_pt
int idx = BLI_findindex(&ami->user_paths, user_path);
if (idx != -1) {
BLI_freelinkN(&ami->user_paths, user_path);
if (idx <= ami->sel_user_path) {
if (--ami->sel_user_path < 0) {
ami->sel_user_path = 0;
}
}
}
RNA_POINTER_INVALIDATE(user_path_ptr);
# else
@ -537,10 +548,9 @@ static void rna_XrActionMapItem_name_update(Main *bmain, Scene *UNUSED(scene), P
{
# ifdef WITH_XR_OPENXR
wmWindowManager *wm = bmain->wm.first;
if (wm && wm->xr.runtime) {
ListBase *actionmaps = WM_xr_actionmaps_get(wm->xr.runtime);
short idx = WM_xr_actionmap_selected_index_get(wm->xr.runtime);
XrActionMap *actionmap = BLI_findlink(actionmaps, idx);
if (wm) {
XrActionMap *actionmap = BLI_findlink(&wm->xr.session_settings.actionmaps,
wm->xr.session_settings.selactionmap);
if (actionmap) {
XrActionMapItem *ami = ptr->data;
WM_xr_actionmap_item_ensure_unique(actionmap, ami);
@ -561,50 +571,51 @@ static void rna_XrActionMapItem_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
# endif
}
static XrActionMap *rna_XrActionMap_new(PointerRNA *ptr, const char *name, bool replace_existing)
static XrActionMap *rna_XrActionMap_new(XrSessionSettings *settings,
const char *name,
bool replace_existing)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
return WM_xr_actionmap_new(xr->runtime, name, replace_existing);
return WM_xr_actionmap_new(settings, name, replace_existing);
# else
UNUSED_VARS(ptr, name, replace_existing);
UNUSED_VARS(settings, name, replace_existing);
return NULL;
# endif
}
static XrActionMap *rna_XrActionMap_new_from_actionmap(PointerRNA *ptr, XrActionMap *am_src)
static XrActionMap *rna_XrActionMap_new_from_actionmap(XrSessionSettings *settings,
XrActionMap *am_src)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
return WM_xr_actionmap_add_copy(xr->runtime, am_src);
return WM_xr_actionmap_add_copy(settings, am_src);
# else
UNUSED_VARS(ptr, am_src);
UNUSED_VARS(settings, am_src);
return NULL;
# endif
}
static void rna_XrActionMap_remove(ReportList *reports, PointerRNA *ptr, PointerRNA *actionmap_ptr)
static void rna_XrActionMap_remove(XrSessionSettings *settings,
ReportList *reports,
PointerRNA *actionmap_ptr)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
XrActionMap *actionmap = actionmap_ptr->data;
if (WM_xr_actionmap_remove(xr->runtime, actionmap) == false) {
if (WM_xr_actionmap_remove(settings, actionmap) == false) {
BKE_reportf(reports, RPT_ERROR, "ActionMap '%s' cannot be removed", actionmap->name);
return;
}
RNA_POINTER_INVALIDATE(actionmap_ptr);
# else
UNUSED_VARS(ptr, reports, actionmap_ptr);
UNUSED_VARS(settings, reports, actionmap_ptr);
# endif
}
static XrActionMap *rna_XrActionMap_find(PointerRNA *ptr, const char *name)
static XrActionMap *rna_XrActionMap_find(XrSessionSettings *settings, const char *name)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
return WM_xr_actionmap_find(xr->runtime, name);
return WM_xr_actionmap_find(settings, name);
# else
UNUSED_VARS(ptr, name);
UNUSED_VARS(settings, name);
return NULL;
# endif
}
@ -634,9 +645,9 @@ static void rna_XrActionMap_name_update(Main *bmain, Scene *UNUSED(scene), Point
{
# ifdef WITH_XR_OPENXR
wmWindowManager *wm = bmain->wm.first;
if (wm && wm->xr.runtime) {
if (wm) {
XrActionMap *actionmap = ptr->data;
WM_xr_actionmap_ensure_unique(wm->xr.runtime, actionmap);
WM_xr_actionmap_ensure_unique(&wm->xr.session_settings, actionmap);
}
# else
UNUSED_VARS(bmain, ptr);
@ -691,6 +702,28 @@ static void rna_XrSessionSettings_use_absolute_tracking_set(PointerRNA *ptr, boo
# endif
}
static void rna_XrSessionSettings_actionmaps_begin(CollectionPropertyIterator *iter,
PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
rna_iterator_listbase_begin(iter, &xr->session_settings.actionmaps, NULL);
# else
UNUSED_VARS(iter, ptr);
# endif
}
static int rna_XrSessionSettings_actionmaps_length(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
return BLI_listbase_count(&xr->session_settings.actionmaps);
# else
UNUSED_VARS(ptr);
return 0;
# endif
}
/** \} */
/* -------------------------------------------------------------------- */
@ -1062,71 +1095,6 @@ static void rna_XrSessionState_nav_scale_set(PointerRNA *ptr, float value)
# endif
}
static void rna_XrSessionState_actionmaps_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
ListBase *lb = WM_xr_actionmaps_get(xr->runtime);
rna_iterator_listbase_begin(iter, lb, NULL);
# else
UNUSED_VARS(iter, ptr);
# endif
}
static int rna_XrSessionState_actionmaps_length(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
ListBase *lb = WM_xr_actionmaps_get(xr->runtime);
return BLI_listbase_count(lb);
# else
UNUSED_VARS(ptr);
return 0;
# endif
}
static int rna_XrSessionState_active_actionmap_get(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
const wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
return WM_xr_actionmap_active_index_get(xr->runtime);
# else
UNUSED_VARS(ptr);
return -1;
# endif
}
static void rna_XrSessionState_active_actionmap_set(PointerRNA *ptr, int value)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
WM_xr_actionmap_active_index_set(xr->runtime, (short)value);
# else
UNUSED_VARS(ptr, value);
# endif
}
static int rna_XrSessionState_selected_actionmap_get(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
const wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
return WM_xr_actionmap_selected_index_get(xr->runtime);
# else
UNUSED_VARS(ptr);
return -1;
# endif
}
static void rna_XrSessionState_selected_actionmap_set(PointerRNA *ptr, int value)
{
# ifdef WITH_XR_OPENXR
wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
WM_xr_actionmap_selected_index_set(xr->runtime, (short)value);
# else
UNUSED_VARS(ptr, value);
# endif
}
/** \} */
/* -------------------------------------------------------------------- */
@ -1537,12 +1505,10 @@ static void rna_def_xr_actionmaps(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_srna(cprop, "XrActionMaps");
srna = RNA_def_struct(brna, "XrActionMaps", NULL);
RNA_def_struct_sdna(srna, "XrSessionSettings");
RNA_def_struct_ui_text(srna, "XR Action Maps", "Collection of XR action maps");
func = RNA_def_function(srna, "new", "rna_XrActionMap_new");
RNA_def_function_flag(func, FUNC_NO_SELF);
parm = RNA_def_pointer(func, "xr_session_state", "XrSessionState", "XR Session State", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_boolean(func,
@ -1555,9 +1521,6 @@ static void rna_def_xr_actionmaps(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "new_from_actionmap", "rna_XrActionMap_new_from_actionmap");
RNA_def_function_flag(func, FUNC_NO_SELF);
parm = RNA_def_pointer(func, "xr_session_state", "XrSessionState", "XR Session State", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_pointer(
func, "actionmap", "XrActionMap", "Action Map", "Action map to use as a reference");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
@ -1565,17 +1528,12 @@ static void rna_def_xr_actionmaps(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_XrActionMap_remove");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "xr_session_state", "XrSessionState", "XR Session State", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "actionmap", "XrActionMap", "Action Map", "Removed action map");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "find", "rna_XrActionMap_find");
RNA_def_function_flag(func, FUNC_NO_SELF);
parm = RNA_def_pointer(func, "xr_session_state", "XrSessionState", "XR Session State", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(
@ -1617,7 +1575,7 @@ static void rna_def_xr_actionmap(BlenderRNA *brna)
rna_def_xr_actionmap_items(brna, prop);
prop = RNA_def_property(srna, "selected_item", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "selitem");
RNA_def_property_int_sdna(prop, NULL, "sel_item");
RNA_def_property_ui_text(prop, "Selected Item", "");
/* XrUserPath */
@ -1658,6 +1616,10 @@ static void rna_def_xr_actionmap(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "User Paths", "OpenXR user paths");
rna_def_xr_user_paths(brna, prop);
prop = RNA_def_property(srna, "selected_user_path", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sel_user_path");
RNA_def_property_ui_text(prop, "Selected User Path", "Currently selected user path");
prop = RNA_def_property(srna, "op", PROP_STRING, PROP_NONE);
RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME);
RNA_def_property_ui_text(prop, "Operator", "Identifier of operator to call on action event");
@ -1755,7 +1717,7 @@ static void rna_def_xr_actionmap(BlenderRNA *brna)
rna_def_xr_actionmap_bindings(brna, prop);
prop = RNA_def_property(srna, "selected_binding", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "selbinding");
RNA_def_property_int_sdna(prop, NULL, "sel_binding");
RNA_def_property_ui_text(prop, "Selected Binding", "Currently selected binding");
/* XrComponentPath */
@ -1795,6 +1757,10 @@ static void rna_def_xr_actionmap(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Component Paths", "OpenXR component paths");
rna_def_xr_component_paths(brna, prop);
prop = RNA_def_property(srna, "selected_component_path", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sel_component_path");
RNA_def_property_ui_text(prop, "Selected Component Path", "Currently selected component path");
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "float_threshold");
RNA_def_property_range(prop, 0.0, 1.0);
@ -1982,6 +1948,28 @@ static void rna_def_xr_session_settings(BlenderRNA *brna)
"Absolute Tracking",
"Allow the VR tracking origin to be defined independently of the headset location");
RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
prop = RNA_def_property(srna, "actionmaps", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop,
"rna_XrSessionSettings_actionmaps_begin",
"rna_iterator_listbase_next",
"rna_iterator_listbase_end",
"rna_iterator_listbase_get",
"rna_XrSessionSettings_actionmaps_length",
NULL,
NULL,
NULL);
RNA_def_property_struct_type(prop, "XrActionMap");
RNA_def_property_ui_text(prop, "XR Action Maps", "");
rna_def_xr_actionmaps(brna, prop);
prop = RNA_def_property(srna, "active_actionmap", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "actactionmap");
RNA_def_property_ui_text(prop, "Active Action Map", "");
prop = RNA_def_property(srna, "selected_actionmap", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "selactionmap");
RNA_def_property_ui_text(prop, "Selected Action Map", "");
}
/** \} */
@ -2312,34 +2300,6 @@ static void rna_def_xr_session_state(BlenderRNA *brna)
prop,
"Navigation Scale",
"Additional scale multiplier to apply to base scale when determining viewer scale");
prop = RNA_def_property(srna, "actionmaps", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "XrActionMap");
RNA_def_property_collection_funcs(prop,
"rna_XrSessionState_actionmaps_begin",
"rna_iterator_listbase_next",
"rna_iterator_listbase_end",
"rna_iterator_listbase_get",
"rna_XrSessionState_actionmaps_length",
NULL,
NULL,
NULL);
RNA_def_property_ui_text(prop, "XR Action Maps", "");
rna_def_xr_actionmaps(brna, prop);
prop = RNA_def_property(srna, "active_actionmap", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop,
"rna_XrSessionState_active_actionmap_get",
"rna_XrSessionState_active_actionmap_set",
NULL);
RNA_def_property_ui_text(prop, "Active Action Map", "");
prop = RNA_def_property(srna, "selected_actionmap", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop,
"rna_XrSessionState_selected_actionmap_get",
"rna_XrSessionState_selected_actionmap_set",
NULL);
RNA_def_property_ui_text(prop, "Selected Action Map", "");
}
/** \} */

View File

@ -1642,23 +1642,17 @@ void WM_xr_haptic_action_stop(wmXrData *xr,
/* wm_xr_actionmap.c */
XrActionMap *WM_xr_actionmap_new(struct wmXrRuntimeData *runtime,
XrActionMap *WM_xr_actionmap_new(XrSessionSettings *settings,
const char *name,
bool replace_existing);
/**
* Ensure unique name among all action maps.
*/
void WM_xr_actionmap_ensure_unique(struct wmXrRuntimeData *runtime, XrActionMap *actionmap);
XrActionMap *WM_xr_actionmap_add_copy(struct wmXrRuntimeData *runtime, XrActionMap *am_src);
bool WM_xr_actionmap_remove(struct wmXrRuntimeData *runtime, XrActionMap *actionmap);
XrActionMap *WM_xr_actionmap_find(struct wmXrRuntimeData *runtime, const char *name);
void WM_xr_actionmap_clear(XrActionMap *actionmap);
void WM_xr_actionmaps_clear(struct wmXrRuntimeData *runtime);
ListBase *WM_xr_actionmaps_get(struct wmXrRuntimeData *runtime);
short WM_xr_actionmap_active_index_get(const struct wmXrRuntimeData *runtime);
void WM_xr_actionmap_active_index_set(struct wmXrRuntimeData *runtime, short idx);
short WM_xr_actionmap_selected_index_get(const struct wmXrRuntimeData *runtime);
void WM_xr_actionmap_selected_index_set(struct wmXrRuntimeData *runtime, short idx);
void WM_xr_actionmap_ensure_unique(XrSessionSettings *settings, XrActionMap *actionmap);
XrActionMap *WM_xr_actionmap_add_copy(XrSessionSettings *settings, XrActionMap *am_src);
bool WM_xr_actionmap_remove(XrSessionSettings *settings, XrActionMap *actionmap);
XrActionMap *WM_xr_actionmap_find(XrSessionSettings *settings, const char *name);
void WM_xr_actionmaps_free(XrSessionSettings *settings);
XrActionMapItem *WM_xr_actionmap_item_new(XrActionMap *actionmap,
const char *name,

View File

@ -95,6 +95,29 @@ static void window_manager_foreach_id(ID *id, LibraryForeachIDData *data)
static void write_wm_xr_data(BlendWriter *writer, wmXrData *xr_data)
{
BKE_screen_view3d_shading_blend_write(writer, &xr_data->session_settings.shading);
LISTBASE_FOREACH (XrActionMap *, am, &xr_data->session_settings.actionmaps) {
BLO_write_struct(writer, XrActionMap, am);
LISTBASE_FOREACH (XrActionMapItem *, ami, &am->items) {
BLO_write_struct(writer, XrActionMapItem, ami);
if (ami->op[0] && ami->op_properties) {
IDP_BlendWrite(writer, ami->op_properties);
}
LISTBASE_FOREACH (XrUserPath *, user_path, &ami->user_paths) {
BLO_write_struct(writer, XrUserPath, user_path);
}
LISTBASE_FOREACH (XrActionMapBinding *, amb, &ami->bindings) {
BLO_write_struct(writer, XrActionMapBinding, amb);
LISTBASE_FOREACH (XrComponentPath *, component_path, &amb->component_paths) {
BLO_write_struct(writer, XrComponentPath, component_path);
}
}
}
}
}
static void window_manager_blend_write(BlendWriter *writer, ID *id, const void *id_address)
@ -123,6 +146,34 @@ static void window_manager_blend_write(BlendWriter *writer, ID *id, const void *
static void direct_link_wm_xr_data(BlendDataReader *reader, wmXrData *xr_data)
{
BKE_screen_view3d_shading_blend_read_data(reader, &xr_data->session_settings.shading);
BLO_read_list(reader, &xr_data->session_settings.actionmaps);
LISTBASE_FOREACH (XrActionMap *, am, &xr_data->session_settings.actionmaps) {
BLO_read_list(reader, &am->items);
LISTBASE_FOREACH (XrActionMapItem *, ami, &am->items) {
if (ami->op[0] && ami->op_properties) {
BLO_read_data_address(reader, &ami->op_properties);
IDP_BlendDataRead(reader, &ami->op_properties);
ami->op_properties_ptr = MEM_callocN(sizeof(PointerRNA), "wmOpItemPtr");
WM_operator_properties_create(ami->op_properties_ptr, ami->op);
ami->op_properties_ptr->data = ami->op_properties;
}
else {
ami->op_properties = NULL;
ami->op_properties_ptr = NULL;
}
BLO_read_list(reader, &ami->user_paths);
BLO_read_list(reader, &ami->bindings);
LISTBASE_FOREACH (XrActionMapBinding *, amb, &ami->bindings) {
BLO_read_list(reader, &amb->component_paths);
}
}
}
}
static void window_manager_blend_read_data(BlendDataReader *reader, ID *id)

View File

@ -201,6 +201,11 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist)
WM_msgbus_destroy(wm->message_bus);
wm->message_bus = NULL;
}
#ifdef WITH_XR_OPENXR
/* Free XR action maps. */
WM_xr_actionmaps_free(&wm->xr.session_settings);
#endif
}
BLI_listbase_clear(&G_MAIN->wm);

View File

@ -117,6 +117,7 @@ void wm_xr_exit(wmWindowManager *wm)
IDP_FreeProperty(wm->xr.session_settings.shading.prop);
wm->xr.session_settings.shading.prop = NULL;
}
WM_xr_actionmaps_free(&wm->xr.session_settings);
}
bool wm_xr_events_handle(wmWindowManager *wm)
@ -168,7 +169,6 @@ void wm_xr_runtime_data_free(wmXrRuntimeData **runtime)
(*runtime)->area = NULL;
}
wm_xr_session_data_free(&(*runtime)->session_state);
WM_xr_actionmaps_clear(*runtime);
GHOST_XrContextDestroy(context);
}

View File

@ -127,6 +127,7 @@ XrActionMapBinding *WM_xr_actionmap_binding_add_copy(XrActionMapItem *ami,
static void wm_xr_actionmap_binding_clear(XrActionMapBinding *amb)
{
BLI_freelistN(&amb->component_paths);
amb->sel_component_path = 0;
}
bool WM_xr_actionmap_binding_remove(XrActionMapItem *ami, XrActionMapBinding *amb)
@ -137,9 +138,9 @@ bool WM_xr_actionmap_binding_remove(XrActionMapItem *ami, XrActionMapBinding *am
wm_xr_actionmap_binding_clear(amb);
BLI_freelinkN(&ami->bindings, amb);
if (idx <= ami->selbinding) {
if (--ami->selbinding < 0) {
ami->selbinding = 0;
if (idx <= ami->sel_binding) {
if (--ami->sel_binding < 0) {
ami->sel_binding = 0;
}
}
@ -192,11 +193,12 @@ static void wm_xr_actionmap_item_clear(XrActionMapItem *ami)
wm_xr_actionmap_binding_clear(amb);
}
BLI_freelistN(&ami->bindings);
ami->selbinding = 0;
wm_xr_actionmap_item_properties_free(ami);
ami->sel_binding = 0;
BLI_freelistN(&ami->user_paths);
ami->sel_user_path = 0;
wm_xr_actionmap_item_properties_free(ami);
}
void WM_xr_actionmap_item_properties_update_ot(XrActionMapItem *ami)
@ -313,6 +315,12 @@ static XrActionMapItem *wm_xr_actionmap_item_copy(XrActionMapItem *ami_src)
BLI_addtail(&ami_dst->bindings, amb_new);
}
BLI_listbase_clear(&ami_dst->user_paths);
LISTBASE_FOREACH (XrUserPath *, path, &ami_src->user_paths) {
XrUserPath *path_new = MEM_dupallocN(path);
BLI_addtail(&ami_dst->user_paths, path_new);
}
if (ami_dst->op_properties) {
ami_dst->op_properties_ptr = MEM_callocN(sizeof(PointerRNA), "wmOpItemPtr");
WM_operator_properties_create(ami_dst->op_properties_ptr, ami_dst->op);
@ -324,12 +332,6 @@ static XrActionMapItem *wm_xr_actionmap_item_copy(XrActionMapItem *ami_src)
ami_dst->op_properties_ptr = NULL;
}
BLI_listbase_clear(&ami_dst->user_paths);
LISTBASE_FOREACH (XrUserPath *, path, &ami_src->user_paths) {
XrUserPath *path_new = MEM_dupallocN(path);
BLI_addtail(&ami_dst->user_paths, path_new);
}
return ami_dst;
}
@ -352,9 +354,9 @@ bool WM_xr_actionmap_item_remove(XrActionMap *actionmap, XrActionMapItem *ami)
wm_xr_actionmap_item_clear(ami);
BLI_freelinkN(&actionmap->items, ami);
if (idx <= actionmap->selitem) {
if (--actionmap->selitem < 0) {
actionmap->selitem = 0;
if (idx <= actionmap->sel_item) {
if (--actionmap->sel_item < 0) {
actionmap->sel_item = 0;
}
}
@ -382,39 +384,49 @@ XrActionMapItem *WM_xr_actionmap_item_find(XrActionMap *actionmap, const char *n
* List of XR action map items.
* \{ */
XrActionMap *WM_xr_actionmap_new(wmXrRuntimeData *runtime, const char *name, bool replace_existing)
static void wm_xr_actionmap_clear(XrActionMap *actionmap)
{
XrActionMap *am_prev = WM_xr_actionmap_find(runtime, name);
LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
wm_xr_actionmap_item_clear(ami);
}
BLI_freelistN(&actionmap->items);
actionmap->sel_item = 0;
}
XrActionMap *WM_xr_actionmap_new(XrSessionSettings *settings,
const char *name,
bool replace_existing)
{
XrActionMap *am_prev = WM_xr_actionmap_find(settings, name);
if (am_prev && replace_existing) {
WM_xr_actionmap_clear(am_prev);
wm_xr_actionmap_clear(am_prev);
return am_prev;
}
XrActionMap *am = MEM_callocN(sizeof(struct XrActionMap), __func__);
BLI_strncpy(am->name, name, MAX_NAME);
if (am_prev) {
WM_xr_actionmap_ensure_unique(runtime, am);
WM_xr_actionmap_ensure_unique(settings, am);
}
BLI_addtail(&runtime->actionmaps, am);
BLI_addtail(&settings->actionmaps, am);
return am;
}
static XrActionMap *wm_xr_actionmap_find_except(wmXrRuntimeData *runtime,
static XrActionMap *wm_xr_actionmap_find_except(XrSessionSettings *settings,
const char *name,
const XrActionMap *am_except)
{
LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
LISTBASE_FOREACH (XrActionMap *, am, &settings->actionmaps) {
if (STREQLEN(name, am->name, MAX_NAME) && (am != am_except)) {
return am;
}
}
return NULL;
}
void WM_xr_actionmap_ensure_unique(wmXrRuntimeData *runtime, XrActionMap *actionmap)
void WM_xr_actionmap_ensure_unique(XrSessionSettings *settings, XrActionMap *actionmap)
{
char name[MAX_NAME];
char *suffix;
@ -425,7 +437,7 @@ void WM_xr_actionmap_ensure_unique(wmXrRuntimeData *runtime, XrActionMap *action
baselen = BLI_strnlen(name, MAX_NAME);
suffix = &name[baselen];
while (wm_xr_actionmap_find_except(runtime, name, actionmap)) {
while (wm_xr_actionmap_find_except(settings, name, actionmap)) {
if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
/* Use default base name. */
BLI_strncpy(name, WM_XR_ACTIONMAP_STR_DEFAULT, MAX_NAME);
@ -455,33 +467,33 @@ static XrActionMap *wm_xr_actionmap_copy(XrActionMap *am_src)
return am_dst;
}
XrActionMap *WM_xr_actionmap_add_copy(wmXrRuntimeData *runtime, XrActionMap *am_src)
XrActionMap *WM_xr_actionmap_add_copy(XrSessionSettings *settings, XrActionMap *am_src)
{
XrActionMap *am_dst = wm_xr_actionmap_copy(am_src);
WM_xr_actionmap_ensure_unique(runtime, am_dst);
WM_xr_actionmap_ensure_unique(settings, am_dst);
BLI_addtail(&runtime->actionmaps, am_dst);
BLI_addtail(&settings->actionmaps, am_dst);
return am_dst;
}
bool WM_xr_actionmap_remove(wmXrRuntimeData *runtime, XrActionMap *actionmap)
bool WM_xr_actionmap_remove(XrSessionSettings *settings, XrActionMap *actionmap)
{
int idx = BLI_findindex(&runtime->actionmaps, actionmap);
int idx = BLI_findindex(&settings->actionmaps, actionmap);
if (idx != -1) {
WM_xr_actionmap_clear(actionmap);
BLI_freelinkN(&runtime->actionmaps, actionmap);
wm_xr_actionmap_clear(actionmap);
BLI_freelinkN(&settings->actionmaps, actionmap);
if (idx <= runtime->actactionmap) {
if (--runtime->actactionmap < 0) {
runtime->actactionmap = 0;
if (idx <= settings->actactionmap) {
if (--settings->actactionmap < 0) {
settings->actactionmap = 0;
}
}
if (idx <= runtime->selactionmap) {
if (--runtime->selactionmap < 0) {
runtime->selactionmap = 0;
if (idx <= settings->selactionmap) {
if (--settings->selactionmap < 0) {
settings->selactionmap = 0;
}
}
@ -491,9 +503,9 @@ bool WM_xr_actionmap_remove(wmXrRuntimeData *runtime, XrActionMap *actionmap)
return false;
}
XrActionMap *WM_xr_actionmap_find(wmXrRuntimeData *runtime, const char *name)
XrActionMap *WM_xr_actionmap_find(XrSessionSettings *settings, const char *name)
{
LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
LISTBASE_FOREACH (XrActionMap *, am, &settings->actionmaps) {
if (STREQLEN(name, am->name, MAX_NAME)) {
return am;
}
@ -501,47 +513,13 @@ XrActionMap *WM_xr_actionmap_find(wmXrRuntimeData *runtime, const char *name)
return NULL;
}
void WM_xr_actionmap_clear(XrActionMap *actionmap)
void WM_xr_actionmaps_free(XrSessionSettings *settings)
{
LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
wm_xr_actionmap_item_clear(ami);
LISTBASE_FOREACH (XrActionMap *, am, &settings->actionmaps) {
wm_xr_actionmap_clear(am);
}
BLI_freelistN(&actionmap->items);
actionmap->selitem = 0;
}
void WM_xr_actionmaps_clear(wmXrRuntimeData *runtime)
{
LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
WM_xr_actionmap_clear(am);
}
BLI_freelistN(&runtime->actionmaps);
runtime->actactionmap = runtime->selactionmap = 0;
}
ListBase *WM_xr_actionmaps_get(wmXrRuntimeData *runtime)
{
return &runtime->actionmaps;
}
short WM_xr_actionmap_active_index_get(const wmXrRuntimeData *runtime)
{
return runtime->actactionmap;
}
void WM_xr_actionmap_active_index_set(wmXrRuntimeData *runtime, short idx)
{
runtime->actactionmap = idx;
}
short WM_xr_actionmap_selected_index_get(const wmXrRuntimeData *runtime)
{
return runtime->selactionmap;
}
void WM_xr_actionmap_selected_index_set(wmXrRuntimeData *runtime, short idx)
{
runtime->selactionmap = idx;
BLI_freelistN(&settings->actionmaps);
settings->actactionmap = settings->selactionmap = 0;
}
/** \} */

View File

@ -72,10 +72,6 @@ typedef struct wmXrRuntimeData {
/** Although this struct is internal, RNA gets a handle to this for state information queries. */
wmXrSessionState session_state;
wmXrSessionExitFn exit_fn;
ListBase actionmaps; /* #XrActionMap */
short actactionmap;
short selactionmap;
} wmXrRuntimeData;
typedef struct wmXrViewportPair {