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

feat: exposing GLTF internals #229

Open
wants to merge 1 commit 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions proto/decentraland/sdk/components/gltf_container.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ message PBGltfContainer {

optional uint32 visible_meshes_collision_mask = 4; // default: 0
optional uint32 invisible_meshes_collision_mask = 5; // default: CL_POINTER | CL_PHYSICS

optional bool internal_feedback = 6; // whether receive internal GLTF scene data in the GltfLoading state or not, default: true
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,17 @@ import "decentraland/sdk/components/common/loading_state.proto";
// the current state of the GltfContainer of an entity.
message PBGltfContainerLoadingState {
common.LoadingState current_state = 1;
repeated string node_paths = 2; // all node paths in the gltf, which can be used with a GltfNode to inspect and modify the gltf contents
repeated string mesh_names = 3; // all meshes in the gltf. unnamed meshes will be auto-assigned a name of the form `MeshX` or `MeshX/PrimitiveY`
// where X is the mesh index and Y is the primitive index (and there is more than 1 primitive). note this may
// conflict with manually named meshes - to avoid any issues make sure all your meshes are explicitly named.
repeated string material_names = 4; // all materials in the gltf. unnamed materials will be auto-assigned a name of the form `MaterialX` where
// X is the material index. note this may conflict with manually named materials - to avoid any issues make
// sure all your materials are explicitly named.
repeated string skin_names = 5; // all mesh skins in the gltf. unnamed skins will be auto-assigned a name of the form `SkinX` where
// X is the skin index. note this may conflict with manually named skins - to avoid any issues make sure all
// your skins are explicitly named.
repeated string animation_names = 6; // all animations in the gltf. unnamed animations will be auto-assigned a name of the form `AnimationX` where
// X is the animation index. note this may conflict with manually named anims - to avoid any issues make sure all
// your animations are explicitly named.
}
42 changes: 42 additions & 0 deletions proto/decentraland/sdk/components/gltf_node.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
syntax = "proto3";
package decentraland.sdk.components;

import "decentraland/sdk/components/common/id.proto";
option (common.ecs_component_id) = 1200;

// a GltfNode links a scene entity with a node from within a gltf, allowing the scene to inspect it or modify it.
// This component must be added to a direct child of an entity with a PbGltfContainer component, or
// to a direct child of another entity with a GltfNode component, and the referenced gltf node must be a descendent of the gltf node
// in the parent.
// The name must match the path of one of the nodes within the Gltf. These are available on the GltfContainerLoadingState component.
//
// The renderer will attach a PbGltfNodeState to the entity describing the state. Once the state is `GNS_READY`,
// - the `Transform` will be updated to match the position of the node within the gltf (relative to the gltf root, or the parent node),
// - a `MeshRenderer` with a GltfMesh mesh type will be added (if the gltf node has a mesh).
// - a `MeshCollider` with a GltfMesh mesh type will be added (if the gltf node has a collider).
// - a `Material` component including a GltfMaterial reference will be added (if the gltf node has a material).
//
// After creation, if an animation moves the node, the `Transform` will be updated.
//
// From the scene, you can modify various components to alter the gltf node:
// - modifying the `Transform` position/rotation/scale will move the node. The position is interpreted relative to the gltf root (or parent node),
// regardless of any intermediate gltf node hierarchy.
// If an animation is playing, the animation takes priority and the scene entity's position will be updated to match the animation.
// - `Visibility` can be added to hide or show the node and it's children in the gltf hierarchy.
// - `MeshRenderer` can be added/modified/removed to create/modify/remove a mesh on the node.
// - `MeshCollider` can be added/modified/removed to create/modify/remove a collider on the node.
// - `Material` can be added or modified to change the material properties. If the gltf node has a material, the original material will be
// used as a base, and any gltf features (e.g. occlusion maps) from the gtlf spec that the renderer supports but that are not exposed in the
// PbMaterial will be maintained.
//
// The scene can add additional entities as children to the gltf node, but structural modifications of the gltf are not possible:
// - changing the scene hierarchy will not change the gltf node hierarchy. Moving the entity out of the gltf will sever the link and
// change the state to `GNS_FAILED`.
// - deleting the scene entity will not delete the gltf node.
//
// Removing the GltfNode will revert any changes to the original gltf. If the GltfNode component is removed and the mesh/collider/material
// are not removed, this will result in a duplication of these components as the previously-linked entity will retain it's components and
// the gltf node will also be displayed.
message PBGltfNode {
string path = 1; // the path of the target node in the Gltf.
}
20 changes: 20 additions & 0 deletions proto/decentraland/sdk/components/gltf_node_state.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
syntax = "proto3";
package decentraland.sdk.components;

import "decentraland/sdk/components/common/id.proto";
option (common.ecs_component_id) = 1201;

// See the details of the GltfNode component for more information.

// The state of a linked gltf node.
// If the state is GNSV_FAILED, the renderer may describe the failure in the error string.
message PBGltfNodeState {
GltfNodeStateValue state = 1;
optional string error = 2;
}

enum GltfNodeStateValue {
GNSV_PENDING = 0;
GNSV_FAILED = 1;
GNSV_READY = 2;
}
11 changes: 11 additions & 0 deletions proto/decentraland/sdk/components/material.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,16 @@ message PBMaterial {
UnlitMaterial unlit = 1;
PbrMaterial pbr = 2;
}

message GltfMaterial {
string gltf_src = 1;
string name = 2;
}

// A gltf material that may provide additional features not supported by the PbMaterial fields.
// If both gltf and material fields are provided, the gltf will be used only for extended features not
// supported by the PbMaterial.
// If this is provided and the `material` field is not provided, the renderer will update the material
// field with data that reflects the gltf material once it is loaded.
optional GltfMaterial gltf = 3;
}
9 changes: 8 additions & 1 deletion proto/decentraland/sdk/components/mesh_collider.proto
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,20 @@ message PBMeshCollider {
// SphereMesh is a sphere shape that contains the Entity.
message SphereMesh {}

// A collider constructed from a Gltf Mesh.
message GltfMesh {
string gltf_src = 1; // the GLTF file path as listed in the scene's manifest.
string name = 2; // the name of the mesh asset
}

optional uint32 collision_mask = 1; // enabled ColliderLayers (default CL_POINTER | CL_PHYSICS)

oneof mesh {
BoxMesh box = 2;
SphereMesh sphere = 3;
CylinderMesh cylinder = 4;
PlaneMesh plane = 5;
GltfMesh gltf = 6;
}
}

