1 # SPDX-FileCopyrightText: 2021-2023 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
7 importlib
.reload(properties
)
9 from . import properties
12 from bpy
.app
.translations
import pgettext_iface
as iface_
13 from bpy
.types
import (
18 # Add space_view3d.py to module search path for VIEW3D_PT_object_type_visibility import.
20 sys
.path
.append(os
.path
.abspath(os
.path
.join(os
.path
.dirname(__file__
), '../../startup/bl_ui')))
21 from space_view3d
import VIEW3D_PT_object_type_visibility
25 class VIEW3D_PT_vr_session(Panel
):
26 bl_space_type
= 'VIEW_3D'
29 bl_label
= "VR Session"
31 def draw(self
, context
):
33 session_settings
= context
.window_manager
.xr_session_settings
36 layout
.use_property_split
= True
37 layout
.use_property_decorate
= False # No animation.
39 is_session_running
= bpy
.types
.XrSessionState
.is_running(context
)
41 # Using SNAP_FACE because it looks like a stop icon -- I shouldn't
42 # have commit rights...
43 toggle_info
= ((iface_("Start VR Session"), 'PLAY') if not is_session_running
44 else (iface_("Stop VR Session"), 'SNAP_FACE'))
45 layout
.operator("wm.xr_session_toggle", text
=toggle_info
[0],
46 translate
=False, icon
=toggle_info
[1])
50 col
= layout
.column(align
=True, heading
="Tracking")
51 col
.prop(session_settings
, "use_positional_tracking", text
="Positional")
52 col
.prop(session_settings
, "use_absolute_tracking", text
="Absolute")
54 col
= layout
.column(align
=True, heading
="Actions")
55 col
.prop(scene
, "vr_actions_enable")
59 class VIEW3D_PT_vr_session_view(Panel
):
60 bl_space_type
= 'VIEW_3D'
65 def draw(self
, context
):
67 session_settings
= context
.window_manager
.xr_session_settings
69 layout
.use_property_split
= True
70 layout
.use_property_decorate
= False # No animation.
72 col
= layout
.column(align
=True, heading
="Show")
73 col
.prop(session_settings
, "show_floor", text
="Floor")
74 col
.prop(session_settings
, "show_annotation", text
="Annotations")
76 col
.prop(session_settings
, "show_selection", text
="Selection")
77 col
.prop(session_settings
, "show_controllers", text
="Controllers")
78 col
.prop(session_settings
, "show_custom_overlays", text
="Custom Overlays")
79 col
.prop(session_settings
, "show_object_extras", text
="Object Extras")
81 col
= col
.row(align
=True, heading
=" ")
84 panel
="VIEW3D_PT_vr_session_view_object_type_visibility",
85 icon_value
=session_settings
.icon_from_show_object_viewport
,
89 col
= layout
.column(align
=True)
90 col
.prop(session_settings
, "controller_draw_style", text
="Controller Style")
92 col
= layout
.column(align
=True)
93 col
.prop(session_settings
, "clip_start", text
="Clip Start")
94 col
.prop(session_settings
, "clip_end", text
="End")
97 class VIEW3D_PT_vr_session_view_object_type_visibility(VIEW3D_PT_object_type_visibility
):
98 def draw(self
, context
):
99 session_settings
= context
.window_manager
.xr_session_settings
100 self
.draw_ex(context
, session_settings
, False) # Pass session settings instead of 3D view.
104 class VIEW3D_MT_vr_landmark_menu(Menu
):
105 bl_label
= "Landmark Controls"
107 def draw(self
, _context
):
110 layout
.operator("view3d.vr_camera_landmark_from_session")
111 layout
.operator("view3d.vr_landmark_from_camera")
112 layout
.operator("view3d.update_vr_landmark")
114 layout
.operator("view3d.cursor_to_vr_landmark")
115 layout
.operator("view3d.camera_to_vr_landmark")
116 layout
.operator("view3d.add_camera_from_vr_landmark")
119 class VIEW3D_UL_vr_landmarks(UIList
):
120 def draw_item(self
, context
, layout
, _data
, item
, icon
, _active_data
,
121 _active_propname
, index
):
123 landmark_active_idx
= context
.scene
.vr_landmarks_active
125 layout
.emboss
= 'NONE'
127 layout
.prop(landmark
, "name", text
="")
130 'RADIOBUT_ON' if (index
== landmark_active_idx
) else 'RADIOBUT_OFF'
132 props
= layout
.operator(
133 "view3d.vr_landmark_activate", text
="", icon
=icon
)
137 class VIEW3D_PT_vr_landmarks(Panel
):
138 bl_space_type
= 'VIEW_3D'
139 bl_region_type
= 'UI'
141 bl_label
= "Landmarks"
142 bl_options
= {'DEFAULT_CLOSED'}
144 def draw(self
, context
):
146 scene
= context
.scene
147 landmark_selected
= properties
.VRLandmark
.get_selected_landmark(context
)
149 layout
.use_property_split
= True
150 layout
.use_property_decorate
= False # No animation.
154 row
.template_list("VIEW3D_UL_vr_landmarks", "", scene
, "vr_landmarks",
155 scene
, "vr_landmarks_selected", rows
=3)
157 col
= row
.column(align
=True)
158 col
.operator("view3d.vr_landmark_add", icon
='ADD', text
="")
159 col
.operator("view3d.vr_landmark_remove", icon
='REMOVE', text
="")
160 col
.operator("view3d.vr_landmark_from_session", icon
='PLUS', text
="")
162 col
.menu("VIEW3D_MT_vr_landmark_menu", icon
='DOWNARROW_HLT', text
="")
164 if landmark_selected
:
165 layout
.prop(landmark_selected
, "type")
167 if landmark_selected
.type == 'OBJECT':
168 layout
.prop(landmark_selected
, "base_pose_object")
169 layout
.prop(landmark_selected
, "base_scale", text
="Scale")
170 elif landmark_selected
.type == 'CUSTOM':
171 layout
.prop(landmark_selected
,
172 "base_pose_location", text
="Location")
173 layout
.prop(landmark_selected
,
174 "base_pose_angle", text
="Angle")
175 layout
.prop(landmark_selected
,
176 "base_scale", text
="Scale")
180 class VIEW3D_PT_vr_actionmaps(Panel
):
181 bl_space_type
= 'VIEW_3D'
182 bl_region_type
= 'UI'
184 bl_label
= "Action Maps"
185 bl_options
= {'DEFAULT_CLOSED'}
187 def draw(self
, context
):
189 scene
= context
.scene
191 layout
.use_property_split
= True
192 layout
.use_property_decorate
= False # No animation.
194 col
= layout
.column(align
=True)
195 col
.prop(scene
, "vr_actions_use_gamepad", text
="Gamepad")
197 col
= layout
.column(align
=True, heading
="Extensions")
198 col
.prop(scene
, "vr_actions_enable_reverb_g2", text
="HP Reverb G2")
199 col
.prop(scene
, "vr_actions_enable_vive_cosmos", text
="HTC Vive Cosmos")
200 col
.prop(scene
, "vr_actions_enable_vive_focus", text
="HTC Vive Focus")
201 col
.prop(scene
, "vr_actions_enable_huawei", text
="Huawei")
204 ### Viewport feedback.
205 class VIEW3D_PT_vr_viewport_feedback(Panel
):
206 bl_space_type
= 'VIEW_3D'
207 bl_region_type
= 'UI'
209 bl_label
= "Viewport Feedback"
210 bl_options
= {'DEFAULT_CLOSED'}
212 def draw(self
, context
):
214 scene
= context
.scene
215 view3d
= context
.space_data
216 session_settings
= context
.window_manager
.xr_session_settings
218 col
= layout
.column(align
=True)
219 col
.label(icon
='ERROR', text
="Note:")
220 col
.label(text
="Settings here may have a significant")
221 col
.label(text
="performance impact!")
225 layout
.prop(view3d
.shading
, "vr_show_virtual_camera")
226 layout
.prop(view3d
.shading
, "vr_show_controllers")
227 layout
.prop(view3d
.shading
, "vr_show_landmarks")
228 layout
.prop(view3d
, "mirror_xr_session")
232 class VIEW3D_PT_vr_info(bpy
.types
.Panel
):
233 bl_space_type
= 'VIEW_3D'
234 bl_region_type
= 'UI'
239 def poll(cls
, context
):
240 return not bpy
.app
.build_options
.xr_openxr
242 def draw(self
, context
):
244 layout
.label(icon
='ERROR', text
="Built without VR/OpenXR features")
248 VIEW3D_PT_vr_session
,
249 VIEW3D_PT_vr_session_view
,
250 VIEW3D_PT_vr_session_view_object_type_visibility
,
251 VIEW3D_PT_vr_landmarks
,
252 VIEW3D_PT_vr_actionmaps
,
253 VIEW3D_PT_vr_viewport_feedback
,
255 VIEW3D_UL_vr_landmarks
,
256 VIEW3D_MT_vr_landmark_menu
,
262 bpy
.utils
.register_class(cls
)
264 # View3DShading is the only per 3D-View struct with custom property
265 # support, so "abusing" that to get a per 3D-View option.
266 bpy
.types
.View3DShading
.vr_show_virtual_camera
= bpy
.props
.BoolProperty(
267 name
="Show VR Camera"
269 bpy
.types
.View3DShading
.vr_show_controllers
= bpy
.props
.BoolProperty(
270 name
="Show VR Controllers"
272 bpy
.types
.View3DShading
.vr_show_landmarks
= bpy
.props
.BoolProperty(
273 name
="Show Landmarks"
279 bpy
.utils
.unregister_class(cls
)
281 del bpy
.types
.View3DShading
.vr_show_virtual_camera
282 del bpy
.types
.View3DShading
.vr_show_controllers
283 del bpy
.types
.View3DShading
.vr_show_landmarks