Initial VR Pose bookmarking system

Idea is to have a list of VR pose bookmarks in the sidebar, so you can
jump back and forth between custom, pinned poses (rotation+location).
Right now the bookmarks have to be a camera, whereby you can choose
between following the active scene camera, or a custom fixed one.
Adding completely custom locations (not bound to a camera or any other
object) will also be added, but needs changes in RNA first.

Note that the latest state of this is mostly untested. I'm travelling
and can't test with an actual VR session.
This commit is contained in:
Julian Eisel 2020-02-06 19:44:12 +01:00
parent 1da441971e
commit a3c97a49c7
1 changed files with 165 additions and 7 deletions

View File

@ -23,6 +23,10 @@ from bpy.types import (
Gizmo,
GizmoGroup,
)
from bpy.props import(
CollectionProperty,
IntProperty,
)
from bl_ui.space_view3d import (
VIEW3D_PT_shading_lighting,
VIEW3D_PT_shading_color,
@ -32,9 +36,9 @@ from bl_ui.space_view3d import (
bl_info = {
"name": "Basic VR Viewer",
"author": "Julian Eisel (Severin)",
"version": (0, 0, 1),
"blender": (2, 81, 0),
"location": "Window > Toggle VR Session",
"version": (0, 0, 2),
"blender": (2, 83, 2),
"location": "3D View > Sidebar > VR",
"description": ("View the viewport with virtual reality glasses "
"(head-mounted displays)"),
"support": "OFFICIAL",
@ -44,6 +48,112 @@ bl_info = {
}
def xr_pose_bookmark_type_update(self, context):
wm = context.window_manager
session_settings = wm.xr_session_settings
bookmark_active = VRPoseBookmark.get_active_bookmark(context)
if not bookmark_active:
return
if bookmark_active.type == 'SCENE_CAMERA':
# By setting the anchor object to None, the scene camera will be used.
session_settings.anchor_object = None
elif bookmark_active.type == 'USER_CAMERA':
# By default, select the scene camera.
if not bookmark_active.camera:
scene = context.scene
bookmark_active.camera = scene.camera
def xr_pose_bookmark_camera_update(self, context):
wm = context.window_manager
session_settings = wm.xr_session_settings
bookmark_active = VRPoseBookmark.get_active_bookmark(context)
if bookmark_active and bookmark_active.type == 'CUSTOM_CAMERA':
# Update the anchor object to the (new) camera of this bookmark.
session_settings.anchor_object = bookmark_active.camera
def xr_pose_bookmark_camera_object_poll(self, object):
return object.type == 'CAMERA'
def xr_pose_bookmark_active_update(self, context):
xr_pose_bookmark_type_update(self, context)
xr_pose_bookmark_camera_update(self, context)
class VRPoseBookmark(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(
name="VR Pose Bookmark",
default="VR Pose"
)
type: bpy.props.EnumProperty(
name="Type",
items=[
('SCENE_CAMERA', "Scene Camera", "Use scene's currently active camera to define the VR view base pose"),
('USER_CAMERA', "Custom Camera", "Use an existing camera to define 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_pose_bookmark_type_update,
)
camera: bpy.props.PointerProperty(
name="Camera",
type=bpy.types.Object,
poll=xr_pose_bookmark_camera_object_poll,
update=xr_pose_bookmark_camera_update,
)
@staticmethod
def get_active_bookmark(context):
wm = context.window_manager
bookmarks = wm.vr_pose_bookmarks
return None if len(bookmarks) < 1 else bookmarks[wm.vr_pose_bookmarks_active]
class VIEW3D_UL_vr_pose_bookmarks(bpy.types.UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
bookmark = item
layout.emboss = 'NONE'
layout.prop(bookmark, "name", text="")
class VIEW3D_PT_vr_pose_bookmarks(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "VR"
bl_label = "Pose Bookmarks"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
wm = context.window_manager
bookmarks = wm.vr_pose_bookmarks
bookmark_active = VRPoseBookmark.get_active_bookmark(context)
row = layout.row()
row.template_list("VIEW3D_UL_vr_pose_bookmarks", "", wm, "vr_pose_bookmarks",
wm, "vr_pose_bookmarks_active", rows=3)
col = row.column(align=True)
col.operator("view3d.vr_pose_bookmark_add", icon='ADD', text="")
col.operator("view3d.vr_pose_bookmark_remove", icon='REMOVE', text="")
if bookmark_active:
layout.prop(bookmark_active, "type")
if bookmark_active.type == 'USER_CAMERA':
layout.prop(bookmark_active, "camera")
elif bookmark_active.type == 'CUSTOM':
pass
class VIEW3D_PT_vr_session(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@ -67,10 +177,6 @@ class VIEW3D_PT_vr_session(bpy.types.Panel):
layout.separator()
layout.prop(session_settings, "anchor_object")
layout.separator()
layout.prop(session_settings, "show_floor", text="Floor")
layout.prop(session_settings, "show_annotation", text="Annotations")
@ -85,6 +191,40 @@ class VIEW3D_PT_vr_session(bpy.types.Panel):
layout.prop(session_settings, "use_positional_tracking")
class VIEW3D_OT_vr_pose_bookmark_add(bpy.types.Operator):
bl_idname = "view3d.vr_pose_bookmark_add"
bl_label = "Add VR Pose Bookmark"
bl_description = "Add a new VR pose bookmark to the list and select it"
bl_options = {'UNDO', 'REGISTER'}
def execute(self, context):
wm = context.window_manager
bookmarks = wm.vr_pose_bookmarks
bookmarks.add()
# select newly created set
wm.vr_pose_bookmarks_active = len(bookmarks) - 1
return {'FINISHED'}
class VIEW3D_OT_vr_pose_bookmark_remove(bpy.types.Operator):
bl_idname = "view3d.vr_pose_bookmark_remove"
bl_label = "Remove VR Pose Bookmark"
bl_description = "Delete the selected VR pose bookmark from the list"
bl_options = {'UNDO', 'REGISTER'}
def execute(self, context):
wm = context.window_manager
bookmarks = wm.vr_pose_bookmarks
bookmark_active_idx = wm.vr_pose_bookmarks_active
bookmarks.remove(bookmark_active_idx)
return {'FINISHED'}
class VIEW3D_PT_vr_session_shading(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@ -233,6 +373,13 @@ classes = (
VIEW3D_PT_vr_session_shading_lighting,
VIEW3D_PT_vr_session_shading_color,
VIEW3D_PT_vr_session_shading_options,
VIEW3D_PT_vr_pose_bookmarks,
VRPoseBookmark,
VIEW3D_UL_vr_pose_bookmarks,
VIEW3D_OT_vr_pose_bookmark_add,
VIEW3D_OT_vr_pose_bookmark_remove,
VIEW3D_GT_vr_camera_cone,
VIEW3D_GGT_vr_viewer,
@ -243,11 +390,22 @@ def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.WindowManager.vr_pose_bookmarks = CollectionProperty(
name="Pose Bookmarks",
type=VRPoseBookmark,
)
bpy.types.WindowManager.vr_pose_bookmarks_active = IntProperty(
update=xr_pose_bookmark_active_update,
)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.WindowManager.vr_pose_bookmarks
del bpy.types.WindowManager.vr_pose_bookmarks_active
if __name__ == "__main__":
register()