三.JS - 单击时删除自定义对象

问题描述

我正在尝试实现:1) SHIFT + 单击要从场景中删除的对象,以及 2) 清除按钮以从场景中删除所有对象。

实时版本:https://cs12students.dce.harvard.edu/~amarkham/sandbox/

如果您从“设备”选项卡添加对象,它似乎可以很好地清除某些对象,但忽略其他对象。加载对象后,我将其添加到场景中并将其推送到数组“对象”。当一个对象被移除时,我想将它从场景和“对象”数组中移除。

我将在此处包含(我认为)相关的代码

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',2).name('key light');
  lightFolder.add(keyLight.position,'x',-50,50).name('key light x');
  lightFolder.add(keyLight.position,'y',100).name('key light y');
  lightFolder.add(keyLight.position,'z',50).name('key light z');
  lightFolder.add(ambientLight,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);

    });
  }
}

感谢您的帮助! Three.js 玩起来很兴奋。

解决方法

您正在对对象数组执行 forEach,并且在该 forEach 中您也在操作(拼接)对象数组:这会导致运行 forEach 时不匹配。

最好只运行 forEach 而不进行操作,然后在 forEach 之后简单地执行:

objects = []