5

I have a JSON model being loaded successfully based on AlteredQualia's skinning example. However, I would like to not reveal the model until it is finished loading. As you can see in this example, the models appear first and then their texture resources load afterwards: http://alteredqualia.com/three/examples/webgl_animation_skinning_tf2.html

I added an opaque div to my webpage and then using the callback of the JSONloader.load() function I move that div out of the way. Unfortunately this callback is triggered when the mesh is added to the scene, which does not seem to be blocked by the skinning images still being loaded, so I end up "revealing" an incomplete scene.

How should I go about fixing this? I have seen that there is a function THREE.ImageUtils.loadTexture() which has a callback function but it does not seem to be involved in this use case where the mesh is declared and defined like so:

var mesh = new THREE.SkinnedMesh(geometry,new THREE.MeshFaceMaterial(materials));
//geometry and materials are both parameters of jsonloader.load callback

I had a look at the source code of MeshFaceMaterial and SkinnedMesh but could not see a solution there.

Thanks for any assistance offered.

gman
  • 100,619
  • 31
  • 269
  • 393
Brian
  • 116
  • 1
  • 5

3 Answers3

3

This is currently not properly sorted out. At the moment there is no callback or event dispatched when everything is loaded :/

mrdoob
  • 19,334
  • 4
  • 63
  • 62
  • Is there a workaround? Perhaps scanning the json file for materials and creating independent textures for each image file just to cache them? – Brian Dec 21 '13 at 13:33
  • Heh, well, it doesn't! I loaded them up using loadTexture first, but even after that the JSONloader still fetched the image file instead of taking it from cache (tested in chrome and firefox). [network monitor screenshot](http://i1.minus.com/ilgSSsQABEyYJ.png) I also tried using [window.onload](http://stackoverflow.com/questions/7919516/using-textures-in-three-js/10983908#10983908) but that event is only ever triggered once. – Brian Dec 23 '13 at 00:58
2

This is a bit of a hack, but at line 10362 (revision 61) of three.js you will see image.onload = function() (it's in the main THREE.Loader prototype). I managed to track that down to be the callback function for loaded textures from JSON models.

If you add your own callback inside that function you can track when textures are loaded.

As I said before though, this is a hack (which helped me out a lot for a particular application) and not a solution, be very careful modifying the library code. You might break stuff you don't know you're breaking.

Botol
  • 21
  • 3
  • Thanks for the suggestion, bit too much of a novice to go modifying the source code for now I think. – Brian Dec 23 '13 at 01:05
1

This is a ridiculously stupid cheat, but it will work as a hack. I agree one needs to realize image loading and everything else at least separately, so things that don't need images aren't twiddling their little electronic thumbs. That said, if optimization ain't your problem......

var texture = THREE.ImageUtils.loadTexture(url); 
while (texture.image.width == 0);
Mark Mullin
  • 1,340
  • 1
  • 9
  • 21
  • This might work but it's not guaranteed to work. Effectively the browser is supposed to do absolutely nothing until your JavaScript exits its current event. The fact that you're spin waiting means you've never exited the event. Basically you're just getting lucky that whatever browser/version you tested on happens to not completely freeze. On top of that, even if it doesn't freeze if the connection is slow the browser may kill your JavaScript as taking too long. You also DoS the user's machine while spin waiting. – gman Dec 10 '16 at 05:22
  • This looks like "busy waiting" for me... . Don't do it this way... . – Trantor Apr 21 '17 at 10:50