Source code for cinema_python.images.camera_utils

"""
A collection of utilities for cinema camera handling.
"""

import numpy as np
import math


[docs]def convert_pose_to_camera(iPosition, iFocalPoint, iViewUp, pose, camType): """Converts input eye, focal point and view up using the pose and camType and returns (neweye, newfp, newviewup)""" def VecNormalize(V1): return V1/np.linalg.norm(V1) def VecMatrixMul(V, M): return [ V[0]*M[0][0] + V[1]*M[0][1] + V[2]*M[0][2], V[0]*M[1][0] + V[1]*M[1][1] + V[2]*M[1][2], V[0]*M[2][0] + V[1]*M[2][1] + V[2]*M[2][2] ] def MatrixMatrixMul(mtx_a, mtx_b): tpos_b = zip(*mtx_b) rtn = [ [sum(ea*eb for ea, eb in zip(a, b)) for b in tpos_b] for a in mtx_a] return rtn iViewUp = VecNormalize(iViewUp) atvec = VecNormalize(np.subtract(iPosition, iFocalPoint)) rightvec = np.cross(atvec, iViewUp) m = [[rightvec[0], rightvec[1], rightvec[2]], [iViewUp[0], iViewUp[1], iViewUp[2]], [atvec[0], atvec[1], atvec[2]]] # OK because orthogonal thus invert equals trans mInv = [[m[0][0], m[1][0], m[2][0]], [m[0][1], m[1][1], m[2][1]], [m[0][2], m[1][2], m[2][2]]] mi = MatrixMatrixMul(mInv, pose) mf = MatrixMatrixMul(mi, m) newUp = VecMatrixMul(iViewUp, mf) if camType == "azimuth-elevation-roll": pi = np.subtract(iPosition, iFocalPoint) pr = VecMatrixMul(pi, mf) pf = np.add(pr, iFocalPoint) return (pf, iFocalPoint, newUp) elif camType == "yaw-pitch-roll": pi = np.subtract(iFocalPoint, iPosition) pr = VecMatrixMul(pi, mf) pf = np.add(pr, iPosition) return (iPosition, pf, newUp) else: print("ERROR unexpected camera type") return (iPosition, iFocalPoint, iViewUp)
[docs]def nearest_camera(poses, mnext): """ find index of the pose that is closest match to mnext """ # TODO: profile, and then if important, optimize this # 1: only need to compare 2 of 3 vectors since they are orthogonal # 2: will be faster still if we push the matrices into numpy # (flatten too perhaps) # algorithm: reduce to distance value, and then pick the index of # pose with least distance to mnext best = -1 bestdist = -1 primary = 0 secondary = 1 tertiary = 2 for i in range(0, len(poses)): cand = poses[i] dist1 = math.sqrt( math.pow(mnext[primary][0]-cand[primary][0], 2) + math.pow(mnext[primary][1]-cand[primary][1], 2) + math.pow(mnext[primary][2]-cand[primary][2], 2)) dist2 = math.sqrt( math.pow(mnext[secondary][0]-cand[secondary][0], 2) + math.pow(mnext[secondary][1]-cand[secondary][1], 2) + math.pow(mnext[secondary][2]-cand[secondary][2], 2)) dist3 = math.sqrt( math.pow(mnext[tertiary][0]-cand[tertiary][0], 2) + math.pow(mnext[tertiary][1]-cand[tertiary][1], 2) + math.pow(mnext[tertiary][2]-cand[tertiary][2], 2)) dist = dist1*dist1+dist2*dist2+dist3*dist3 if best == -1: bestdist = dist best = i if dist < bestdist: # print "NB", dist, i, dist-bestdist bestdist = dist best = i return best