diff --git a/add_camera_rigs/__init__.py b/add_camera_rigs/__init__.py index 6f9f9eeb43cf828e1936cb310c11c07ad370c1e5..7f4accee82f55c5bfcfcb504d17af83ac756aed0 100644 --- a/add_camera_rigs/__init__.py +++ b/add_camera_rigs/__init__.py @@ -19,7 +19,7 @@ bl_info = { "name": "Add Camera Rigs", "author": "Wayne Dixon, Brian Raschko, Kris Wittig, Damien Picard, Flavio Perez", - "version": (1, 4, 3), + "version": (1, 4, 4), "blender": (2, 80, 0), "location": "View3D > Add > Camera > Dolly or Crane Rig", "description": "Adds a Camera Rig with UI", diff --git a/add_camera_rigs/build_rigs.py b/add_camera_rigs/build_rigs.py index 5a23cf21ca67f6b9b22934bdfa8653f651a59d15..6b47fef8882dded142674748dcf4af4e8fc12088 100644 --- a/add_camera_rigs/build_rigs.py +++ b/add_camera_rigs/build_rigs.py @@ -24,8 +24,9 @@ from rna_prop_ui import rna_idprop_ui_prop_get from math import pi from .create_widgets import (create_root_widget, - create_camera_widget, create_aim_widget, - create_circle_widget, create_corner_widget) + create_camera_widget, create_camera_offset_widget, + create_aim_widget, create_circle_widget, + create_corner_widget) def create_prop_driver(rig, cam, prop_from, prop_to): @@ -66,11 +67,23 @@ def create_dolly_bones(rig): ctrl.tail = (0.0, 1.0, 1.7) ctrl.show_wire = True + ctrl_offset = bones.new("Camera_offset") + ctrl_offset.head = (0.0, 0.0, 1.7) + ctrl_offset.tail = (0.0, 1.0, 1.7) + ctrl_offset.show_wire = True + # Setup hierarchy ctrl.parent = root + ctrl_offset.parent = ctrl ctrl_aim.parent = root ctrl_aim_child.parent = ctrl_aim + # Jump into object mode + bpy.ops.object.mode_set(mode='OBJECT') + pose_bones = rig.pose.bones + # Lock the relevant scale channels of the Camera_offset bone + pose_bones["Camera_offset"].lock_scale = (True,) * 3 + def create_crane_bones(rig): """Create bones for the crane camera rig""" @@ -95,6 +108,10 @@ def create_crane_bones(rig): ctrl.head = (0.0, 1.0, 1.7) ctrl.tail = (0.0, 2.0, 1.7) + ctrl_offset = bones.new("Camera_offset") + ctrl_offset.head = (0.0, 1.0, 1.7) + ctrl_offset.tail = (0.0, 2.0, 1.7) + arm = bones.new("Crane_arm") arm.head = (0.0, 0.0, 1.7) arm.tail = (0.0, 1.0, 1.7) @@ -105,6 +122,7 @@ def create_crane_bones(rig): # Setup hierarchy ctrl.parent = arm + ctrl_offset.parent = ctrl ctrl.use_inherit_rotation = False ctrl.use_inherit_scale = False ctrl.show_wire = True @@ -123,9 +141,10 @@ def create_crane_bones(rig): # Lock the relevant loc, rot and scale pose_bones["Crane_arm"].lock_rotation = (False, True, False) pose_bones["Crane_arm"].lock_scale = (True, False, True) - pose_bones["Crane_height"].lock_location = (True, True, True) - pose_bones["Crane_height"].lock_rotation = (True, True, True) + pose_bones["Crane_height"].lock_location = (True,) * 3 + pose_bones["Crane_height"].lock_rotation = (True,) * 3 pose_bones["Crane_height"].lock_scale = (True, False, True) + pose_bones["Camera_offset"].lock_scale = (True,) * 3 def setup_3d_rig(rig, cam): @@ -148,14 +167,16 @@ def setup_3d_rig(rig, cam): # Build the widgets root_widget = create_root_widget("Camera_Root") camera_widget = create_camera_widget("Camera") + camera_offset_widget = create_camera_offset_widget("Camera_offset") aim_widget = create_aim_widget("Aim") # Add the custom bone shapes pose_bones["Root"].custom_shape = root_widget pose_bones["Aim"].custom_shape = aim_widget pose_bones["Camera"].custom_shape = camera_widget + pose_bones["Camera_offset"].custom_shape = camera_offset_widget - # Set the "At" field to the shape mecanism + # Set the "Override Transform" field to the mechanism position pose_bones["Aim"].custom_shape_transform = pose_bones["Aim_shape_rotation-MCH"] # Add constraints to bones @@ -243,7 +264,8 @@ def create_2d_bones(context, rig, cam): driver = center_drivers[1].driver driver.type = 'SCRIPTED' - driver.expression = '({distance_x} - (left_x-right_x))*(res_y/res_x)/2 + (left_y + right_y)/2'.format(distance_x=corner_distance_x) + driver.expression = '({distance_x} - (left_x-right_x))*(res_y/res_x)/2 + (left_y + right_y)/2'.format( + distance_x=corner_distance_x) for direction in ('x', 'y'): for corner in ('left', 'right'): @@ -324,7 +346,8 @@ def create_2d_bones(context, rig, cam): # Focal length driver driver = cam.data.driver_add('lens').driver - driver.expression = 'abs({distance_z} - (left_z + right_z)/2 + cam_z) * 36 / frame_width'.format(distance_z=corner_distance_z) + driver.expression = 'abs({distance_z} - (left_z + right_z)/2 + cam_z) * 36 / frame_width'.format( + distance_z=corner_distance_z) var = driver.variables.new() var.name = 'frame_width' @@ -369,7 +392,8 @@ def create_2d_bones(context, rig, cam): # Shift driver X driver = cam.data.driver_add('shift_x').driver - driver.expression = 'rotation_shift * (((left_x + right_x)/2 - cam_x) * lens / abs({distance_z} - (left_z + right_z)/2 + cam_z) / 36)'.format(distance_z=corner_distance_z) + driver.expression = 'rotation_shift * (((left_x + right_x)/2 - cam_x) * lens / abs({distance_z} - (left_z + right_z)/2 + cam_z) / 36)'.format( + distance_z=corner_distance_z) var = driver.variables.new() var.name = 'rotation_shift' @@ -405,7 +429,8 @@ def create_2d_bones(context, rig, cam): # Shift driver Y driver = cam.data.driver_add('shift_y').driver - driver.expression = 'rotation_shift * -(({distance_y} - (left_y + right_y)/2 + cam_y) * lens / abs({distance_z} - (left_z + right_z)/2 + cam_z) / 36 - (res_y/res_x)/2)'.format(distance_y=corner_distance_y, distance_z=corner_distance_z) + driver.expression = 'rotation_shift * -(({distance_y} - (left_y + right_y)/2 + cam_y) * lens / abs({distance_z} - (left_z + right_z)/2 + cam_z) / 36 - (res_y/res_x)/2)'.format( + distance_y=corner_distance_y, distance_z=corner_distance_z) var = driver.variables.new() var.name = 'rotation_shift' @@ -478,7 +503,10 @@ def build_camera_rig(context, mode): cam.location = (0.0, -1.0, 0.0) # Move the camera to the correct position cam.parent = rig cam.parent_type = "BONE" - cam.parent_bone = "Camera" + if mode == "2D": + cam.parent_bone = "Camera" + else: + cam.parent_bone = "Camera_offset" # Change display to BBone: it just looks nicer rig.data.display_type = 'BBONE' diff --git a/add_camera_rigs/create_widgets.py b/add_camera_rigs/create_widgets.py index 72a8c70d071041aecba28629870b8deebd42051e..4aeea272db672ac553c58c91911795fa76a3829b 100644 --- a/add_camera_rigs/create_widgets.py +++ b/add_camera_rigs/create_widgets.py @@ -54,8 +54,8 @@ def create_corner_widget(name, reverse=False): obj = create_widget(name) if not obj.data.vertices: reverse = -1 if reverse else 1 - verts = (Vector((reverse * 0.0, 0.0, 0.0)), - Vector((reverse * 0.0, 1.0, 0.0)), + verts = (Vector((reverse * 0.0, 0.0, 0.0)), + Vector((reverse * 0.0, 1.0, 0.0)), Vector((reverse * -0.1, 1.0, 0.0)), Vector((reverse * -0.1, 0.1, 0.0)), Vector((reverse * -1.0, 0.1, 0.0)), @@ -154,76 +154,59 @@ def create_camera_widget(name): """Create a camera control widget""" obj = create_widget(name) if not obj.data.vertices: - verts = [(0.27513638138771057, 0.0, -0.27513638138771057), - (0.359483003616333, 0.0, -0.14890272915363312), - (0.38910162448883057, 0.0, 0.0), - (0.359483003616333, 0.0, 0.1489027738571167), - (0.27513638138771057, 0.0, 0.27513638138771057), - (0.1489027589559555, 0.0, 0.359483003616333), - (-1.9481809943044937e-07, 0.0, 0.38910162448883057), - (-1.175054293867106e-07, 0.0, -0.38910162448883057), - (0.148903027176857, 0.0, -0.35948291420936584), - (0.6635494828224182, 0.0, -0.09360162913799286), - (0.6635494828224182, 0.0, 0.09360162913799286), - (0.49765610694885254, 0.0, 0.09360162913799286), - (0.49765610694885254, 0.0, -0.09360168874263763), - (0.6635494828224182, 0.0, 0.17350149154663086), - (0.6635494828224182, 0.0, -0.17350149154663086), - (0.8751950263977051, 0.0, 0.0), - (-0.14890296757221222, 0.0, 0.35948291420936584), - (-0.14890283346176147, 0.0, -0.359483003616333), - (-0.27513641119003296, 0.0, -0.2751363217830658), - (-0.359483003616333, 0.0, -0.14890272915363312), - (-0.38910162448883057, 0.0, 0.0), - (-0.359483003616333, 0.0, 0.1489028036594391), - (-0.2751363217830658, 0.0, 0.27513641119003296), - (1.0342557033027333e-07, 0.0, 0.8751950263977051), - (0.17350155115127563, 0.0, 0.6635494828224182), - (-0.17350146174430847, 0.0, 0.6635494828224182), - (0.09360174089670181, 0.0, 0.49765610694885254), - (-0.09360159188508987, 0.0, 0.49765610694885254), - (-0.09360159188508987, 0.0, 0.6635494828224182), - (0.09360168874263763, 0.0, 0.6635494828224182), - (-0.0936015248298645, 0.0, -0.6635494828224182), - (0.09360174834728241, 0.0, -0.6635494828224182), - (0.09360172599554062, 0.0, -0.49765610694885254), - (-0.09360159933567047, 0.0, -0.49765610694885254), - (0.1735016107559204, 0.0, -0.6635494828224182), - (-0.1735014021396637, 0.0, -0.6635494828224182), - (9.422691960025986e-08, 0.0, -0.8751950263977051), - (-0.8751950263977051, 0.0, 0.0), - (-0.6635494828224182, 0.0, 0.17350131273269653), - (-0.6635494828224182, 0.0, -0.17350167036056519), - (-0.49765610694885254, 0.0, 0.0936015397310257), - (-0.49765610694885254, 0.0, -0.0936017706990242), - (-0.6635494828224182, 0.0, -0.09360179305076599), - (-0.6635494828224182, 0.0, 0.09360147267580032), - (-0.16527177393436432, 0.0, 0.1652718484401703), - (-0.21593798696994781, 0.0, 0.08944448828697205), - (-0.23372963070869446, 0.0, 0.0), - (-0.21593798696994781, 0.0, -0.08944445103406906), - (-0.1652718484401703, 0.0, -0.16527177393436432), - (-0.08944450318813324, 0.0, -0.21593798696994781), - (-0.0894445851445198, 0.0, 0.21593795716762543), - (0.0894446149468422, 0.0, -0.21593795716762543), - (-7.058439166485186e-08, 0.0, -0.23372963070869446), - (-1.1702535118729429e-07, 0.0, 0.23372963070869446), - (0.08944445848464966, 0.0, 0.21593798696994781), - (0.1652718037366867, 0.0, 0.1652718037366867), - (0.21593798696994781, 0.0, 0.08944446593523026), - (0.23372963070869446, 0.0, 0.0), - (0.21593798696994781, 0.0, -0.08944445848464966), - (0.1652718037366867, 0.0, -0.1652718037366867)] - + verts = [(0.275136, 0, -0.275136), (0.359483, 0, -0.148903), + (0.389102, 0, 0), (0.359483, 0, 0.148903), + (0.275136, 0, 0.275136), (0.148903, 0, 0.359483), + (-1.94818e-07, 0, 0.389102), (-1.17505e-07, 0, -0.389102), + (0.148903, 0, -0.359483), (0.663549, 0, -0.0936016), + (0.663549, 0, 0.0936016), (0.497656, 0, 0.0936016), + (0.497656, 0, -0.0936017), (0.663549, 0, 0.173501), + (0.663549, 0, -0.173501), (0.875195, 0, 0), + (-0.148903, 0, 0.359483), (-0.148903, 0, -0.359483), + (-0.275136, 0, -0.275136), (-0.359483, 0, -0.148903), + (-0.389102, 0, 0), (-0.359483, 0, 0.148903), + (-0.275136, 0, 0.275136), (1.03426e-07, 0, 0.875195), + (0.173502, 0, 0.663549), (-0.173501, 0, 0.663549), + (0.0936017, 0, 0.497656), (-0.0936016, 0, 0.497656), + (-0.0936016, 0, 0.663549), (0.0936017, 0, 0.663549), + (-0.0936015, 0, -0.663549), (0.0936017, 0, -0.663549), + (0.0936017, 0, -0.497656), (-0.0936016, 0, -0.497656), + (0.173502, 0, -0.663549), (-0.173501, 0, -0.663549), + (9.42269e-08, 0, -0.875195), (-0.875195, 0, 0), + (-0.663549, 0, 0.173501), (-0.663549, 0, -0.173502), + (-0.497656, 0, 0.0936015), (-0.497656, 0, -0.0936018), + (-0.663549, 0, -0.0936018), (-0.663549, 0, 0.0936015), + ] edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8), (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16, 22), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17), (6, 16), (23, 24), (23, 25), (24, 29), (25, 28), (26, 29), (27, 28), (31, 32), (30, 33), (32, 33), (31, 34), (30, 35), (34, 36), (35, 36), (37, 38), (37, 39), (38, 43), (39, 42), (40, 41), (40, 43), (41, 42), - (50, 53), (49, 52), (44, 45), (45, 46), (46, 47), (47, 48), (48, 49), - (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56), (56, 57), - (57, 58), (58, 59), (27, 26)] + (27, 26)] + + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + return obj + + +def create_camera_offset_widget(name): + """Create a camera offset control widget""" + obj = create_widget(name) + if not obj.data.vertices: + verts = [(0.23286, 0, 0), (0.215135, 0, 0.0891117), + (0.164657, 0, 0.164657), (0.0891117, 0, 0.215135), + (0, 0, 0.23286), (-0.0891117, 0, 0.215135), + (-0.164657, 0, 0.164657), (-0.215135, 0, 0.0891117), + (-0.23286, 0, 0), (-0.215135, 0, -0.0891117), + (-0.164657, 0, -0.164657), (-0.0891117, 0, -0.215135), + (0, 0, -0.23286), (0.0891117, 0, -0.215135), + (0.164657, 0, -0.164657), (0.215135, 0, -0.0891117), + ] + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), + (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), + (15, 0)] mesh = obj.data mesh.from_pydata(verts, edges, [])