Sprite positioning in 3D scene

TBH, I’m surprised that you do the things in the way that is as complicated as possible.

You can use just one sprite that has a texture of marker and deletion glyphs. The idea: when you raycast an array of sprites, you can also get UV coordinates, so just use it for layout of the sprite, when you know where your deletion mark is in UV coordinates :slight_smile:

I’ve created a small example, based on the same code from the official example.
Keep in mind: it’s just a concept, not the ultimate solution.

Additional variables in the beginning:

  raycaster = new THREE.Raycaster(),
  mouse = new THREE.Vector2(),
  intersects = [];
  var spriteMaterial = new THREE.SpriteMaterial({
  map: new THREE.TextureLoader().load(
    "https://cywarr.github.io/small-shop/Marker.png"
    )
  });
  var markers = [], markersCounter = 0;

So, the event for double click is:

  document.addEventListener(
    "dblclick",
    event => {
      mouse.x = event.clientX / window.innerWidth * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

      raycaster.setFromCamera(mouse, camera);

      let marker = new THREE.Sprite(spriteMaterial);
      marker.scale.set(20, 20, 1);
      marker.name = "marker" + markersCounter;
      raycaster.ray.at(210, marker.position);
      scene.add(marker);
      markers.push(marker);
      markersCounter++;
    },
    false
  );

And I’ve added the logic of deletion to the mouse down event:

  // Deletion
  mouse.x = clientX / window.innerWidth * 2 - 1;
  mouse.y = -(clientY / window.innerHeight) * 2 + 1;
  
  raycaster.setFromCamera(mouse, camera);
  
  intersects = raycaster.intersectObjects(markers);
  
  if (intersects.length > 0){
    let obj = intersects[0];
    let uv = obj.uv;
    if (Math.min(uv.x, uv.y) > 0.75) { 
      obj.object.visible = false; // you have to do the stuff for real clearance
    }
  }
3 Likes