zhaomingjian / jsc3d

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

Add/remove .obj from scene #105

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I've been trying to get this working. 

I have an .obj as main mesh in scene. I then have multiple meshes that can 
attach/removed to it.

Following this conversation https://code.google.com/p/jsc3d/issues/detail?id=52 
I can pass in an array of .obj and load all into a new scene. 

What I'm trying to do is not replace the scene. Ie. I'm trying to load the 
'accessories' to the main mesh scene, without having to reload everything.

Is it possible? or do I have to replace the scene each time I add an obj to 
scene? 

Original issue reported on code.google.com by terro...@gmail.com on 22 Aug 2014 at 1:59

GoogleCodeExporter commented 9 years ago
In your case, just don't call viewer.replaceScene() which replaces current 
scene, but add the new meshes into it via scene.addChild() each a time like 
this:

  // say you already have the new meshes loaded into the array named 'accessories'
  // init the meshes and add them to the current scene
  for (var i=0; i<accessories.length; i++) {
    accessories[i].init();
    scene.addChild(accessories[i]);
  }
  // tell the viewer to render a new frame immediately with all the changes
  viewer.update();

The function scene.addChild() is documented here: 
http://jsc3d.googlecode.com/svn/trunk/jsc3d/docs/symbols/JSC3D.Scene.html#addChi
ld.

Original comment by Humu2...@gmail.com on 23 Aug 2014 at 2:02

GoogleCodeExporter commented 9 years ago
Thanks for response. Its not the meshes in the array, just the addresses 
'meshes/eg1.obj', meshes/eg2.obj' etc.

So, I need to load them first through ObjLoader, put into an array and then add 
to scene?

Original comment by terro...@gmail.com on 23 Aug 2014 at 8:07

GoogleCodeExporter commented 9 years ago
Exactly correct. Since you have read the previous discussion 
https://code.google.com/p/jsc3d/issues/detail?id=52, it should not be a 
difficulty.

Original comment by Humu2...@gmail.com on 23 Aug 2014 at 9:55

GoogleCodeExporter commented 9 years ago
Hehe, was seconds away from posting... figured it out with your help thanks. I 
was running init on obj location, not on the mesh after being loaded.

With the accessories being swapped out and new ones added (each accessory slot 
has 10 or so .obj options), I also just do removechild on existing accessories 
array before running through the new array to prevent multiple meshes per slot 
overlapping eachother. 

Now that its working, I have that 'I'm dumb' feeling as its was so simple

Anyway, thanks again

Original comment by terro...@gmail.com on 23 Aug 2014 at 10:04

GoogleCodeExporter commented 9 years ago
I'm glad to hear that :-)

Original comment by Humu2...@gmail.com on 23 Aug 2014 at 2:34

GoogleCodeExporter commented 9 years ago
Sorry to bother you again, I'm a little stuck.

With these multiple meshes in multiple slots, I thus have multiple textures.

Been trying to run through all scene objects and apply textures to specific 
ones. I been running off the code you posted here 
https://code.google.com/p/jsc3d/issues/detail?id=53 the idea being my textures 
are in an array which corresponds with the object array and as it passes them 
in the scene, it will apply the created texture. Can't get it running though, 
after a few swapping out of textures and models, they start to apply to 
different models.

So, now thinking instead of running through all, is there a way I can call a 
specific mesh in scene and only apply texture to it? e.g., mesh.name.setTexture?

Original comment by terro...@gmail.com on 26 Aug 2014 at 3:39

GoogleCodeExporter commented 9 years ago
Is it because the correspondence was not maintained in correct way, or you did 
not take care of the asynchronous loading of the models and the textures?  I 
guess you should check on these first.

Each mesh object has a private property mesh.internalId which is unique in an 
application's life cycle. It can be used if you need to identify your meshes.

Original comment by Humu2...@gmail.com on 28 Aug 2014 at 2:53

GoogleCodeExporter commented 9 years ago
Yeah, I've tried many different ways I could think of at trying to sort this... 
maybe I'm over thinking it.

Heres how it started originally. I have a page with many buttons in many 
'slots’  around a central .obj that pass many objects urls to the viewer with 
many texture variations, but, there are only x amount of slots. So to make it 
'easier' (so I thought) I would place these into arrays of slots and update a 
scene array. So, the scene is always removing old and updating to the new scene 
array.

Eg.
Button is pressed for slotX, it sends new obj url and texture url to 
appropriate vars.

slotA = x.obj;
slotB = y.obj;
slotC = z.obj;
tslotA = x.png;
tslotB = y.png;
tslotC = z.pngj;

I remove old children in scene, then load all new meshes - meshes aren’t a 
problem, switching in and out as the should be

meshesToDisplayArray = [slotA,slotB,slotC];

var onModelLoaded = function(scene) {
    var meshes = scene.getChildren();
    for (var i=0; i<meshes; i++) {
        meshes[i].init();
        theScene.addChild(meshes[i]);
    }           
};

for (var i=0; i< meshesToDisplayArray.length; i++) {
    var loader = new JSC3D.ObjLoader;
    loader.onload = onModelLoaded;
    loader.loadFromUrl(meshesToDisplayArray[i]);
};

textureUpdate(); — I’ve had this anywhere and everywhere… this is where 
I’m having the issue, after a couple of mesh and texture swaps, the textures 
no longer apply to correct mesh

function textureUpdate(){
    var texturesToDisplayArray = [tslotA,tslotB,tslotC];
    var textures = [];
    var textureOwners = {};
    var meshes = viewer.getScene().getChildren();
    for (var i=0; i<meshes.length; i++) {
        var newTex = new JSC3D.Texture;
        textures.push(newTex);
        textureOwners[i] = meshes[i];
        newTex.onready = function() {
            textureOwners[textures.indexOf(this)].setTexture(this);
            viewer.update();
        };
        newTex.createFromUrl(texturesToDisplayArray[i], false);
    }
}

I been basically using the above… and been trying many variation and even 
passing texture through directly in the update, but for whatever reason, I 
can’t get it right, meshes load and display perfectly, textures just mixing 
up.

I’m obviously missing something somewhere...

Original comment by terro...@gmail.com on 29 Aug 2014 at 9:50

GoogleCodeExporter commented 9 years ago
It won't work correctly because you didn't maintain the correspondance between 
the meshes and the textures in a right way.

Be aware the requests and the responses are all asynchronous. When you've sent 
requests (they could be model files or images) r1, r2, r3, ..., the responses 
may come back in arbitrary order.  A scheme must be applied to determine which 
texture corresponds to which mesh.

Original comment by Humu2...@gmail.com on 29 Aug 2014 at 12:43