diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 14f48b9c..a76809df 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -3,13 +3,14 @@ on: branches: - main - experimental + - experimental-bevy pull_request: release: types: - created env: - BRANCH_TAG: ${{ github.ref_name == 'experimental' && 'experimental' || '' }} + BRANCH_TAG: ${{ github.ref_name == 'experimental' && 'experimental' || github.ref_name == 'experimental-bevy' && 'experimental-bevy' || '' }} name: build-deploy jobs: diff --git a/proto/decentraland/common/texture.proto b/proto/decentraland/common/texture.proto index 98df84e6..a667355f 100644 --- a/proto/decentraland/common/texture.proto +++ b/proto/decentraland/common/texture.proto @@ -36,10 +36,17 @@ message VideoTexture { optional TextureFilterMode filter_mode = 3; // default = FilterMode.Bilinear } +message UiCanvasTexture { + uint32 ui_canvas_entity = 1; + optional TextureWrapMode wrap_mode = 2; // default = TextureWrapMode.Clamp + optional TextureFilterMode filter_mode = 3; // default = FilterMode.Bilinear +} + message TextureUnion { oneof tex { Texture texture = 1; // default = null AvatarTexture avatar_texture = 2; // default = null VideoTexture video_texture = 3; // default = null + UiCanvasTexture ui_texture = 4; } -} \ No newline at end of file +} diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 2a8c839f..0b928e0d 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -56,8 +56,31 @@ message MovePlayerToResponse { bool success = 1; } +message WalkPlayerToRequest { + decentraland.common.Vector3 new_relative_position = 1; + float stop_threshold = 2; + optional float timeout = 3; // max seconds before the request is failed; not passed to the movement scene +} + +message WalkPlayerToResponse { + bool success = 1; +} + message TeleportToResponse { } +message SetUiFocusRequest { + string element_id = 1; +} + +message ClearUiFocusRequest { } + +message GetUiFocusRequest { } + +message UiFocusResponse { + // the element that is/was focussed + optional string element_id = 1; +} + message CopyToClipboardRequest { string text = 1; } @@ -97,6 +120,12 @@ service RestrictedActionsService { rpc MovePlayerTo(MovePlayerToRequest) returns (MovePlayerToResponse) {} // TeleportTo will move the user to the specified world LAND parcel coordinates + // WalkPlayerTo will walk the player to a position relative to the current scene, + // managed by the movement controller scene. Returns success when the player reaches + // within stop_threshold distance, or false if the path is blocked, the player gets + // stuck, the player interrupts the walk with manual input, or the optional timeout expires. + rpc WalkPlayerTo(WalkPlayerToRequest) returns (WalkPlayerToResponse) {} + rpc TeleportTo(TeleportToRequest) returns (TeleportToResponse) {} // TriggerEmote will trigger an emote in this current user @@ -119,6 +148,15 @@ service RestrictedActionsService { rpc TriggerSceneEmote(TriggerSceneEmoteRequest) returns (SuccessResponse) {} // CopyToClipboard copies the provided text into the clipboard + // Sets the focus to a specific UI element + rpc SetUiFocus(SetUiFocusRequest) returns (UiFocusResponse) {} + + // Clears the focus from any currently focused textentry or dropdown + rpc ClearUiFocus(ClearUiFocusRequest) returns (UiFocusResponse) {} + + // Returns the element_id of any currently focused textentry or dropdown + rpc GetUiFocus(GetUiFocusRequest) returns (UiFocusResponse) {} + rpc CopyToClipboard(CopyToClipboardRequest) returns (EmptyResponse) {} // StopEmote will stop the current emote diff --git a/proto/decentraland/sdk/components/avatar_equipped_data.proto b/proto/decentraland/sdk/components/avatar_equipped_data.proto index 1890fbd5..84cc3631 100644 --- a/proto/decentraland/sdk/components/avatar_equipped_data.proto +++ b/proto/decentraland/sdk/components/avatar_equipped_data.proto @@ -10,4 +10,5 @@ option (common.ecs_component_id) = 1091; message PBAvatarEquippedData { repeated string wearable_urns = 1; repeated string emote_urns = 2; -} \ No newline at end of file + repeated string force_render = 3; // slots that will render even if hidden +} diff --git a/proto/decentraland/sdk/components/avatar_modifier_area.proto b/proto/decentraland/sdk/components/avatar_modifier_area.proto index c8936d94..8c527149 100644 --- a/proto/decentraland/sdk/components/avatar_modifier_area.proto +++ b/proto/decentraland/sdk/components/avatar_modifier_area.proto @@ -23,6 +23,7 @@ message PBAvatarModifierArea { decentraland.common.Vector3 area = 1; // the 3D size of the region repeated string exclude_ids = 2; // user IDs that can enter and remain unaffected repeated AvatarModifierType modifiers = 3; // list of modifiers to apply + optional bool use_collider_range = 5; // if true, the player will be considered inside the area when they are within 0.3m of the area. default true } // AvatarModifierType is an effect that should be applied to avatars inside the region. diff --git a/proto/decentraland/sdk/components/avatar_movement.proto b/proto/decentraland/sdk/components/avatar_movement.proto new file mode 100644 index 00000000..df77299e --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_movement.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/vectors.proto"; + +option (common.ecs_component_id) = 1501; + +message PBAvatarMovement { + decentraland.common.Vector3 velocity = 1; + float orientation = 2; // 0-360, yaw only; this is the authoritative facing (other clients read it, and physics treats the avatar as upright). Lean is expressed separately via tilt_pitch/tilt_roll. + optional decentraland.common.Vector3 ground_direction = 3; + optional bool walk_success = 4; // set for one frame when a walk_target ends: true = reached target, false = failed; absent = in progress or no walk + optional MovementAnimation animation = 5; // if set, the engine plays this animation instead of selecting one from velocity heuristics + optional float tilt_pitch = 6; // render-only forward/back lean in degrees, applied on top of `orientation` (rotation about the avatar's local X axis). Does not affect the physics capsule (stays upright) or the facing other clients read. Defaults to 0. + optional float tilt_roll = 7; // render-only sideways lean in degrees, applied on top of `orientation` (rotation about the avatar's local Z axis). Same constraints as tilt_pitch. Useful e.g. for glider banking. Defaults to 0. +} + +// Describes the animation the movement scene wants the avatar to play. +// One GLB = one clip (following the scene-emote convention: single clip, or a clip named with `_Avatar` suffix). +// When absent the engine falls back to its built-in velocity-based selection (walk/run/jump/idle). +message MovementAnimation { + string src = 1; // scene-relative path to the gltf/glb asset (resolved via the scene content map) + bool loop = 2; // whether the clip repeats once it reaches the end + float speed = 3; // playback speed multiplier (1.0 = clip's native rate) + bool idle = 4; // true: a triggerSceneEmote may take over; false: emotes are suppressed while this animation plays + optional float transition_seconds = 5; // cross-fade duration when `src` changes; defaults to 0.2 when unset. Not applied to loop/speed/idle changes. + optional float playback_time = 6; // if set, the engine seeks to this position (in seconds) this frame. Clear on subsequent frames to allow normal playback. The scene can read `AvatarAnimationState.playback_time` first to decide. + repeated string sounds = 7; // scene-relative paths to audio clips (.mp3/.ogg) to play this frame on the avatar audio bus. Fire-and-forget: each listed clip plays once per frame it appears; leaving a clip set for multiple frames re-triggers it. No stop mechanism. Use `AvatarAnimationState.playback_time` to trigger sounds at the right point in the clip (e.g. foot plants). +} + +// engine behaviour (uses only capsule shapecasts and GJK closest point for portability): +// 1: set avatar orientation from movement info -> P1 +// 2: record "ground collider" - nearest collider within threshold distance in ground_direction using avatar collider shapecast +// 3: update all colliders, record previous transform and new transform. +// 4: apply ground collider movement: take collider closest point, modify P1 translation and rotation by closest point translation and rotation change -> P2 +// 5: resolve collisions using position-based constraints +// initialize constraints to -inf, +inf +// repeat +// for each collider[i] that collides with the P3+N player: +// if closest point = capsule middle (i.e. collider collides with P3 collider but with radius 0), +// ignore / continue +// else +// update constraints based on minimum movement to escape collision +// e.g. if avatar is 1cm into the floor, constraint_min = max(constraint_min, vec3(0, 0.01, 0)) +// reposition player to satisfy constraints for each axis: +// y: satsify floor before ceiling: new position = max(constraint_min, min(constraint_max, current position)) +// x and z: if squashed, take average, else satisfy the required constraint +// if constraint_min > constraint_max then new position = average(constraint_min, constraint_max) +// else new position = clamp(current position, constraint_min, constraint_max) +// while position !~= previous position +// 6: apply velocity (collide and slide) +// disable anything we are initially colliding with +// shapecast avatar from position to position + velocity * timestep +// on impact: +// project velocity onto slide plane (standard "Collide & Slide") +// velocity = old velocity - (normal * dot(velocity, normal)) +// repeat continue with residual velocity and residual time +// 7: provide AvatarMovementInfo values +// actual velocity = (final - P3+N) / timestep +// external_velocity = (P3+N - P1) / timestep \ No newline at end of file diff --git a/proto/decentraland/sdk/components/avatar_movement_info.proto b/proto/decentraland/sdk/components/avatar_movement_info.proto new file mode 100644 index 00000000..aa1f5716 --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_movement_info.proto @@ -0,0 +1,36 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/vectors.proto"; +import "decentraland/sdk/components/avatar_locomotion_settings.proto"; +import "decentraland/sdk/components/input_modifier.proto"; + +option (common.ecs_component_id) = 1500; + +message PBAvatarMovementInfo { + float step_time = 1; // the length of time the current step velocity will apply for + float previous_step_time = 2; // the length of time the previous step velocity applied for + decentraland.common.Vector3 requested_velocity = 3; // the velocity requested for the previous frame + decentraland.common.Vector3 actual_velocity = 4; // the resulting velocity taking collisions into account + decentraland.common.Vector3 external_velocity = 5; // the velocity imparted by movement of the "ground" platform or pushing from other moving colliders + decentraland.sdk.components.PBAvatarLocomotionSettings active_avatar_locomotion_settings = 6; + decentraland.sdk.components.PBInputModifier active_input_modifier = 7; + optional decentraland.common.Vector3 walk_target = 8; // if set, the movement scene should walk the player to this scene-relative position + optional float walk_threshold = 9; // stop distance for walk_target; considered reached when within this distance + optional AvatarAnimationState active_animation_state = 10; // current state of a scene-driven movement animation. Absent when the engine is using its velocity-based fallback. `playback_time` freezes while a triggerSceneEmote is overriding the animation. +} + +// Mirror of the scene-driven movement animation currently playing, reported by the engine. +// Readable by any scene (not just the controller) so niche effects (e.g. dust cloud on landing) can react. +// Active emotes are not represented here — scenes already have their own way to read them. +message AvatarAnimationState { + string src = 1; // same scene-relative path the controlling scene supplied + bool loop = 2; // mirrors the request + float speed = 3; // mirrors the request + bool idle = 4; // mirrors the request + float playback_time = 5; // seconds into the clip; wraps on loop; frozen while an emote override is playing + float duration = 6; // total clip length in seconds + uint32 loop_count = 7; // how many times the clip has completed since it started +} diff --git a/proto/decentraland/sdk/components/avatar_shape.proto b/proto/decentraland/sdk/components/avatar_shape.proto index 29f363f8..c9d3bd0d 100644 --- a/proto/decentraland/sdk/components/avatar_shape.proto +++ b/proto/decentraland/sdk/components/avatar_shape.proto @@ -40,5 +40,6 @@ message PBAvatarShape { repeated string emotes = 11; // available emotes (default empty) optional bool show_only_wearables = 12; // hides the skin + hair + facial features (default: false) + repeated string force_render = 13; // slots that will render even if hidden } diff --git a/proto/decentraland/sdk/components/camera_layer.proto b/proto/decentraland/sdk/components/camera_layer.proto new file mode 100644 index 00000000..f62ad849 --- /dev/null +++ b/proto/decentraland/sdk/components/camera_layer.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/colors.proto"; + +option (common.ecs_component_id) = 1503; + +message PBCameraLayer { + // layer to which these settings apply. must be > 0 + // Layer 0 is the default "real world" layer viewed by the player and cannot be modified. + uint32 layer = 1; + + // should the sun light affect this layer? default false + optional bool directional_light = 2; + + // should this layer show player avatars? default false + optional bool show_avatars = 3; + + // should this layer show the sky? default false + optional bool show_skybox = 4; + + // should this layer show distance fog? default false + optional bool show_fog = 5; + + // ambient light overrides for this layer. default -> use same as main camera + optional decentraland.common.Color3 ambient_color_override = 6; + optional float ambient_brightness_override = 7; +} diff --git a/proto/decentraland/sdk/components/camera_layers.proto b/proto/decentraland/sdk/components/camera_layers.proto new file mode 100644 index 00000000..9fcac006 --- /dev/null +++ b/proto/decentraland/sdk/components/camera_layers.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; + +option (common.ecs_component_id) = 1208; + +message PBCameraLayers { + repeated uint32 layers = 1; +} \ No newline at end of file diff --git a/proto/decentraland/sdk/components/camera_mode_area.proto b/proto/decentraland/sdk/components/camera_mode_area.proto index 6d754d43..8da228a1 100644 --- a/proto/decentraland/sdk/components/camera_mode_area.proto +++ b/proto/decentraland/sdk/components/camera_mode_area.proto @@ -22,4 +22,5 @@ option (common.ecs_component_id) = 1071; message PBCameraModeArea { decentraland.common.Vector3 area = 1; // the 3D size of the region common.CameraType mode = 2; // the camera mode to enforce + optional bool use_collider_range = 4; // if true, the player will be considered inside the area when they are within 0.3m of the area. default true } diff --git a/proto/decentraland/sdk/components/common/input_action.proto b/proto/decentraland/sdk/components/common/input_action.proto index 52ee8667..7ad11de0 100644 --- a/proto/decentraland/sdk/components/common/input_action.proto +++ b/proto/decentraland/sdk/components/common/input_action.proto @@ -29,6 +29,9 @@ enum PointerEventType { PET_HOVER_LEAVE = 3; PET_PROXIMITY_ENTER = 4; PET_PROXIMITY_LEAVE = 5; + PET_DRAG_LOCKED = 6; + PET_DRAG = 7; + PET_DRAG_END = 8; } enum InteractionType { diff --git a/proto/decentraland/sdk/components/global_light.proto b/proto/decentraland/sdk/components/global_light.proto new file mode 100644 index 00000000..2fb05ca7 --- /dev/null +++ b/proto/decentraland/sdk/components/global_light.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package decentraland.sdk.components; + +import "decentraland/common/colors.proto"; +import "decentraland/common/vectors.proto"; + +import "decentraland/sdk/components/common/id.proto"; +option (common.ecs_component_id) = 1206; + +// defines the global scene light settings. must be added to the scene root. +// to control sunlight color, intensity, shadows etc, you can also add a PBLight to the scene root. +message PBGlobalLight { + // the direction the directional light shines in. + // default depends on time of day and explorer implementation + optional decentraland.common.Vector3 direction = 1; + // ambient light color + // default: White + optional decentraland.common.Color3 ambient_color = 2; + // ambient light intensity. the explorer default ambient brightness is multiplied by this non-physical quantity. + // default 1 + optional float ambient_brightness = 3; +} diff --git a/proto/decentraland/sdk/components/gltf_container_loading_state.proto b/proto/decentraland/sdk/components/gltf_container_loading_state.proto index 2bd38240..daa39933 100644 --- a/proto/decentraland/sdk/components/gltf_container_loading_state.proto +++ b/proto/decentraland/sdk/components/gltf_container_loading_state.proto @@ -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. } diff --git a/proto/decentraland/sdk/components/gltf_node.proto b/proto/decentraland/sdk/components/gltf_node.proto new file mode 100644 index 00000000..8e908cbb --- /dev/null +++ b/proto/decentraland/sdk/components/gltf_node.proto @@ -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. +} diff --git a/proto/decentraland/sdk/components/gltf_node_state.proto b/proto/decentraland/sdk/components/gltf_node_state.proto new file mode 100644 index 00000000..1ce9512e --- /dev/null +++ b/proto/decentraland/sdk/components/gltf_node_state.proto @@ -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; +} diff --git a/proto/decentraland/sdk/components/material.proto b/proto/decentraland/sdk/components/material.proto index bb3545f8..694b1b50 100644 --- a/proto/decentraland/sdk/components/material.proto +++ b/proto/decentraland/sdk/components/material.proto @@ -54,4 +54,16 @@ message PBMaterial { UnlitMaterial unlit = 1; PbrMaterial pbr = 2; } -} \ No newline at end of file + + 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; +} diff --git a/proto/decentraland/sdk/components/mesh_collider.proto b/proto/decentraland/sdk/components/mesh_collider.proto index ac28cdb0..056937cf 100644 --- a/proto/decentraland/sdk/components/mesh_collider.proto +++ b/proto/decentraland/sdk/components/mesh_collider.proto @@ -30,6 +30,12 @@ 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 { @@ -37,6 +43,7 @@ message PBMeshCollider { SphereMesh sphere = 3; CylinderMesh cylinder = 4; PlaneMesh plane = 5; + GltfMesh gltf = 6; } } diff --git a/proto/decentraland/sdk/components/mesh_renderer.proto b/proto/decentraland/sdk/components/mesh_renderer.proto index eee8c134..a6095017 100644 --- a/proto/decentraland/sdk/components/mesh_renderer.proto +++ b/proto/decentraland/sdk/components/mesh_renderer.proto @@ -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. @@ -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; } } diff --git a/proto/decentraland/sdk/components/primary_pointer_info.proto b/proto/decentraland/sdk/components/primary_pointer_info.proto index 1a60d82a..2113c46e 100644 --- a/proto/decentraland/sdk/components/primary_pointer_info.proto +++ b/proto/decentraland/sdk/components/primary_pointer_info.proto @@ -28,6 +28,8 @@ message PBPrimaryPointerInfo { optional PointerType pointer_type = 1; // The type of input device being used optional decentraland.common.Vector2 screen_coordinates = 2; // Current position in screen space (pixels) optional decentraland.common.Vector2 screen_delta = 3; // Movement since last frame (pixels) + // ray direction that can be used with the primary camera origin for + // raycasting from the cursor into the world optional decentraland.common.Vector3 world_ray_direction = 4; // Direction vector for 3D ray casting } @@ -36,4 +38,7 @@ message PBPrimaryPointerInfo { enum PointerType { POT_NONE = 0; // No pointer input POT_MOUSE = 1; // Traditional mouse input + POT_PAD = 2; + POT_TOUCH = 3; + POT_WAND = 4; } diff --git a/proto/decentraland/sdk/components/raycast.proto b/proto/decentraland/sdk/components/raycast.proto index 5514bfb7..2896c041 100644 --- a/proto/decentraland/sdk/components/raycast.proto +++ b/proto/decentraland/sdk/components/raycast.proto @@ -45,6 +45,12 @@ message PBRaycast { // Collision mask, by default CL_POINTER | CL_PHYSICS optional uint32 collision_mask = 9; + + // shape to cast, default ray + optional RaycastShape shape = 11; + + // include hits with entities from other scenes + optional bool include_world = 12; } // RaycastQueryType indicates whether the ray should stop on the first collition, or continue. @@ -56,3 +62,10 @@ enum RaycastQueryType { // Do not perform the raycast, only set the raycast result with empty hits RQT_NONE = 2; } + +enum RaycastShape { + // cast a point, get collisions along a ray + RS_RAY = 0; + // cast the avatar collider shape, get collisions from sweeping the shape + RS_AVATAR = 1; +} \ No newline at end of file diff --git a/proto/decentraland/sdk/components/texture_camera.proto b/proto/decentraland/sdk/components/texture_camera.proto new file mode 100644 index 00000000..1cf167cb --- /dev/null +++ b/proto/decentraland/sdk/components/texture_camera.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/colors.proto"; + +option (common.ecs_component_id) = 1207; + +message PBTextureCamera { + // rendered texture width + optional uint32 width = 1; + // rendered texture height + optional uint32 height = 2; + // which layer of entities to render. entity layers can be specified by adding PBCameraLayers to target entities. + // defaults to 0 + optional uint32 layer = 3; + + // default black + optional decentraland.common.Color4 clear_color = 6; + // default infinity + optional float far_plane = 7; + + oneof mode { + Perspective perspective = 8; + Orthographic orthographic = 9; + /* Portal portal = 10; */ + }; + + // controls whether this camera acts as a receiver for audio on sources with matching `PBCameraLayers`. + // range: 0 (off) - 1 (full volume) + // default: 0 + optional float volume = 10; +} + +message Perspective { + // vertical field of view in radians + // defaults to pi/4 = 45 degrees + optional float field_of_view = 1; +} + +message Orthographic { + // vertical extent of the visible range in meters + // defaults to 4m + optional float vertical_range = 1; +} diff --git a/proto/decentraland/sdk/components/ui_canvas.proto b/proto/decentraland/sdk/components/ui_canvas.proto new file mode 100644 index 00000000..041069d0 --- /dev/null +++ b/proto/decentraland/sdk/components/ui_canvas.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +import "decentraland/sdk/components/common/id.proto"; +package decentraland.sdk.components; + +option (common.ecs_component_id) = 1203; + +import "decentraland/common/colors.proto"; + +// The UiCanvas component can be attached to a ui root entity to specify properties of the ui texture. +message PBUiCanvas { + uint32 width = 1; + uint32 height = 2; + + optional decentraland.common.Color4 color = 3; // default = (0.0, 0.0, 0.0, 0.0) / transparent +} diff --git a/proto/decentraland/sdk/components/ui_input.proto b/proto/decentraland/sdk/components/ui_input.proto index 33dac448..d32dfdd2 100644 --- a/proto/decentraland/sdk/components/ui_input.proto +++ b/proto/decentraland/sdk/components/ui_input.proto @@ -17,4 +17,6 @@ message PBUiInput { optional common.Font font = 11; // default=0 optional int32 font_size = 12; // default=10 optional string value = 13; + optional bool multi_line = 14; // default=false; when true, the input accepts newlines and behaves as a textarea + optional bool clear_on_submit = 15; // default=true; when false, the input value is preserved after pressing Enter } \ No newline at end of file diff --git a/proto/decentraland/sdk/components/ui_scroll_result.proto b/proto/decentraland/sdk/components/ui_scroll_result.proto new file mode 100644 index 00000000..7875f886 --- /dev/null +++ b/proto/decentraland/sdk/components/ui_scroll_result.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/vectors.proto"; + +option (common.ecs_component_id) = 1202; + +message PBUiScrollResult { + decentraland.common.Vector2 value = 1; +} \ No newline at end of file diff --git a/proto/decentraland/sdk/components/ui_transform.proto b/proto/decentraland/sdk/components/ui_transform.proto index 0e3c9f0c..429a4123 100644 --- a/proto/decentraland/sdk/components/ui_transform.proto +++ b/proto/decentraland/sdk/components/ui_transform.proto @@ -4,6 +4,7 @@ package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; import "decentraland/common/colors.proto"; +import "decentraland/common/vectors.proto"; option (common.ecs_component_id) = 1050; @@ -80,6 +81,20 @@ enum PointerFilterMode { PFM_BLOCK = 1; } +enum ShowScrollBar { + SSB_BOTH = 0; + SSB_ONLY_VERTICAL = 1; + SSB_ONLY_HORIZONTAL = 2; + SSB_HIDDEN = 3; +} + +message ScrollPositionValue { + oneof value { + decentraland.common.Vector2 position = 1; + string reference = 2; + } +} + message PBUiTransform { int32 parent = 1; int32 right_of = 2; @@ -174,5 +189,10 @@ message PBUiTransform { optional decentraland.common.Color4 border_right_color = 72; optional float opacity = 73; // default: 1 + + optional string element_id = 74; // reference for scroll_position. default empty + optional ScrollPositionValue scroll_position = 75; // default position=(0,0) + optional ShowScrollBar scroll_visible = 76; // default ShowScrollBar.SSB_BOTH + optional int32 z_index = 77; // default: 0 — controls render stacking order. Higher values appear in front of lower values. } diff --git a/public/sdk-components.proto b/public/sdk-components.proto index f1a19d05..1722a186 100644 --- a/public/sdk-components.proto +++ b/public/sdk-components.proto @@ -9,15 +9,22 @@ import public "decentraland/sdk/components/avatar_base.proto"; import public "decentraland/sdk/components/avatar_emote_command.proto"; import public "decentraland/sdk/components/avatar_equipped_data.proto"; import public "decentraland/sdk/components/avatar_modifier_area.proto"; +import public "decentraland/sdk/components/avatar_movement.proto"; +import public "decentraland/sdk/components/avatar_movement_info.proto"; import public "decentraland/sdk/components/avatar_shape.proto"; import public "decentraland/sdk/components/billboard.proto"; +import public "decentraland/sdk/components/camera_layer.proto"; +import public "decentraland/sdk/components/camera_layers.proto"; import public "decentraland/sdk/components/camera_mode_area.proto"; import public "decentraland/sdk/components/camera_mode.proto"; import public "decentraland/sdk/components/engine_info.proto"; import public "decentraland/sdk/components/explorer_ui_events_result.proto"; +import public "decentraland/sdk/components/global_light.proto"; import public "decentraland/sdk/components/gltf_container.proto"; import public "decentraland/sdk/components/gltf_node_modifiers.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"; @@ -30,16 +37,19 @@ import public "decentraland/sdk/components/raycast_result.proto"; import public "decentraland/sdk/components/raycast.proto"; import public "decentraland/sdk/components/realm_info.proto"; import public "decentraland/sdk/components/text_shape.proto"; +import public "decentraland/sdk/components/texture_camera.proto"; import public "decentraland/sdk/components/touch_screen_controls.proto"; import public "decentraland/sdk/components/tween.proto"; import public "decentraland/sdk/components/tween_state.proto"; import public "decentraland/sdk/components/tween_sequence.proto"; import public "decentraland/sdk/components/ui_background.proto"; +import public "decentraland/sdk/components/ui_canvas.proto"; import public "decentraland/sdk/components/ui_dropdown_result.proto"; import public "decentraland/sdk/components/ui_dropdown.proto"; import public "decentraland/sdk/components/ui_input_result.proto"; import public "decentraland/sdk/components/ui_input.proto"; import public "decentraland/sdk/components/ui_input_binding.proto"; +import public "decentraland/sdk/components/ui_scroll_result.proto"; import public "decentraland/sdk/components/ui_text.proto"; import public "decentraland/sdk/components/ui_transform.proto"; import public "decentraland/sdk/components/video_player.proto";