Well sadly, no one was brave enough to reply, but since I had to get this done I found the solution in the sflender script. It was a little complicated, and since my version is a little shorter, and nobody had this on the forums, I figured I’d post it.
So in summary, there are two functions that are desperately needed in the Blender Python API. The functions below (Perspective, Ortho) should be reproduced in blender and be able to receive a camera object, and return a perspective or orthographic matrix.
Right now my cropToObject() function is calling those other functions and converting the results to allow me to find the border around an object so that I can automatically crop the render to that object. This function also returns a two-dimensional array containing the x/y position of the upper left corner of the object in the render. Hope this helps anyone trying to map global world locations to two-dimensional (2d to 3d) camera / render coordinates.
def cropToObject(ob,camera):
print "crop to object"
coords = ob.getBoundBox()
context = SCENE.getRenderingContext()
w = context.sizeX
h = context.sizeY
ax = context.aspectX
ay = context.aspectY
mW = w/2
mH = h/2
cam = camera.getInverseMatrix()
cam.transpose()
cmra = camera.getData()
fovy = atan(0.5/(float(w*ax)/float(h*ay))/(cmra.lens/32))
fovy = fovy *360/pi
if cmra.type == 'ortho':
m2 = Ortho(fovy,float(w*ax)/float(h*ay),cmra.clipStart, cmra.clipEnd,17) #cmra.scale)
else:
m2 = Perspective(fovy,float(w*ax)/float(h*ay),cmra.clipStart, cmra.clipEnd)
mP = m2 * cam
xPos,yPos = w,0
x1, y1, x2, y2 = 1.0, 1.0, 0, 0
for p in coords:
p.resize4D()
p = mP * p
x = int((p[0]/p[3])*mW)+mW
y = int((p[1]/p[3])*mH)+mH
if x < xPos: xPos = x
if y > yPos: yPos = y
v = Vector(x*1.0/w,y*1.0/h,0)
if v.x < x1: x1 = v.x
if v.y < y1: y1 = v.y
if v.x > x2: x2 = v.x
if v.y > y2: y2 = v.y
if xPos < 0: xPos = 0
if yPos < 0: yPos = 0
return [x1, y1, x2, y2],[w-xPos,h-yPos]
# ---------------------------------------------------------------
# Function : Perspective
# Inputs :
# OutPuts :
# Description :
# ---------------------------------------------------------------
def Perspective(fovy, aspect, near,far):
top = near * tan(fovy * pi / 360.0)
bottom = -top
left = bottom*aspect
right= top*aspect
x = (2.0 * near) / (right-left)
y = (2.0 * near) / (top-bottom)
a = (right+left) / (right-left)
b = (top+bottom) / (top - bottom)
c = - ((far+near) / (far-near))
d = - ((2*far*near)/(far-near))
return Matrix([x,0.0,a,0.0],[0.0,y,b,0.0],[0.0,0.0,c,d],[0.0,0.0,-1.0,0.0])
# ---------------------------------------------------------------
# Function f: Ortho
# Inputs :
# OutPuts :
# Description :
# ---------------------------------------------------------------
def Ortho(fovy, aspect ,near,far,scale):
top = near * tan(fovy * pi / 360.0) * (scale * 10)
bottom = -top
left = bottom * aspect
right= top * aspect
rl = right-left
tb = top-bottom
fn = near-far
tx = -((right+left)/rl)
ty = -((top+bottom)/tb)
tz = ((far+near)/fn)
return Matrix([2.0/rl,0.0,0.0,tx],[0.0,2.0/tb,0.0,ty],[0.0,0.0,2.0/fn,tz],[0.0,0.0,0.0,1.0])