-
Notifications
You must be signed in to change notification settings - Fork 10
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
Add OMI_collider #63
Add OMI_collider #63
Changes from all commits
0b66ac0
c005c99
77ce4ab
fd83df8
d39d474
140166b
8c5d0e9
abee9f3
b14522f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,259 @@ | ||
<!-- Based on structure of the OMI_audio_emitter --> | ||
|
||
# OMI_collider | ||
|
||
## Contributors | ||
|
||
* Mauve Signweaver, Mauve Software Inc. | ||
* YOUR NAME HERE | ||
|
||
## Status | ||
|
||
Open Metaverse Interoperability Group Stage 1 Proposal | ||
|
||
## Dependencies | ||
|
||
Written against the glTF 2.0 spec. | ||
|
||
## Overview | ||
|
||
This extension allows for the addition of colliders to gLTF scenes. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo, |
||
|
||
Colliders can be added to GLTF nodes along with information about the "type" of collider it is representing. | ||
|
||
This extension does not perscribe what Colliders should do within a scene, but engines may choose to treat colliders as Static physics bodies by default. | ||
For a more thorough physics body specification, implement the `OMI_physics_body` extension. | ||
|
||
### Example: | ||
|
||
```json= | ||
{ | ||
"nodes": [ | ||
{ | ||
"name": "ball", | ||
"extensions": { | ||
"OMI_collider": { | ||
"type": "sphere", | ||
"radius": 0.5 | ||
} | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
## glTF Scheme Updates | ||
|
||
This extension consists of a new `Collider` data structure which can be added to a glTF `Node` in an an object called `OMI_collider` added to the `extensions` object within the `Node` object. | ||
|
||
The extension must also be added to the glTF's `extensionsUsed` array and because it is optional, it does not need to be added to the `extensionsRequired` array. | ||
|
||
### Example: | ||
|
||
|
||
```json= | ||
{ | ||
"extensionsUsed": [ | ||
"OMI_collider" | ||
], | ||
"nodes": [ | ||
{ | ||
"name": "ball", | ||
"extensions": { | ||
"OMI_collider": { | ||
"type": "sphere", | ||
"radius": 0.5 | ||
} | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
### `isTrigger` | ||
|
||
Specifying `isTrigger: true` in the collider hints to engines that this collider should not be used for physics interactions and should exist as a "trigger volume" which emits events when an entity intersects with it. | ||
By default an engine may assume that the collider is a static (or rigid) physics body. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
EDIT: Hmm, good points below, see my latest comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think some engines combine whether a collider is a trigger or not with the physics body (I think it was unreal) so I'm not sure I agree with that. 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm in my opinion I think "isTrigger" actually should be here in OMI_collider and not in OMI_physics, a collider may be a trigger without the need of having a rigidbody (physics), but a rigidbody -without- a collider, wont work with "isTrigger" flag. Also, Im taking as reference from how its applied in Unity3D (https://docs.unity3d.com/ScriptReference/Collider.html) where isTrigger is applied from Collider component, and also im taking as reference how is applied in Rapier3D (https://rapier.rs/docs/user_guides/javascript/colliders) where sensor is set from Collider definition There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @memelotsqui Good points! In Godot, a trigger needs an Area node as a parent of the colliders. How does it work in Unity if you want multiple collider shapes to trigger the same thing? If we have this API on both the colliders and physics bodies, we can still import this in Godot, but we should specify how these are imported. Perhaps if a trigger collider has a parent physics object of type trigger, then they use that parent physics object Area node (and possibly multiple shapes could use it, not sure how this would work in Unity). Otherwise if trigger colliders are on their own without a trigger physics object parent, we generate 2 nodes in Godot, an Area and a collider shape child, or 1 GameObject with a component in Unity, and then this trigger is on its own. If we move this API to only be on the colliders and not on the physics bodies, then this basically means that we would always have to generate 2 nodes in Godot, and always 1 GameObject with a component in Unity, and it wouldn't be possible to make a trigger have multiple shapes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My understanding for Godot is that you can add an Area node as a child of a physics body, and then put all of the "isTrigger" collision shapes as children of the area node, while adding the non-isTrigger shapes as direct children of the physics body itself. I have seen multiple posts online that use this trick inside of Godot to detect collision events separate from the body itself, such as: https://godotengine.org/qa/92172/collision-detection-independent-of-a-kinematicbody It would be good to make a demo project so we can show that this works, but I'm pretty sure it is possible. |
||
|
||
### Collider Types | ||
|
||
We've looked at the different types of collision shapes between major game engines (Unity/Unreal/Godot) and looked at what properties are common between them. | ||
|
||
Colliders inherit whatever transform is given to them by the `node` they are attached to. This includes rotation and translation, however it is discouraged to scale these nodes as that can cause problems in some physics engines. | ||
|
||
TODO: There's limits on the sorts of transforms, Unreal can't rotate colliders, has to be axis aligned (local axis to the game component) Maybe only more restrictive only when on a rigid body direcly. | ||
|
||
Here is a table of what the shapes can be represented with in different game engines: | ||
|
||
| Shape | Unity | Godot | Unreal | Ammo | | ||
| -------- | ------------ | --------------------- | ------- | ---------- | | ||
| Box | Box | BoxShape | Box | Box | | ||
| Sphere | Sphere | SphereShape | Sphere | Sphere | | ||
| Capsule | Capsule | CapsuleShape | Capsule | Capsule | | ||
| Hull | Mesh(convex) | ConvexPolygonShape | Mesh? | ConvexHull | | ||
| Mesh | Mesh | ConcavePolygonShape | Mesh | Mesh | | ||
| Compound | Compound | Add mutiple colliders | ??? | ??? | | ||
Comment on lines
+88
to
+95
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I highly recommend adding cylinders to this list. Cylinders are very useful, I would use them extensively. It's the perfect shape to use for barrels and circular platforms (which I'd like to store in GLTF files). For engines that do not support cylinders, they can be approximated with capsules, and we can provide guidelines of what to do if this is needed. Maybe even allow providing extra data to hint at what the best way to approximate the shape is (like shrink/grow/average)? We could also discourage the use of cylinders in general, but I think it's very much worth having it in the standard since there are many use cases. |
||
|
||
|
||
#### Box | ||
|
||
This represents a "box" shape which can either be a cube or an arbitrary rectangular prism. You can specify an `extents` property which is an array that contains the `[x, y, z]` sizes. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should consider making this Also, like Sphere with a default radius of 0.5, we should specify that a box has a default size of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I came up with these names from looking at existing properties in different engines. Are any engines using a generic |
||
|
||
#### Sphere | ||
|
||
This represents a "ball" shape which has a `radius` property which must be set to 0.5 if a `radius` field is omitted. | ||
|
||
#### Capsule | ||
|
||
This represents a "pill" shape which has a `radius` and `height` property. By default the `capsule`'s height is aligned with the vertical axis. If you wish to align it along a different axis, apply the appropriate transform to the `node`. The `radius` field must be set to `0.5` if omitted, and the `height` must be set to `1` if omitted. The final height of the capsule is `height + radius * 2`. TODO: Improve wording? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From our meeting: Is there any way to represent a cylinder with a capsule? Is that currently the right way to represent a cylinder in a physics engine that doesn't support cylinders? |
||
|
||
#### Hull | ||
|
||
This type represents "convex hull" meshes which can be used to represent complex shapes in 3D. Note that it being "convex" means that it cannot have "holes" or divets that lead inside. This use can can be optimized by most if not all physics engines to improve speeds compared to doing collision detection on all faces within the mesh. | ||
|
||
The `mesh` property of the extension must be used to link to an element in the `meshes` array. Note that the mesh MUST be a `trimesh` to work. | ||
|
||
Due to limitations of some game engines (e.g. Unity), authors SHOULD limit the polygon count to 255 vertexes. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hull meshes can be used to be used compound, multiples of 255 vertices compunded. |
||
#### Mesh | ||
|
||
Avoid using this type unless you're absolutely sure you need this level of detail. | ||
Most objects can be represented with a convex hull (or a combination of convex hulls) or a set of primitives and will perform drastically better. It is recommended to use one or more convex hull mesh or primitive collider. | ||
|
||
This type represents an arbitrary 3D mesh for collision detection which can be useful for shapes that cannot be represented by a convex hull. (e.g. something you can go inside of). | ||
|
||
The `mesh` property of the extension must be used to link to an element in the `meshes` array. Note that the mesh MUST be a `trimesh` to work. | ||
|
||
TODO: Same limits as regular meshes in GLTF | ||
|
||
#### Compound | ||
|
||
Compound colliders can be used to group several colliders together in order to give an entity a complex shape using several primitives without resorting to an entire mesh. | ||
|
||
A `Node` set to be a `compund` collider will use any direct child nodes with the `OMI_collider` extension as part of it's collision shape. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
### Using Colliders | ||
|
||
### JSON Schema | ||
```json= | ||
{ | ||
"$schema": "http://json-schema.org/draft-04/schema", | ||
"title": "Collider", | ||
"type": "object", | ||
"required": [ | ||
"type" | ||
], | ||
"properties": { | ||
"type": { | ||
"type": "string", | ||
"description": "The type of collider this node represents", | ||
"enum": [ | ||
"box", | ||
"sphere", | ||
"capsule", | ||
"hull", | ||
"mesh", | ||
"compound" | ||
] | ||
}, | ||
"isTrigger": { | ||
"type": "boolean", | ||
"description": "When true this collider will not collide with physics bodies in the scene", | ||
"default": false | ||
} | ||
}, | ||
"oneOf": [ | ||
{ | ||
"properties": { | ||
"required": [ | ||
"type", | ||
"extents" | ||
], | ||
"type": { | ||
"const": "box" | ||
}, | ||
"extents": { | ||
"type": "array", | ||
"description": "half-extents for a Box (x, y, z)." | ||
} | ||
} | ||
}, | ||
{ | ||
"properties": { | ||
"required": [ | ||
"type", | ||
"radius", | ||
"height" | ||
], | ||
"type": { | ||
"const": "sphere" | ||
}, | ||
"radius": { | ||
"type": "number", | ||
"description": "The radius to use for the collision shape. Applies to sphere/capsule" | ||
}, | ||
"height": { | ||
"type": "number", | ||
"description": "The height of the capsule shape." | ||
} | ||
} | ||
}, | ||
{ | ||
"properties": { | ||
"required": [ | ||
"type", | ||
"mesh" | ||
], | ||
"type": { | ||
"const": "capsule" | ||
} | ||
} | ||
}, | ||
{ | ||
"properties": { | ||
"required": [ | ||
"type", | ||
"mesh" | ||
], | ||
"type": { | ||
"enum": [ | ||
"mesh", | ||
"hull" | ||
] | ||
}, | ||
"mesh": { | ||
"description": "A reference to the mesh from the `meshes` array to use for either the Hull or Mesh shapes. The mesh MUST be a trimesh. Make sure your mesh is actually a convex hull if you use Hull, and try to avoid a full Mesh since they are very slow.", | ||
"allOf": [ | ||
{ | ||
"$ref": "glTFid.schema.json" | ||
} | ||
] | ||
} | ||
} | ||
}, | ||
{ | ||
"properties": { | ||
"required": [ | ||
"type" | ||
], | ||
"type": { | ||
"const": "compound" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
## Known Implementations | ||
|
||
TODO | ||
|
||
## Resources: | ||
|
||
- Godot Collision Shapes (Box, Sphere, Capsule, Convvex, Concave): https://docs.godotengine.org/en/stable/classes/class_sphereshape.html#class-sphereshape | ||
- Unity Colliders (Box, Sphere, Capsule, Mesh / Convex Hull): https://docs.unity3d.com/Manual/CollidersOverview.html | ||
- Unreal Engine Collision Shapes (Sphere, Capsule, Box, or Line): https://docs.unrealengine.com/4.27/en-US/API/Runtime/PhysicsCore/FCollisionShape/ | ||
- Unreal Engine Mesh Collisions: https://docs.unrealengine.com/4.27/en-US/WorkingWithContent/Types/StaticMeshes/HowTo/SettingCollision/ | ||
- Mozilla Hubs ammo-shape (Box, Sphere, Hull, Mesh): https://github.com/MozillaReality/hubs-blender-exporter/blob/bb28096159e1049b6b80da00b1ae1534a6ca0855/default-config.json#L608 | ||
- Babylon AmmoJS MeshBuilder (Box, Capsule, Cylinder, ???): https://doc.babylonjs.com/typedoc#meshbuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add all contributors to the spec.