Skip to content

Commit

Permalink
fix: avatar attach collider and send raycast_hit in global pointer ev…
Browse files Browse the repository at this point in the history
…ents (#199)
  • Loading branch information
leanmendoza authored Jan 26, 2024
1 parent 13ee7c9 commit 2db9d2f
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 29 deletions.
1 change: 0 additions & 1 deletion godot/src/decentraland_components/avatar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ func async_load_wearables():
return

wearables_by_category = curated_wearables[0]
var hiding_list: PackedStringArray = curated_wearables[1]

var body_shape = wearables_by_category.get(Wearables.Categories.BODY_SHAPE)
if body_shape == null:
Expand Down
74 changes: 59 additions & 15 deletions godot/src/decentraland_components/avatar_attach.gd
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
extends Node

# in seconds
const TIME_TO_RETURN_BACK_LAYER = 0.5

@export var user_id: String = "":
set(value):
if user_id != value:
Expand All @@ -12,30 +15,68 @@ extends Node
# AAPT_RIGHT_HAND = 3;
var attach_point: int = -1

var _computed_colliders: Array[Node]
var _main_scene_tree: SceneTree
var _player_node: Node3D


func _ready():
func init():
var scene = SceneHelper.search_scene_node(self.get_parent())
scene.tree_changed.connect(self._on_tree_changed)

# Compute initial transform position
_process(0)
process_priority = 0

_main_scene_tree = get_tree()

func _set_children_physics(node: Node, enable: bool):
for child in node.get_children():
_set_children_physics(child, enable)
var colliders: Array[Node] = []
get_collider_tree(self.get_parent(), colliders)
update_colliders(colliders)


func get_collider_tree(node: Node, colliders: Array[Node]) -> void:
for child in node.get_children():
get_collider_tree(child, colliders)
if child.has_meta("dcl_col"):
if enable:
child.collision_layer = child.get_meta("dcl_col")
else:
child.collision_layer = 0
colliders.push_back(child)


func _exit_tree():
_set_children_physics(self.get_parent(), true)
func update_colliders(current_colliders: Array[Node]) -> void:
for collider in current_colliders:
var col_index := _computed_colliders.find(collider)
if col_index != -1:
_computed_colliders.remove_at(col_index)
else:
collider.collision_layer = 0

async_apply_after_physics(_computed_colliders.duplicate())

_computed_colliders = current_colliders


func async_apply_after_physics(_computed_colliders: Array[Node]):
await _main_scene_tree.create_timer(TIME_TO_RETURN_BACK_LAYER).timeout

func _enter_tree():
_set_children_physics(self.get_parent(), false)
for old_collider in _computed_colliders:
# Corner case when is moved from one avatar attach to other
if not is_parented_with_avatar_attach(old_collider):
old_collider.collision_layer = old_collider.get_meta("dcl_col")


func is_parented_with_avatar_attach(_collider: Node) -> bool:
# TODO
return false


func _on_tree_changed():
var colliders: Array[Node] = []
get_collider_tree(self.get_parent(), colliders)
update_colliders(colliders)


func _exit_tree():
update_colliders([])


func _process(_delta):
Expand All @@ -45,7 +86,8 @@ func _process(_delta):

if _player_node == null:
look_up_player()
return
if _player_node == null:
return

match attach_point:
0:
Expand All @@ -67,9 +109,11 @@ func _process(_delta):


func look_up_player():
var primary_player_user_id := Global.player_identity.get_address_str()

# default to current player
if user_id.is_empty():
# TODO: change this
var look_up_player_user_id := user_id if not user_id.is_empty() else primary_player_user_id
if primary_player_user_id == look_up_player_user_id:
_player_node = get_node("/root/explorer/world/Player/Avatar")
else:
_player_node = Global.avatars.get_avatar_by_address(user_id)
4 changes: 2 additions & 2 deletions godot/src/ui/explorer.gd
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ func _on_control_menu_request_pause_scenes(enabled):

func move_to(position: Vector3):
player.set_position(position)
var parcel_position = Vector2(player.position.x * 0.0625, -player.position.z * 0.0625)
if not Global.scene_fetcher.is_scene_loaded(parcel_position.x, parcel_position.y):
var cur_parcel_position = Vector2(player.position.x * 0.0625, -player.position.z * 0.0625)
if not Global.scene_fetcher.is_scene_loaded(cur_parcel_position.x, cur_parcel_position.y):
loading_ui.enable_loading_screen()


Expand Down
1 change: 0 additions & 1 deletion godot/src/utils/promise.gd
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ class AllAwaiter:
class AllAwaiterEx:
var results: Array = []
var resolved: Array = []
var _mask: int
var _promise: Promise = Promise.new()

func _init(funcs: Array) -> void:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use godot::engine::Node3D;
use godot::prelude::*;

use crate::dcl::components::SceneEntityId;

#[derive(GodotClass)]
#[class(init, base=Node3D)]
pub struct DclNodeEntity3d {
entity_id: i32,
#[base]
_base: Base<Node3D>,
}

#[godot_api]
impl DclNodeEntity3d {
pub fn new_alloc(entity_id: SceneEntityId) -> Gd<Self> {
let entity_id = entity_id.as_i32();
let mut obj = Gd::from_init_fn(|_base| DclNodeEntity3d { _base, entity_id });
obj.set_name(GString::from(format!("e{:x}", entity_id)));
obj
}

#[func]
fn e_id(&self) -> i32 {
self.entity_id
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ pub struct DclSceneNode {

#[godot_api]
impl DclSceneNode {
#[signal]
pub fn tree_changed(&self) {}

pub fn new_alloc(scene_id: i32, is_global: bool) -> Gd<Self> {
let mut obj = Gd::from_init_fn(|_base| {
// accepts the base and returns a constructed object containing it
Expand Down
2 changes: 2 additions & 0 deletions rust/decentraland-godot-lib/src/godot_classes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod dcl_confirm_dialog;
pub mod dcl_ether;
pub mod dcl_global;
pub mod dcl_gltf_container;
pub mod dcl_node_entity_3d;
pub mod dcl_realm;
pub mod dcl_scene_node;
pub mod dcl_ui_background;
Expand All @@ -20,6 +21,7 @@ pub mod font;
pub mod portables;
pub mod promise;
pub mod rpc_sender;

pub trait JsonGodotClass
where
Self: serde::Serialize + serde::de::DeserializeOwned,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ pub fn update_avatar_attach(scene: &mut Scene, crdt_state: &mut SceneCrdtState)

avatar_attach_node.set_name(GString::from("AvatarAttach"));

node_3d.add_child(avatar_attach_node);
node_3d.add_child(avatar_attach_node.clone());
avatar_attach_node.call("init".into(), &[]);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ pub fn pointer_events_system(
SceneEntityId::new(0, 0),
PbPointerEventsResult {
button: *input_action as i32,
hit: None,
hit: raycast_hit.clone(),
state,
timestamp: global_tick_number,
analog: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub fn update_transform_and_parent(
let root_node = godot_dcl_scene.root_node_3d.clone().upcast::<Node>();
while godot_dcl_scene.hierarchy_dirty_3d {
godot_dcl_scene.hierarchy_dirty_3d = false;
godot_dcl_scene.hierarchy_changed_3d = true;

let unparented = godot_dcl_scene
.unparented_entities_3d
Expand Down
16 changes: 8 additions & 8 deletions rust/decentraland-godot-lib/src/scene_runner/godot_dcl_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use crate::{
},
SceneDefinition, SceneId,
},
godot_classes::{dcl_scene_node::DclSceneNode, dcl_ui_control::DclUiControl},
godot_classes::{
dcl_node_entity_3d::DclNodeEntity3d, dcl_scene_node::DclSceneNode,
dcl_ui_control::DclUiControl,
},
};
use godot::{builtin::meta::ConvertError, engine::Json, prelude::*};
use std::{
Expand All @@ -26,6 +29,7 @@ pub struct GodotDclScene {

pub root_node_3d: Gd<DclSceneNode>,
pub hierarchy_dirty_3d: bool,
pub hierarchy_changed_3d: bool,
pub unparented_entities_3d: HashSet<SceneEntityId>,

pub parent_node_ui: Gd<DclUiControl>,
Expand Down Expand Up @@ -186,6 +190,7 @@ impl GodotDclScene {

root_node_3d,
hierarchy_dirty_3d: false,
hierarchy_changed_3d: false,
unparented_entities_3d: HashSet::new(),

root_node_ui: root_node_ui_control,
Expand Down Expand Up @@ -241,14 +246,9 @@ impl GodotDclScene {

let godot_entity_node = self.entities.get_mut(entity).unwrap();
if godot_entity_node.base_3d.is_none() {
let mut new_node_3d = Node3D::new_alloc();
new_node_3d.set_name(GString::from(format!(
"e{:?}_{:?}",
entity.number, entity.version
)));

let new_node_3d = DclNodeEntity3d::new_alloc(*entity);
self.root_node_3d.add_child(new_node_3d.clone().upcast());
godot_entity_node.base_3d = Some(new_node_3d);
godot_entity_node.base_3d = Some(new_node_3d.upcast());
}

let node_3d = godot_entity_node.base_3d.as_ref().unwrap().clone();
Expand Down
8 changes: 8 additions & 0 deletions rust/decentraland-godot-lib/src/scene_runner/update_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@ pub fn _process_scene(
SceneUpdateState::ComputeCrdtState => {
update_avatar_scene_updates(scene, crdt_state);

if scene.godot_dcl_scene.hierarchy_changed_3d {
scene
.godot_dcl_scene
.root_node_3d
.call_deferred("emit_signal".into(), &["tree_changed".to_variant()]);
scene.godot_dcl_scene.hierarchy_changed_3d = false;
}

// Set transform
let camera_transform = DclTransformAndParent::from_godot(
camera_global_transform,
Expand Down

0 comments on commit 2db9d2f

Please sign in to comment.