evil professeur
evil professeur

Reputation: 369

Three.js reverse raycasting

I'm setting up a world map on a curved plane that the user can rotate and highlight countries. When a country is clicked, I determine what exactly was clicked and then show a tooltip with some information about the selected country, like on the screenshot below:

tooltip screenshot

The map itself is generated in three, but the tooltip is a regular old div. The thing is, I'd like the tooltip to stay glued to that particular point of the texture, even if the plane is rotated. The original positioning of the tooltip is based on the information from the raycaster. As such, I'd want the app to return the current position of that precise point, relative to the container (or window) - based on uv coordinate for instance. How can I achieve that?

Upvotes: 2

Views: 978

Answers (1)

evil professeur
evil professeur

Reputation: 369

Basing on the link provided by @prisoner849, I've implemented the following solution:

a) on mouseup event I set a new tooltip 3D origin point (only if there was no significant delta in mouse position, to discern between clicking and dragging the camera)

b) every frame, the following function is fired, which converts the 3D coords to 2D and calculates the position of the tooltip:

function setTooltipOrigin( camera, renderer, tooltip, lastClickPoint ) {
  var canvas = renderer.domElement,
  point = new THREE.Vector3();

  point.x = lastClickPoint.x,
  point.y = lastClickPoint.y,
  point.z = lastClickPoint.z,

  point.project( camera );

  point.x = Math.round(( 0.5 + point.x / 2 ) * ( canvas.width / window.devicePixelRatio ));
  point.y = Math.round(( 0.5 - point.y / 2 ) * ( canvas.height / window.devicePixelRatio ));

  point.x -= 14; //small adjustment to the position, so the line points to the click point
  point.y -= (tooltip.scrollHeight * 0.7); //same for y

  tooltip.style.transform = 'translate(' + point.x + 'px, ' + point.y + 'px)';
}

Upvotes: 3

Related Questions