Asynchronous asset loading with notification

I’m looking into ways of asynchronously loading remote resources, while presenting some kind of impostors in meantime.

For textures, it might be simple - I can probably return Texture object and then silently replace Image on it when things are finally retrieved from remote locaton. For models, it is more tricky - I will need to code some kind of application callback which will replace given node when things are ready (maybe as a control attached to impostor model).

Has anybody done it in the past? Maybe some code existing for that?

1 Like

You could load the model in a separate thread, and when the loading is done enqueue to the application a callable that remove the dummy model and attach the real model to the scene .
This way you have no need of callbacks, and you can have some parallel loading of the models.

Reviving this thread, because it turned out that texture impostor is not as easy as I have thought.

For models, I will use approach suggestred by @nehon. But in case of textures, I would like to display placeholder texture and then silently replace it when real one is loaded in background.

My first thought was to put some kind of ‘FallbackLocator’ as last one in chain and return placeholder Image from there (actually a clone of it), register it somewhere and then replace contents with real data after it is being loaded. But of course it is wrong - I’m supposed to return AssetInfo, not image itself from the locator.
Other option coming to mind was to catch asset not found exception on top level - but this defeats the purpose, because if I load model referencing 4 textures, I don’t want entire load to fail - I want to have proper model, just with placeholder textures for time being.
I could achieve that by putting some extra logic in loaders itself, to recognize special asset info returned by FallbackLocator - but this would have to be done in every single of them. Possible work around that by providing ‘GenericImageLoader’, register it for all image extensions, add that logic there and for proper assets redirect to real loader by hand. Should work, but feels quite ugly.

Is there any smarter way to do that ?

Make a low model, load that as the normal model.

Use a fixed naming scheme for the higher model/textures eg _low.j30 _high.j3o

then from time to time skan trough the scenegraph for low models, and start a background load for the high version. /textures

Alternativly abstract the whole concept of models and other assets (they way I do it currently)

everything is registed into a small embedded database, and with each qualit level.
Then I say give me model 564 and I get it fast, and can start a background task for the high model.

Just make a control that changes the texture after it has been loaded?

@normen said: Just make a control that changes the texture after it has been loaded?

Sure - but point is how to put placeholder texture there in first place. I know it is missing on locator level, but have to return placeholder Image from loader level. In theory, I could prepare simple textures in each of the formats (jpg,dds,png,tga,plt and whatever else happens to be there) and parse then over and over, to later replace when things are loaded in background. Unfortunately, there is no way for asset locator to return asset directly, bypassing the loader.

@abies said: Sure - but point is how to put placeholder texture there in first place. I know it is missing on locator level, but have to return placeholder Image from loader level. In theory, I could prepare simple textures in each of the formats (jpg,dds,png,tga,plt and whatever else happens to be there) and parse then over and over, to later replace when things are loaded in background. Unfortunately, there is no way for asset locator to return asset directly, bypassing the loader.

Why not specify the name of the texture in the control and serialize it along with the model?

You mean to actually put placeholder texture everywhere by default and replace it as soon as real one loads? Might work. My original issue is not with long-loading model/textures from local storage, but rather with ones I need to download on the fly from remote location (which can take 10+ seconds for example). But probably treating everything as possibly remote can work as well, at the cost of few extra replaces which will happen very quickly.

@abies said: You mean to actually put placeholder texture everywhere by default and replace it as soon as real one loads? Might work. My original issue is not with long-loading model/textures from local storage, but rather with ones I need to download on the fly from remote location (which can take 10+ seconds for example). But probably treating everything as possibly remote can work as well, at the cost of few extra replaces which will happen very quickly.

Why then go in between the model, loader and texture? Just load the whole model on another thread and attach it when its ready?