Skip to content

KHR_implicit_shapes extension Draft Proposal#2370

Open
eoineoineoin wants to merge 18 commits into
KhronosGroup:mainfrom
eoineoineoin:collisionShapeMerge
Open

KHR_implicit_shapes extension Draft Proposal#2370
eoineoineoin wants to merge 18 commits into
KhronosGroup:mainfrom
eoineoineoin:collisionShapeMerge

Conversation

@eoineoineoin

@eoineoineoin eoineoineoin commented Mar 19, 2024

Copy link
Copy Markdown
Member

Draft of an extension which describes generic, non-renderable shapes suitable for collision detection.

Known Implementations

Blender importer/exporter
Babylon.js importer
Godot importer

Sample Assets

https://github.com/eoineoineoin/glTF_Physics/tree/master/samples

Comment thread extensions/2.0/Khronos/KHR_collision_shapes/README.md Outdated
Comment thread extensions/2.0/Khronos/KHR_collision_shapes/README.md Outdated
Comment thread extensions/2.0/Khronos/KHR_collision_shapes/README.md Outdated
Comment thread extensions/2.0/Khronos/KHR_collision_shapes/README.md Outdated
Comment thread extensions/2.0/Khronos/KHR_collision_shapes/README.md Outdated
Comment thread extensions/2.0/Khronos/KHR_collision_shapes/README.md Outdated
Comment thread extensions/2.0/Khronos/KHR_collision_shapes/README.md Outdated
@EricGriffith

Copy link
Copy Markdown
  1. It would be great to include example usage of the schemas in the spec.

  2. both seems to be a typo here:

As both the mesh shape

  1. The convex property name is confusing. To me, it implies that the mesh is required to be convex. I prefer the previous version where convex and mesh were separate shapes. If momentum means it they must stay combined, please use a more descriptive name like convexHull.

  2. The skin and weights properties should probably be disallowed when a mesh shape is used together with a node that uses the same mesh for rendering. Otherwise, every extension using these shapes will need to repeat the same normative text explaining the precedence of the two (node + shape) skin properties and the three (node + mesh + shape) weights properties.

Rename "convex"->"convexHull". Tidy up phrasing, documentation.
Improved introduction text; add an inline sample defining a shape.
Clarifications around degenerate shapes & node scale.
Remove backticks when not referring to a property.

@aaronfranke aaronfranke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contents of this PR do not match the repo in which the extension was developed: https://github.com/eoineoineoin/glTF_Physics/tree/master/extensions/2.0/Khronos/KHR_collision_shapes/schema

If changes are needed, the original repo should also be updated so that it stays in sync.

@npolys

npolys commented May 31, 2024 via email

Copy link
Copy Markdown
    Remove convex hull options from base KHR_collision_shapes; for many
    cases, convex hulls are not necessary and having to support convex hull
    generation in a viewer may be a significant implementation burden.

    Refactor morph targets to support the common use-case of describing a
    mesh collider which intends to use the same morph target weights as a
    node's instance weights. Add an explicit recommendation for how an
    extension can reference a collision shape.

    Upgrade schemas to draft 2020-12.
@eoineoineoin eoineoineoin changed the title Merge of KHR_collision_shapes extension KHR_collision_shapes extension Draft Proposal Jul 10, 2024
@wallabyway

wallabyway commented Aug 6, 2024

Copy link
Copy Markdown

@eoineoineoin - Thanks for bringing up 'implicit shapes'.

If I could pick two shapes that would help AEC, it would be cylinder and cube. We could add a million other shapes, but I would compromise everything, just to get these two into a future spec somehow.

We pay a very high price for cylinders (HVAC, railings, cables, rebar, etc). If the industry agreed on this, there would be a lot of precision gained (measurement), less data-loss (from pre-baked tessellation) and far fewer triangles transported and rendered.

Same for 'Cubes'. If the industry agreed on a cube shape, rather than "I think these 16 triangles are a cube", it would add a lot of meaning for AEC - the design intent is captured, it's manifold, it has an agreed volume, render outline-style without guessing, improved z-fighting of overlapping volumes.

I know it's a very low bar, but you've got to start somewhere and these two additions add an impressive amount of value IMHO.

@javagl

javagl commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

@wallabyway I've lost track of some of the discussion/developments here, and am (unfortuantely) not up to date. But a while ago, I also advocated for basically creating KHR_shapes and KHR_collision (using KHR_shapes) extensions. Somewhere around eoineoineoin/glTF_Physics#1 (comment) . The use-case would be for CAD/AEC (maybe going so far that these could even serve as a basis for some CSG at some point...).

