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

MSFT_CollisionPrimitives and MSFT_RigidBodies #2257

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 75 additions & 0 deletions extensions/2.0/Vendor/MSFT_collision_primitives/README.md
@@ -0,0 +1,75 @@
# MSFT\_collision_primitives

## Status

Draft

## Dependencies

Written against glTF 2.0 spec.

## Overview

This extension adds the ability to specify collision primitives inside a glTF asset. This extension does not mandate any particular behavior for those objects aside from their collision geometry. These types may be used in combination with additional extensions or application-specific business logic. The MSFT\_rigid_bodies extension uses primitives defined in this spec to provide geometric primitives for collision detection in a rigid body simulation.

## glTF Schema Updates

The `MSFT_collision_primitives` extension can be added to any `node` to define one or more of the following properties:

| |Type|Description|
|-|-|-|
|**collider**|`object`|Create a collision shape in the physics engine for this node.|

### Colliders

This extension provides a set of document-level objects, which can be referenced by nodes in the scene. The precise usage of these collider primitives should be specified by the extensions which utilizes the colliders. In general, these colliders are used to specify geometry which can be used for collision detection. Typically, the geometry specified by the collider will be simpler than any meshes used by the node or it's children, enabling real-time applications to perform queries such as intersection tests.

Implementations of this extension should ensure that collider transforms are always kept in sync with node transforms - for example animated node transforms should be applied to the applications' internal representation of the collision geometry.

To describe the shape that represents this node, should use, colliders must define exactly one of the following properties:

| |Type|Description|
|-|-|-|
|**sphere**|`object`|A sphere centered at the origin in local space.|
|**box**|`object`|An axis-aligned box centered at the origin in local space.|
|**capsule**|`object`|A capsule centered at the origin and aligned along the Y axis in local space.|
|**cylinder**|`object`|A cylinder centered at the origin and aligned along the Y axis in local space.|
|**convex**|`object`|A convex hull wrapping a `mesh` object.|
|**trimesh**|`object`|A triangulated representation of a `mesh` object.|

The sphere, box, capsule, cylinder and convex types should all produce _solid_ colliders by default - a rigid body anywhere inside the shape should be pushed out of it.
However the trimesh type always represents an infinitely thin shell or sheet - for example a trimesh collider created from a `mesh` object in the shape of a box will be represented as a hollow box.

If you want your collider to have an offset from the local space (for example a sphere _not_ centered at local origin, or a rotated box), you should add an extra node to the hierarchy and apply your transform and your collider properties to that.

**Collision Filtering**

By default each `collider` can generate collisions with every other `collider`, provided they are sufficiently close. If you want certain objects in your scene to ignore collisions with others, you can provide the following optional collider properties:

| |Type|Description|
|-|-|-|
|**collisionSystems**|`[string]`|An array of arbitrary strings indicating the `system` a node is in.|
|**notCollideWithSystems**|`[string]`|An array of strings representing the systems which this node will _not_ collide with|
|**collideWithSystems**|`[string]`|An array of strings representing the systems which this node can collide with|

Both `collideWithSystems` and `notCollideWithSystems` are provided so that users can override the default collision behavior with minimal configuration -- only one of these should be specified per-collider. Note, given knowledge of all the systems in a scene and one of the values `notCollideWithSystems`/`collideWithSystems` the unspecified field can be calculated: `collideWithSystems = notCollideWithSystems'`

`notCollideWithSystems` is useful for an object which should collide with everything except those listed in `notCollideWithSystems` (i.e., used to opt-out of collisions) while `collideWithSystems` is the inverse -- the collider should _not_ collide with any other collider except those listed in `collideWithSystems`

A node `A` will collide with node `B` if `A.collisionSystem ⊆ B.collideWithSystems && A.collisionSystem ⊄ B.notCollideWithSystems`

Note, that this can generate asymmetric states - `A` might determine that it _does_ collide with `B`, but `B` may determine that it _does not_ collide with `A`. As the default behavior is that collision should be enabled, both `doesCollide(A, B)` and `doesCollide(B, A)` tests should be performed and collision should not occur if either returns false.

### JSON Schema

* **JSON schema**: [glTF.MSFT_collision_primitives.schema.json](schema/glTF.MSFT_collision_primitives.schema.json)

## Known Implementations

