Select Box optimization (Select Box/Select Cube/VertexData)

I found this to be an interesting problem, so here is my solution:

This works by:

  • generating a frustum in world space (by projecting the selected rectangle) that runs from the near camera plane to the far camera plane
  • finding the meshes that intersect the frustum
  • for each mesh, it loops over all the vertices and checks if the vertex is inside the frustum to color it in red.

In the code, (va0, va1, va2, va3) are the points of the frustum that are on the near plane, and (vb0, vb1, vb2, vb3) the points on the far plane.

It then generates the frustum planes (in world space) in frustumPlanes.

To speed up the check that a vertex is in the frustum, we transform the frustum planes in the local space of the mesh only once (transfFrustumPlanes), instead of transforming each vertex in the world space.

markVertexes can operate in two modes:

  • fast mode (checkFaces==false). In this mode, each vertex is tested against the frustum. This means that vertices that relate to the back faces will also be colored red if they are inside the frustum.
  • Precise mode (checkFaces==true). In this mode, we loop over the faces instead of the vertices and check whether the face is a front or back face by projecting the 3 vertices and doing a cross product between the two projected edges. We do not check the vertices with respect to the frustum if the face is a back face, so only the “front” vertices will be colored in red. You could speed up this case by projecting the vertices once before the loop instead of projecting them inside the loop (which means that vertices that are shared by several faces will be projected several times).

Note: type doit() in the browser console to switch between the select mode / move camera mode

2 Likes