Possible Preformance Improvement?


We are a small group of people working on a simple game using the panda engine, and we’ve sort of hit a minor problem with performance, so just wanted to ask if:

Is there a difference in performance from loading a Model and am Actor (which never uses any animation and is just stationary)? We are currently using Actors, but there is no animation going on and there most likely wont be, so would it help to load our objects as Models instead? (They seem to be pretty much the same thing)


Is there a way to reuse an actor/models geometry, so it does not have to be loaded twice? Read the example about the 50 dancers on a line, where you could share animation, but still have to render every polygon, and it made us wonder if there’s is a way to efficiently reuse geometry once it has already been loaded into another actor?

Hope the questions made sense!


Yes, a huge difference. But the difference between the two is decided at the time you generate the egg file. If you have a model that is never intended to be animated, you need to convert it with the “none” animation flag, not the “model” animation flag. Very important distinction. The way to tell the difference is to look for the flag appearing in your egg file; if it has a flag, it was converted with the “model” animation flag, and therefore is less than optimal for rendering as static geometry. Another way to tell is if you can load it into an Actor successfully. If you can, it was converted with the “model” animation flag, and therefore is less than optimal for rendering as static geometry.

By this, I’m going to assume you mean “rendered twice”, not “loaded twice”. (In fact, the model gets loaded from disk only once.) No, in general, if you want to see two of a particular model onscreen, it means that all of its polygons have to get drawn twice. There’s no way around this. (Geometry shaders can reduce this burden somewhat, but they’re no panacea, and they’re not presently supported by Panda anyway.)

If you are loading lots of different models and populating the scene with them, you might be exceeding the Geom count. You can check this in PStats. As a general rule of thumb, you want to keep your Geom count below about 300 for 60fps, and below about 600 for 30fps. (This limitation is caused by your PC hardware and has nothing to do with Panda.) If your Geom count is too high, you can reduce it via judicious use of flattenMedium() and flattenStrong().


Hi, I’m making the game with Hesel. Our animator says there doesn’t seem to be any such option in the Max-plugin - could you be more specific on where to find this option? Thanks for the thorough answer from before, btw.


In the max exporter, you can choose between “model”, “anim”, “both” and “pose” – you need to use the “model” option to convert just the static model.

Hmm, I don’t use Max, and don’t know anything about the Max plugin. Can someone with more experience here answer this question?

Looking at the manual, it does appear that the animation type export options are limited to “Model”, “Animation”, “Both”, and “Pose”. Can this really be true? Does the Max exporter not even provide the “None” option to export as a static model? It’s hard to believe that such an egregious oversight could have persisted for so long–but I guess the Max exporter has been lying dormant for a while until it was recently revamped with 1.5.3.

Maybe the 1.5.3 version fixes this problem? Are you using this version?

In any case, if the exporter itself does not provide this option, you will need to hand-edit the egg file and remove the flag, and also any entries in the egg file.


1.5.3 still has those exact options.

Actually, what’s the exact difference between “Model” and “None”? I believe “Model” already exports a static mesh? (With bones, if you added them, yes. Should I make an option to export it without bones?)

In all of the other Panda converters, “model” means an animatable model; it’s very different from a static model, and is loaded differently by Panda. Indeed, the presence of “model”, “animation”, and “both” implies that “model” is the animatable model that may be controlled by “animation”.

Perhaps “pose” is the right choice? In the other converters, “pose” is a less-often used option that gets an animated model already posed in a single frame. But maybe it’s used here to mean a static model.


Ah. I’ll look into adding this feature – it shouldn’t be that hard.

“pose” indeed means exactly what you referred to.

Actually, upon looking more closely at the source code, “pose” is what you want. It exports static geometry based on the animations of that frame, if any. Though it omits the bones, dart tags, etc. It just flattens the bone positions on the vertices.

Excellent, many thanks!

While you’re in there, also consider renaming the label “Export type” to “Animation type” to reduce confusion.


I just renamed it, and picked up for 1.5.4.

As for the “None” option: I looked a bit more at the Max api, and It seems in Max the only way to access the geometry is to grab it from a given frame. So, if I’d add a “none” option, I’d end up with exactly the same thing as the “pose” mode, which the exporter treats like a static mesh without any character, joint or animation data. I don’t think it’s a good idea to just duplicate the “pose” mode, I think it’s better to just document this in the manual.

The important point is whether the exporter adds the tag and any entries to the “Pose” option. If it doesn’t, then “Pose” really is the same thing as animation type “None” in the other converters, and we should probably rename it (or name it “Static”) for clarity.

It’s the presence of the tag that cues Panda to load the model differently. With the tag, Panda will load the model as a Character node, ready for animation; without it, Panda will load it and optimize it as ordinary, static geometry.


“Pose” mode indeed doesn’t export any joints or dart tags. Are you sure I should make it “None”? Since it does a little bit more than just static, you can specify a frame and the static geometry at that exact frame will get exported.
Maybe there’s a better name that sounds more accurate, such as “Static/Pose” or something like that.

Well, that’s kind of the same thing that “None” does in maya2egg, too. You can specify a frame, and the static pose of that model at that frame is exported.

But I agree that “None” is a terribly confusing name, especially if the field is labeled “export type”. I think “Static” is clear, though, and I don’t think the option to specify a frame number for a “Static” export is particularly confusing.


Okay, I just renamed it into Static:

Picked it up for 1.5.4.

Once again, thanks for the thorough replies. The problem, however, was indeed that we have way too many Geoms. I might need to elaborate on our game, in order to explain why our scene graph contains to many small nodes, so here goes. We’re making a game in which a plant grows dynamically, and to make this look natural, each branch is made up of quite small segments, that are jittered a little with respect to each other. Since we haven’t used Panda3D before we only kept the amount of polygons in mind, not the amount of scene graph nodes. We can use flatten, but the problem then is, that when the plant grows we add small segments at the end of each branch. When we use flatten, putting something in relative to the ends of each of the branches suddenly becomes much harder. Is there a nice way to get the cumulative transformation and rotation of the end nodes before flattening them with the rest of the tree? Is the solution to use getQuat() and getNetTransform and then apply those to the new nodes? Or is there an easier way?

Why not keep an unflattened copy of your tree handy, but not under the scene graph? Each time you need to grow the tree, add your new branches, then copy it to the scene graph and flatten it with:

newTree = tree.copyTo(parent)

The flatten operation itself can get expensive after a while, so you’ll have to find the right balance there.


Wow, that never occurred to us. Thank you very much, I’ll try it out and let you know how it worked tomorrow. Much easier than changing the overall creation of the tree, and running out of memory is hardly anything that’ll happen with our simple geometry :smiley: