FlattenStrong - is this way valid?

By markjacksonguy at 2012-02-15

Those test buildings are ugly. :laughing: It’ll be awhile before I can get rid of them.

I’m creating rock instances and writting placement code (geometry and texture will randomlize later). Each rock instance has a PandaNode and all geometry (and anything else) is attached to the PandaNode. I thus, move/rotate the PandaNode to manipulate the geometry’s position and rotation.

This enables me to place collision on the PandaNode instead of the geometry.

Here’s the thing…

I realize I will create a lot of those rock instances in order to fillout the entire landmass. I came up with this method…

RockInstanceA will act like a parent instance. What I did was reparent RockInstanceB’s and RockInstanceC’s PandaNode to RockInstanceA’s PandaNode. I then called flattenStrong() on RockInstanceA’s PandaNode().

My question is, is this way valid? Will all geometry involved with rock instances A, B and C become one? (I’m not sure about what happens to the unseen collision barriers).

I have another question aside from the above one-

If I have a model, self.TreeA = loader.loadModel(“TreeA”), and use the same variable to load another model, self.TreeA = loader.loadModel(“AppleTree”),

what will happend to the first model resource? Will it drop from memory or get lost?


would it be better to call removeNode() first, then load up another resource (using the same varible)?

self.TreeA = loader.loadModel(“AppleTree”)

Might be a good thing to have a loader.replaceModel(), which would infact dump the first resoure and load in the new one, using the same varible.

Darksiders (PC) uses Fmod!

That should work. You can confirm this with RockInstanceA.ls() and/or RockInstanceA.analyze(). Compare the output of these two calls before and after the call to flattenStrong().

Note that flatten will indeed also combine collision barriers; however, you usually don’t want collision barriers to combine as aggressively as you want visible geometry to combine. This is because the collision traversal benefits from a deeper hierarchy; if you flatten your collision geometry too much, then the collision traversal has to walk through a linear list of many polygons to look for a collision, instead of being able to early-out large groups of polygons in a properly-nested hierarchy.

(In many cases, you may not need to care about the small difference in performance, but it can become a large difference if you go too far.)

Note that this is more to do with Python than with Panda itself. When you assign a new value on top of an existing variable, the value that was previously stored in that variable goes out of scope. When a NodePath goes out of scope, however, Panda does not remove the corresponding node from the scene graph. (If it did, many things would disappear that you didn’t mean for them to.) So it means your previous model remains attached to the scene and you no longer have a handle to it. So you need to call self.TreeA.removeNode(), or at least self.TreeA.detachNode(), first.

Feel free to write your own convenience method that removes and replaces a model in one call.


I went back and placed all collision barriers under render; although I didn’t notice anything with the speed.

Note that this is also a flat hierarchy. Ideally, you want your collision barriers to be grouped into a deeply-nested hierarchy, with nearby objects parented together under a common node. This allows the collision traverser to early-out all of the objects under that one node with a single test, if that node’s bounding volume is far away.

This is, for example, the sort of structure that egg-octree sets up, and this is why egg-octree has a performance benefit. I’m not necessarily saying that egg-octree is the right solution for you (or even that you need a solution at this point for what may not even be a problem), but if your collision traversal time ever becomes a bottleneck, you will want to be able to think about ways to improve it.


The only issue with selecting egg-octree formatting while exporting from blender is the fact, the collision barriers no longer respond; it’s like they aren’t even there.

Unless they have to be excessed in a different way.

If I remember correctly, they don’t show in the preview either, if exported as Octree.

I had an issue with positioning while reparenting my rock objects to the first rock instance’s PandaNode. Instead, I reparented all the geometry to the first one. In other words, RockInstanceA’s geometry attached to its PandaNode served as the parent for all the other geometry of the RockInsances; RockInstanceB’s and RockInstanceC’s geometry were reparented to RockInstanceA’s, but not the PandaNodes.

I hope this method is valid.

Keep in mind, those rocks and objects alike will do nothing. They are just there for decoration.

By markjacksonguy at 2012-02-17

Like my Palm Tree model? It’s a little dark; the sun is rising again.


Notice the two groups of rocks - the one set near the top of the screenshot and the one set near the bottom.

