aardvark-platform / aardvark.algodat

Aardvark.Algodat contains advanced geometric and photometric data structures and algorithms. It is part of the open-source Aardvark Platform for visual computing, real-time graphics, and visualization.
https://aardvarkians.com/
GNU Affero General Public License v3.0
34 stars 6 forks source link

Implement ray-polymesh intersections #24

Closed hyazinthh closed 1 year ago

hyazinthh commented 1 year ago

Introduces methods for intersecting Ray3d with PolyMesh directly, without having to build a k-d tree:

// Filter for hit candidates, returns true for valid intersections and false otherwise
public delegate bool RayHitFilter(in RayHit3d hit);

// Computes all intersections and returns them (arbitrary order)
public List<RayHit3d> GetRayIntersections(Ray3d ray, RayHitFilter filter = null);

// Computes first (i.e. closest to ray origin) intersection
public bool TryGetRayIntersection(Ray3d ray, out RayHit3d hit, RayHitFilter filter = null);

Opted to not follow the Aardvark.Base API as it is a bit convoluted and does not have any methods reporting multiple intersections (which was explicitly requested for this feature). RayHit3d contains all the information anyone would want to query.

Points I'd like to discuss:

1) Are overloads for checking for any intersection required? E.g. Aardvark.Base intersection methods usually have an overload that returns if any intersections were found, returning bool.

2) Is TryGetRayIntersection named appropriately? It returns the first intersection, not any.

3) Do we need overloads that only return V3d (akin to Aardvark.Base)? This is obviously already included in RayHit3d and the benefit of only returning a V3d instead of a 56 byte sized struct does not warrant cluttering the API in my opinion. The intersection tests themselves will dominate the total cost anyway.

4) Intersection methods in Aardvark.Base have an explicit tmin and tmax parameters. Adding them here directly would be superfluous since the same functionality can be achieved by using a filter.

5) For triangulated faces, the intersection test is simple. For faces with more than 3 vertices Face.Polygon3d is used which copies the vertices into a separate array. The intersection with the polygon also allocates memory as the polygon is triangulated internally. Not sure if this can be done more efficiently without implementing a new general ray - polygon intersection method.

luithefirst commented 1 year ago

Opinion on your points:

Other remarks:

hyazinthh commented 1 year ago

I don't think it's a limitation that the triangle index and barycentric coordinates are not returned for general polygons. If an intersection with a general polygon is found, this information simply is not there. Internally, the polygon gets triangulated to compute the intersection, but conceptionally there are no triangles and therefore the hit information cannot contain a triangle index and barycentric coordinates. If the user is interested in ray - triangle intersections, they must make sure the mesh is triangulated beforehand.