When "shapes" are defined here (non-renderable, as part of a "collision" extension), then someone will create a new extension that defines the same shapes, but "renderable". And in the worst case, one defines a "box" as (min, max), and the other one defines a "box" as (origin, size), and we all know what happens then...

Some further related discussion is in #1135 and around #1986 (comment) , and many issues that are linked to/from these. (It's hard to wrap this up - that's why I lost track...).

@eoineoineoin

Copy link
Copy Markdown
Member Author

@wallabyway I've lost track of some of the discussion/developments here, and am (unfortuantely) not up to date. But a while ago, I also advocated for basically creating KHR_shapes and KHR_collision (using KHR_shapes) extensions. Somewhere around eoineoineoin/glTF_Physics#1 (comment) . The use-case would be for CAD/AEC (maybe going so far that these could even serve as a basis for some CSG at some point...).

When "shapes" are defined here (non-renderable, as part of a "collision" extension), then someone will create a new extension that defines the same shapes, but "renderable". And in the worst case, one defines a "box" as (min, max), and the other one defines a "box" as (origin, size), and we all know what happens then...

Some further related discussion is in #1135 and around #1986 (comment) , and many issues that are linked to/from these. (It's hard to wrap this up - that's why I lost track...).

Hey Marco,

Right, it does seem that there's interest in using the shapes for rendering, amongst other things. So, at the very least, there's a rename of the extension and associated reworking of documentation in the works, to ensure it's obviously usable for multiple different use-cases.

The "mesh" shape type is causing us some hassle, though, so I want to see if you have any thoughts here. For things like physics, selectability, UI, etc., it's useful to be able to describe a shape which is derived from a glTF.mesh. Though, for the "shape rendering" extension, this shape.mesh is redundant, since glTF meshes are already renderable via nodes. That leaves us with a couple of options:

  1. Remove shapes.mesh, require "physics extension" and friends to reference glTF.mesh via some other mechanism
  2. Leave as-is; "shape rendering extension" and friends would define how those shapes.mesh are handled

My concern is that with option 1, the options available in the shapes.mesh today will have to be re-defined by any extension which wants to use meshes. Similarly, with option 2, extensions might all require documentation to say how each shape type is handled (though, this might need to be the case anyway?) Any preferences? Other ideas?

@javagl

javagl commented Aug 14, 2024

Copy link
Copy Markdown
Contributor

It's hard to say anything really profound here, without all the context, and not knowing the plans that may have been discussed internally already. So all I can say is very high-level, and should be taken with a grain of salt.

I think that having a real glTF mesh as a collision shape already does raise questions. Meshes can be arbitrarily complex, could be self-intersecting, don't have to be manifold - heck, a mesh could actually be a soup of unconnected triangles. Quickly looking at the README here, it does not seem to impose any real constraints for that mesh. I could imagine that implementors of physics engines will not really know what to do with that, and think that there should either be

  1. a description in the README about how to deal with such shapes (i.e. which degrees of freedom implementors have for handling it - like computing a convex hull from it, and using that as the collision shape)
  2. or constraints on the specification level - like that mesh must be manifold or maybe even that it must be a convex hull (some thoughts about convex hulls are also mentioned at the bottom of this comment)

