Search code examples
pythonapimatrixprojectionmaya

Project a 2D Point to 3D using a depth value. Maya Python API


I'm trying to figure out how to project a 3D point from a 2D Point. I'd like to be able to give it a depth value to project to. Anyone have any examples for maya?

Thanks!

Here's the best I've been able to do:

def screenToWorld(point2D=None,
                  depth=None,
                  viewMatrix=None,
                  projectionMatrix=None,
                  width=None,
                  height=None):
    '''
    @param point2D - 2D Point.
    @param viewMatrix - MMatrix of modelViewMatrix (World inverse of camera.)
    @param projectionMatrix - MMatrix of camera's projectionMatrix.
    @param width - Resolution width of camera.
    @param height - Resolution height of camera.
    Returns worldspace MPoint.
    '''
    point3D = OpenMaya.MPoint()
    point3D.x = (2.0 * (point2D[0] / width)) - 1.0
    point3D.y = (2.0 * (point2D[1] / height)) - 1.0

    viewProjectionMatrix = (viewMatrix * projectionMatrix)

    point3D.z = viewProjectionMatrix(3, 2)
    point3D.w = viewProjectionMatrix(3, 3)
    point3D.x = point3D.x * point3D.w
    point3D.y = point3D.y * point3D.w
    point3D = point3D * viewProjectionMatrix.inverse()

    return point3D

As you can tell it does not use the depth value. I'm not sure how to incorporate it using the projection matrix and viewMatrix.

Any help is greatly appreciated! -Chris


Solution

  • So I think i got a solution for this:

    import maya.OpenMaya as OpenMaya
    
    def projectPoint(worldPnt, camPnt, depth):
        '''
        @param worldPnt - MPoint of point to project. (WorldSpace)
        @param camPnt - MPoint of camera position. (WorldSpace)
        @param depth - Float value of distance.
        Returns list of 3 floats.
        '''
        #Get vector from camera to point and normalize it.
        mVec_pointVec = worldPnt - camPnt
        mVec_pointVec.normalize()
    
        #Multiply it by the depth and the camera offset to it.
        mVec_pointVec *= depth
        mVec_pointVec += OpenMaya.MVector(camPnt.x, camPnt.y, camPnt.z)
    
        return [mVec_pointVec.x, mVec_pointVec.y, mVec_pointVec.z]
    

    I didn't really need to convert it to 2d then back to 3d. I just needed to extend the vector from camera.