Fix T98039: Node Wrangler node preview no longer working
[blender-addons.git] / viewport_vr_preview / properties.py
blob55a4d4ebf8c5af73ac1f5a112b91d81447ebb509
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # <pep8 compliant>
5 import bpy
6 from bpy.types import (
7 PropertyGroup,
9 from bpy.app.handlers import persistent
12 ### Landmarks.
13 @persistent
14 def vr_ensure_default_landmark(context: bpy.context):
15 # Ensure there's a default landmark (scene camera by default).
16 landmarks = bpy.context.scene.vr_landmarks
17 if not landmarks:
18 landmarks.add()
19 landmarks[0].type = 'SCENE_CAMERA'
22 def vr_landmark_active_type_update(self, context):
23 wm = context.window_manager
24 session_settings = wm.xr_session_settings
25 landmark_active = VRLandmark.get_active_landmark(context)
27 # Update session's base pose type to the matching type.
28 if landmark_active.type == 'SCENE_CAMERA':
29 session_settings.base_pose_type = 'SCENE_CAMERA'
30 elif landmark_active.type == 'OBJECT':
31 session_settings.base_pose_type = 'OBJECT'
32 elif landmark_active.type == 'CUSTOM':
33 session_settings.base_pose_type = 'CUSTOM'
36 def vr_landmark_active_base_pose_object_update(self, context):
37 session_settings = context.window_manager.xr_session_settings
38 landmark_active = VRLandmark.get_active_landmark(context)
40 # Update the anchor object to the (new) camera of this landmark.
41 session_settings.base_pose_object = landmark_active.base_pose_object
44 def vr_landmark_active_base_pose_location_update(self, context):
45 session_settings = context.window_manager.xr_session_settings
46 landmark_active = VRLandmark.get_active_landmark(context)
48 session_settings.base_pose_location = landmark_active.base_pose_location
51 def vr_landmark_active_base_pose_angle_update(self, context):
52 session_settings = context.window_manager.xr_session_settings
53 landmark_active = VRLandmark.get_active_landmark(context)
55 session_settings.base_pose_angle = landmark_active.base_pose_angle
58 def vr_landmark_active_base_scale_update(self, context):
59 session_settings = context.window_manager.xr_session_settings
60 landmark_active = VRLandmark.get_active_landmark(context)
62 session_settings.base_scale = landmark_active.base_scale
65 def vr_landmark_type_update(self, context):
66 landmark_selected = VRLandmark.get_selected_landmark(context)
67 landmark_active = VRLandmark.get_active_landmark(context)
69 # Don't allow non-trivial base scale for scene camera landmarks.
70 if landmark_selected.type == 'SCENE_CAMERA':
71 landmark_selected.base_scale = 1.0
73 # Only update session settings data if the changed landmark is actually
74 # the active one.
75 if landmark_active == landmark_selected:
76 vr_landmark_active_type_update(self, context)
79 def vr_landmark_base_pose_object_update(self, context):
80 landmark_selected = VRLandmark.get_selected_landmark(context)
81 landmark_active = VRLandmark.get_active_landmark(context)
83 # Only update session settings data if the changed landmark is actually
84 # the active one.
85 if landmark_active == landmark_selected:
86 vr_landmark_active_base_pose_object_update(self, context)
89 def vr_landmark_base_pose_location_update(self, context):
90 landmark_selected = VRLandmark.get_selected_landmark(context)
91 landmark_active = VRLandmark.get_active_landmark(context)
93 # Only update session settings data if the changed landmark is actually
94 # the active one.
95 if landmark_active == landmark_selected:
96 vr_landmark_active_base_pose_location_update(self, context)
99 def vr_landmark_base_pose_angle_update(self, context):
100 landmark_selected = VRLandmark.get_selected_landmark(context)
101 landmark_active = VRLandmark.get_active_landmark(context)
103 # Only update session settings data if the changed landmark is actually
104 # the active one.
105 if landmark_active == landmark_selected:
106 vr_landmark_active_base_pose_angle_update(self, context)
109 def vr_landmark_base_scale_update(self, context):
110 landmark_selected = VRLandmark.get_selected_landmark(context)
111 landmark_active = VRLandmark.get_active_landmark(context)
113 # Only update session settings data if the changed landmark is actually
114 # the active one.
115 if landmark_active == landmark_selected:
116 vr_landmark_active_base_scale_update(self, context)
119 def vr_landmark_active_update(self, context):
120 wm = context.window_manager
122 vr_landmark_active_type_update(self, context)
123 vr_landmark_active_base_pose_object_update(self, context)
124 vr_landmark_active_base_pose_location_update(self, context)
125 vr_landmark_active_base_pose_angle_update(self, context)
126 vr_landmark_active_base_scale_update(self, context)
128 if wm.xr_session_state:
129 wm.xr_session_state.reset_to_base_pose(context)
132 class VRLandmark(PropertyGroup):
133 name: bpy.props.StringProperty(
134 name="VR Landmark",
135 default="Landmark"
137 type: bpy.props.EnumProperty(
138 name="Type",
139 items=[
140 ('SCENE_CAMERA', "Scene Camera",
141 "Use scene's currently active camera to define the VR view base "
142 "location and rotation"),
143 ('OBJECT', "Custom Object",
144 "Use an existing object to define the VR view base location and "
145 "rotation"),
146 ('CUSTOM', "Custom Pose",
147 "Allow a manually defined position and rotation to be used as "
148 "the VR view base pose"),
150 default='SCENE_CAMERA',
151 update=vr_landmark_type_update,
153 base_pose_object: bpy.props.PointerProperty(
154 name="Object",
155 type=bpy.types.Object,
156 update=vr_landmark_base_pose_object_update,
158 base_pose_location: bpy.props.FloatVectorProperty(
159 name="Base Pose Location",
160 subtype='TRANSLATION',
161 update=vr_landmark_base_pose_location_update,
163 base_pose_angle: bpy.props.FloatProperty(
164 name="Base Pose Angle",
165 subtype='ANGLE',
166 update=vr_landmark_base_pose_angle_update,
168 base_scale: bpy.props.FloatProperty(
169 name="Base Scale",
170 description="Viewer reference scale associated with this landmark",
171 default=1.0,
172 min=0.000001,
173 update=vr_landmark_base_scale_update,
176 @staticmethod
177 def get_selected_landmark(context):
178 scene = context.scene
179 landmarks = scene.vr_landmarks
181 return (
182 None if (len(landmarks) <
183 1) else landmarks[scene.vr_landmarks_selected]
186 @staticmethod
187 def get_active_landmark(context):
188 scene = context.scene
189 landmarks = scene.vr_landmarks
191 return (
192 None if (len(landmarks) <
193 1) else landmarks[scene.vr_landmarks_active]
197 classes = (
198 VRLandmark,
202 def register():
203 for cls in classes:
204 bpy.utils.register_class(cls)
206 bpy.types.Scene.vr_landmarks = bpy.props.CollectionProperty(
207 name="Landmark",
208 type=VRLandmark,
210 bpy.types.Scene.vr_landmarks_selected = bpy.props.IntProperty(
211 name="Selected Landmark"
213 bpy.types.Scene.vr_landmarks_active = bpy.props.IntProperty(
214 update=vr_landmark_active_update,
217 bpy.app.handlers.load_post.append(vr_ensure_default_landmark)
220 def unregister():
221 for cls in classes:
222 bpy.utils.unregister_class(cls)
224 del bpy.types.Scene.vr_landmarks
225 del bpy.types.Scene.vr_landmarks_selected
226 del bpy.types.Scene.vr_landmarks_active
228 bpy.app.handlers.load_post.remove(vr_ensure_default_landmark)