That said, from my current, limited understanding, I'm not sure what the problem would be with the point that " glTF meshes are already renderable via nodes" that you mentioned:

  • A glTF can define a mesh
  • The mesh can be attached to a node, so that it is rendered
  • The mesh can be referred to by a shape
  • A shape can be attached to a node, so that it is rendered
    (At least, that's what is considered as part of the 'generalization' to use shapes not only for collisions, but also for rendering)

If I understood your concern correctly, then it is that someone could do something like
node -> shape -> mesh
instead of the direct
node -> mesh
to render a mesh. If this is correct, then: Yes, that would be "quirky", and an unnecessary 'detour'. But it would just be the result of saying "Attach this shape to the node (regardless of what kind of shape it is)".

Or, referring to your point

with option 2, extensions might all require documentation to say how each shape type is handled

Then I think that the mesh type would actually be the easiest case here: It would boil down to rendering the mesh as-if it was attached directly to the node. (For the other types, this may be more tricky - e.g. "How many triangles should a rendered sphere consist of?" ...)

(I might be missing a point here...)

@eoineoineoin eoineoineoin changed the title KHR_collision_shapes extension Draft Proposal KHR_implicit_shapes extension Draft Proposal Oct 16, 2024
@lyuma

lyuma commented Oct 17, 2024

Copy link
Copy Markdown

I have been reading through the recent changes to use a collider or trigger "geometry" object.

I have some concern with the new version of the spec because it references "node", that implies referencing a node, which must be visible in core gltf. Is there a way to use meshes in physics colliders without rendering those meshes?

Related to this problem is a confusing paragraph here, so I would like some clarification on this:

Collision shapes are parameterized in local space of the node they are associated with. If a shape is required to have an offset from the local space of the node the shape is associated with (for example a sphere not centered at local origin or a rotated box,) a child node should be added with the desired offset applied, and the shape properties added to that child.

if I understand correctly, does this paragraph that the nodes and child nodes (a comment by Khronos members implies this actually means descendants) in the context of mesh geometry are taken in local space of the referenced geometry / node?

if so, can I ask if an acceptable way to implement hidden mesh collision shapes is to make a node whose scale is [0,0,0] (which hides the mesh as per the core gltf spec): since the collision shape children use a coordinate space relative to this node, child nodes will ignore the 0 scale. Does this make any sense?

if for some reason using [0,0,0] scale is not possible, the only alternatives I can think of are using a translation at 1e+99 to effectively hide the mesh, or relying on the node visbility extension (but this will not degrade well to older versions of Blender, for example)

Comment thread extensions/2.0/Khronos/KHR_implicit_shapes/README.md Outdated
Comment thread extensions/2.0/Khronos/KHR_implicit_shapes/README.md Outdated

| | Type | Description |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **plane** | `object` | A plane centered at the origin in local space, with normal along the Y axis in local space, optionally with finite extents and may be double or single-sided. |

This comment was marked as resolved.


When the `type` of a shape refers to a shape type defined by this extension, the shape must not supply a value for a different shape type e.g. a shape whose `type` is "box" must not have a defined `sphere` property. Similarly, if `type` does not reference a shape type declared by `KHR_implicit_shapes`, an extension or other mechanism should supply an alternate shape definition.

By default, planes have infinite extents along their tangent and bitangent vectors, specified as X and Z in local space, respectively. A plane may optionally provide `sizeX` and `sizeZ` properties to specify a finite size along these axes.

This comment was marked as resolved.

This comment was marked as resolved.

@javagl javagl mentioned this pull request Oct 24, 2025
}
```

To describe the geometry which represents the object, shapes must define at most one of the following properties:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider requiring the corresponding object (so it's always available in the Object Model).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that even if a shape was utilizing the default values, you'd want to require an empty object? e.g.

"shapes" = [
{
     "type": "sphere",
     "sphere": {}
}
...

One complication on REQUIREing one of the objects that other extensions may add additional types and may not wish to have a fallback:

"shapes" = [
{
     "type": "teapot",
     "extensions": {
            "ext_teapot_shape" : {
                       ....
            }
    }
}
...

For those types, we wouldn't want to require an unrelated object in the shape.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even when an object is syntactically empty it's not semantically empty because most shape properties have default values so, e.g., "sphere": {} actually means "sphere": { "radius": 0.5 }.

The extension should require an object matching the type so future extensions wouldn't require unrelated objects.


When the `type` of a shape refers to a shape type defined by this extension, the shape must not supply a value for a different shape type e.g. a shape whose `type` is "box" must not have a defined `sphere` property. Similarly, if `type` does not reference a shape type declared by `KHR_implicit_shapes`, an extension or other mechanism should supply an alternate shape definition.

By default, planes have infinite extents along their tangent and bitangent vectors, specified as X and Z in local space, respectively. A plane may optionally provide `sizeX` and `sizeZ` properties to specify a finite total size along these axes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As currently written, the language may imply that either both plane extents must be set or none.


By default, planes have infinite extents along their tangent and bitangent vectors, specified as X and Z in local space, respectively. A plane may optionally provide `sizeX` and `sizeZ` properties to specify a finite total size along these axes.

Degenerate shapes are prohibited. If provided, a plane must have positive non-zero `sizeX` and `sizeZ` extents. A sphere must have a positive, non-zero radius. A box shape must have positive non-zero values for each component of `size`. The cylinder and capsule shapes must have a positive, non-zero `height`, both `radiusTop` and `radiusBottom` must be non-negative, and at least one of `radiusTop` and `radiusBottom` must be non-zero.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto about planes.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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