Expand All @@ -59,4 +66,4 @@ enum ColliderLayer {
CL_CUSTOM6 = 8192;
CL_CUSTOM7 = 16384;
CL_CUSTOM8 = 32768;
}
}
11 changes: 8 additions & 3 deletions proto/decentraland/sdk/components/mesh_renderer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import "decentraland/sdk/components/common/id.proto";
option (common.ecs_component_id) = 1018;

// The MeshRenderer component renders a basic geometric shape for an Entity. It can be a cube, a
// plane, a sphere or a cylinder.
// plane, a sphere, a cylinder, or a Gltf mesh.
//
// The cube and plane variants can include a UV texture mapping, so specific areas of a material
// texture are rendered on different faces of the shape. They are serialized as a sequence of 2D
// `float` coordinates, one for each corner of each side of each face.
//
// More complex shapes require the use of a `GltfContainer` component.
message PBMeshRenderer {

// BoxMesh renders a prism shape.
Expand All @@ -34,10 +32,17 @@ message PBMeshRenderer {
message SphereMesh {
}

// A mesh from a Gltf.
message GltfMesh {
string gltf_src = 1; // the GLTF file path as listed in the scene's manifest.
string name = 2; // the name of the mesh asset
}

oneof mesh {
BoxMesh box = 1;
SphereMesh sphere = 2;
CylinderMesh cylinder = 3;
PlaneMesh plane = 4;
GltfMesh gltf = 5;
}
}
2 changes: 2 additions & 0 deletions public/sdk-components.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import public "decentraland/sdk/components/camera_mode.proto";
import public "decentraland/sdk/components/engine_info.proto";
import public "decentraland/sdk/components/gltf_container.proto";
import public "decentraland/sdk/components/gltf_container_loading_state.proto";
import public "decentraland/sdk/components/gltf_node.proto";
import public "decentraland/sdk/components/gltf_node_state.proto";
import public "decentraland/sdk/components/material.proto";
import public "decentraland/sdk/components/mesh_collider.proto";
import public "decentraland/sdk/components/mesh_renderer.proto";
Expand Down
Loading