Right now, that visible geometry has been flattened into one (with the very first rock instance’s geometry).

Just wondering…

Can I group (flatten) all rock instance geometry no matter where they are placed or should I flatten (group) them based on which ones are closest?

In other words, will performance drop if different geometry far away from each other is flattened together?

I’m guessing drwr will say yes.

It’s not quite so cut-and-dried, but yes: in general, you want to flatten things that are close together, instead of things that are far apart. This gives you better cull performance.


It’s going to be tough to pull this off. I already see the fps starting to fall hard with the more instances I add.

When I create the true building structures, I think I will use one large texture mat to hold all textures, with the purpose of somehow calling flattenStrong on all structures combining them into one.

My intuition is telling me that, even if I where to successful do that, it won’t matter much as foar as the fps.

I believe I’m just seeing the limitations of the enigine. :cry:

I was playing the game “Children of the Nile” and had over 500 characters and buildings on screen and the fps fought hard to stay at around 60. “Freakin” awesome graphic engine there.

Instead of using texture compressing and scaling in the config, I will truly cut all textures in half later on, but keep a copy of the higher res ones. There could be some issue that causes texture compression to not happen, so it would be better to go with smaller textures by default.

I’m just hoping the finished game can at least run at 30 fps (although I’m on a 2.4ghz multi core system now :cry: ).

Don’t confuse a finished game with an engine. If you can find a game engine that does this sort of optimization for you automatically, I’d love to hear about it.


This isn’t a case of optimizing (for me). All engines have their limits, even the ones created by means of hard cash from large corps. P3D also has its limitations.

Once the limitations are understood, one can better use what power it has to offer for something worth spending the time on.

With that written…

I still think I can finish my game and manage to have a decent fps. I am currently doing some more optimizing (as you mention in your last post). If my theory is correct, I might can finish this game with a “50ish” fps; “40ish” at worst.

I’m not expecting “children of the nile” or “tomb raider anniversary” kind of fps out of P3D. P3D’s logic is unlike anything I’ve ever seen or worked with.

Sure I finished projects with fps in the 100s or more using other engines, but I don’t really expect that with P3D.

Even when comparing its logic to engines of today, one can clearly see its an “engine of its own”, which is a good thing. It’s nice being distinctive.

Don’t “ruffle” your feathers. :smiley:

By markjacksonguy at 2012-02-17

I just proved I was right.

The better understanding you have of a graphic engine and its limitations, you can better optimize a game.

After testing my theory based on P3D’s structure, I was able to increase my fps by a “Whopping” 100 frames!


I should no doubt be able to finish my RTS game and have some fps to burn.

For the purpose of further optimizing and not making an epically critical mistake (which is possible since I’m not drwr, original P3D programmer), I ask this question…

If you have 10 instances with geometry all bound into one by using flattenStrong, but later decide instance 7 of the 10 should be destroyed, what kind of impact will that have (if any)?

Would the 9 remaining instances have to be flattened all over again, or can I expect the deleted instance to be removed without issues?

It sounds like you just proved you were wrong, but maybe I didn’t understand what you were saying. It sounded like you were saying you’d never be able to achieve 100fps in Panda.

I think there are 3 remaining instances, but yes, you’d have to flatten them again.


Actually, I’m over 100 fps. The good thing is, I’m not done optimizing. It’s kind of hard to do everything at once, so I have to code some, then maybe jump to graphic optimizing if I need to remove some bad test objects.

There is still level design optimizing, which I haven’t even gotten to yet. Even now, I am still getting rid of the bad test models and putting in some true level 1 models with correct textures sizes.

Once that is finished I can get back to coding. I won’t get a chance to touch level optimizing until level one is just about done (code side of things).

I lost fps earlier because I was pushing the engine too far. Once I realized that, I was able to make the changes needed to work within the engine’s capabilities.

All engines do have different limitations. For instance, I was playing a commercial game earlier and on a blank screen (nothing drawn, but processing in the background) the fps clocked over 2K. I’ve seen games clock over 5K with almost empty screens.

Empty screens are not optimized levels either. Some engines are just flat out faster and that’s the truth; and that’s why a developer should always work within a graphic engines limitations and not try to go beyond that.

I remember a developer from SCEA talking about the samething, some time ago.