Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More robust oriented bounding box computations #11600

Open
javagl opened this issue Oct 31, 2023 · 4 comments
Open

More robust oriented bounding box computations #11600

javagl opened this issue Oct 31, 2023 · 4 comments

Comments

@javagl
Copy link
Contributor

javagl commented Oct 31, 2023

The OrientedBoundingBox::fromPoints method implements an eigenvector-based approach for computing the oriented bounding box of the given set of points, as decribed in "Collision queries using oriented bounding boxes" by Stefan Gottschalk (PDF file).

This approach is prone to distortions - roughly: When there is a "dense" set of points that do not contribute to the actual extremes, then these points will cause a suboptimal eigenvector to be computed. This can be observed, for example, in these cases:

  1. An oriented bounding box of a cube-shaped set of points: The bounding box is not tightly fitting

    OBB Debug 01 from all part

  2. An oriented bounding box that was computed from the corners of the first bounding box - this fits perfectly:

    OBB Debug 02 from corners part

  3. When adding a few more of the original points, the oriented bounding box becomes worse:

    OBB Debug 03 from corners and others part

This happens although these inner points should not affect the bounding box. This phenomenon is also described in the original thesis:

Cesium OBB issue

Approaches for improving the robustness are described in the thesis as well. The most important one is to compute the bounding box not based on all points, but only based on the points of the convex hull of the original points. The idea here is that only the "extreme" points should contribute to the eigenvector computation.

I tried this out, with the quickhull3d library. It does improve the result in some cases - for example, the case 3. from the list above does no longer cause any problems. But still, depending on the exact arrangement of the points, the convex hull may not solve the issue. For example, when computing the convex hull of the cube-shaped set of points, then the hull contains some triangles that are not exactly the "cube faces", but only inserted due to inaccuracies. Depending on where exactly these points are, they may still distort the eigenvectors.

I tried to go one step further, and applied the MeshoptSimplifier.simplify method of the meshoptimizer library to the convex hull, with the goal to get rid of the triangles that are only caused by these inaccuracies. But even when the (optimized) convex hull is a perfect cube, the approach does not necessarily yield good (or even "not bad") oriented bounding boxes:

Cesium OBB Convex Hull Opt part

The thesis specifically mentions an approach for computing the covariance matrix (that serves as the basis for computing the eigenvectors) based on triangles (and not only based on vertices/points). But....

  • the implementation becomes a bit more complex
  • it still requires the computation of the convex hull
  • it might still require the optimization/simplification of the convex hull
  • and it's still not clear whether that would solve the issue and yield "good" bounding boxes more reliably
@javagl
Copy link
Contributor Author

javagl commented Nov 7, 2023

I did some experiments for computing the bounding box with https://github.com/Esri/dito.ts . The results are summarized in CesiumGS/3d-tiles-tools#79 (comment) .

The tl;dr is: The method is noticably slower, but gives better results in nearly all cases.

The implementation in dito.ts was ported from the original C/C++-based implementation. It uses some vector math (really simple things, add/subtract/dot/length) that is implemented based on raw arrays. Iff this method should be supported by CesiumJS, then one could consider to implement it based on the existing Cartesian* classes.

@javagl
Copy link
Contributor Author

javagl commented Aug 26, 2024

Just establishing a connection to #4785 here...

@ggetz
Copy link
Contributor

ggetz commented Aug 27, 2024

@javagl Would you call these duplicates? I'd be in favor of consolidating these issues.

@javagl
Copy link
Contributor Author

javagl commented Aug 27, 2024

@ggetz The older issue does not provide sooo much specific information beyond this one, except for

(The task to port the results from CesiumGS/3d-tiles-tools#79 (comment) to CesiumJS is on my TODO-list, but in the "When I'm really bored"-section 😁 )

I think that either of them could be closed. This one has a bit more specific information. So closing the older one with a comment pointing to this one could make sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment