Skip to content

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

@aaronfranke

Description

@aaronfranke

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

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

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:

    {
      "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:

    {
      "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:

    {
      "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:

    {
      "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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions