AssertionError: has_mat() at line 555 of c:\temp\mkpr\panda3

run() File "C:\Panda3D-1.2.3\direct\src\showbase\ShowBase.py", line 1959, in run
self.taskMgr.run()
 File "C:\Panda3D-1.2.3\direct\src\task\Task.py", line 821, in run
self.step()
 File "C:\Panda3D-1.2.3\direct\src\task\Task.py", line 769, in step
self.__stepThroughList(taskPriList)
 File "C:\Panda3D-1.2.3\direct\src\task\Task.py", line 703, in __stepThroughList
ret = self.__executeTask(task)
 File "C:\Panda3D-1.2.3\direct\src\task\Task.py", line 633, in __executeTask
ret = task(task)
 File "C:\Panda3D-1.2.3\direct\src\showbase\ShowBase.py", line 1286, in igLoop
self.graphicsEngine.renderFrame()

AssertionError: has_mat() at line 555 of c:\temp\mkpr\panda3d-1.2.3\built\include\transformState.I
Script terminated.

What happened?

You have an invalid transform on one of your nodes–e.g. you stored the result of divide-by-zero on a node’s position.

This is supposed to be impossible, because Panda is supposed to assert at the time the bad transform is discovered. Usually, when I’ve seen this error happen, it’s caused by a mismatched dll, for instance, you are inadvertently picking up libpanda.dll from an older version of Panda.

That, or you have some code that has run over the end of an array or otherwise corrupted memory, which isn’t supposed to be possible in Python. But maybe you tried to fill pixels into a texture array that hadn’t been allocated, or some such mistake.

In short, hard to say what happened exactly, but some part of the executing code (not pictured above) did something very wrong.

David

I think I found your impossible error. When I changed:

Scale = (1,0,1)
myCard.wrtReparentTo(myNewParent)
myCard.setScale(*Scale)
myCard.setShear(0,0,0)

To:

Scale = (1,1,1)
myCard.wrtReparentTo(myNewParent)
myCard.setScale(*Scale)
myCard.setShear(0,0,0)

It works fine. I’ll try to reproduce it in something simpler.

I reproduced it in seven lines:

from pandac.PandaModules import *
import direct.directbase.DirectStart

DECK = CardMaker('DECK')
myCard = render.attachNewNode(DECK.generate())
camera.reparentTo(myCard)
myCard.setSy(0)

run()

It doesn’t matter which coordinate you scale to zero. You said this is supposed to be impossible, is this a bug?

Ah. Yes, it’s kind of a bug. The bug is that it didn’t detect the situation that you created before it came time to render.

What you have done is set a scale of 0 on the camera node (or, technically, on a node that the camera is parented to, but it amounts to the same thing since a node inherits the scale of its parents). In doing so, you have squashed the camera’s view frustum into two dimensions, so that anything the camera attempts to look at will now be a divide-by-zero operation. Thus, it is mathematically impossible to render the scene.

Think of it this way: when you rotate the camera, from the camera’s point of view you have rotated the universe by the opposite direction. The same thing happens when you scale the camera: if you scale the camera to 0.5, from the camera’s point of the the entire universe has been scaled by 2.0. But if you scale the camera to 0.0, in any dimension, from the camera’s point of view everything in the universe has just been scaled to infinity!

So you have created an impossible scene, contradicting my overly bold claim that Panda is supposed to make it impossible to do this accidentally, by immediately detecting when you have done so. Oops! I’ll put some more checks in to see if I can detect this situation a little sooner.

David