camera from location, target and up vectors

i’ve spent a couple of days now with no result. I have to import camera defined by location, target and up vectors. The only way i have now is to make empties at vectors positions and add damped tracks to camera which is, with a few hundreds of cameras, pretty messy and useless. I am sure there must be a few lines resulting in a matrix to be applied to camera object and it is done. Pity I wasn’t paying much attention in math classes years ago :frowning:

Please help, i feel desperate…
c.

The previous week I did a test for my project were I tried to mimic the LookAt command of Matrix class.


import bpy
from mathutils import Vector, Matrix

#https://github.com/mono/opentk/blob/master/Source/OpenTK/Math/Matrix4.cs
def matrixLookat(eye, target, up):
    z = eye - target
    x = up.cross(z)
    y = z.cross(x)
    
    x.normalize()
    y.normalize()
    z.normalize()
    
    rot = Matrix()
    rot[0][0] = x[0]
    rot[0][1] = y[0]
    rot[0][2] = z[0]
    rot[0][3] = 0
    rot[1][0] = x[1]
    rot[1][1] = y[1]
    rot[1][2] = z[1]
    rot[1][3] = 0
    rot[2][0] = x[2]
    rot[2][1] = y[2]
    rot[2][2] = z[2]
    rot[2][3] = 0
    
    # eye not need to be minus cmp to opentk 
    # perhaps opentk has z inverse axis
    tran = Matrix.Translation(eye)
    return tran * rot

class LookatOperator(bpy.types.Operator):
    bl_idname = "object.lookat_operator"
    bl_label = "Object transform Look At Target"
    
    def execute(self, context):
        if len(context.selected_objects) != 2:
            print("Please select two objects")
            return {"FINISHED"}
        
        list = context.selected_objects
        obj1 = context.object # active_object
        list.remove(obj1)
        obj2 = list[0]
        print("Source: " + str(obj1))
        print("Target: " + str(obj2))
        
        obj1.matrix_world = matrixLookat(
            obj1.matrix_world.translation,
            obj2.matrix_world.translation,
            Vector([0, 0, 1]))
        
        return {"FINISHED"}

bpy.utils.register_class(LookatOperator)

I am not sure if this can be of any use, perhaps it could be added in a scene handler to updated in each animation frame for all of the cameras.

Also keep in mind that you can generate fake positions based on existing ones, and you do not need to create hundreds of empties to track them to.


Vector([0, 0, 0]) + (Vector([0, 0, 1]) * 10)
#Result
Vector((0.0, 0.0, 10.0))

Interpretation of this expression
position_of_object + (z_global_axis_in_this_case * ten_units)

Thanks a million const, that’s exactly what i needed
c.

This could be simplified:

rot[0][0] = x[0]
rot[0][1] = y[0]
rot[0][2] = z[0]

rot[0][:3] = x