hello. i’ve been trying to figure this out for a while but so far i’ve come up with nothing.
i have the coordinates of a point in world space and i need to transform this point to normalized device coordinates using the active camera (lower left corner is -1, -1 and upper right is (1, 1)). how would one go about this? if it helps, the camera is assumed to have a perspective projection.
i want to achieve this automatically with a python script. the idea, in pseudo code, is this:
#get a vertex in world coordinates, (x, y, z)
vertex = getTheVertexSomehow()
#get the active camera
cam = bpy.context.scene.camera
#express the vertex in the normalized device coordinates
#(or image coordinates) that would result if rendering with the active camera
vertexNDC = this is where i'm stuck
that would just give me the position of the vertices of ‘Plane’ in world coordinates which is already given, as i described.
i need to use the active camera transform matrix and projection matrix to compute the position of the vertex in the coordinate frame of an image rendered using the active camera.
I was just using the AddMesh Torus AddOn and I noticed it has an entire section for aligning the mesh to the current viewport. Perhaps there is some code in there that might help? It is part of the standard Blender download so you’ll have to dig around to find the .py file.
import bpy
from mathutils import *
from math import *
# Getting width, height and the camera
scn = bpy.data.scenes['Scene']
w = scn.render.resolution_x*scn.render.resolution_percentage/100.
h = scn.render.resolution_y*scn.render.resolution_percentage/100.
cam = bpy.data.cameras['Camera']
camobj = bpy.data.objects['Camera']
# Some point in 3D you want to project v
v = bpy.context.scene.cursor_location
# Getting camera parameters
# Extrinsic
RT = camobj.matrix_world.inverted()
# Intrinsic
C = Matrix().to_3x3()
C[0][0] = -w/2 / tan(cam.angle/2)
ratio = w/h
C[1][1] = -h/2. / tan(cam.angle/2) * ratio
C[0][2] = w / 2.
C[1][2] = h / 2.
C[2][2] = 1.
C.transpose()
# Projecting v with the camera
p = C * RT * v
p /= p[2]
print(p)