0

I am using ThreeJS to load OBJs into a webpage, which I have done succesfully, but now I want to add buttons to my page that will swap out the displayed OBJ file for a different one. I have attempted to name the object when loading it:

object.name = "selectedObject";

so that I can remove it from the scene when the new button is clicked

scene.remove( selectedObject );

and attach the new object:

scene.add(newobject);

But I am getting lost in how to implement this into the general code/what the correct syntax would be.

Here's the code for loading the model:

            var objectloading = 'obj/male02/new.obj';
var loader = new THREE.OBJLoader( manager );
            loader.load( objectloading, function ( object ) {

                object.traverse( function ( child ) {

                    if ( child instanceof THREE.Mesh ) {

                        child.material.map = texture;

                    }

                } );

                object.position.y = -30;
                scene.add( object );

            }, onProgress, onError );

Any help is apreciated, thanks!

Nicolas KK
  • 21
  • 5

1 Answers1

1

Well there's many ways to go about it. What it comes down to is that your code needs to account for what has been loaded. You can traverse a scene, but capturing and listing your obj files into specific lists on your own is much cleaner, especially later when implementing things like raycasting.

I would write some functions, perhaps even a class if I planned on supporting other mesh types in the future and wanted a single interface. Importantly, you do not pass the mesh name as the parameter to scene.add and scene.remove, you pass a reference to the actual object. Three.js does this so that it can nullify the parent and call the object "removed" dispatch event in the Three.js library.

So for example purposes, one way is to store your objects in a hash, and use the url to the mesh as the parameter for adding and removal.

var meshes = {};

addObj = function(url){
  var objectloading = url;
  var loader = new THREE.OBJLoader( manager );
  loader.load( objectloading, function ( object ) {
      object.traverse( function ( child ) {
          if ( child instanceof THREE.Mesh ) {
              child.material.map = texture;
          }
      } );
      object.position.y = -30;
      meshes[url] = object;
      scene.add(object);

  }, onProgress, onError );
}

removeObj = function(url){
  scene.remove(meshes[url]);
  delete meshes[url];
}

for example, toggle between two models,

in a button click:

removeObj('obj/male02/old.obj');
addObj('obj/male02/new.obj');

and then in another button click:

removeObj('obj/male02/new.obj');
addObj('obj/male02/old.obj');

Although any String can be used for member names in "meshes," using urls could become problematic if the application grows and the url is actually a service uri utilizing a POST request, then you'll need another layer of references, possibly and usually using the UUID give to each object added to Three.js.

Radio
  • 2,810
  • 1
  • 21
  • 43