RigidBodyCombiner culling-errors.

while i tried to optimize my cute little cuboid clone for slower machines i used the rigid body combiner to reduce the overhead caused by the sometimes high ammount of tiles in my maps. while the optimisation works very well (framrerate doubled for most maps)… it causes some… strange culling problems with some of the tiles.
most of the tiles are fine, but usualy start and finish-tile are disappearing from time to time. it seems to be related to the tile-camera position. sometimes the whole map dissappears.

all tiles are directly under under the rigidbodycombiner node, which is wrapped in a node path, this’s level-node-path’s center usualy is close to the start-position and, in the following video, always withing the screen.

the tiles themselfs are animated using intervals and sequences. most of the time those work just fine, just sometimes single animations just refuse to play at all. disabling all animation doesnt change the dissapearing of tiles.

http://www.youtube.com/watch?v=4uYfKbKCYPI

if i do not use the rigid body combiner and reparent the tiles to the regular levelnodepath it works perfectly fine.

drwr… any ideas? broken bounding calculations for the rigidbodycombiner? culling issues? … or any idea what’s going on?

just in case. this is the code generating the level, i dont think i’m doing things terribly wrong cause it seems to somewhat work, including the performance gain.

    def loadLevelData(self,inputData):
        
        rigidNode = RigidBodyCombiner("LevelNode")
        levelNode = NodePath(rigidNode)
        inputData = inputData.replace("\n","").strip().replace(" ","").lstrip("<").rstrip(">").split("><")
        
        for tileData in inputData:
            tile = self.loadTile(tileData)
            if tile != None:
                tile.reparentTo(levelNode)
                tile.setPos( self.getPosFromTile(tile) )
            else:
                print "ERROR, could not load tile with data: ",tileData
        rigidNode.collect()
        levelNode.analyze()  
        return levelNode

Hmm, I do think I see a possible bug within the RigidBodyCombiner with respect to bounding volumes. It computes the bounding volume of the internal Geom at the time of collect(), and doesn’t update it. It’s not obvious how that’s causing the precise problem you’re seeing though.

As a workaround, try this: after you call rigidNode.collect(), call:

inode = rigidNode.getInternalScene().node()
inode.setBounds(OmniBoundingVolume())
inode.setFinal(True)

This sets it to not perform any additional culling beyond the node-level culling at the top of the RigidBodyCombiner, which is what I think should have been done by the RigidBodyCombiner anyway.

As to the unanimated start and finish tiles, that’s probably because they didn’t have a transform on them at the time you called collect(). From the API spec for RigidBodyCombiner:

So, consider using a ModelNode at the root of each tile (you might have one anyway if you loaded them from an egg file–a ModelRoot node is a subclass of ModelNode) and call node.setPreserveTransform(ModelNode.PTNet).

David

the omni-bounding volume trick fixed the dissaperance of blocks :slight_smile: many thanks.

for the animated tiles. now that you mention it. the tile not moving is the one which has the position 0,0,0. if i make it 0,0,0.00001 it already works :slight_smile:.

so all errors are worked around. time spend with drawing halfed. so performance should now be perfectly fine even on old machines (need to test it later on some truly ancient hardware)

only thing that’s strange. at the time of collect() all tiles are already in place, so the bounding volume should be fine most of the time (except for the level-switching animation).

oh talking about strange issues. i experienced quite big issues with pstats. threadblocking caused my app to freeze for a few moments over and over. i’ll investigate that a bit more and open a seperate thread once i found something less vague.

OK, I’ve just committed a fix to RigidBodyCombiner that will apply this OmniBoundingVolume automatically in the future. It’s the right thing to do. I don’t fully understand what’s going wrong with the bounding volumes in your case, but it probably doesn’t matter. It’s probably related to a transform on the RigidBodyCombiner itself; I bet it was applying that transform twice to the bounding volume it was computing inappropriately, and that was moving the bounding volume off camera some of the time. Well, whatever.

I’ve occasionally seen problems like this in the past, but I thought I’d solved them all. :frowning:

David

about that pstats issue. it happend yesturday night, i wasnt able to reproduce it today. my application was quite choppy although pstat did not show any threadblocks this time.
rdb suggested “pstats-max-rate 10” and it worked perfectly. everything runs smooth now :slight_smile:

about that omnivolume patch you commitet. i could imagine a few cases where this would cause a performance drop, especially on huge-tile-based moving maps (i admit those are very rare and i dont use them either). i suggest to put a note somewhere so people know about it just in case.
thx for all your help!

No, there is no performance concern here, because the whole point of a RigidBodyCombiner is to combine all of its elements into a single Geom. This means you’re always going to render either all of the contents of the RigidBodyCombiner, or none of them; and it never makes sense to attempt to perform culling within these elements. It was just a mistake on my part that I forgot to turn off culling in the first place.

Note that culling is still performed on the RigidBodyCombiner node itself, and its bounding volume is correctly computed.

David

oh i see. i thought omni was quite… completly omni due to it’s name. good thing to know there is nothing to worry about. one thing less to keep in the back of my mind.