1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup RNA
19  */
20 
21 #include "DNA_view3d_types.h"
22 #include "DNA_xr_types.h"
23 
24 #include "RNA_define.h"
25 #include "RNA_enum_types.h"
26 
27 #include "WM_types.h"
28 
29 #include "rna_internal.h"
30 
31 #ifdef RNA_RUNTIME
32 
33 #  include "BLI_math.h"
34 
35 #  include "WM_api.h"
36 
rna_XrSessionState_is_running(bContext * C)37 static bool rna_XrSessionState_is_running(bContext *C)
38 {
39 #  ifdef WITH_XR_OPENXR
40   const wmWindowManager *wm = CTX_wm_manager(C);
41   return WM_xr_session_exists(&wm->xr);
42 #  else
43   UNUSED_VARS(C);
44   return false;
45 #  endif
46 }
47 
rna_XrSessionState_reset_to_base_pose(bContext * C)48 static void rna_XrSessionState_reset_to_base_pose(bContext *C)
49 {
50 #  ifdef WITH_XR_OPENXR
51   wmWindowManager *wm = CTX_wm_manager(C);
52   WM_xr_session_base_pose_reset(&wm->xr);
53 #  else
54   UNUSED_VARS(C);
55 #  endif
56 }
57 
58 #  ifdef WITH_XR_OPENXR
rna_XrSessionState_wm_xr_data_get(PointerRNA * ptr)59 static wmXrData *rna_XrSessionState_wm_xr_data_get(PointerRNA *ptr)
60 {
61   /* Callers could also get XrSessionState pointer through ptr->data, but prefer if we just
62    * consistently pass wmXrData pointers to the WM_xr_xxx() API. */
63 
64   BLI_assert(ptr->type == &RNA_XrSessionState);
65 
66   wmWindowManager *wm = (wmWindowManager *)ptr->owner_id;
67   BLI_assert(wm && (GS(wm->id.name) == ID_WM));
68 
69   return &wm->xr;
70 }
71 #  endif
72 
rna_XrSessionState_viewer_pose_location_get(PointerRNA * ptr,float * r_values)73 static void rna_XrSessionState_viewer_pose_location_get(PointerRNA *ptr, float *r_values)
74 {
75 #  ifdef WITH_XR_OPENXR
76   const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
77   WM_xr_session_state_viewer_pose_location_get(xr, r_values);
78 #  else
79   UNUSED_VARS(ptr);
80   zero_v3(r_values);
81 #  endif
82 }
83 
rna_XrSessionState_viewer_pose_rotation_get(PointerRNA * ptr,float * r_values)84 static void rna_XrSessionState_viewer_pose_rotation_get(PointerRNA *ptr, float *r_values)
85 {
86 #  ifdef WITH_XR_OPENXR
87   const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
88   WM_xr_session_state_viewer_pose_rotation_get(xr, r_values);
89 #  else
90   UNUSED_VARS(ptr);
91   unit_qt(r_values);
92 #  endif
93 }
94 
95 #else /* RNA_RUNTIME */
96 
rna_def_xr_session_settings(BlenderRNA * brna)97 static void rna_def_xr_session_settings(BlenderRNA *brna)
98 {
99   StructRNA *srna;
100   PropertyRNA *prop;
101 
102   static const EnumPropertyItem base_pose_types[] = {
103       {XR_BASE_POSE_SCENE_CAMERA,
104        "SCENE_CAMERA",
105        0,
106        "Scene Camera",
107        "Follow the active scene camera to define the VR view's base pose"},
108       {XR_BASE_POSE_OBJECT,
109        "OBJECT",
110        0,
111        "Object",
112        "Follow the transformation of an object to define the VR view's base pose"},
113       {XR_BASE_POSE_CUSTOM,
114        "CUSTOM",
115        0,
116        "Custom",
117        "Follow a custom transformation to define the VR view's base pose"},
118       {0, NULL, 0, NULL, NULL},
119   };
120 
121   srna = RNA_def_struct(brna, "XrSessionSettings", NULL);
122   RNA_def_struct_ui_text(srna, "XR Session Settings", "");
123 
124   prop = RNA_def_property(srna, "shading", PROP_POINTER, PROP_NONE);
125   RNA_def_property_flag(prop, PROP_NEVER_NULL);
126   RNA_def_property_ui_text(prop, "Shading Settings", "");
127   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
128 
129   prop = RNA_def_property(srna, "base_pose_type", PROP_ENUM, PROP_NONE);
130   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
131   RNA_def_property_enum_items(prop, base_pose_types);
132   RNA_def_property_ui_text(
133       prop,
134       "Base Pose Type",
135       "Define where the location and rotation for the VR view come from, to which "
136       "translation and rotation deltas from the VR headset will be applied to");
137   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
138 
139   prop = RNA_def_property(srna, "base_pose_object", PROP_POINTER, PROP_NONE);
140   RNA_def_property_flag(prop, PROP_EDITABLE);
141   RNA_def_property_ui_text(prop,
142                            "Base Pose Object",
143                            "Object to take the location and rotation to which translation and "
144                            "rotation deltas from the VR headset will be applied to");
145   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
146 
147   prop = RNA_def_property(srna, "base_pose_location", PROP_FLOAT, PROP_TRANSLATION);
148   RNA_def_property_ui_text(prop,
149                            "Base Pose Location",
150                            "Coordinates to apply translation deltas from the VR headset to");
151   RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
152   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
153 
154   prop = RNA_def_property(srna, "base_pose_angle", PROP_FLOAT, PROP_AXISANGLE);
155   RNA_def_property_ui_text(
156       prop,
157       "Base Pose Angle",
158       "Rotation angle around the Z-Axis to apply the rotation deltas from the VR headset to");
159   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
160 
161   prop = RNA_def_property(srna, "show_floor", PROP_BOOLEAN, PROP_NONE);
162   RNA_def_property_boolean_sdna(prop, NULL, "draw_flags", V3D_OFSDRAW_SHOW_GRIDFLOOR);
163   RNA_def_property_ui_text(prop, "Display Grid Floor", "Show the ground plane grid");
164   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
165 
166   prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE);
167   RNA_def_property_boolean_sdna(prop, NULL, "draw_flags", V3D_OFSDRAW_SHOW_ANNOTATION);
168   RNA_def_property_ui_text(prop, "Show Annotation", "Show annotations for this view");
169   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
170 
171   prop = RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE);
172   RNA_def_property_range(prop, 1e-6f, FLT_MAX);
173   RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3);
174   RNA_def_property_ui_text(prop, "Clip Start", "VR viewport near clipping distance");
175   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
176 
177   prop = RNA_def_property(srna, "clip_end", PROP_FLOAT, PROP_DISTANCE);
178   RNA_def_property_range(prop, 1e-6f, FLT_MAX);
179   RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3);
180   RNA_def_property_ui_text(prop, "Clip End", "VR viewport far clipping distance");
181   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
182 
183   prop = RNA_def_property(srna, "use_positional_tracking", PROP_BOOLEAN, PROP_NONE);
184   RNA_def_property_boolean_sdna(prop, NULL, "flag", XR_SESSION_USE_POSITION_TRACKING);
185   RNA_def_property_ui_text(
186       prop,
187       "Positional Tracking",
188       "Allow VR headsets to affect the location in virtual space, in addition to the rotation");
189   RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
190 }
191 
rna_def_xr_session_state(BlenderRNA * brna)192 static void rna_def_xr_session_state(BlenderRNA *brna)
193 {
194   StructRNA *srna;
195   FunctionRNA *func;
196   PropertyRNA *parm, *prop;
197 
198   srna = RNA_def_struct(brna, "XrSessionState", NULL);
199   RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
200   RNA_def_struct_ui_text(srna, "Session State", "Runtime state information about the VR session");
201 
202   func = RNA_def_function(srna, "is_running", "rna_XrSessionState_is_running");
203   RNA_def_function_ui_description(func, "Query if the VR session is currently running");
204   RNA_def_function_flag(func, FUNC_NO_SELF);
205   parm = RNA_def_pointer(func, "context", "Context", "", "");
206   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
207   parm = RNA_def_boolean(func, "result", 0, "Result", "");
208   RNA_def_function_return(func, parm);
209 
210   func = RNA_def_function(srna, "reset_to_base_pose", "rna_XrSessionState_reset_to_base_pose");
211   RNA_def_function_ui_description(func, "Force resetting of position and rotation deltas");
212   RNA_def_function_flag(func, FUNC_NO_SELF);
213   parm = RNA_def_pointer(func, "context", "Context", "", "");
214   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
215 
216   prop = RNA_def_property(srna, "viewer_pose_location", PROP_FLOAT, PROP_TRANSLATION);
217   RNA_def_property_array(prop, 3);
218   RNA_def_property_float_funcs(prop, "rna_XrSessionState_viewer_pose_location_get", NULL, NULL);
219   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
220   RNA_def_property_ui_text(
221       prop,
222       "Viewer Pose Location",
223       "Last known location of the viewer pose (center between the eyes) in world space");
224 
225   prop = RNA_def_property(srna, "viewer_pose_rotation", PROP_FLOAT, PROP_QUATERNION);
226   RNA_def_property_array(prop, 4);
227   RNA_def_property_float_funcs(prop, "rna_XrSessionState_viewer_pose_rotation_get", NULL, NULL);
228   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
229   RNA_def_property_ui_text(
230       prop,
231       "Viewer Pose Rotation",
232       "Last known rotation of the viewer pose (center between the eyes) in world space");
233 }
234 
RNA_def_xr(BlenderRNA * brna)235 void RNA_def_xr(BlenderRNA *brna)
236 {
237   RNA_define_animate_sdna(false);
238 
239   rna_def_xr_session_settings(brna);
240   rna_def_xr_session_state(brna);
241 
242   RNA_define_animate_sdna(true);
243 }
244 
245 #endif /* RNA_RUNTIME */
246