Threading and setGeom

In my game, I’m dynamically altering geometry by using node.setGeom(geomId, geom). Creating the geometries can take a while, so I’m trying to create them in a thread, and then later change the geometry of the node to the new geom. Unfortunately, the game is freezing when I call setGeom with a geom that has been created in a thread (or a separate task chain).

What I’m doing is:

thread.start_new_thread(ThreadedUpdate, (self, self.blocks, self.blockTexture, self.x, self.y, self.z))
def ThreadedUpdate(self, blocks, blockTexture, x, y, z):

Then later

geom = self.threadQueue.get_nowait()
node.setGeom(geomId, geom)

I can print out the geom after the thread creates it, but the game freezes without displaying errors as soon as I call setGeom with the new geom. If I do everything the same, but call ThreadUpdate without giving it its own thread, it works successfully.

I noticed the warning in the API, but I’m not quite sure what it means:

Description: Replaces the nth Geom of the node with a new pointer. There must already be a Geom in this slot.
Note that if this method is called in a downstream stage (for instance, during cull or draw), then it will propagate the new list of Geoms upstream all the way to pipeline stage 0, which may step on changes that were made independently in pipeline stage 0. Use with caution.

That warning isn’t relevant unless you are using pipelining (e.g. with “threading-model Cull/Draw” in your Config.prc). Even though it’s not usually a significant problem.

One thing that is a problem is having geometry in the scene graph while it is simultaneously being modified in a child thread. This can cause deadlocks or graphics failures when the render thread tries to draw incomplete data. When you’re creating geometry in a child thread, it’s important to ensure that (a) you don’t add it to the scene graph until it is fully created, and (b) once it is added to the scene graph, you no longer modify that particular object.

Other than these ideas, I don’t know what’s causing your lockup. This should work in general; and I do things like this from time to time successfully.


Thanks for the reply. I’ll look into it more and see what I can come up with.