Collision checking is a more general problem and I think you'll have more success if you think about it in a context outside of Three.js. There are a number of methods for managing large numbers of objects that need to check for collision with each other. Here are a few optimizations that might be relevant to you here:
The first optimization is for each object to have a boolean property indicating whether it moved since the last physics update. If both objects you're comparing haven't moved, you don't need to recalculate collision. This is mostly relevant if you have a large number of objects in a steady state (like crates you can push around). There are a number of other optimizations you can build on top of this; for example, often if two objects haven't moved, they won't be colliding, because if they were colliding they would be recoiling (moving apart).
The second optimization is that you usually only need to check collision within a certain distance. For example, if you know that all of your objects are smaller than 100 units, then you can just check whether (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2 > 100^2
. If the check is true (indicating the distance between the two objects is large) then you don't need to calculate detailed collisions. In fact this is more or less the near
/far
optimization that Raycaster
provides for you, but you are not making use of it in your code, since you are always calling the intersectObject
method.
The third optimization is that you are allocating a bunch of new Raycaster
and related objects in every physics update. Instead, you can keep a pool of Raycasters (or even a single Raycaster) and just update their properties. This will avoid a lot of garbage collecting.
Finally, the most common generalized approach to dealing with a large number of collideable objects is called spatial partitioning. The idea is basically that you divide your world into a given number of spaces and keep track of which space objects are in. Then, when you need to calculate collision, you only need to check other objects that are in the same space. The most common approach for doing this is to use an Octree (an 8-ary tree). As WestLangley mentioned, Three.js has an Octree implementation starting in r59, along with an example (source). Here is a reasonable introduction to the concept of spatial partitioning using 2D examples.
Outside of these optimizations, if you need to do anything particularly complicated, you may want to consider using an external physics library, which will manage optimizations like these for you. The most popular ones for use with Three.js at the moment are Physijs, Cannon.js, and Ammo.js.