Hello Peter,
following code will create an animation where each animation track camera will have same position as corresponding image camera but looking at next camera with roll equal to 0:
import Metashape, math
chunk = Metashape.app.document.chunk
track = chunk.addCameraTrack()
track.label = "Camera Track Path"
keyframes = list()
T = chunk.transform.matrix
cameras = [camera for camera in chunk.cameras if camera.type != Metashape.Camera.Type.Keyframe and camera.transform] # only regular aligned cameras not keyframe
for i in range(0, len(cameras) - 1):
cc1gc = T.mulp(cameras[i].center)
m = chunk.crs.localframe(cc1gc)
if 'PROJCS' not in chunk.crs.wkt and 'GEOGCS' in chunk.crs.wkt: #case of GEOGCS
cc1 = m.mulp(T.mulp(cameras[i].center))
cc2 = m.mulp(T.mulp(cameras[i + 1].center))
else:
cc1 = chunk.crs.project(T.mulp(cameras[i].center))
cc2 = chunk.crs.project(T.mulp(cameras[i + 1].center))
yaw = math.atan((cc2.x-cc1.x)/(cc2.y-cc1.y))*180.0/math.pi
pitch = math.asin((cc2.z-cc1.z)/(cc2-cc1).norm())*180.0/math.pi
if (cc2.y-cc1.y) < 0 :
yaw = yaw + 180
R = Metashape.Utils.ypr2mat(Metashape.Vector((yaw,90+pitch,0))) # Rotation matrix constructed from (yaw, pitch, roll) vector
R = Metashape.Matrix( [[m[0,0],m[0,1],m[0,2]], [m[1,0],m[1,1],m[1,2]], [m[2,0],m[2,1],m[2,2]]]).t() * R * Metashape.Matrix().Diag((1, -1, -1))
row = list()
for j in range(0, 3):
row.append(Metashape.Vector(R.row(j)))
row[j].size = 4
row[j].w = cc1gc[j]
row.append(Metashape.Vector([0, 0, 0, 1]))
M = Metashape.Matrix([row[0], row[1], row[2], row[3]])
pos = chunk.addCamera()
pos.type = Metashape.Camera.Type.Keyframe
pos.transform = T.inv() * M
keyframes.append(pos)
track.keyframes = keyframes
chunk.camera_track = track
print("Done")
Hope this can be useful,