问题描述
我正在尝试实现: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 = []