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?
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.
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.
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.
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.
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
convert ray to mesh local coordinates.
call scene.getIntersectingSubMeshCandidates with each mesh and (local) ray.
rewrite submesh _intersectTriangles() to retain all triangles, that I mentioned in the earlier post.
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.
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 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.
I think your second PG is the same marching algorithm as I implemented, but makes two assumptions that could be problematic:
assumes reverse direction is less than 1000 (with comment TODO: calculate smallest usable value)
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.