选择附近对象的3DObject事件处理程序应选择self Three.js

时间:2016-12-23 00:13:09

标签: javascript 3d three.js geometry plane

我一整天都在深入研究文档,教程,stackoverflow问题,无法找到解决这个问题的方法。请怜悯我并帮助我!

我有一个喷壶,我把一个事件监听器,但在mousedown,左边和左边的物体被选中,即。树干或树叶(代码不包括在内)然后我可以拖放那个物体直到我把它放下并且它超出了喷壶的范围。如果我把它放在喷壶附近,当我点击它时会再次被选中。这不是预期的行为,我想要点击选择的实际浇水,然后继续拖放等等。这里有很多代码,但我不知道问题出在哪里所以我是包括几乎所有的。这就像喷壶认为它在其他地方或者射线认为它在其他地方射击。如果我可以解决任何问题或发送更多代码,请告诉我。我昨天刚开始学习three.js,所以肯定有些事情我不明白,但我很清楚这里应该发生什么......这不是它:D

const WateringCan = function() {
  this.mesh = new THREE.Object3D();
  const mat = new THREE.MeshStandardMaterial({ metalness: 0.8, color: 0xadb2bd });

  // Create the can
  const geomCan = new THREE.CylinderGeometry(15, 15, 25, 10, 10);
  geomCan.applyMatrix( new THREE.Matrix4().makeScale(1.1, 1.0, 0.6));
  geomCan.computeBoundingBox();
  geomCan.computeFaceNormals();
  const can = new THREE.Mesh(geomCan, mat);
  can.castShadow = true;
  can.receiveShadow = true;
  this.mesh.add(can);

  // Create the handle
  const geomHandle = new THREE.TorusGeometry( 10, 2, 8, 6, Math.PI);
  geomHandle.applyMatrix( new THREE.Matrix4().makeScale(0.9, 1.1, 1.0));
  const handle = new THREE.Mesh(geomHandle, mat);
  handle.rotation.z = 4.5;
  handle.position.x = 13.5;
  handle.castShadow = true;
  handle.receiveShadow = true;
  this.mesh.add(handle);

  // Create spout
  const geomSpout = new THREE.CylinderGeometry(1, 3, 20, 5, 5);
  const spout = new THREE.Mesh(geomSpout, mat);
  spout.rotation.z = 1;
  spout.position.x = -22;
  spout.position.y = 10;
  spout.position.z = 3;
  spout.castShadow = true;
  spout.receiveShadow = true;
  this.mesh.add(spout);

  const domEvents = new THREEx.DomEvents(camera, renderer.domElement);
  domEvents.addEventListener(can, 'mousedown', (e) => onWateringCanMouseDown(e));
};

let wateringCan;
function createWateringCan() {
  wateringCan = new WateringCan();
  wateringCan.name = "wateringCan";
  wateringCan.mesh.position.x = 120;
  wateringCan.mesh.position.y = -30;
  wateringCan.mesh.position.z = -10;
  scene.add(wateringCan.mesh);
  objects.push(wateringCan.mesh);
}

let plane;
function createPlane() {
  plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(WIDTH, HEIGHT, 8, 8), new THREE.MeshBasicMaterial({ color: 0xffffff, alphaTest: 0, visible: false }));
  scene.add(plane);
}

let selection;
function onWateringCanMouseDown(e) {

  const mouseX = (e.clientX / WIDTH) * 2 - 1;
  const mouseY = -(e.clientY / HEIGHT) * 2 + 1;

  const mouse3D = new THREE.Vector3(mouseX, mouseY, 0.5);
  mouse3D.unproject(camera);

  raycaster.set(camera.position, mouse3D.sub(camera.position).normalize());

  const intersectedObjects = raycaster.intersectObjects(objects, true); 
  if (intersectedObjects.length > 0) {

    selection = intersectedObjects[0].object;

    const intersectPlane = raycaster.intersectObject(plane);
    offset.z = selection.position.z;
    offset.copy(intersectPlane[0].point).sub(plane.position);
  }
}

function onDocumentMouseMove(e) {
  const mouseX = (e.clientX / WIDTH) * 2 - 1;
  const mouseY = -(e.clientY / HEIGHT) * 2 + 1;

  const mouse3D = new THREE.Vector3(mouseX, mouseY, 0.5);
  mouse3D.unproject(camera);
  raycaster.set(camera.position, mouse3D.sub(camera.position).normalize());
  raycaster.setFromCamera( mouse3D.clone(), camera);
  if (selection) {
    offset.z = selection.position.z;
    const intersectPlane = raycaster.intersectObject(plane);
    selection.position.copy(intersectPlane[0].point.sub(offset));
  } else {
    const intersectedObjects = raycaster.intersectObjects(objects);
    if (intersectedObjects.length > 0) {
      plane.position.copy(intersectedObjects[0].object.position);
      plane.lookAt(camera.position);
    }
  }
}

function onDocumentMouseUp(e) {
  selection = null;
}

我已经尝试过的东西:computeBoundingBox()在我已经应用的所有内容上,以稍微不同的方式重构mouse3D / raycaster,将罐子移开很远(然后没有选择任何东西)。我也在文档上设置了一段时间的事件监听器,我没有遇到这个问题,但是喷壶片并没有相互粘连,个别的喷口/罐头/把手会被拖放。但至少它知道我点击了它们!还有能力拖拽页面上的所有内容很有趣,但也不是重点,就像我不需要树上的所有树叶四处移动。

如果可以,请帮助我!!我一整天都在乱搞这一切,它正在杀死我的灵魂。 :d

1 个答案:

答案 0 :(得分:0)

好的,好的。我没有发现这种奇怪行为背后的原因是什么,所以我决定重组我正在做的事情,我不再有这个问题了。

我做的是:

  • 从喷壶中取出事件监听器并将其放回文件

  • 删除了所有对象,但是我的对象数组中的喷壶可以通过raycaster.intersectObjects查看,所以现在除了可以拖放之外什么都没有了

  • 现在一切都很好了