jackyoyyf / jsc3d

Automatically exported from code.google.com/p/jsc3d
0 stars 0 forks source link

viewer.getScene() seems to return false #9

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I'm trying to load a simple non-textured .obj with
viewer.setParameter('SceneUrl',filename)

I can display it fine, but I cannot find a way to get attach a new texture to 
this object.

I assumed I'd have to get the scene with

viewer.getScene()

and then iterate through the meshes from scene.getChildren() and add a texture 
to each. But getScene() seems to return false even though the object has loaded 
and is displaying properly.

Is there some trick that I am missing here?  All the examples that use textures 
seem to work off either an mtl file (which I can't use because I need to 
control the textures in javascript) or without using .obj files. 

Finally, does this support, or will it support in the future, transparency?  
When I tried it it didn't seem to show any of the faces from behind the object, 
so I'm assuming it doesn't do that yet.

Original issue reported on code.google.com by jol...@mindat.org on 14 Oct 2012 at 9:20

GoogleCodeExporter commented 9 years ago
I see. viewer.getScene() method will return a JSC3D.Scene object which is 
currently used, or null if nothing is loaded in advance. If you want to load a 
model at runtime, then the viewer.replaceSceneFromUrl() method will be very 
handy.

You can use mesh.setTexture() to change texture of a mesh. However at most 
cases you should encapsulate that in a callback method because loading texture 
from the network is an asynchronous task. You can overwrite texture.onready to 
achieve this. The following snippet demonstrates how to change texture at 
runtime, assuming there is only one mesh in the scene:

  // create a new Texture instance
  var myTexture = new JSC3D.Texture;
  // setup the handler which will be called when texture is ready
  myTexture.onready = function() {
    // assume a single model has already been loaded
    var scene = viewer.getScene();
    var myMesh = scene.getChildren()[0];
    // set texture to the model
    myMesh.setTexture(this);
    // notify viewer to deliver a new frame
    viewer.update();
  }
  // begin to load this texture from a given url
  myTexture.createFromUrl('.../my_texture_image.jpg');

That's it.

Transparency is already supported at both material and texture level. For 
material, the material.transparency property controls the opacity of the 
attaching mesh. For texture, If a texture image contains alpha channel, it will 
be automatically adopted in the texture (only png supports alpha channel). When 
a texture is loaded, the texture.hasTransparency property indicates whether it 
is transparent. Both will additively affect the rendering of the attaching mesh.

Please use the svn repository to get the latest code. The one in the download 
section is very dated :-)

Original comment by Humu2...@gmail.com on 15 Oct 2012 at 4:49

GoogleCodeExporter commented 9 years ago
Thank you for your prompt reply! Sadly, I'm no closer to getting any texture or 
material changes in my .obj file.

I've uploaded a stripped back example showing the problem here:

http://www.mindat.org/3d/

I'm sure it's something simple I'm forgetting, but I have tried a lot of 
different things :)

Jolyon

Original comment by jol...@mindat.org on 15 Oct 2012 at 8:02

GoogleCodeExporter commented 9 years ago
Hi, Jolyon:

I took a look into the model file brilliant.obj used in your demo. It seems 
that it does not defines any texture coordinate. A mesh should contains texture 
coordinates to enable texture mapping. Please refer to this document 
http://en.wikipedia.org/wiki/Wavefront_.obj_file for detailed info on obj file 
format.

Original comment by Humu2...@gmail.com on 16 Oct 2012 at 3:27

GoogleCodeExporter commented 9 years ago
Hi,

I have very similar problem. I believe this issue is due to slow model loading.

It seems like if there were two threads which I thought is not possible with 
JavaScript.

However, if the code above is called, the getScene() can really return null.

If I tried to debug the code and the same code worked. The only difference was 
stepping every single command. I use Firefox.

Try to use timeout function to load the teture or some button..

Original comment by mazan...@gmail.com on 27 Dec 2012 at 10:21

GoogleCodeExporter commented 9 years ago
I just added this code for delay and setting the texture works fine for me:

setTimeout( function () { 
setTexture(viewer,"modules/mod_3dmodelview/demo/test.jpg",true);
},1000);

calling my function setTexture directly resolves in error as the function 
getScene() inside the function will return null as the scene is still not 
loaded.

Why is it, I do not know. Is there better way to handle that problem?

Original comment by mazan...@gmail.com on 27 Dec 2012 at 10:28