Crash when setting FOV

I’ve isolated a bug that’s been bothering me (and ThomasEgi):

from pandac.PandaModules import loadPrcFileData, VBase2
loadPrcFileData("", "win-size 575 600")
from direct.directbase import DirectStart
base.camLens.setFov(VBase2(600.0 / 575.0, 1))
run()

Gives this error:

Traceback (most recent call last):
  File "/home/pro-rsoft/temp.py", line 6, in <module>
    run()
  File "/home/pro-rsoft/Projects/panda3d/direct/src/showbase/ShowBase.py", line 2306, in run
    self.taskMgr.run()
  File "direct/src/task/TaskNew.py", line 471, in run
    self.step()
  File "direct/src/task/TaskNew.py", line 429, in step
    self.mgr.poll()
  File "/home/pro-rsoft/Projects/panda3d/direct/src/showbase/ShowBase.py", line 1523, in __igLoop
    self.graphicsEngine.renderFrame()
AssertionError: !mat.is_nan() at line 280 of panda/src/pgraph/transformState.cxx

Whatever I fill in for the FOV, it won’t work. If I leave away that line, it suddenly works.
We’re running the 1.6.0 trunk from a few days ago.

Try this variant:

from pandac.PandaModules import loadPrcFileData, VBase2
loadPrcFileData("", "win-size 575 600\naspect-ratio 1")
from direct.directbase import DirectStart
base.camLens.setFov(VBase2(600.0 / 575.0, 1))
run()

What appears to be happening is Panda’s automatic aspect-ratio matching code, which attempts to match the aspect ratio of the lens to the aspect ratio of the window, is kicking in when the window gets actually created, which happens the first frame after you import DirectStart, and therefore after you have set an explicit aspect ratio with the two-parameter setFov().

These two efforts are competing, and there appears to be some bug in there that’s causing the fov to end up getting set to (0, 0) instead, which leads to a matrix full of NaN’s. I can fix the bug, but I don’t think this is what you intended anyway. Putting “aspect-ratio 1” in the Config.prc sets a fixed aspect ratio, and tells Panda not to try to auto-adjust the aspect ratio any more (and allows the aspect ratio you set in code to stick).

Of course, you could also just put an explicit aspect ratio of 1.04348 (that is, 600/575) in your Config.prc, and never mind the call to setFov.

Or, you could just use the one-parameter setFov(), and let Panda go ahead and automatically match the aspect ratio to the window. That would work too.

David

OK, thanks.
I discovered the bug when resizing a window to a WxH size where H is higher than W, when using ARToolKit. Apparently, ARToolKit sets the Fov after doing some fancy calculations to make it somewhat match the webcam’s fov. Is it in this case thus not needed for panda to set the FOV based on the aspect ratio?

Well, you only want to have one entity trying to set the aspect ratio. If you use the two-component setFov, you are setting the aspect ratio yourself; in this case, you don’t want Panda to come along behind you and try to reset the aspect ratio to something else.

If you want to set the aspect ratio explicitly, you should disable Panda’s auto-setting of the aspect ratio. Presently, it looks like the only way to do this is by setting the aspect-ratio config variable at startup time (base.__configAspectRatio is a private variable; I guess we should add some accessor functions that allow you to change your mind at runtime whether you want Panda to manage the aspect ratio). If you disable Panda’s aspect ratio management, then future changes to the window shape will stretch the contents of the window rather than crop it.

If you want to let Panda manage the aspect ratio according to the window shape, then you should just use the one-parameter setFov. In this case, future changes to the window shape will crop the contents of the window rather than stretch it.

David

Ok, thanks for the explanation.