KhronosGroup / KhronosGroup/glTF

Create a specification for primitive physics shapes (boxes, spheres, etc)

Open
#1,986 11 comments 8 reactions 0 assignees View on GitHub
Dominant language
HTML
Stars
7.8k
Forks
1.2k
Avg merge
17h 26m
Merged PRs (30d)
5

Description

EDIT: Please note that the specific details in this proposal no longer reflect what I believe to be the best approach. The goals behind this proposal, specifying geometric shapes, are still valid.

I'm working on Godot Engine and I would like the ability to specify primitive geometric shapes in a GLTF file for the purpose of being read and used by a physics system and by other systems such as audio.

I have seen that #1135 exists, and it has received some negative feedback. It's a huge proposal which includes things like physics materials, joint constraints, gravity, and more. Really the full extent of that proposal is overkill for what I want, so I am opening this proposal to hopefully get something simpler added to the specification.

Godot has a GLTF exporter, so I will try to be as specific as possible as to what the output currently looks like in the `.gltf` file and what the desired output would be if this specification was added.

Here is a screenshot of an example scene I am working with (`core.tscn` from the TPS demo):

![Screenshot from 2021-05-28 05-34-19](https://user-images.githubusercontent.com/1646875/119964867-a37fb080-bf77-11eb-8a15-942c72a9c2fc.png)

And here is that same screenshot but with the meshes hidden, so that only the primitive colliders are visible:

![Screenshot from 2021-05-28 05-34-25](https://user-images.githubusercontent.com/1646875/119964883-a67aa100-bf77-11eb-8b05-d0a41192a83e.png)

When exporting, the collision primitives easily visible in the second screenshot are not preserved. However, each of the collision shapes do get exported with a name, rotation, and translation, just with no shape defined. It looks like this in the `.gltf`:

```gltf
{
"extensions": {},
"name": "MainFloor2",
"rotation": [0, -0.078459, 0, 0.996917],
"translation": [21.6304, -14.5, 3.42592]
},
```

If allowed by the spec, the information about primitive shapes could look something like this:

```gltf
{
"extensions": {
"primitive_box": { "size": [11, 4.2, 4] }
},
"name": "MainFloor2",
"rotation": [0, -0.078459, 0, 0.996917],
"translation": [21.6304, -14.5, 3.42592]
},
```

Here is an overview of what the proposed API could look like. All numbers must be >= 0.

* Box
* Suggested name: `primitive_box`
* Has `size` member of type Vector3 (three numbers), which specify the "diameter" of the box, so `size` of `[1, 1, 1]` means a 1x1x1 cube.
* Alternative implementation: Replace `size` with `extents` that defines the "radius" of the box, so `extents` of `[1, 1, 1]` means a 2x2x2 cube.
* Sphere
* Suggested name: `primitive_sphere`
* Has `radius` member which is one number that defines the distance from the center to the surface.
* Capsule
* Suggested name: `primitive_capsule`
* Has `radius` member which is one number that defines the distance from the center to the surface of both "cap" semi-spheres.
* Has `height` member which is one number that defines the distance from the very bottom to the very top.
* Cylinder
* Suggested name: `primitive_cylinder`
* Has `radius` member which is one number that defines the distance from the center to the edge of both circles.
* Has `height` member which is one number that defines the distance between the centers of both circles.
* Note: Not all physics systems and other systems support cylinders, because doing so is more complex than the other primitives. In this case, a convex hull will need to be used.

Arguments can be made for a few other primitive types, such as cones, cylinders with different end sizes, and rays. However, the above are the only ones I'm familiar with and I know to be broadly useful.

This information would be much more efficient than storing mesh triangles for each physics object, and would make it easier to move scenes between projects and even between different game engines. These shapes could be used by more than just collision, for two examples in Godot, Area nodes can be used to change the audio settings for some part(s) of the level, and can also be used to change the gravity for some part(s) of the level.

---

This is really two proposals in one, with the below dependent upon, but really separate from, the above. Without the below, software would just have to guess as to what the purpose of the shapes are, or let the user specify with import settings.

To make this proposal even more useful, it would be nice to be able to define the purpose of the shapes. Because physics bodies are very often composed out of multiple shapes, each object with a shape would be children of a parent physics body of some kind. In the case above, one of them looks like this in the `.gltf` file:

```gltf
{
"children": [
259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300,
301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328,
329, 330, 331, 332, 333, 334, 335, 336
],
"extensions": {},
"name": "RadialColliders2",
"rotation": [0, 0.782608, 0, 0.622515]
},
```

Then, the parent body would have its purposed defined, something like this:

```gltf
{
"children": [
259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300,
301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328,
329, 330, 331, 332, 333, 334, 335, 336
],
"extensions": {
"shape_usage": "static_collision"
},
"name": "RadialColliders2",
"rotation": [0, 0.782608, 0, 0.622515]
},
```

The exact API of this part is something I'm less sure about than the above shape API. We want to be able to specify many different types of physics bodies to provide as much information as possible to software, including rigid, kinematic, static, character, area detection, audio manipulation, and more. The specific details of these things (like defining mass or whatever) are simple and specific enough that we should consider letting each piece of software handle it on their own. It could be argued that these things (like mass etc) are worth defining in GLTF, but not in this proposal specifically. In this proposal the goal is to be able to define primitive geometric shapes, and likely also define the purpose of the shapes.

Contributor guide

Open the contributing guide

Research direction

Review the primitive shape and shape_usage examples in this issue alongside related proposal #1135. Define a current, agreed specification for primitive shapes and their intended use, with the API details and scope resolved; the issue notes that its original approach is outdated.

Written by the indexing model from the issue text.

Assessment

Domain
computer-graphics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.