[Bf-extensions-cvs] [fe21f93a] master: VR Scene-Inspection: Extend Landmarks feature set

Sebastian Koenig noreply at git.blender.org
Wed Jul 22 14:12:04 CEST 2020


Commit: fe21f93ae98d7633c3caf93a68caa1d5ebf06c54
Author: Sebastian Koenig
Date:   Wed Jul 22 12:03:26 2020 +0200
Branches: master
https://developer.blender.org/rBAfe21f93ae98d7633c3caf93a68caa1d5ebf06c54

VR Scene-Inspection: Extend Landmarks feature set

* Enable custom poses for landmarks (so they don't require adding a new
  camera).
* New landmark operators, available in Sidebar menu:
** "Add VR Landmark from Selected Camera"
** "Update Custom Landmark" (updates landmark to match current VR viewer
   pose)
** "Cursor to VR Landmark"
** "Active Camera to Landmark"
** "New Camera from Landmark"
* "Show Landmarks" option, adding gizmos as landmark indicators to 3D
  Views.

This should make the landmarks more practical.

Patch by Sebastian Koenig, with some smaller edits.
Followup commits will do further edits.

Part of T71347.

===================================================================

M	viewport_vr_preview.py

===================================================================

diff --git a/viewport_vr_preview.py b/viewport_vr_preview.py
index db8dd176..11437fe1 100644
--- a/viewport_vr_preview.py
+++ b/viewport_vr_preview.py
@@ -22,6 +22,11 @@ import bpy
 from bpy.types import (
     Gizmo,
     GizmoGroup,
+    PropertyGroup,
+    UIList,
+    Menu,
+    Panel,
+    Operator,
 )
 from bpy.props import (
     CollectionProperty,
@@ -32,7 +37,7 @@ from bpy.app.handlers import persistent
 
 bl_info = {
     "name": "VR Scene Inspection",
-    "author": "Julian Eisel (Severin)",
+    "author": "Julian Eisel (Severin), Sebastian Koenig",
     "version": (0, 2, 0),
     "blender": (2, 83, 0),
     "location": "3D View > Sidebar > VR",
@@ -65,8 +70,8 @@ def xr_landmark_active_type_update(self, context):
         session_settings.base_pose_type = 'SCENE_CAMERA'
     elif landmark_active.type == 'USER_CAMERA':
         session_settings.base_pose_type = 'OBJECT'
-    # elif landmark_active.type == 'CUSTOM':
-        # session_settings.base_pose_type = 'CUSTOM'
+    elif landmark_active.type == 'CUSTOM':
+        session_settings.base_pose_type = 'CUSTOM'
 
 
 def xr_landmark_active_camera_update(self, context):
@@ -147,7 +152,21 @@ def xr_landmark_active_update(self, context):
       wm.xr_session_state.reset_to_base_pose(context)
 
 
-class VRLandmark(bpy.types.PropertyGroup):
+class VIEW3D_MT_landmark_menu(Menu):
+    bl_label = "Landmark Controls"
+
+    def draw(self, _context):
+        layout = self.layout
+
+        layout.operator("view3d.vr_landmark_from_camera")
+        layout.operator("view3d.update_vr_landmark")
+        layout.separator()
+        layout.operator("view3d.cursor_to_vr_landmark")
+        layout.operator("view3d.active_cam_to_vr_landmark")
+        layout.operator("view3d.new_cam_to_vr_landmark")
+
+
+class VRLandmark(PropertyGroup):
     name: bpy.props.StringProperty(
         name="VR Landmark",
         default="Landmark"
@@ -161,11 +180,9 @@ class VRLandmark(bpy.types.PropertyGroup):
             ('USER_CAMERA', "Custom Camera",
              "Use an existing camera to define the VR view base location and "
              "rotation"),
-            # Custom base poses work, but it's uncertain if they are really
-            # needed. Disabled for now.
-            # ('CUSTOM', "Custom Pose",
-            #  "Allow a manually definied position and rotation to be used as "
-            #  "the VR view base pose"),
+            ('CUSTOM', "Custom Pose",
+             "Allow a manually definied position and rotation to be used as "
+             "the VR view base pose"),
         ],
         default='SCENE_CAMERA',
         update=xr_landmark_type_update,
@@ -209,7 +226,7 @@ class VRLandmark(bpy.types.PropertyGroup):
         )
 
 
-class VIEW3D_UL_vr_landmarks(bpy.types.UIList):
+class VIEW3D_UL_vr_landmarks(UIList):
     def draw_item(self, context, layout, _data, item, icon, _active_data,
                   _active_propname, index):
         landmark = item
@@ -227,7 +244,7 @@ class VIEW3D_UL_vr_landmarks(bpy.types.UIList):
         props.index = index
 
 
-class VIEW3D_PT_vr_landmarks(bpy.types.Panel):
+class VIEW3D_PT_vr_landmarks(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_category = "VR"
@@ -250,20 +267,23 @@ class VIEW3D_PT_vr_landmarks(bpy.types.Panel):
         col = row.column(align=True)
         col.operator("view3d.vr_landmark_add", icon='ADD', text="")
         col.operator("view3d.vr_landmark_remove", icon='REMOVE', text="")
+        col.operator("view3d.vr_landmark_from_session", icon='PLUS', text="")
+
+        col.menu("VIEW3D_MT_landmark_menu", icon='DOWNARROW_HLT', text="")
 
         if landmark_selected:
             layout.prop(landmark_selected, "type")
 
             if landmark_selected.type == 'USER_CAMERA':
                 layout.prop(landmark_selected, "base_pose_camera")
-            # elif landmark_selected.type == 'CUSTOM':
-            #     layout.prop(landmark_selected,
-            #                 "base_pose_location", text="Location")
-            #     layout.prop(landmark_selected,
-            #                 "base_pose_angle", text="Angle")
+            elif landmark_selected.type == 'CUSTOM':
+                layout.prop(landmark_selected,
+                            "base_pose_location", text="Location")
+                layout.prop(landmark_selected,
+                            "base_pose_angle", text="Angle")
 
 
-class VIEW3D_PT_vr_session_view(bpy.types.Panel):
+class VIEW3D_PT_vr_session_view(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_category = "VR"
@@ -285,7 +305,7 @@ class VIEW3D_PT_vr_session_view(bpy.types.Panel):
         col.prop(session_settings, "clip_end", text="End")
 
 
-class VIEW3D_PT_vr_session(bpy.types.Panel):
+class VIEW3D_PT_vr_session(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_category = "VR"
@@ -295,7 +315,8 @@ class VIEW3D_PT_vr_session(bpy.types.Panel):
         layout = self.layout
         session_settings = context.window_manager.xr_session_settings
 
-        layout.use_property_split = False
+        layout.use_property_split = True
+        layout.use_property_decorate = False  # No animation.
 
         is_session_running = bpy.types.XrSessionState.is_running(context)
 
@@ -327,7 +348,8 @@ class VIEW3D_PT_vr_info(bpy.types.Panel):
         layout = self.layout
         layout.label(icon='ERROR', text="Built without VR/OpenXR features.")
 
-class VIEW3D_OT_vr_landmark_add(bpy.types.Operator):
+
+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"
@@ -345,7 +367,104 @@ class VIEW3D_OT_vr_landmark_add(bpy.types.Operator):
         return {'FINISHED'}
 
 
-class VIEW3D_OT_vr_landmark_remove(bpy.types.Operator):
+class VIEW3D_OT_vr_landmark_from_camera(Operator):
+    bl_idname = "view3d.vr_landmark_from_camera"
+    bl_label = "Add VR Landmark from selected camera"
+    bl_description = "Add a new VR landmark from the selected camera to the list and select it"
+    bl_options = {'UNDO', 'REGISTER'}
+
+    @classmethod
+    def poll(cls, context):
+        cam_selected = 0
+
+        vl_objects = bpy.context.view_layer.objects
+        if vl_objects.active and vl_objects.active.type == 'CAMERA':
+            cam_selected = 1
+        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 = 'USER_CAMERA'
+        lm.base_pose_camera = 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 current session to the list and select it"
+    bl_options = {'UNDO', 'REGISTER'}
+
+    @classmethod
+    def poll(cls, context):
+        view3d = context.space_data
+        return bpy.types.XrSessionState.is_running(context)
+
+    def execute(self, context):
+        from mathutils import Matrix, Quaternion
+        scene = context.scene
+        landmarks = scene.vr_landmarks
+        wm = context.window_manager
+
+        lm = landmarks.add()
+        lm.type = "CUSTOM"
+
+        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 Landmark"
+    bl_description = "Update an existing landmark from live session"
+    bl_options = {'UNDO', 'REGISTER'}
+
+    @classmethod
+    def poll(cls, context):
+        view3d = context.space_data
+        scene = context.scene
+        landmarks = scene.vr_landmarks
+        active_landmark = scene.vr_landmarks[scene.vr_landmarks_active]
+        # return bpy.types.XrSessionState.is_running(context) and active_landmark.type == 'CUSTOM'
+        return active_landmark.type == 'CUSTOM'
+
+    def execute(self, context):
+        from mathutils import Matrix, Quaternion
+        scene = context.scene
+        landmarks = scene.vr_landmarks
+        wm = context.window_manager
+
+        lm = landmarks[scene.vr_landmarks_active]
+
+        loc = wm.xr_session_state.viewer_pose_location
+        rot = wm.xr_session_state.viewer_pose_rotation.to_euler()
+        # only for testing
+        # loc = landmarks[0].base_pose_location
+        # rot = landmarks[0].base_pose_angle
+
+        lm.base_pose_location = loc
+        lm.base_pose_angle = rot
+
+        # now activate the landmark again to trigger viewer reset
+        bpy.ops.view3d.vr_landmark_activate()
+
+        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"
@@ -364,7 +483,71 @@ class VIEW3D_OT_vr_landmark_remove(bpy.types.Operator):
         return {'FINISHED'}
 
 
-class VIEW3D_OT_vr_landmark_activate(bpy.types.Operator):
+class VIEW3D_OT_cursor_to_vr_landmark(Operator):
+    bl_idname = "view3d.cursor_to_vr_landmark"
+    bl_label = "Cursor to VR Landmark"
+    bl_description = "Set the 3D Cursor to the active VR Landmark"
+    bl_options = {'UNDO', 'REGISTER'}
+
+    def execute(self, context):
+        scene = context.scene
+        lm = scene.vr_landmarks[scene.vr_landmarks_selected]
+        if lm.type == 'SCENE_CAMERA':
+            lm_pos = scene.camera.location
+        elif lm.type == 'USER_CAMERA':
+            lm_pos = lm.base_pose_camera.location
+        else:
+            lm_pos = lm.base_pose_location
+        scene.cursor.location = lm_pos
+
+        return{'FINISHED'}
+
+
+class VIEW3d_OT_new_cam_to_vr_landmark(Operator):
+    bl_idname = "view3d.new_cam_to_vr

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list