Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'viewport_vr_preview/operators.py')
-rw-r--r--viewport_vr_preview/operators.py521
1 files changed, 521 insertions, 0 deletions
diff --git a/viewport_vr_preview/operators.py b/viewport_vr_preview/operators.py
new file mode 100644
index 00000000..932dac31
--- /dev/null
+++ b/viewport_vr_preview/operators.py
@@ -0,0 +1,521 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+if "bpy" in locals():
+ import importlib
+ importlib.reload(properties)
+else:
+ from . import properties
+
+import bpy
+from bpy.types import (
+ Gizmo,
+ GizmoGroup,
+ Operator,
+)
+import bgl
+import math
+from math import radians
+from mathutils import Euler, Matrix, Quaternion, Vector
+
+
+### Landmarks.
+class VIEW3D_OT_vr_landmark_add(Operator):
+ bl_idname = "view3d.vr_landmark_add"
+ bl_label = "Add VR Landmark"
+ bl_description = "Add a new VR landmark to the list and select it"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ def execute(self, context):
+ scene = context.scene
+ landmarks = scene.vr_landmarks
+
+ landmarks.add()
+
+ # select newly created set
+ scene.vr_landmarks_selected = len(landmarks) - 1
+
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_vr_landmark_from_camera(Operator):
+ bl_idname = "view3d.vr_landmark_from_camera"
+ bl_label = "Add VR Landmark from Camera"
+ bl_description = "Add a new VR landmark from the active camera object to the list and select it"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ @classmethod
+ def poll(cls, context):
+ cam_selected = False
+
+ vl_objects = bpy.context.view_layer.objects
+ if vl_objects.active and vl_objects.active.type == 'CAMERA':
+ cam_selected = True
+ return cam_selected
+
+ def execute(self, context):
+ scene = context.scene
+ landmarks = scene.vr_landmarks
+ cam = context.view_layer.objects.active
+ lm = landmarks.add()
+ lm.type = 'OBJECT'
+ lm.base_pose_object = cam
+ lm.name = "LM_" + cam.name
+
+ # select newly created set
+ scene.vr_landmarks_selected = len(landmarks) - 1
+
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_vr_landmark_from_session(Operator):
+ bl_idname = "view3d.vr_landmark_from_session"
+ bl_label = "Add VR Landmark from Session"
+ bl_description = "Add VR landmark from the viewer pose of the running VR session to the list and select it"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ @classmethod
+ def poll(cls, context):
+ return bpy.types.XrSessionState.is_running(context)
+
+ def execute(self, context):
+ scene = context.scene
+ landmarks = scene.vr_landmarks
+ wm = context.window_manager
+
+ lm = landmarks.add()
+ lm.type = "CUSTOM"
+ scene.vr_landmarks_selected = len(landmarks) - 1
+
+ loc = wm.xr_session_state.viewer_pose_location
+ rot = wm.xr_session_state.viewer_pose_rotation.to_euler()
+
+ lm.base_pose_location = loc
+ lm.base_pose_angle = rot[2]
+
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_update_vr_landmark(Operator):
+ bl_idname = "view3d.update_vr_landmark"
+ bl_label = "Update Custom VR Landmark"
+ bl_description = "Update the selected landmark from the current viewer pose in the VR session"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ @classmethod
+ def poll(cls, context):
+ selected_landmark = properties.VRLandmark.get_selected_landmark(context)
+ return bpy.types.XrSessionState.is_running(context) and selected_landmark.type == 'CUSTOM'
+
+ def execute(self, context):
+ wm = context.window_manager
+
+ lm = properties.VRLandmark.get_selected_landmark(context)
+
+ loc = wm.xr_session_state.viewer_pose_location
+ rot = wm.xr_session_state.viewer_pose_rotation.to_euler()
+
+ lm.base_pose_location = loc
+ lm.base_pose_angle = rot
+
+ # Re-activate the landmark to trigger viewer reset and flush landmark settings to the session settings.
+ properties.vr_landmark_active_update(None, context)
+
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_vr_landmark_remove(Operator):
+ bl_idname = "view3d.vr_landmark_remove"
+ bl_label = "Remove VR Landmark"
+ bl_description = "Delete the selected VR landmark from the list"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ def execute(self, context):
+ scene = context.scene
+ landmarks = scene.vr_landmarks
+
+ if len(landmarks) > 1:
+ landmark_selected_idx = scene.vr_landmarks_selected
+ landmarks.remove(landmark_selected_idx)
+
+ scene.vr_landmarks_selected -= 1
+
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_vr_landmark(Operator):
+ bl_idname = "view3d.cursor_to_vr_landmark"
+ bl_label = "Cursor to VR Landmark"
+ bl_description = "Move the 3D Cursor to the selected VR Landmark"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ @classmethod
+ def poll(cls, context):
+ lm = properties.VRLandmark.get_selected_landmark(context)
+ if lm.type == 'SCENE_CAMERA':
+ return context.scene.camera is not None
+ elif lm.type == 'OBJECT':
+ return lm.base_pose_object is not None
+
+ return True
+
+ def execute(self, context):
+ scene = context.scene
+ lm = properties.VRLandmark.get_selected_landmark(context)
+ if lm.type == 'SCENE_CAMERA':
+ lm_pos = scene.camera.location
+ elif lm.type == 'OBJECT':
+ lm_pos = lm.base_pose_object.location
+ else:
+ lm_pos = lm.base_pose_location
+ scene.cursor.location = lm_pos
+
+ return{'FINISHED'}
+
+
+class VIEW3D_OT_add_camera_from_vr_landmark(Operator):
+ bl_idname = "view3d.add_camera_from_vr_landmark"
+ bl_label = "New Camera from VR Landmark"
+ bl_description = "Create a new Camera from the selected VR Landmark"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ def execute(self, context):
+ scene = context.scene
+ lm = properties.VRLandmark.get_selected_landmark(context)
+
+ cam = bpy.data.cameras.new("Camera_" + lm.name)
+ new_cam = bpy.data.objects.new("Camera_" + lm.name, cam)
+ scene.collection.objects.link(new_cam)
+ angle = lm.base_pose_angle
+ new_cam.location = lm.base_pose_location
+ new_cam.rotation_euler = (math.pi, 0, angle)
+
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_camera_to_vr_landmark(Operator):
+ bl_idname = "view3d.camera_to_vr_landmark"
+ bl_label = "Scene Camera to VR Landmark"
+ bl_description = "Position the scene camera at the selected landmark"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene.camera is not None
+
+ def execute(self, context):
+ scene = context.scene
+ lm = properties.VRLandmark.get_selected_landmark(context)
+
+ cam = scene.camera
+ angle = lm.base_pose_angle
+ cam.location = lm.base_pose_location
+ cam.rotation_euler = (math.pi / 2, 0, angle)
+
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_vr_landmark_activate(Operator):
+ bl_idname = "view3d.vr_landmark_activate"
+ bl_label = "Activate VR Landmark"
+ bl_description = "Change to the selected VR landmark from the list"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ index: bpy.props.IntProperty(
+ name="Index",
+ options={'HIDDEN'},
+ )
+
+ def execute(self, context):
+ scene = context.scene
+
+ if self.index >= len(scene.vr_landmarks):
+ return {'CANCELLED'}
+
+ scene.vr_landmarks_active = (
+ self.index if self.properties.is_property_set(
+ "index") else scene.vr_landmarks_selected
+ )
+
+ return {'FINISHED'}
+
+
+### Gizmos.
+class VIEW3D_GT_vr_camera_cone(Gizmo):
+ bl_idname = "VIEW_3D_GT_vr_camera_cone"
+
+ aspect = 1.0, 1.0
+
+ def draw(self, context):
+ if not hasattr(self, "frame_shape"):
+ aspect = self.aspect
+
+ frame_shape_verts = (
+ (-aspect[0], -aspect[1], -1.0),
+ (aspect[0], -aspect[1], -1.0),
+ (aspect[0], aspect[1], -1.0),
+ (-aspect[0], aspect[1], -1.0),
+ )
+ lines_shape_verts = (
+ (0.0, 0.0, 0.0),
+ frame_shape_verts[0],
+ (0.0, 0.0, 0.0),
+ frame_shape_verts[1],
+ (0.0, 0.0, 0.0),
+ frame_shape_verts[2],
+ (0.0, 0.0, 0.0),
+ frame_shape_verts[3],
+ )
+
+ self.frame_shape = self.new_custom_shape(
+ 'LINE_LOOP', frame_shape_verts)
+ self.lines_shape = self.new_custom_shape(
+ 'LINES', lines_shape_verts)
+
+ # Ensure correct GL state (otherwise other gizmos might mess that up)
+ bgl.glLineWidth(1)
+ bgl.glEnable(bgl.GL_BLEND)
+
+ self.draw_custom_shape(self.frame_shape)
+ self.draw_custom_shape(self.lines_shape)
+
+
+class VIEW3D_GT_vr_controller_grip(Gizmo):
+ bl_idname = "VIEW_3D_GT_vr_controller_grip"
+
+ def draw(self, context):
+ bgl.glLineWidth(1)
+ bgl.glEnable(bgl.GL_BLEND)
+
+ self.color = 0.422, 0.438, 0.446
+ self.draw_preset_circle(self.matrix_basis, axis='POS_X')
+ self.draw_preset_circle(self.matrix_basis, axis='POS_Y')
+ self.draw_preset_circle(self.matrix_basis, axis='POS_Z')
+
+
+class VIEW3D_GT_vr_controller_aim(Gizmo):
+ bl_idname = "VIEW_3D_GT_vr_controller_aim"
+
+ def draw(self, context):
+ bgl.glLineWidth(1)
+ bgl.glEnable(bgl.GL_BLEND)
+
+ self.color = 1.0, 0.2, 0.322
+ self.draw_preset_arrow(self.matrix_basis, axis='POS_X')
+ self.color = 0.545, 0.863, 0.0
+ self.draw_preset_arrow(self.matrix_basis, axis='POS_Y')
+ self.color = 0.157, 0.565, 1.0
+ self.draw_preset_arrow(self.matrix_basis, axis='POS_Z')
+
+
+class VIEW3D_GGT_vr_viewer_pose(GizmoGroup):
+ bl_idname = "VIEW3D_GGT_vr_viewer_pose"
+ bl_label = "VR Viewer Pose Indicator"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'WINDOW'
+ bl_options = {'3D', 'PERSISTENT', 'SCALE', 'VR_REDRAWS'}
+
+ @classmethod
+ def poll(cls, context):
+ view3d = context.space_data
+ return (
+ view3d.shading.vr_show_virtual_camera and
+ bpy.types.XrSessionState.is_running(context) and
+ not view3d.mirror_xr_session
+ )
+
+ @staticmethod
+ def _get_viewer_pose_matrix(context):
+ wm = context.window_manager
+
+ loc = wm.xr_session_state.viewer_pose_location
+ rot = wm.xr_session_state.viewer_pose_rotation
+
+ rotmat = Matrix.Identity(3)
+ rotmat.rotate(rot)
+ rotmat.resize_4x4()
+ transmat = Matrix.Translation(loc)
+
+ return transmat @ rotmat
+
+ def setup(self, context):
+ gizmo = self.gizmos.new(VIEW3D_GT_vr_camera_cone.bl_idname)
+ gizmo.aspect = 1 / 3, 1 / 4
+
+ gizmo.color = gizmo.color_highlight = 0.2, 0.6, 1.0
+ gizmo.alpha = 1.0
+
+ self.gizmo = gizmo
+
+ def draw_prepare(self, context):
+ self.gizmo.matrix_basis = self._get_viewer_pose_matrix(context)
+
+
+class VIEW3D_GGT_vr_controller_poses(GizmoGroup):
+ bl_idname = "VIEW3D_GGT_vr_controller_poses"
+ bl_label = "VR Controller Poses Indicator"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'WINDOW'
+ bl_options = {'3D', 'PERSISTENT', 'SCALE', 'VR_REDRAWS'}
+
+ @classmethod
+ def poll(cls, context):
+ view3d = context.space_data
+ return (
+ view3d.shading.vr_show_controllers and
+ bpy.types.XrSessionState.is_running(context) and
+ not view3d.mirror_xr_session
+ )
+
+ @staticmethod
+ def _get_controller_pose_matrix(context, idx, is_grip, scale):
+ wm = context.window_manager
+
+ loc = None
+ rot = None
+ if is_grip:
+ loc = wm.xr_session_state.controller_grip_location_get(context, idx)
+ rot = wm.xr_session_state.controller_grip_rotation_get(context, idx)
+ else:
+ loc = wm.xr_session_state.controller_aim_location_get(context, idx)
+ rot = wm.xr_session_state.controller_aim_rotation_get(context, idx)
+
+ rotmat = Matrix.Identity(3)
+ rotmat.rotate(Quaternion(Vector(rot)))
+ rotmat.resize_4x4()
+ transmat = Matrix.Translation(loc)
+ scalemat = Matrix.Scale(scale, 4)
+
+ return transmat @ rotmat @ scalemat
+
+ def setup(self, context):
+ for idx in range(2):
+ self.gizmos.new(VIEW3D_GT_vr_controller_grip.bl_idname)
+ self.gizmos.new(VIEW3D_GT_vr_controller_aim.bl_idname)
+
+ for gizmo in self.gizmos:
+ gizmo.aspect = 1 / 3, 1 / 4
+ gizmo.color_highlight = 1.0, 1.0, 1.0
+ gizmo.alpha = 1.0
+
+ def draw_prepare(self, context):
+ grip_idx = 0
+ aim_idx = 0
+ idx = 0
+ scale = 1.0
+ for gizmo in self.gizmos:
+ is_grip = (gizmo.bl_idname == VIEW3D_GT_vr_controller_grip.bl_idname)
+ if (is_grip):
+ idx = grip_idx
+ grip_idx += 1
+ scale = 0.1
+ else:
+ idx = aim_idx
+ aim_idx += 1
+ scale = 0.5
+ gizmo.matrix_basis = self._get_controller_pose_matrix(context, idx, is_grip, scale)
+
+
+class VIEW3D_GGT_vr_landmarks(GizmoGroup):
+ bl_idname = "VIEW3D_GGT_vr_landmarks"
+ bl_label = "VR Landmark Indicators"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'WINDOW'
+ bl_options = {'3D', 'PERSISTENT', 'SCALE'}
+
+ @classmethod
+ def poll(cls, context):
+ view3d = context.space_data
+ return (
+ view3d.shading.vr_show_landmarks
+ )
+
+ def setup(self, context):
+ pass
+
+ def draw_prepare(self, context):
+ # first delete the old gizmos
+ for g in self.gizmos:
+ self.gizmos.remove(g)
+
+ scene = context.scene
+ landmarks = scene.vr_landmarks
+
+ for lm in landmarks:
+ if ((lm.type == 'SCENE_CAMERA' and not scene.camera) or
+ (lm.type == 'OBJECT' and not lm.base_pose_object)):
+ continue
+
+ gizmo = self.gizmos.new(VIEW3D_GT_vr_camera_cone.bl_idname)
+ gizmo.aspect = 1 / 3, 1 / 4
+
+ gizmo.color = gizmo.color_highlight = 0.2, 1.0, 0.6
+ gizmo.alpha = 1.0
+
+ self.gizmo = gizmo
+
+ if lm.type == 'SCENE_CAMERA':
+ cam = scene.camera
+ lm_mat = cam.matrix_world if cam else Matrix.Identity(4)
+ elif lm.type == 'OBJECT':
+ lm_mat = lm.base_pose_object.matrix_world
+ else:
+ angle = lm.base_pose_angle
+ raw_rot = Euler((radians(90.0), 0, angle))
+
+ rotmat = Matrix.Identity(3)
+ rotmat.rotate(raw_rot)
+ rotmat.resize_4x4()
+
+ transmat = Matrix.Translation(lm.base_pose_location)
+
+ lm_mat = transmat @ rotmat
+
+ self.gizmo.matrix_basis = lm_mat
+
+
+classes = (
+ VIEW3D_OT_vr_landmark_add,
+ VIEW3D_OT_vr_landmark_remove,
+ VIEW3D_OT_vr_landmark_activate,
+ VIEW3D_OT_vr_landmark_from_session,
+ VIEW3D_OT_add_camera_from_vr_landmark,
+ VIEW3D_OT_camera_to_vr_landmark,
+ VIEW3D_OT_vr_landmark_from_camera,
+ VIEW3D_OT_cursor_to_vr_landmark,
+ VIEW3D_OT_update_vr_landmark,
+
+ VIEW3D_GT_vr_camera_cone,
+ VIEW3D_GT_vr_controller_grip,
+ VIEW3D_GT_vr_controller_aim,
+ VIEW3D_GGT_vr_viewer_pose,
+ VIEW3D_GGT_vr_controller_poses,
+ VIEW3D_GGT_vr_landmarks,
+)
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)