| … | … | @@ -0,0 +1,189 @@ |
| 1 | <!-- Based on structure of the OMI_audio_emitter --> |
| 2 | |
| 3 | # OMI_collider |
| 4 | |
| 5 | ## Contributors |
| 6 | |
| 7 | * Mauve Signweaver, Mauve Software Inc. |
| 8 | * YOUR NAME HERE |
| 9 | |
| 10 | ## Status |
| 11 | |
| 12 | Open Metaverse Interoperability Group Stage 1 Proposal |
| 13 | |
| 14 | ## Dependencies |
| 15 | |
| 16 | Written against the glTF 2.0 spec. |
| 17 | |
| 18 | ## Overview |
| 19 | |
| 20 | This extension allows for the addition of colliders to gLTF scenes. |
| 21 | |
| 22 | Colliders can be added to GLTF nodes along with information about the "type" of collider it is representing. |
| 23 | |
| 24 | This extension does not perscribe what Colliders should do within a scene. |
| 25 | |
| 26 | ### Example: |
| 27 | |
| 28 | ```json= |
| 29 | { |
| 30 | "nodes": [ |
| 31 | { |
| 32 | "name": "ball", |
| 33 | "extensions": { |
| 34 | "OMI_collider": { |
| 35 | "type": "sphere", |
| 36 | "radius": 0.5 |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | ] |
| 41 | } |
| 42 | ``` |
| 43 | |
| 44 | ## glTF Scheme Updates |
| 45 | |
| 46 | 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. |
| 47 | |
| 48 | 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. |
| 49 | |
| 50 | ### Example: |
| 51 | |
| 52 | |
| 53 | ```json= |
| 54 | { |
| 55 | "extensionsUsed": [ |
| 56 | "OMI_collider" |
| 57 | ], |
| 58 | "nodes": [ |
| 59 | { |
| 60 | "name": "ball", |
| 61 | "extensions": { |
| 62 | "OMI_collider": { |
| 63 | "type": "sphere", |
| 64 | "sphereRadius": 0.5 |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | ] |
| 69 | } |
| 70 | ``` |
| 71 | |
| 72 | |
| 73 | ### Collider Types |
| 74 | |
| 75 | 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. |
| 76 | |
| 77 | 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. |
| 78 | |
| 79 | 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. |
| 80 | |
| 81 | Here is a table of what the shapes can be represented with in different game engines: |
| 82 | |
| 83 | | Shape | Unity | Godot | Unreal | Ammo | |
| 84 | | -------- | ------------ | --------------------- | ------- | ---------- | |
| 85 | | Box | Box | BoxShape | Box | Box | |
| 86 | | Sphere | Sphere | SphereShape | Sphere | Sphere | |
| 87 | | Capsule | Capsule | CapsuleShape | Capsule | Capsule | |
| 88 | | Hull | Mesh(convex) | ConvexPolygonShape | Mesh? | ConvexHull | |
| 89 | | Mesh | Mesh | ConcavePolygonShape | Mesh | Mesh | |
| 90 | | Compound | Compound | Add mutiple colliders | ??? | ??? | |
| 91 | |
| 92 | #### Box |
| 93 | |
| 94 | 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 `[width, height, depth]`. TODO: Relate these values to specific axis? |
| 95 | |
| 96 | #### Sphere |
| 97 | |
| 98 | This represents a "ball" shape which has a `radius` property which must be set to 0.5 if a `radius` field is omitted. |
| 99 | |
| 100 | #### Capsule |
| 101 | |
| 102 | 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? |
| 103 | |
| 104 | #### Hull |
| 105 | |
| 106 | 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. |
| 107 | |
| 108 | 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. |
| 109 | |
| 110 | Due to limitations of some game engines, authors MUST limit the polygon count to 255 vertexes. TODO: Check if there's a lower limit for this somewhere |
| 111 | |
| 112 | #### Mesh |
| 113 | |
| 114 | Avoid using this type unless you're absolutely sure you need this level of detail. |
| 115 | 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. |
| 116 | |
| 117 | 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). |
| 118 | |
| 119 | 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. |
| 120 | |
| 121 | TODO: Same limits as regular meshes in GLTF |
| 122 | |
| 123 | #### Compound |
| 124 | |
| 125 | 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. |
| 126 | |
| 127 | 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. |
| 128 | |
| 129 | ### Using Colliders |
| 130 | |
| 131 | ### JSON Schema |
| 132 | ```json= |
| 133 | { |
| 134 | "$schema": "http://json-schema.org/draft-04/schema", |
| 135 | "title": "Collider", |
| 136 | "type": "object", |
| 137 | "required": ["type"] |
| 138 | "properties": { |
| 139 | "type": { |
| 140 | "type": "string", |
| 141 | "description": "The type of collider this node represents", |
| 142 | "enum": [ |
| 143 | "box", |
| 144 | "sphere", |
| 145 | "capsule", |
| 146 | "hull", |
| 147 | "mesh", |
| 148 | "compound" |
| 149 | ] |
| 150 | }, |
| 151 | "radius": { |
| 152 | "type": "number", |
| 153 | "description": "The radius to use for the collision shape. Applies to box/sphere/capsule", |
| 154 | "default": 0.5 |
| 155 | }, |
| 156 | "extents": { |
| 157 | "type": "array", |
| 158 | "description": "half-extents for a Box (width/height/depth). Overwrites the radius field if set.", |
| 159 | "default": [0.5, 0.5, 0.5] |
| 160 | }, |
| 161 | "height": { |
| 162 | "type": "number", |
| 163 | "description": "The height of the capsule shape.", |
| 164 | "default": 1 |
| 165 | }, |
| 166 | "mesh": { |
| 167 | "description": "A reference to the mesh from the `meshes` array to use for either the Hull or Mesh shapes. The mest 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.", |
| 168 | "allOf": [ |
| 169 | { |
| 170 | "$ref": "glTFid.schema.json" |
| 171 | } |
| 172 | ] |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | ``` |
| 177 | |
| 178 | ## Known Implementations |
| 179 | |
| 180 | TODO |
| 181 | |
| 182 | ## Resources: |
| 183 | |
| 184 | - Godot Collision Shapes (Box, Sphere, Capsule, Convvex, Concave): https://docs.godotengine.org/en/stable/classes/class_sphereshape.html#class-sphereshape |
| 185 | - Unity Colliders (Box, Sphere, Capsule, Mesh / Convex Hull): https://docs.unity3d.com/Manual/CollidersOverview.html |
| 186 | - Unreal Engine Collision Shapes (Sphere, Capsule, Box, or Line): https://docs.unrealengine.com/4.27/en-US/API/Runtime/PhysicsCore/FCollisionShape/ |
| 187 | - Unreal Engine Mesh Collisions: https://docs.unrealengine.com/4.27/en-US/WorkingWithContent/Types/StaticMeshes/HowTo/SettingCollision/ |
| 188 | - Mozilla Hubs ammo-shape (Box, Sphere, Hull, Mesh): https://github.com/MozillaReality/hubs-blender-exporter/blob/bb28096159e1049b6b80da00b1ae1534a6ca0855/default-config.json#L608 |
| 189 | - Babylon AmmoJS MeshBuilder (Box, Capsule, Cylinder, ???): https://doc.babylonjs.com/typedoc#meshbuilder |