Trace rays against a BVH instead of the nearest face centroids - #84
Draft
akaszynski wants to merge 2 commits into
Draft
Trace rays against a BVH instead of the nearest face centroids#84akaszynski wants to merge 2 commits into
akaszynski wants to merge 2 commits into
Conversation
The projection in create_mesh cast each cluster normal at the 1000 faces whose centroids were nearest the centroid, and stopped at the first of them it hit. Neither half holds: the face a ray meets first need not have a near centroid, and past 1000 faces it is not a candidate at all. Build a BVH over the surface and take the true nearest intersection. Exact rather than approximate, and 5.6-15x faster on the projection since it replaces a k=1000 kd-tree query with a tree walk.
The Moller-Trumbore determinant is the sine of the angle between the ray and the plane of the face, times twice the area of the face. Rejecting on a fixed 1e-6 therefore threw out small faces whatever their angle: 99.7% of the faces of the bunny subdivided once, whose centroids moveclus then could not move at all. Divide the area back out at build time so the test is on the angle alone, and reject a face of no area outright rather than dividing by zero and relying on NaN comparisons to fall through.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
create_mesh(moveclus=True)projects each cluster centroid onto the surface along its normal. It did that by taking the 1000 faces whose centroids were nearest the cluster centroid and stopping at the first one the ray hit. Both halves are approximations: the face a ray meets first need not be one whose centroid is near it, and beyond 1000 faces it is not a candidate at all. This builds a BVH over the surface, ported from femorph, and takes the true nearest intersection.The second commit is the bigger one. The Möller-Trumbore determinant is the sine of the angle between the ray and the plane of the face times twice the area of the face, so rejecting on a fixed
1e-6threw out small faces regardless of angle: 99.7% of the faces of the bunny subdivided once, whose centroidsmoveclusthen could not move at all. Dividing the area back out makes the test scale free, and takes the bunny at 5000 clusters from 32 of its points moving to 4968, and its worst distance from the surface from 5.5e-4 to 1.6e-17. The airplane goes from 1.09 off a model 2000 across to 2.8e-14.Also 5.9-15x faster on the projection and 4.5-10x on
create_meshoverall, since a tree walk replaces a k=1000 kd-tree query.ray_traceloses itsneigh,no_inf,num_threadsandout_of_bounds_idxarguments and returns the index of the face hit rather than an index into a candidate list.MAX_THREADSgoes with it: it fed anum_threadsparameter the extension never read.Tests check the tree against a brute-force reference over every face on four meshes in both directions, and pin each case that was wrong: the nearest centroid not being the nearest face, a hit beyond the thousandth candidate, mesh scale, and a face of no area. The airplane test fails on main at 1.09.
Groundwork for #83, which needs the hit face to tell a legitimate projection from a runaway.
Changes drafted by Claude Opus 5 but fully understood by me.