diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index ecd23366..4f8fe603 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -2,14 +2,14 @@ on: push: branches: - main + - protocol-squad - experimental pull_request: release: types: - created - -env: - BRANCH_TAG: ${{ github.ref_name == 'experimental' && 'experimental' || '' }} +env: + IS_A_PR: ${{ github.event.pull_request.number != 'null' && github.head_ref != 'protocol-squad' }} name: build-deploy jobs: @@ -21,6 +21,13 @@ jobs: outputs: dcl_protocol_s3_bucket_key: ${{ steps.publish_dcl_protocol.outputs.s3-bucket-key }} steps: + - name: (PR) Check if it's a PR + if: ${{ env.IS_A_PR == 'true' }} + run: | + echo "run from a PR" + echo "from env '${{env.IS_A_PR}}'" + echo "- '${{github.event.pull_request.number}}'" + echo "- env '${{github.head_ref}}'" - uses: actions/checkout@v4 - name: install run: make install @@ -32,6 +39,8 @@ jobs: uses: menduz/oddish-action@master id: publish_dcl_protocol with: + custom-tag: protocol-squad + branch-to-custom-tag: protocol-squad registry-url: 'https://registry.npmjs.org' access: public ## use action runId instead of current date to generate snapshot numbers @@ -47,18 +56,16 @@ jobs: ## inform gitlab after publishing to proceed with CDN propagation gitlab-token: ${{ secrets.GITLAB_TOKEN }} gitlab-pipeline-url: ${{ secrets.GITLAB_URL }} - custom-tag: ${{ env.BRANCH_TAG }} - branch-to-custom-tag: ${{ env.BRANCH_TAG }} env: - BRANCH_NAME: ${{ github.ref_name }} + BRANCH_NAME: ${{ github.head_ref }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} AWS_DEFAULT_REGION: us-east-1 AWS_ACCESS_KEY_ID: ${{ secrets.SDK_TEAM_AWS_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.SDK_TEAM_AWS_SECRET }} notify_deployment: - needs: [check_and_build] - if: ${{ github.event.pull_request.number }} + needs: [check_and_build] + if: github.event.pull_request.number != 'null' && github.head_ref != 'protocol-squad' runs-on: ubuntu-latest name: Deployment Notification steps: diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 264fbd47..d659402a 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,7 +1,10 @@ on: push: branches-ignore: - - "main" + - "protocol-squad" + +env: + BASE_BRANCH: protocol-squad # TODO: change to main for merging into main name: validate-compatibility jobs: @@ -19,4 +22,4 @@ jobs: - name: build and compile test run: make test - name: run the check script - run: ./scripts/check-proto-compabitility.sh + run: ./scripts/check-proto-compabitility.sh ${{ env.BASE_BRANCH }} diff --git a/package.json b/package.json index 18990f05..1e5294e5 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "@dcl/protocol", "version": "1.0.0", "description": "", - "repository": "decentraland/protocol.git", + "repository": { + "type": "git", + "url": "git+https://github.com/decentraland/protocol.git" + }, "homepage": "https://github.com/decentraland/protocol#readme", "bugs": "https://github.com/decentraland/protocol/issues", "keywords": [], 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 97d19faf..fb8bc648 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -48,12 +48,35 @@ message SuccessResponse { message TriggerEmoteResponse { } -message MovePlayerToResponse { +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; } @@ -66,6 +89,12 @@ service RestrictedActionsService { // whole interpolation being completed or interrupted (e.g: by input movement) rpc MovePlayerTo(MovePlayerToRequest) returns (MovePlayerToResponse) {} + // 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) {} + // TeleportTo will move the user to the specified world LAND parcel coordinates rpc TeleportTo(TeleportToRequest) returns (TeleportToResponse) {} @@ -88,6 +117,15 @@ service RestrictedActionsService { // TriggerSceneEmote will trigger an scene emote file in this current user rpc TriggerSceneEmote(TriggerSceneEmoteRequest) returns (SuccessResponse) {} + // 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(SetUiFocusRequest) returns (UiFocusResponse) {} + + // Returns the element_id of any currently focused textentry or dropdown + rpc GetUiFocus(GetUiFocusRequest) returns (UiFocusResponse) {} + // CopyToClipboard copies the provided text into the clipboard rpc CopyToClipboard(CopyToClipboardRequest) returns (EmptyResponse) {} } 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_locomotion_settings.proto b/proto/decentraland/sdk/components/avatar_locomotion_settings.proto new file mode 100644 index 00000000..a16f2169 --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_locomotion_settings.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; + +option (common.ecs_component_id) = 1211; + +// The PBAvatarLocomotionSettings component allows scenes to modify locomotion settings defining things such +// as the avatar movement speed, jump height etc. +message PBAvatarLocomotionSettings { + optional float walk_speed = 1; // Maximum speed when walking (in meters per second) + optional float jog_speed = 2; // Maximum speed when jogging (in meters per second) + optional float run_speed = 3; // Maximum speed when running (in meters per second) + optional float jump_height = 4; // Height of a regular jump (in meters) + optional float run_jump_height = 5; // Height of a jump while running (in meters) + optional float hard_landing_cooldown = 6; // Cooldown time after a hard landing before the avatar can move again (in seconds) +} diff --git a/proto/decentraland/sdk/components/avatar_modifier_area.proto b/proto/decentraland/sdk/components/avatar_modifier_area.proto index aea88858..81cdbf6a 100644 --- a/proto/decentraland/sdk/components/avatar_modifier_area.proto +++ b/proto/decentraland/sdk/components/avatar_modifier_area.proto @@ -23,10 +23,32 @@ 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 AvatarMovementSettings movement_settings = 4; + 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. enum AvatarModifierType { AMT_HIDE_AVATARS = 0; // avatars are invisible AMT_DISABLE_PASSPORTS = 1; // selecting (e.g. clicking) an avatar will not bring up their profile. + AMT_HIDE_NAMETAGS = 2; // the name tag displayed above an avatar is hidden. +} + +message AvatarMovementSettings { + optional AvatarControlType control_mode = 1; + // if not explicitly set, the following properties default to user's preference settings + optional float run_speed = 2; // speed the player moves at, in m/s + optional float friction = 3; // how fast the player gets up to speed or comes to rest. higher = more responsive + optional float gravity = 4; // how fast the player accelerates vertically when not on a solid surface, in m/s. should normally be negative + optional float jump_height = 5; // how high the player can jump, in meters. should normally be positive. gravity must have the same sign for jumping to be possible + optional float max_fall_speed = 6; // max fall speed in m/s. should normally be negative + optional float turn_speed = 7; // speed the player turns in tank mode, in radians/s + optional float walk_speed = 8; // speed the player walks at, in m/s + optional bool allow_weighted_movement = 9; // whether to allow player to move at a slower speed (e.g. with a walk-key or when using a gamepad/joystick). defaults to true +} + +enum AvatarControlType { + CCT_NONE = 0; // avatar cannot move + CCT_RELATIVE = 1; // avatar moves relative to the camera origin + CCT_TANK = 2; // avatar moves like a tank: left/right rotate the player, forward/backward advance/retreat the player } diff --git a/proto/decentraland/sdk/components/avatar_movement.proto b/proto/decentraland/sdk/components/avatar_movement.proto new file mode 100644 index 00000000..74851531 --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_movement.proto @@ -0,0 +1,46 @@ +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, we don't allow pitch/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 +} + +// 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..bb9e006a --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_movement_info.proto @@ -0,0 +1,22 @@ +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 +} 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..e6efc0c3 --- /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..7a073bbf 100644 --- a/proto/decentraland/sdk/components/camera_mode_area.proto +++ b/proto/decentraland/sdk/components/camera_mode_area.proto @@ -9,7 +9,7 @@ import "decentraland/sdk/components/common/id.proto"; option (common.ecs_component_id) = 1071; // The CameraModeArea component can be attached to an Entity to define a region of space where -// the player's camera mode (1st-person or 3rd-person) is overridden. +// the player's camera mode (1st-person, 3rd-person or cinematic) is overridden. // // The Entity's Transform position determines the center-point of the region, while its size is // given as a vector in the `area` property below. The Transform rotation is applied, but the scale @@ -19,7 +19,26 @@ option (common.ecs_component_id) = 1071; // // Note that, while commonly used to delineate a 2D area in a scene (hence the name), the region // is actually a 3D volume. +// +// When mode is set to CtCinematic, the cinematic_settings field must also be provided. message PBCameraModeArea { - decentraland.common.Vector3 area = 1; // the 3D size of the region - common.CameraType mode = 2; // the camera mode to enforce + decentraland.common.Vector3 area = 1; // the 3D size of the region + common.CameraType mode = 2; // the camera mode to enforce + optional CinematicSettings cinematic_settings = 3; + 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 +} + +message CinematicSettings { + uint32 camera_entity = 1; // Entity that defines the cinematic camera transform. + // Position -> camera's position + // Rotation -> camera's direction + // scale.z -> zoom level + // scale.x and scale.y -> unused + optional bool allow_manual_rotation = 2; // whether the user can move the camera's rotation. default false + optional float yaw_range = 3; // how far the camera can rotate around the y-axis / look left/right, in radians. default unrestricted + optional float pitch_range = 4; // how far the camera can rotate around the x-axis / look up-down, in radians. default unrestricted + // note: cameras can never look up/down further than Vec3::Y + optional float roll_range = 5; // how far the camera can rotate around the z-axis / tilt, in radians. default unrestricted + optional float zoom_min = 6; // minimum zoom level. must be greater than 0. defaults to the input zoom level + optional float zoom_max = 7; // maximum zoom level. must be greater than 0. defaults to the input zoom level } diff --git a/proto/decentraland/sdk/components/common/input_action.proto b/proto/decentraland/sdk/components/common/input_action.proto index c21def37..617f45b1 100644 --- a/proto/decentraland/sdk/components/common/input_action.proto +++ b/proto/decentraland/sdk/components/common/input_action.proto @@ -17,6 +17,7 @@ enum InputAction { IA_ACTION_4 = 11; IA_ACTION_5 = 12; IA_ACTION_6 = 13; + IA_MODIFIER = 14; } // PointerEventType is a kind of interaction that can be detected. @@ -27,6 +28,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..0fa10ba8 --- /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..86d1e26a --- /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 048b9553..46ead4cc 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..3790d96c --- /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_canvas_information.proto b/proto/decentraland/sdk/components/ui_canvas_information.proto index f2e84e97..5dd10cf6 100644 --- a/proto/decentraland/sdk/components/ui_canvas_information.proto +++ b/proto/decentraland/sdk/components/ui_canvas_information.proto @@ -21,4 +21,10 @@ message PBUiCanvasInformation { // chat UI hidden and with no minimap could have a rect that covers the whole screen. // on the contrary, if the chat UI is shown, the rect would be smaller. decentraland.common.BorderRect interactable_area = 4; + // informs the sdk about the screen inset area (safe margins). these are the + // insets from each edge of the screen that are reserved by the device or + // platform UI (for example: the notch, status bar, home indicator, or rounded + // corners on mobile). scenes should avoid placing critical UI within these + // insets to ensure it is not occluded. on desktop this is typically (0, 0, 0, 0). + optional decentraland.common.BorderRect screen_inset_area = 5; } 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_text.proto b/proto/decentraland/sdk/components/ui_text.proto index 9e5bb5fb..6af0782d 100644 --- a/proto/decentraland/sdk/components/ui_text.proto +++ b/proto/decentraland/sdk/components/ui_text.proto @@ -23,4 +23,7 @@ message PBUiText { optional common.Font font = 4; // font for the text (default: sans-serif) optional int32 font_size = 5; // size of the text (default: 10) optional TextWrap text_wrap = 6; // wrap text when the border is reached (default: TW_WRAP) + + optional float outline_width = 7; // width of the outline (default: 0) + optional decentraland.common.Color4 outline_color = 8; // RGBA color of the outline (default: opaque black) } 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 a2f966cb..466b46a1 100644 --- a/public/sdk-components.proto +++ b/public/sdk-components.proto @@ -9,6 +9,8 @@ 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_mode_area.proto"; @@ -17,6 +19,8 @@ import public "decentraland/sdk/components/engine_info.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"; diff --git a/scripts/check-proto-compabitility.sh b/scripts/check-proto-compabitility.sh index c7f7120a..7a9289df 100755 --- a/scripts/check-proto-compabitility.sh +++ b/scripts/check-proto-compabitility.sh @@ -1,15 +1,26 @@ #!/bin/bash set -e -x +# Check if the first argument (branch_name) is provided +if [ -z "$1" ]; then + echo "Error: Missing branch name parameter." + echo "Usage: $0 " + exit 1 +fi + +# Continue with the rest of the script +branch_name="$1" +echo "Branch name provided: $branch_name" + # Download the main branch ref zip -protocol_main_zip_url="https://github.com/decentraland/protocol/archive/refs/heads/main.zip" -protocol_main_zip_local="./protocol-main.zip" +protocol_zip_url="https://github.com/decentraland/protocol/archive/refs/heads/${branch_name}.zip" +protocol_zip_local="./protocol-main.zip" TMP_ZIP_DIR=$(mktemp -d) -curl -L "$protocol_main_zip_url" -o "$protocol_main_zip_local" -unzip "$protocol_main_zip_local" -d "$TMP_ZIP_DIR" -rm "$protocol_main_zip_local" || true +curl -L "$protocol_zip_url" -o "$protocol_zip_local" +unzip "$protocol_zip_local" -d "$TMP_ZIP_DIR" +rm "$protocol_zip_local" || true ln -s "$(pwd)/node_modules" "$TMP_ZIP_DIR/protocol-main/node_modules"