0

I have been experimenting with three.js for the past few days making an interactive environment where you can pick up a watering can(drag and drop), click on it to make it spout water, and a mango on a tree in the scene will grow.

I have implemented drag and drop successfully due to their being a lot of tutorials on it all sporting basically the exact same code. I feel like there is a bug with this solution though and I have found it in other peoples jfiddles etc so in my limited experience it seems like a problem with the actual code and not just my implementation of it.

the common implementation I have found on here goes like this:

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 onDocumentMouseDown(e) {
  e.preventDefault();

  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.copy(intersectPlane[0].point).sub(plane.position);
  }
}

function onDocumentMouseMove(e) {
  e.preventDefault();
  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) {
    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;
}

With this implementation, when you click on the object and dont move it for a second, the object "jumps" back to its original position. also, if I have dragged the object across the x-axis and I try to drag it again from that position, it "jumps" to (0, 0, 0) which is the more annoying part.

I am not familiar with how to make a jfiddle and I think I have too much code going on for it to be successful anyways, but you can see what i mean in this other jfiddle which thank you to whoever made it, it was really helpful to me!! and sorry I am using it as an example of what I think might be a bug.

If you play around with the box for a bit, you can see that it "jumps" back to the center. The code for this jsfiddle is essentially the same as every other solution I have found on stackoverflow and other three.js specific tutorials. Has anyone implemented drag and drop in a different way and avoided this problem? Is this unavoidable as it seems everyone uses this method despite this issue?

I would be very very grateful for any help anyone is willing to give. Thank you for your time in reading and thinking about this!

b-insh
  • 21
  • 3
  • I expect the three.js examples will be of more help: http://threejs.org/examples/webgl_interactive_draggablecubes.html and http://threejs.org//examples/webgl_interactive_cubes.html. Also http://stackoverflow.com/questions/26652888/three-js-orthographic-camera-object-picking/26656345#26656345 – WestLangley Dec 30 '16 at 21:38
  • Thank you for your response! West Langley himself :) those are amazing! I don't know how much they apply to my situation as the first seems to use DragControls and the second doesn't have any dragging, I have improved the situation somewhat by not having an offset at all but the underlying problem remains of the object thinking that its position is always it's original position, no matter where I move it. – b-insh Dec 30 '16 at 23:32
  • The implied suggestion was to use the coding patterns as illustrated in the links, but it is up to you. Sorry, I can't help you debug your code. – WestLangley Dec 31 '16 at 02:27

0 Answers0