1

I'm trying to implement: 1) SHIFT + click on object to remove from scene, and 2) clear button to remove all objects from scene.

Live version: https://cs12students.dce.harvard.edu/~amarkham/sandbox/

If you add objects from 'Equipment' tab, it seems to clear some objects fine but ignore others. When the object is loaded, I am adding it to the scene and the pushing it to an array 'objects'. When an object is removed, I'd like to remove it from the scene and 'objects' array.

I'll include the code that (I think) is relevant here:

let objects = [];
window.addEventListener('keydown', function(e) {userPress = e.keyCode;});
window.addEventListener('keyup', function(e) {userPress = undefined;});

function init() {

...

dragControls = new THREE.DragControls(objects, camera, renderer.domElement);
  dragControls.addEventListener('dragstart', event => {
    //if shift pressed on click, remove target object from scene and objects array
    if (userPress === 16) {
      event.object.material = undefined;
      event.object.geometry = undefined;
      event.object.parent.remove(event.object);
      objects.splice(event.target, 1);
      console.log(objects.length);
      console.log(objects);
    }
    //else disable orbit control, show selected
    else {
      controls.enabled = false;
      event.object.material.transparent = true;
      event.object.material.opacity = 0.75;
    }
  });
  //bind y position to 0
  dragControls.addEventListener('drag', event => {
    event.object.position.y = 0;
  });
  //show unselected if object present on dragend
  dragControls.addEventListener('dragend', event => {
    if (event.object.material == undefined) {}
    else {
      controls.enabled = true;
      event.object.material.transparent = false;
      event.object.material.opacity = 1.0;
    }
  });

...

//dat.GUI
  gui = new dat.GUI();
  guiProperty = {
    reset: resetCamera,
    clear: function() {clearScene();},
    decimator: function() {getOBJ('decimator_12G_4K');},
    atem_mini_pro: function() {getOBJ('atem_mini_pro');},
    macbook_pro_13: function() {getOBJ('macbook_pro_13');}
  };

  var lightFolder = gui.addFolder('Lights');
  lightFolder.add(keyLight, 'intensity', 0, 2).name('key light');
  lightFolder.add(keyLight.position, 'x', -50, 50).name('key light x');
  lightFolder.add(keyLight.position, 'y', 0, 100).name('key light y');
  lightFolder.add(keyLight.position, 'z', -50, 50).name('key light z');
  lightFolder.add(ambientLight, 'intensity', 0, 5).name('ambient light');

  var objFolder = gui.addFolder('Equipment');
  objFolder.add(guiProperty, 'decimator').name('Decimator 4K');
  objFolder.add(guiProperty, 'atem_mini_pro').name('Atem Mini Pro');
  objFolder.add(guiProperty, 'macbook_pro_13').name('MacBook Pro 13"');

  gui.add(guiProperty, 'reset').name('Reset');
  gui.add(guiProperty, 'clear').name('Clear');

...


}

function getOBJ(name) {
  var modelPath = '../assets/models/' + name + '.obj';
  var texturePath = '../assets/textures/' + name + '.jpg';
  var newOBJ = new THREE.OBJLoader();
  var textureLoader = new THREE.TextureLoader();
  var texture = textureLoader.load(texturePath);
  var material = new THREE.MeshPhongMaterial({
    map: texture
  });

  newOBJ.load(modelPath, function(object) {
    object.traverse(function(node) {
      if (node.isMesh) {
        node.material = material;
        node.castShadow = true;
      }
    });
    object.name = name;
    objects.push(object);           //push mesh to objects array
    scene.add(object);              //add mesh to scene
    console.log(objects.length);
    console.log(objects);
  });

function clearScene() {
  if (objects.length > 0) {
    objects.forEach(function(object) {
      if (object.isMesh && object.name != '')
      object.material = undefined;
      object.geometry = undefined;
      object.parent.remove(object);
      objects.splice(object, 1);

    });
  }
}

Thanks for any help! Three.js has been exciting to play around with.

LanderIII
  • 11
  • 1

1 Answers1

-1

You are performing a forEach on the objects array, and inside that forEach you are also manipulating (splice) the object array: this leads to mismatches while running the forEach.

It's better to just run the forEach without the manipulation, and after the forEach simply do:

objects = []
Maarten Veerman
  • 1,546
  • 1
  • 8
  • 10