This script takes user inputed data and placer a camera exactly the same 3D location and rotation as was used on set. When shooting, find a base line in the shot and measure the length . Then measure the distance from either end to the camera. Also measure the following: the camera hight (relative to the base line), the dutch and tilt and how far the centre of the shot is along the base line.
# ##### 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 #####
import bpy, math
class CameraPanel(bpy.types.Panel):
bl_label = "Camera Setup"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "render"
def draw(self, context):
layout = self.layout
scn = bpy.context.scene
row = layout.row()
col = row.column()
col.label(text="Camera Placement Data:")
col.prop( scn, "base_line" )
col.prop( scn, "camera_centre" )
col.prop( scn, "camera_left" )
col.prop( scn, "camera_right" )
col.prop( scn, "camera_height" )
col.prop( scn, "camera_dutch" )
col.prop( scn, "camera_tilt" )
row = layout.row()
col.operator( "camera.placer_op" )
col.label(text="General Camera Data:")
col.prop( scn, "focal_length" )
col.prop( scn, "focus_distance" )
col.prop( scn, "f_stop" )
col.operator( "camera.general_settings" )
class CameraPlacer(bpy.types.Operator):
bl_idname = "camera.placer_op"
bl_label = "Place Camera"
def execute(self, context):
#Convert user inputs to float (not string)
Base_line = bpy.context.scene.base_line
Base_line = float(Base_line)
Camera_centre = bpy.context.scene.camera_centre
Camera_centre = float(Camera_centre)
Camera_left = bpy.context.scene.camera_left
Camera_left = float(Camera_left)
Camera_right = bpy.context.scene.camera_right
Camera_right = float(Camera_right)
Camera_height = bpy.context.scene.camera_height
Camera_height = float(Camera_height)
Camera_dutch = bpy.context.scene.camera_dutch
Camera_dutch = float(Camera_dutch)
Camera_tilt = bpy.context.scene.camera_tilt
Camera_tilt = float(Camera_tilt)
#Work out left angle
Angle_left = (Base_line**2 + Camera_left**2 - Camera_right**2) / (2 * Base_line * Camera_left)
Angle_left = math.acos(Angle_left)
#Find cordinates
Stantion_point_x = (Camera_left) * math.cos(Angle_left)
Stantion_point_y = (Camera_left) * math.sin(Angle_left)
#Work out tilt and dutch
Final_tilt = 90 + Camera_tilt
Final_tilt = math.radians(Final_tilt)
Final_dutch = math.radians(Camera_dutch)
# Work out Z rotation
#calculate CC to SP
Angle_left = (Base_line**2 + Camera_left**2 - Camera_right**2) / (2 * Base_line * Camera_left)
d = (Camera_centre**2 + Camera_left**2 - 2 * Camera_centre * Camera_left * Angle_left)
CC_to_SP = math.sqrt(d)
#Stantion_point_x-CC
x = Stantion_point_x-Camera_centre
#Z_rotation
Z_rotation = math.acos((Stantion_point_y**2 + CC_to_SP**2 - x**2) / (2 * Stantion_point_y * CC_to_SP))
if Camera_centre > (Base_line / 2):
Z_rotation = 180 - (math.degrees(Z_rotation))
Z_rotation = -(math.radians(Z_rotation))
else:
Z_rotation = 180 - (math.degrees(Z_rotation))
Z_rotation = math.radians(Z_rotation)
bpy.ops.object.add(type='EMPTY', location=(Base_line, 0, 0))
bpy.data.objects['Empty'].name = "Base_left"
bpy.ops.object.add(type='EMPTY', location=(Camera_centre, 0, 0))
bpy.data.objects['Empty'].name = "Camera_centre"
bpy.ops.object.add(type='CAMERA', location=(Stantion_point_x, Stantion_point_y, Camera_height), rotation=(Final_tilt, Final_dutch, Z_rotation))
bpy.ops.object.add(type='EMPTY', location=(0, 0, 0))
bpy.data.objects['Empty'].name = "Base_right"
#Parent to Camera_right
bpy.ops.object.select_all(action='TOGGLE')
bpy.data.objects['Camera'].select = True
bpy.data.objects['Base_left'].select = True
bpy.data.objects['Camera_centre'].select = True
bpy.data.objects['Base_right'].select = True
bpy.ops.object.parent_set(type='OBJECT')
bpy.ops.object.select_all(action='TOGGLE')
return {'FINISHED'}
class CameraSettings(bpy.types.Operator):
bl_idname = "camera.general_settings"
bl_label = "Update Settings"
def execute(self, context):
bpy.data.cameras['Camera'].lens = bpy.context.scene.focal_length
bpy.data.cameras['Camera'].dof_distance = bpy.context.scene.focus_distance
bpy.data.cameras['Camera'].show_limits = True
return {'FINISHED'}
def register():
bpy.utils.register_class( CameraPanel )
bpy.utils.register_class( CameraPlacer )
bpy.utils.register_class( CameraSettings )
def unregister():
bpy.utils.register_class( CameraPanel )
bpy.utils.register_class( CameraPlacer )
bpy.utils.register_class( CameraSettings )
if __name__ == '__main__':
bpy.types.Scene.base_line = bpy.props.FloatProperty( name = "Base Line", default = 0, min = 0, precision = 5, description = "Length of Base line")
bpy.types.Scene.camera_centre = bpy.props.FloatProperty( name = "Camera Centre", default = 0, min = 0, precision = 5, description = "Distance from base line right to centre of the camera")
bpy.types.Scene.camera_left = bpy.props.FloatProperty( name="Camera Left", default = 0, min = 0, precision = 5, description = "Length of camera left side")
bpy.types.Scene.camera_right = bpy.props.FloatProperty( name="Camera Right", default = 0, min = 0, precision = 5, description = "Length of camera right side")
bpy.types.Scene.camera_height = bpy.props.FloatProperty( name="Camera Height", default = 0, precision = 5, description = "Height of camera oabove the base line")
bpy.types.Scene.camera_dutch = bpy.props.FloatProperty( name="Camera Dutch", default = 0, precision = 5, description = "Camera Dutch. Positive=right, negative=left")
bpy.types.Scene.camera_tilt = bpy.props.FloatProperty( name="Camera Tilt", default = 0, precision = 5, description = "Camera Tilt. Positive=lens up, negative=lens down")
bpy.types.Scene.focal_length = bpy.props.FloatProperty( name="Focal Length", default = 35, precision = 3, description = "Perspective Camera lens value in Millimetres" )
bpy.types.Scene.focus_distance = bpy.props.FloatProperty( name="Focus Distance", default = 0, precision = 3, description = "Distance to object in Focus" )
bpy.types.Scene.f_stop = bpy.props.FloatProperty( name="F. Stop", default = 5.6, precision = 3, description = "F. Stop value of the camera" )
register()
This script should be useful for matching locked of shots and possibly pans (with some work) to CGI. Sorry if that’s a bad explination, if you have any questions I’ll try to explain it better. It is based on the method used in the VES Handbook.
Thanks
Tom