How to retrieve all intersection points?

Hi community, coders, fans of babylon,

I have simple code shows 2 meshes and there is a ray that intersects both meshes. I need to retrieve all intersection points or also I can call it hitpoints. All I got is info about 2 points. One for each mesh.
Maybe I have seen kind of info about this topic, so sorry for repeating this.
Anyway is there a way of working to retrive all points that the ray intersects with each face and not only with the mesh?

Playground

thanks for support

You mean entry and exit point per mesh? Then you could shoot the ray in the opposite direction from the end of the first one.

2 Likes

intersection/picking will return 1 point per mesh. @Joe_Kerr is right: shoot another ray or do marching: shoot ray with previous intersection point as origin.

1 Like

Thanks for replies. Here I have more clear picture what I am trying to do. The picture depicts crossection of 2 parts (meshes) and after the ray came thru I need to see info about 6 points (red). Only one direction is allowed. It concerns to real physical simulation. I still belive babylon framewok has capability to perform this. If not, I am not sure how to do it in other way.

@Cedric gave you the easiest answer: do marching.

If you dig into the Babylon source code, submesh contains private _intersectTriangles() that has the related code.

In _intersectTriangles, the statement checks for intersection distance and selects the closer triangle, throwing away the further triangle. Near line 633:

if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance)

What you’re asking for is for that code to retain all intersecting triangles (e.g. push onto an array). The code doesn’t do that at the moment, but you could create a function to keep and return all triangles/points.

There is a lot of code that does material checking and predicate checking before that point (and also checking lines, ribbons, and alternate code paths for other kinds of meshes). It would be pretty major to update all related code to enable returning multiple intersecting points per mesh. But it might be worth rolling your own intersectMultiTriangles() and iterating on submeshes data to collect all triangles.

1 Like

Thank you guys. Although it is not a clear or direct solution, it sounds like an possible approach how to retrive the points. Hopefully :+1:

1 Like

Confirmed. Here’s the marching ray approach. Just a small loop added in your playground. I have settings for max points per mesh and an optional place to add a little extra to the marching ray if you find that it needs to march beyond epsilon.

1 Like

Thanks. I took a look at it. I need to more investigate it. It seems the distance of the last point does not make sense because it should be the biggest number as farest point from origin. But thank you. Now I can see it could be a way. I was a little sceptic at first because I thought it will be more computationally demanding due to marching. The thing is I would need to create and calculate about 1·10^6 of the rays. But step by step

Distance is the distance to the location of the hit. The code I pointed to sorts all the hits on the mesh to return the one with shortest distance (when fast is false). That is what you want so that marching algorithm works. When fast is true, it will return the hit it finds first in order of vertices within the vertex buffer.

It might tale a while to work through 1e6 rays but it also depends on how many meshes.

You might be able to speed up the code by getting the hits as you are doing currently, then for each mesh

  1. convert ray to mesh local coordinates.
  2. call scene.getIntersectingSubMeshCandidates with each mesh and (local) ray.
  3. rewrite submesh _intersectTriangles() to retain all triangles, that I mentioned in the earlier post.
  4. rewrite other _intersect*() functions needed, depending on mesh types.

If that’s not fast enough, you’ll have to consider other ways to accomplish what you need.

Interesting topic.

I’ve created a function to get the entry and exit points:

If you use irregular polygons you can create small sub rays along the the ray and check for intersections in the irregular polygon utilizing the getMeshIntersectionByRay from the previous PG:

There is plenty of room for improvement…

I have a better idea (hopefully a much faster :smiley: one using the GPU as well ) so I’m not gonna tweak this PG any further. Hang tight, I already started to work on it.

3 Likes

GPU may be a good improvement.

I think your second PG is the same marching algorithm as I implemented, but makes two assumptions that could be problematic:

  1. assumes reverse direction is less than 1000 (with comment TODO: calculate smallest usable value)
  2. assumes precision, aka marching offset to next start, is a constant .1.

In my code, precision is set to ray.epsilon and calculating the reverse origin is not needed.

Also the use of reverse ray just doubles the number of intersection checks even though the forward ray will also find the reverse case (after marching to it).

Very interested in your GPU version to see if that performs better!

Edit: commenting out the CreateSphere on the exit point shows that it duplicates the intersection detection and is not necessary because the “entry point” will eventually march to each exit point.

Edit: oh, I see you did comment it out in “Enhanced” function.

Great ideas. Now it’s time to build the basic demo to test it out the overall speed. I am going to use code from HiGreg and roland or the combination of both, I dont know. I’ ll be in touch.

2 Likes

I am aware of all the issues you mentioned:

You’re absolutely right. I started with a different approach but ended with CPU raymarching.

1 Like

If you are in the mood and have free time maybe you could try out my backup idea to use depth peeling :wink:

My two cents: Idea with spatial filtering. Only take into account the meshes that may be hit by the ray.

Ray-Mesh Intersection Analyzer

by gemini 2.5, chatGPT, claude


index.zip (4.1 KB)

Intersection Detection System

Two-Stage Process:

  1. Spatial Filtering (Candidate Selection)
  • Uses Babylon.js Octree for spatial optimization (when available)
  • Fallback: Manual distance-based filtering
  • Only considers objects within 25 units of the ray line
  • Visual Feedback: Candidate objects are highlighted in yellow
  1. Precise Intersection Testing
  • Performs detailed ray-casting for each candidate object
  • Uses Babylon.js pickWithRay() for accurate collision detection
  • Validates intersection points are within ray length
  • Visual Feedback: Actual intersection points marked with red spheres

BUG: red spheres are not visible but the positions are logged in the console.

2 Likes