MatrixLens Not working?

I’m trying to make a texture camera w/a custom MatrixLens. As a test, I’ve been trying to create a MatrixLens that mimics the lens of the default camera created by “base.makeCamera”.

I pulled the perspective projection calculations directly out of perspectiveLens.cxx. I also set all of the available lens variables to match that of the default camera. However, when I toggle to my MatrixLens I always get a blank screen.

Have I totally bungled something here or is this an issue w/MatrixLens.

My code is below,

import direct.directbase.DirectStart

from direct.showbase.DirectObject import DirectObject

from pandac.PandaModules import *
from pandac.PandaModules import LensNode
from pandac.PandaModules import Point3,Vec3,Vec4 
from pandac.PandaModules import Mat4
from pandac.PandaModules import MatrixLens

class LensTest(DirectObject):
    def __init__(self):
        #setup the texture buffer viewer
        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        self.accept("m", self.matrixLens) #Press M to see the matrixlens
        self.accept("d", self.defaultLens) #press D to see the default lens
        base.bufferViewer.setCardSize(1.0, 0.0)
        #we get a handle to the default window
        #we now get buffer thats going to hold the texture of our new scene
        self.altBuffer=mainWindow.makeTextureBuffer("perspectiveSurface", 512, 512)
        #now we have to setup a new scene graph to make this scene

        #this takes care of setting up ther camera properly
        #setup something to look at in the texture view
        #This is just a basic plane w/a texture on it
        self._backdropTex = loader.loadModel("assets/models/sets/GypsyCamp/Backdrop.egg")
        #put the default camera and the texture camera at the same
        #relative position
        #Fetch the default lens to use as referenc
        self._defaultLens = self.altCam.node().getLens()
        #setup something to look at in the main view
        #This is just a basic plane w/a texture on it
        #This part is really just so you're not seeing a blank screen when you start up
        self._backdrop = loader.loadModel("assets/models/sets/GypsyCamp/Backdrop.egg")
        print "AspectRatio: "+str(self._defaultLens.getAspectRatio())
        print "Default Film Size: "+str(self._defaultLens.getFilmSize())
        print "Default Focal Length: "+str(self._defaultLens.getFocalLength())
        print "Default Coordinate system: "+str(self._defaultLens.getCoordinateSystem())
        print "Default Far: "+str(self._defaultLens.getFar())
        print "Default Near: "+str(self._defaultLens.getNear())
        print "Default FOV: "+str(self._defaultLens.getFov())
        print "Default Keystone: "+str(self._defaultLens.getKeystone())
        print "Default ViewMat: "
        print str(self._defaultLens.getViewMat())
        print "Default Projection Matrix"
        print (str(self._defaultLens.getProjectionMat()))
        #Compute the projection matrix as done in perspectiveLens.cxx
        fl = self._defaultLens.getFocalLength()
        fFar = self._defaultLens.getFar();
        fNear = self._defaultLens.getNear();
        far_minus_near = fFar-fNear;
        a = (fFar + fNear);
        b = -2.0 * fFar * fNear;
        newProj =Mat4(  fl,  0.0,  0.0,  0.0,
                        0.0,  0.0,     a,  1.0,
                        0.0,    fl,  0.0,  0.0,
                        0.0,  0.0,     b,  0.0)
        #create a new MatrixLens and set it up to copy the default camera
        self._matLens = MatrixLens()
        #print out all the custom camera values and compare them w/the default camera
        #they should match up perfectly
        print "Custom Aspect Ratio: "+str(self._matLens.getAspectRatio())
        print "Custom Film Size: "+str(self._matLens.getFilmSize())
        print "Custom Focal Length: "+str(self._matLens.getFocalLength())
        print "Custom Coordinate system: "+str(self._matLens.getCoordinateSystem())
        print "Custom Far: "+str(self._matLens.getFar())
        print "Custom Near: "+str(self._matLens.getNear())
        print "Custom FOV: "+str(self._matLens.getFov())
        print "Custom Keystone: "+str(self._matLens.getKeystone())
        print "Custom ViewMat: "
        print str(self._matLens.getViewMat())
        print "User projection Matrix"
        print (str(self._matLens.getProjectionMat()))

#Switching to the matrix lens makes the scene disappear
#Even though it has exactly the same parameters as the default lens
    def matrixLens(self):
        print("Matrix lens")
#The default lens looks just fine
    def defaultLens(self):
        print("Default lens")

lensTest = LensTest()

I just pasted in your code, and when I press the ‘m’ and the ‘d’ keys to toggle between the Matrix lens and the Default lens, the view doesn’t change.

Am I misunderstanding the problem?


Hi, thanks for your attention on this.

In order to see my issue you have to press ‘v’ to bring up the texture buffer viewer. With the texture buffer view up pressing ‘m’ and ‘d’ toggles which lens is being used on the camera that is rendering the scene to the texture. Sorry for not mentioning this in my previous post.

Thanks again for your attention.

It looks like you omitted part of the matrix calculation from perspectiveLens.cxx. You need to add the following lines:

        a /= far_minus_near
        b /= far_minus_near

After you have computed a, b, and far_minus_near.

With this change, it makes the matrices come out the same.

Note that I discovered this by comparing lensTest._matLens.getProjectionMat() with lensTest._defaultLens.getProjectionMat(). They should have been the same, but they were different–by a scale factor of about 1 : 1000, which is approximately far_minus_near.


Arghh! Right on the money! You don’t even want to know how long I spent staring at that code. Thanks a million!