Loading models (multiple times the same model) from RAM ?

I’ve looked into the “Solar System” sample code and noticed that the same model is loaded multiple times from disk.

I wonder how to preload that model once to RAM and then load it from there - if it’s used more than once (same for textures) ?

Btw: Does that model use x-times the RAM if it’s x-time present in the scene or just one time ? Same goes again for textures.

Panda is smart about loading models, if you load the same model a second time it should be loaded from cache. Textures are also kept in a TexturePool and are (usually) loaded from disk only the first time.

If you want to draw a model x times but only want to send it to the gpu once, then you need to look into hardware instancing, but I’m not sure I’ve seen a good, modern GLSL example here on the fora (there are some using Cg shaders and some bad ones -including my own). If you do need some working instancing code, I can write something next week :wink:

I’ll give you an example:

While doing my modeling I noticed that my battleship had 4 turrets, only different in position and rotation. Even more secondary batteries.

So I thought about placing empties at those turret positions and load one turret after loading the model and place it four times at it’s positions.
Since all 4 turrets share the same texture (and have the same UV Map) I thought about putting them onto the turrets by loadTexture instead of using the YABEE. YABEE would bake 4 textures i think and export the turret multiple times as well. Not sure how it would handle linked duplicates in Blender (not tried).

My basic Idea is to have a factory class that I just pull a complete model from - once I’m done. Allowing me (for example) to use the same model, but with different turrets and textures and change them while the game is running.

I have zero knowledge how Panda3D handles models/textures in this case, so I thought I’ll ask before writing it. As far as GPUs are concerned I have to read into that stuff as well.

The easiest way would to have an empty for every turret you want to spawn. Name them to something like “TurretEmpty0” to “TurretTempty123”. Assuming your turret prefab is named “MyTurret”, you could spawn instances of your turret to the empties with something similar to this (untested! you might have to adjust it):


# Load the model from disk
my_model = loader.loadModel("MySpaceship.egg")

# Find the turret prefab in your model
turret = my_model.find("**/MyTurret") # Just using "MyTurret" might work aswell

# Find all nodes which start with "TurretEmpty"
turret_prefabs = my_model.find_all_matches("**/TurretEmpty*")
for prefab in turret_prefabs:
     turret.instance_to(prefab)

You can add a game property to your empty called “file”, make it a string, and set it to the filename of the .egg to load. This is basically an automatic way to do what tobspr just indicated.

You can use Blender’s DupliGroup functionality in combination with using the “Link” feature to link another .blend file into your scene blend to make it actually show up in Blender as well, for easier positioning.

Thanks :slight_smile:

Both solutions sound neat and have a use of their own:

A#
Setting up some factory class and looping through everything on disk is interesting, because I could do something like this, after I loaded each model into some kind of map, so I could access them by their keys:

shipFactory.getShip("Battleship", "380mm", "150mm", "40mm", "Camouflage")

(Translated to: Battleship with 380mm main guns, 150mm secondary guns, 40mm point defense and camouflage textures)

“shipFactory” it’self would just put everything together and return the model so I can use it in my scene.

B#
The approach rdb suggested allows something I like too, instead of some factory class I could use make one Empty - add a link a gun.egg to it and copy it all over the place, since Blender will name the Empties for me.

Not sure atm… I will see once I made more models and modules for them what works best.

Is is possible to store some data in game properties that I can grab from Panda3D ?

Yes, this mechanism is quite flexible. You can call a Game Property anything you like (except for a built-in recognized string), and then fetch it from a Panda node as a tag using getTag or getNetTag.

You can also find nodes by a tag, eg.

for node in model.findAllMatches("**/=gun"):
    ...

will return all nodePaths with a “gun” game property whereas

for node in model.findAllMatches("**/=gun=380mm"):
    ...

will find return the nodePath of each object/empty with the “gun” game property set to “380mm”.

Unfortunately I had to use .copyTo because I cannot put a particle system on some kind of instance :frowning:

Same error as here (even though I did not try to create instances of the particle systems):

panda3d.org/forums/viewtopic … 4&p=104780

There’s no compelling reason to use instanceTo on anything other than animated models. Even if you use copyTo, Panda will only copy the actual geometry if it is modified (copy-on-write).