Python: Convert a point into camera-space (BGE) For a particular object and a particular camera, I wish to convert each vertex into camera space, perform some maths on it and convert it back.

Specifically I need to convert the vertex first into world space, and then into camera space.

Something like:

v_world = obj.matrix_world * v.co
v_cam = cam.matrix_world.invert() * v_world


Which I could tidy up by doing:

# first create matrix that goes from object-space to camera-space
ob_to_cam = obj.matrix_world * cam.matrix_world.invert()

for v in ob.vertices:
    v_cam = ob_to_cam * v.co
    v_cam_out = my_maths_processing(v_cam)

    v.co = ob_to_cam.invert() * v_cam_out


Is this correct?  Is there a tidier way?

This link http://blenderartists.org/forum/archive/index.php/t-246525.html gives:

M1 = Cam.worldTransform # camera 4x4 transform matrix
M2 = Obj.worldTransform # object matrix
M = M1.inverted()*M2 # conventions valid for blender 2.62


There is another suggestion on the same page, to use:

bge.types.KX_Camera
bge.types.KX_Camera.world_to_camera


http://www.blender.org/documentation/blender_python_api_2_62_0/bge.types.html#bge.types.KX_Camera

http://www.blender.org/documentation/blender_python_api_2_62_0/bge.types.html#bge.types.KX_Camera.world_to_camera

But I'm unfamiliar with 'bge' -- blender game object. Should I be using this object?
The camera_to_world and its inverse world_to_camera transform matrices provide the simplest way to convert between camera and world space. However, the more difficult part is accessing the vertices in the game engine.

Getting vertices in the game engine requires three nested loops. First, loop through a game object's meshes, then loop through each mesh's materials, and finally get a VertexProxy for each index in the material. With the XYZ property on the proxy, we can multiply the world to camera transformational matrix by the vertex position to get the vertex in camera space coordinates.

After processing the vertex, multiple the camera to world matrix by the vertex and assign it to the XYZ property on the proxy.

import bge

scene = bge.logic.getCurrentScene()

camera = scene.cameras["Camera"]
cube = scene.objects["Cube"]

for mesh in cube.meshes:
    for material in mesh.materials:
        for i in range(mesh.getVertexArrayLength(material.material_index)):
            proxy = mesh.getVertex(material.material_index, i)
            vertex = camera.world_to_camera * proxy.XYZ

            #process vertex in camera space

            proxy.XYZ = camera.camera_to_world * vertex