How to preload (or cache) assets

Hey,

We need to load a lot of models in realtime. Currently we just let the AssetManager load every model in our game initialization. We thought, this would “preload” the models and the AssetManager would save them in a cache where he could take the models from if we create them at realtime during the game. Unfortunately, loading the models at realtime still causes the game to freeze for a few seconds (for a model with ~12000 vertices) - which indicates that caching isn’t working or enabled by default.
Is this possible in jMonkey?

Greetings!

It does but OpenGL still has to upload the data to the GPU when it really displays it. You could add one frame at the beginning of the game where that happens and you add all models to the scene once, when setting the cull hint to never you can even do it without displaying anything.

Out of curiosity, are you loading more than a single model in any given frame?

If so, limiting this to 1 add, 1 remove per frame will help a bit as a secondary option.

After some research I found out that the problem is caused by the LOD generation. Even if the data is already uploaded to the GPU, jMonkey does still recalculate the LOD.
This is the code I use to bake the LOD. I load the Geometry “geom” with the AssetManager right before this code.

[java]
LodGenerator lodGenerator = new LodGenerator(geom);
lodGenerator.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL, 0.5f, 0.75f);

LodControl lc = new LodControl();
lc.setTrisPerPixel(1.0f);
geom.addControl(lc);

[/java]

Edit:
Shouldn’t jMonkey recognize that the data of this asset is already in memory and skip the loading of the LOD? What if I only bake the LOD once for every 3D-file? If I generate the LOD for the first Geometry instance using a 3D file, will jMonkey recognize that other instances use the same model and use the LOD generated in the first instance?

What do you mean “jmonkey does recalculate them”? You do in your code right there?

Yes. We generate the LODs right after loading an asset. The performance inpact that occurs when generating the LODs would be acceptable if it would only happen once. We didn’t want to generate the LODs in the SDK.

But then just don’t call the generation multiple times?

What I did now:

For every Geometry I create, I check if the the file was already loaded by the AssetManager (i save all loaded files in an ArrayList).

If it was not loaded, i generate the LODs and set the LODControler.

If it was already loaded, i do NOT generate the LODs and only set the LODControler.

[java]
if(!(AssetCache.getInstance().assetsLoaded.contains(loadPath)))
{
LodGenerator lodGenerator = new LodGenerator(geom);
lodGenerator.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL, 0.5f, 0.75f);
}

LodControl lc = new LodControl();
lc.setTrisPerPixel(1.0f);
geom.addControl(lc);
[/java]

Unfortunately, in the case that the geometry was already loaded, i get an Exception that the Geometry has not set any LODs.