[Blender exporter](https://github.com/eoineoineoin/glTF_Physics_Blender_Exporter) (work in progress)

[Godot importer](https://github.com/eoineoineoin/glTF_Physics_Godot_Importer) (work in progress)

## Validator

To do
@@ -0,0 +1,23 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Parameters describing a box collider.",
"allOf" : [ { "$ref" : "glTFProperty.schema.json" } ],
"properties" : {
"size" : {
"type" : "array",
"description" : "The extents of the box in each axis in local space.",
"items" : {
"type": "number",
"minimum": 0.0
},
"minItems" : 3,
"maxItems" : 3,
"default" : [ 1.0, 1.0, 1.0 ]
},
"extensions" : {},
"extras" : {}
},
"required": ["size"]
}
@@ -0,0 +1,24 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Parameters describing a capsule collider.",
"allOf" : [ { "$ref" : "glTFProperty.schema.json" } ],
"properties" : {
"height" : {
"type" : "number",
"description": "The height of the capsule, centered along the Y axis.",
"minimum": 0.0,
"default" : 0.5
},
"radius" : {
"type" : "number",
"description": "The radius of the capsule.",
"minimum": 0.0,
"default" : 0.25
},
"extensions" : {},
"extras" : {}
},
"required": ["height", "radius"]
}
@@ -0,0 +1,16 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Parameters describing a convex collider.",
"allOf" : [ { "$ref" : "glTFProperty.schema.json" } ],
"properties" : {
"mesh" : {
"description": "The ID of the mesh from which to build the convex hull.",
"allOf": [{"$ref": "glTFid.schema.json"}]
},
"extensions" : {},
"extras" : {}
},
"required": ["mesh"]
}
@@ -0,0 +1,24 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Parameters describing a cylinder collider.",
"allOf" : [ { "$ref" : "glTFProperty.schema.json" } ],
"properties" : {
"height" : {
"type" : "number",
"description": "The height of the cylinder, centered along the Y axis.",
"minimum": 0.0,
"default" : 0.5
},
"radius" : {
"type" : "number",
"description": "The radius of the cylinder around the axis.",
"minimum": 0.0,
"default" : 0.25
},
"extensions" : {},
"extras" : {}
},
"required": ["height", "radius"]
}
@@ -0,0 +1,100 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Parameters describing a node's physics collision geometry.",
"allOf" : [ { "$ref" : "glTFChildOfRootProperty.schema.json" } ],
"properties" : {
"collisionSystem": {
"type": "array",
"description": "An array of strings representing the names of the collision system which this collider belongs to.",
"items": {
"type": "string"
}
},
"collideWithSystems": {
"type": "array",
"description": "An array of string representing the name of the collision systems which this node can collide with.",
"items": {
"type": "string"
}
},
"notCollideWithSystems": {
"type": "array",
"description": "An array of strings representing the names of the collision systems which this node does not collide with.",
"items": {
"type": "string"
}
},
"extensions" : {},
"extras" : {}
},
"oneOf": [
{
"type": "object",
"description" : "A set of parameter values that are used to define a sphere collider.",
"properties": {
"sphere": {
"type": "object",
"$ref" : "glTF.MSFT_collision_primitives.collider.sphere.schema.json"
}
},
"required": ["sphere"]
},
{
"type": "object",
"description" : "A set of parameter values that are used to define a box collider.",
"properties": {
"box": {
"type": "object",
"$ref" : "glTF.MSFT_collision_primitives.collider.box.schema.json"
}
},
"required": ["box"]
},
{
"type": "object",
"description" : "A set of parameter values that are used to define a capsule collider.",
"properties": {
"capsule": {
"type": "object",
"$ref" : "glTF.MSFT_collision_primitives.collider.capsule.schema.json"
}
},
"required": ["capsule"]
},
{
"type": "object",
"description" : "A set of parameter values that are used to define a cylinder collider.",
"properties": {
"cylinder": {
"type": "object",
"$ref" : "glTF.MSFT_collision_primitives.collider.cylinder.schema.json"
}
},
"required": ["cylinder"]
},
{
"type": "object",
"description" : "A set of parameter values that are used to define a convex collider.",
"properties": {
"convex": {
"type": "object",
"$ref" : "glTF.MSFT_collision_primitives.collider.convex.schema.json"
}
},
"required": ["convex"]
},
{
"type": "object",
"description" : "A set of parameter values that are used to define a mesh collider.",
"properties": {
"mesh": {
"type": "object",
"$ref" : "glTF.MSFT_collision_primitives.collider.trimesh.schema.json"
}
},
"required": ["trimesh"]
}
]
}
@@ -0,0 +1,18 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Parameters describing a sphere collider.",
"allOf" : [ { "$ref" : "glTFProperty.schema.json" } ],
"properties" : {
"radius" : {
"type" : "number",
"description": "The radius of the sphere.",
"minimum": 0.0,
"default" : 0.5
},
"extensions" : {},
"extras" : {}
},
"required": ["radius"]
}
@@ -0,0 +1,16 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Parameters describing a mesh collider.",
"allOf" : [ { "$ref" : "glTFProperty.schema.json" } ],
"properties" : {
"mesh" : {
"description": "The ID of the mesh from which to build the physics representation.",
"allOf": [{"$ref": "glTFid.schema.json"}]
},
"extensions" : {},
"extras" : {}
},
"required": ["mesh"]
}
@@ -0,0 +1,17 @@
{
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "MSFT_collision_primitives glTF extension",
"type" : "object",
"description" : "Top level collision primitives.",
"allOf" : [ { "$ref" : "glTFProperty.schema.json" } ],
"properties" : {
"colliders" : {
"type": "array",
"description": "An array of collider descriptions.",
"items": {
"$ref" : "glTF.MSFT_collision_primitives.collider.schema.json"
},
"minItems": 1
}
}
}