# convert world coordinates to camera (render) coordinates?

I’m writing a script to automatically crop a render to certain objects (using blender’s border functionality). I’m using the getBoundBox() function to get the bounds of the object. However, I’m having a hard time translating camera coordinates into render coordinates to give blender the correct borders to render with. My code is below. I based it on this very helpful post. Right now the border positions change depending on how much the user is zoomed in / panned over. I noticed that using getViewMatrix() instead of getPerspectiveMatrix() gives values that don’t change with view/pan, but I still don’t know how to translate to render coordinates.

``````
#dehomogenizes a vector
def dehom(v):
ret = Vector(v[0]/v[3],v[1]/v[3],v[2]/v[3])
return ret

def cropToObject(ob,cam):
print "crop to object"
cam.select(1)
Window.CameraView()

pm = Window.GetPerspMatrix()
#pm = Window.GetViewMatrix()
coords = ob.getBoundBox()

x, y, x2, y2 = 1.0, 1.0, 0, 0
#order is important!
for c in coords:
v = Vector(c)
v.resize4D()
v = v * pm
v = dehom(v)
v += Vector(0.5,0.5,0.5)
print v
if v.x &lt; x: x = v.x
if v.y &lt; y: y = v.y
if v.x &gt; x2: x2 = v.x
if v.y &gt; y2: y2 = v.y

print 'coords',x,y,x2,y2
return [x, y, x2, y2]

``````

bydesign

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 &lt; xPos: xPos = x
if y &gt; yPos: yPos = y

v = Vector(x*1.0/w,y*1.0/h,0)
if v.x &lt; x1: x1 = v.x
if v.y &lt; y1: y1 = v.y
if v.x &gt; x2: x2 = v.x
if v.y &gt; y2: y2 = v.y

if xPos &lt; 0: xPos = 0
if yPos &lt; 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])

``````