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

Clarify details of convex hulls #11

Closed
robertlong opened this issue Dec 23, 2022 · 7 comments
Closed

Clarify details of convex hulls #11

robertlong opened this issue Dec 23, 2022 · 7 comments

Comments

@robertlong
Copy link

  • Are convex hulls generated at runtime?
    • I'd argue against convex hull decomposition at runtime. The mesh should contain at least one primitive with a POSITION accessor and Triangle Strip mode (5) or computed from Triangles (4).
  • What are the max number of vertices for a mesh referenced by a hull?
    • Unity has a maximum of 255 per hull so I'd probably recommend 255
  • Are multiple mesh primitives supported?
    • I'd argue for allowing multiple primitives since the glTF mesh spec already allows for multiple primitives. Also some glTF loaders, for example Unity and Three.js, load glTF nodes as GameObject/Object3D's which have a higher runtime cost than representing just the collision shapes.
@eoineoineoin
Copy link
Owner

eoineoineoin commented Jan 10, 2023

Hey Robert,

Sorry for the delay here; was on holidays, without my Physics PC with me.

Just to go through your points:

Are convex hulls generated at runtime?

Right now, I have a Havok and Godot and implementation of the spec and I'm generating the hulls at load time. I think there's so much variability in how different engines represent hulls that generating them at load time is the only reasonable thing to do - I think just specifying the vertices is the most compatible way to do this - all the other information can be derived from a set of vertex positions.

Obviously, this adds an additional overhead at load time, but there's interesting ways around this - for example, in USD, if you use NVIDIA Omniverse to create a hull, the output file has two objects which represent that hull -- one is the generic "vertices" representation, and the other is just a blob containing the "baked" data in PhysX's native format. I really like this approach - it's an excellent compromise between having an open format and having a runtime-optimized format.

Agree on your suggestion for clarification of the accesors.

What are the max number of vertices for a mesh referenced by a hull?

I really don't want to put a limit on this - I feel that the file format shouldn't be hindered by the limitations of current software. Not every engine has a limit (e.g. Bullet, Newton Dynamics, Jolt (I think)) - so it really seems strange to limit that inside the file itself. Our own engine has a limit of 252 (!) and, while we've never had anyone request an increase to that, I feel like that's an internal implementation detail. Each engine already has code to generate a hull from an arbitrary set of points and I'd expect those methods to handle the case where there's too many input vertices. If that is a problem, a person implementing the spec could apply a simplification algorithm to the input, but, for flexibility, I wouldn't like to mandate any particular behaviour here.

Are multiple mesh primitives supported?

Interesting! Not something we had considered, but will take a look at this - it sounds good. Definitely feel this should be homogenous with the rest of the spec.

@aaronfranke
Copy link
Contributor

I think just specifying the vertices is the most compatible way to do this

With OMI_collider, I originally had it using a predefined list of vertices, but we discussed this in OMI and changed it to be generated from a mesh. For improved compatibility and load performance, you can pre-compute a convex hull and then convert that into a triangle mesh for saving into the file, and an engine can regenerate the hull quickly.

Can you clarify what you intend as the format for storing this data in the file? "just specifying the vertices" - how would this be done in the file, an array of floats, inside of a mesh, etc?

What are the max number of vertices for a mesh referenced by a hull?

I really don't want to put a limit on this

Keep in mind that we want to ensure the format is compatible between many engines, and a limit of 255 (or 252) is not very limiting, so prohibiting more complex convex hulls is a small sacrifice to achieve greater compatibility.

Are multiple mesh primitives supported?

Interesting! Not something we had considered, but will take a look at this - it sounds good. Definitely feel this should be homogenous with the rest of the spec.

For the current version of OMI_collider, it specifies that we only use the first surface / mesh primitive, but this is open to change. I do want to avoid a situation where there are multiple colliders in one collider, if we want multiple surface / mesh primitives to have multiple convex shapes then I think that should require multiple colliders.

@robertlong
Copy link
Author

What are the max number of vertices for a mesh referenced by a hull?

I really don't want to put a limit on this

Also not having a limit will greatly increase the burden on current implementers. Simplification seems a bit odd as a requirement for this spec. Is there any other suggestions you have for compatibility?

@eoineoineoin
Copy link
Owner

I think we need to be careful around terminology here (sorry if my "simplification" comment added confusion); if an engine has a limitation on the number of vertices in a convex hull, that is not a limitation on the number of vertices which can be input to the convex hull generation algorithm. In general, it's not possible to precict the number of vertices in hull(mesh) without running hull(), and the result will obviously differ among different algorithms.

I constructed these objects in blender; a simplex with 4 vertices, a simplex with lots of vertices, a complicated concave shape, and a sphere. With the exception of the 4-vertex simplex, they all have more than the limit that Unity has on the number of vertices in the convex hull:

2023-01-16 16_47_14-Blender_  C__Users_eomcl_Blender_glTF_Physics_Assets_HullComplexityTest blend

Importing and adding colliders in Unity, they look like this:

2023-01-16 16_47_37-Unity_glTF_test - SampleScene - PC, Mac   Linux Standalone - Unity 2019 4 12f1 P

You can see the complicated simplex and concave object has (correctly) had a lot of the redundant vertices dropped, with zero effect on the actual hull. The sphere, on the other hand, has hit the maximum number of vertices Unity supports, so it has dropped some, with a small effect on the resulting volume (and it reports a warning indicating that happened.)

As such, I don't see any benefit from adding a limit on the number of vertices in a hull (I don't even know what such a limit would be) and think it would unnecessarily limit people who were actually making the content. There's precedent for not imposing a limit - in KhronosGroup/UnityGLTF#175, it's reported that Unity had a 65k vertex limit, but nobody would reasonably suggest changing the spec to impose a limit - it's the responsibility of the importing software to make it work as well as possible.

@eoineoineoin
Copy link
Owner

It actually seems like Unity's 256 limit is the number of faces in the hull - not the number of vertices. So, I don't think the real "max number of vertices" is a predictable value.

@aaronfranke
Copy link
Contributor

aaronfranke commented Jan 16, 2023

Perhaps the solution here is to have it be a suggested limit, and show a warning in validators that the model may be imported differently in different engines if over that limit, but allow being over the limit and expect software to handle it. It makes sense to not limit the spec by limitations of existing software, but we also want to avoid situations where users are surprised when their standardized assets behave differently in different software.

@robertlong
Copy link
Author

robertlong commented Feb 2, 2023

I think if the mesh referenced by the hull is actually a convex hull and the mesh looks more like Unity's generated hull then that's great. The issue I have is that there's nothing stopping you from defining a hull's mesh that is like the simplex with many vertices or the complex Suzanne model. IMO these are undesirable hull meshes and the point of this hull type IMO is providing all of the data needed at runtime to create an efficient collider. These hulls are computed offline before exporting the glTF not at runtime.

If they are over a 256 vertex or face limit we can simplify at runtime and use this as the hull. I suppose we don't have to mandate an upper limit, but it can make it harder to implement and I'd put a strongly worded "SHOULD" next to a recommended vertex or face limit.

Personally I'm likely to not support hulls over my physics engine's cap. I don't want to implement a mesh slicing algorithm in my engine to use this data. I'd rather do it in some offline pipeline. So if we don't set a cap I think you're more likely to get people like myself who will fragment the ecosystem by not supporting those assets. I think you're right there shouldn't be a limit and I'd love to support them, but it's a lot of work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants