flattenStrong()--how does it work code wise?

Hey everyone. I need a little help in understanding how the flattenStrong() call works via code.

Reason: My model is a hug model with a lot of GeomNodes. To lower the number of GeomNodes, I would call flattenStrong(), but this breaks culling by limiting the number of GeomNodes to just one.

Idea: My idea is to mode how flattenStrong() works by just grouping the GeomNodes togather and then just flatten thos GeomNodes to just one GeomNodes… or math wise… take the 2812 GeomNodes / by 75 (or target number limiter) and group that many into the signal GeomNode giving me just 75 GeomNode intotal.

Ok ^^: So my question is… how would you go about scaning the model, break it down into the 2812 GeomNodes, then combind/group them to be flattenStrong()?

My other idea was to use the quadtree support by fenrirwolf on the octree scrip, but the scrip doesn’t seem to work right. Half my model and none of the textures stay.

It’s a fine idea. You can group all the GeomNodes that you want to collapse together under a single PandaNode, then call flattenStrong() on that node.

Or, you can just call flattenMedium() instead, which doesn’t flatten everything quite as aggressively.

There’s another easy thing to do. root.flattenStrong() actually maps to the following sequence of lower-level calls:

gr = SceneGraphReducer()
gr.flatten(root.node(), ~0)
gr.unify(root.node(), False)

That’s all well and good, but you can exercise more control by making the calls yourself. In particular, you can do this:

gr = SceneGraphReducer()
gr.flatten(root.node(), ~gr.CSOther)
gr.unify(root.node(), False)

Specifying a CombineRadius of 100.0 (or whatever value you deem appropriate) and passing ~gr.CSOther as the second parameter to gr.flatten() tells the SceneGraphReducer to group objects together within a radius of 100.0 feet. Objects farther apart than that won’t be flattened together.


Thanks drwr… but I guess what I am asking for is how would you go about collapsing the GeomNodes together under a single PandaNode.

So far what I got.

      self.environ = loader.loadModel("Misc/a1/a1.bam")
      geomNodeCollection = self.environ.findAllMatches('**/+GeomNode')
      x = 0
      x2 = 0
      y = 0
      geomNode = {}
      dummygeomNode = {}
      self.TargetgeomNodeLimit = 74
      NumberOfgeomNode = len(geomNodeCollection.asList())
      for nodePath in geomNodeCollection.asList():
        geomNode[x] = nodePath.node()
        x = x + 1
        x2 = x2 + 1
        if x2 == (2812/self.TargetgeomNodeLimit):
          dummygeomNode[y] = render.attachNewNode("DummyNode"+str(y))
          for i in range((x-(NumberOfgeomNode/self.TargetgeomNodeLimit)),x):
            print str(geomNode[i])
          y = y + 1
          x2 = 0

Looks like you’ve got the right general idea. Is there a specific question you wanted to ask about it?



This line. Um, I know geomNode do not have a reparentTo funcation… how would you go about adding/collapsing it to the dummygeomNode?

GeomNode doesn’t, but NodePath does. So just replace this line:

geomNode[x] = nodePath.node() 

with this:

geomNode[x] = nodePath 

So that you save the NodePath referencing the GeomNode, not just the GeomNode itself.


Thanks again drwr :slight_smile: I got it working ^^ Going to play around with it and try different ways to optimize how it works.

I’ll try the code you posted, too. Just a little over my head on how it works atm for me:)

First time editing a model by code ^^ I think I did perty good job at it lol. Didn’t see increase fps for say, but some areas did.