The GltfContainer
component allows to load GLTF models into the scene. The
GltfContainerLoadingState
component allows to track the loading state of the GLTF
model.
parameters:
COMPONENT_ID: 1041
COMPONENT_NAME: core::GltfContainer
CRDT_TYPE: LastWriteWin-Element-Set
parameters:
COMPONENT_ID: 1049
COMPONENT_NAME: core::GltfContainerLoadingState
CRDT_TYPE: LastWriteWin-Element-Set
message PBGltfContainer {
// the GLTF file path as listed in the deployed entity
string src = 1;
// disable automatic physics collider creation (default: false)
optional bool disable_physics_colliders = 2;
// copies the visible meshes into a virtual MeshCollider with CL_POINTER collider_mask (default: false)
optional bool create_pointer_colliders = 3;
}
// GltfContainerLoadingState is set by the engine and provides information about
// the current state of the GltfContainer of an entity.
message PBGltfContainerLoadingState {
enum LoadingState {
UNKNOWN = 0;
LOADING = 1;
NOT_FOUND = 2;
FINISHED_WITH_ERROR = 3;
FINISHED = 4;
}
LoadingState current_state = 1;
}
The only supported version of glTF is 2.0. The engine MUST NOT support any other version for this component.
The loading of the glTF will be done by the engine. The src
property will be used
to load the glTF from the deployed entity filesystem (ADR-80).
In the scope of a scene, it is RECOMMENDED that the engine caches the loaded glTF files, so that if the same glTF is used in multiple entities, it is only loaded once. Instancing should be used.
Even though marked as optional by the specification, any protocol that is not
data:
MUST not be supported, i.e. file://
or https://
.
The only resolvable assets for the glTF are the ones deployed along with the .gltf/.glb file.
Those will be resolved using the same mechanism as the src
property of the
component.
Since data:
URLs are a bottleneck for parsing resources, it is RECOMMENDED that
tooling and engines in "developer mode" warn the scene creators about its
performance implications.
As per general performance recommendations, every engine and loader SHOULD implement the following extensions:
KHR_materials_basisu
for texture compression
Due to the fact that the deployments contain hashed assets, it is natural to thing that glTF models inside the engine internally, could be shared across scenes. That is not always true. Here is an example of a scene that uses a glTF model that is not shared with other scenes:
Scene(Hash="A")
└── "box.gltf"(Hash=0x11111111)
└── "assets/texture.png"(Hash=0x123123123)
Scene(Hash="B")
└── "box.gltf"(Hash=0x11111111)
└── "assets/texture.png"(Hash=0xFFFFFFFF)
We can clearly see that regardless of the deployed texture, the glTF model remains exactly the same file. This is a common usecase and if caching is applied, the process MUST be aware of all the dependencies of the glTF itself to prevent a vector of attack (poisoning other scene's models with a different texture).
All animations in a glTF instance MUST be stopped as the default state.
Each entity will have its own animation state. The engine MUST provide a way to control the animations of each entity via the Animator component this will be detailed in the (ADR-216).
This version of the component does not specify any way to modify the materials of the models. This is a future work.
_collider
meshes
All meshes of a node with a name ending in _collider
will generate internally
MeshCollider
. Those meshes MUST be invisible and the rest of the properties of
the mesh like its position in an animation should be honored. That enables colliders to be
animated along with visible meshes. It is RECOMMENDED that all the engines implement a way to
visualize the colliders for debugging purposes, making these meshes visible with a distinctive
material.
This convention is permanent and is not affected by any flag or configuration.
Physics colliders (ColliderMask.CL_PHYSICS
) are automatically generated based on
the _collider
meshes if the property
disable_physics_colliders == false
.
It is possible that the value of disable_physics_colliders
is changed at runtime,
so the engine SHOULD be able to enable/disable the colliders at runtime.
Skinned meshes are not supported for colliders of any kind.
All visible meshes (not ending in _collider
) MAY create an internal
MeshCollider
if the property create_pointer_colliders == true
. This
is useful for meshes that are not meant to be colliders but that should still be able to
receive pointer events. Those colliders will have the
ColliderMask.CL_POINTER
mask.
The MeshCollider
will be created with the same properties as the visible mesh, so
it will be animated along with the visible mesh.
It is possible that the value of create_pointer_colliders
is changed at runtime,
so the engine SHOULD be able to enable/disable the colliders at runtime.
Skinned meshes are not supported for colliders of any kind.
Besides the automatic colliders generated by the engine, it is possible to provide custom colliders with custom masks. This is done by adding a custom property to the glTF file. This is the RECOMMENDED via to provide custom colliders that puts the responsibility of the collider creation in the content creator.
The glTF
extra property
named dcl_collider_mask: uint32
is reserved to the engine and it will be used to
generate the collider with the provided mask.
The dcl_collider_mask
property MUST be a valid uint32
value. If the
value is not valid, the engine MUST ignore it.
To disable all the assumptions made by the engine, the RECOMMENDED values are
create_pointer_colliders := false
and
disable_physics_colliders := true
.
The meshes of node names ending in _collider
MUST always be invisible.
This enables both invisible colliders and visible colliders to operate at once.
The dcl_collider_mask will be used as MeshCollider.collider_mask
for each mesh if
provided, behaviors of disable_physics
and enable_pointers
will be
additive to the collider_mask when they enable the significant bits.
On the contrary, if disable_physics == true
the
ColliderMask.CL_PHYSICS
collider bit MUST be disabled for every mesh of
the model, overriding it even if defined by the dcl_collider_mask
extra property.
For cases depending on the complete loading of an asset like calculating raycasts or
colliders, the engine MUST provide a way to report the loading state of the glTF. This is done
via the GltfContainerLoadingState
component. The component provides information
about the current state of loading using the following properties:
message PBGltfContainerLoadingState {
enum LoadingState {
UNKNOWN = 0;
LOADING = 1;
NOT_FOUND = 2;
FINISHED_WITH_ERROR = 3;
FINISHED = 4;
}
LoadingState current_state = 1;
}
Where UNKNOWN
is the default state, LOADING
is the state when the
glTF is being loaded, NOT_FOUND
is the state when the glTF is not found,
FINISHED_WITH_ERROR
is the state when the glTF finished loading but with errors
and FINISHED
is the state when the glTF finished loading without errors.
This component also represents the instancing state of the glTF. If the glTF is instanced, the
current_state
will be FINISHED
. Otherwise, the
current_state
will be LOADING
until the glTF is instanced correctly.
The FINISHED_WITH_ERROR
can be caused by the following errors:
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.