1
$\begingroup$

I am writing a script that randomizes camera position in relation to a single object, but most of the time when I render the object is not in view so I get the plain grey background. I think there is a flaw in the class that reorients the camera so that the object is within the frame. Can help me? Here is the class meant to point the camera back towards the object. I am on blender version 2.81.16, which is the latest version that is compatible with a plug in I need.

def point_camera(camera, point=(0., 0., 0.)):
    """ point camera to 'location' looking directly at origin
    args:
        location: list of 3 representing the location to point at
        origin: list of floats that represent where the camera
        will be looking at
    returns:
        None
    """
    point = Vector(point)
    camera_location = camera.location
    direction = point - camera_location
    quaternion_rotation = direction.to_track_quat('-Z', 'Y')
    euler_rotation = quaternion_rotation.to_euler()
    camera.rotation_euler = euler_rotation

Thank you

$\endgroup$
3
  • 1
    $\begingroup$ Instead of scripting the camera rotation, wouldn’t it be simpler and easier to just add a constraint to track the camera to the object? The script would then just need to concern itself with the location and the constraint will do the rest. $\endgroup$ Jun 22 '20 at 5:40
  • $\begingroup$ You might want to look at this answer for more information $\endgroup$
    – Gorgious
    Jun 22 '20 at 6:42
  • 1
    $\begingroup$ Recommend you work in global coordinates camera_location = camera.matrix_world.to_translation() and set the cameras world matrix. Also at play here if pointing to an object is the objects origin can be anywhere... so if using a track to constraint may be easiest to track to an empty, and place the empty at objects bounding box centre (for example) $\endgroup$
    – batFINGER
    Jun 22 '20 at 7:04
0
$\begingroup$

Global Coordinates

Recommend you work in global coordinates

camera_location = camera.matrix_world.to_translation() 

and set the cameras world matrix.

import bpy
from mathutils import Vector

def point_camera(camera, point=Vector()):
    point = Vector(point) # recast len 3 iterable
    cmw = camera.matrix_world
    direction = cmw.translation - point
    M = direction.to_track_quat('Z', 'Y').to_matrix().to_4x4()
    M.translation = cmw.translation

    camera.matrix_world = M
    
# test call

point_camera(bpy.context.scene.camera, (0, 0, 0))

Also at play here if pointing to an object is the objects origin can be anywhere... so if using a track to constraint may be easiest to track to an empty, and place the empty at objects bounding box centre (for example)

Given a mesh object ob its global bounding box centre location would be

bbc = ob.matrix_world @ sum((Vector(v) for v in ob.bound_box), Vector()) / 8 

Note: Object constraints, drivers and keyframes all work together to create an objects world matrix. Keep this in mind, as code above that sets the matrix world may produce strange results on constrained (or otherwise set) objects.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.