Clicking a 3D mesh in elm-webgl
How do you add click event handlers to a mesh using elm-webgl? To know if you clicked on a mesh there are two problems that need to be solved:
1) How do you translate a 2d mouse position to a coordinate in 3d space?
2) How do you know which object is displayed at that 3d coordinate?
For a working example project: https://github.com/mahulst/raycast-elm-webgl
Demo: https://mahulst.github.io/raycast-elm-webgl/
The idea is actually pretty simple, you don’t translate the mouse position to a 3d coordinate, but rather to a line in 3d space going from the camera position in the direction of the mouse position. Once that you have the coordinate of the origin (usually the camera position) and the direction the line is going, you need to know if the line intersects with any of the triangles of the mesh.
The implementation of this idea is not so simple, but luckily there are a lot of smart people around who figured out how to make this work.
First we need to know how displaying 3d objects actually works and maybe even understand some of the internals. There are plenty of great resources around. I like this one:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
I hope you read the linked article, but it explains how to display 3d coordinates from a certain view point and perspective on a 2d viewport. For the first problem we are trying to solve we need to do the exact opposite. My solution is based on this:
http://antongerdelan.net/opengl/raycastinghtml
This is the resulting elm function:
This will give you a destination coordinate. And as you already have the camera position as the origin, you can now draw a line between two points.
That leaves only the intersection check to be implemented. There is an existing solution to this problem: Möller–Trumbore intersection algorithm.
Here is the elm version: