Feasibility of splitting model loading

Since model files (created inside or outside of jME) usually will include TextureStates (assuming the model uses textures), we're prevented from backgrounding model loads, since texture loads require the GL thread.  Could anybody opine whether the following tactic would work to allow me to load large models over the network from a background (non-GL) thread?  I also want it to work for the use case of local models that have a lot of procedural intialization code, like to merge morphs… basically anything that would cause the scene frames to lock noticably as the model instantiates.



Modify the required JMEImporter classes, or the savable implementation methods, to just save off texture image URLs and Spatial.lock*() needs; and add a new method like glInit() which would apply these settings which require the GL thread.  Then the loading code would do something like:



    // background thread
    incipientSpatial = importerImpl.load(modelUrl);
    // add to jME update thread queue, or Threading.invokeOnOpenGLThread(), etc.
    ...
    // GL thread
    incipientSpatial.glInit();
    targetParent.attachChild(incipientSpatial);



Postnote:  I think that Ogre XML models probably do not have these problems, perhaps to accommodate this use case (Ogre XML materials may be loaded separately).  If so, that's a great benefit of OgreXML and I'll use that when I can, but I need this to work with non-Ogre-XML models too.

Also hit this snag a while back. All the model loaders assume you want to create the meshes and textures in one hit, not good for background worker threads.



Jme also has a design floor in detecting a new texture and uploading the texture to the card - wont go into this now



Unfortunately cannot post source as i dont own it but…



What the model loaders need to do is to create a TextureCatalog of all textures used, the catalog will hold entries of the texture data.

The texture data will comprise :-

  String textureName; // in the case of 3ds this was the TextureChunk texName

  float vScale;

  float uScale;

  TextureState meshTextureState; // this is the TextureState per the 3ds loader Material Block myTexState

  int textureUnit = 0; // the texture unit this applies to

  ArrayList<Spatial> spatials = new ArrayList<Spatial>()





When ready to add textures, a simple task added to the scengraph queue can be run to load the texture and add it to the spatial. ( It wont actually be put on the card untill its in the frustrum, not good for various reasons )














Thanks for the details.  Looks like no easy fix.  I'll be thinking over the best fit for my app.  I don't think I'll have time to implement this year.