Skip to content

Commit

Permalink
Added initial support for swapping items between hands
Browse files Browse the repository at this point in the history
This pull request allows swapping items between hands. The changes will also be necessary when implementing two-handed grabs.
  • Loading branch information
Malcolmnixon committed Nov 2, 2023
1 parent 40a1d59 commit 8baa4e7
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 13 deletions.
1 change: 1 addition & 0 deletions VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- Upgraded project to Godot 4.1 as the new minimum version.
- Added reporting of stage load errors.
- Blend player height changes and prevent the player from standing up under a low ceiling.
- **minor-breakage** Added support for swapping held items between hands.

# 4.2.1
- Fixed snap-zones showing highlight when disabled.
Expand Down
1 change: 1 addition & 0 deletions addons/godot-xr-tools/functions/function_pickup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ func drop_object() -> void:

# let go of this object
picked_up_object.let_go(
self,
_velocity_averager.linear_velocity() * impulse_factor,
_velocity_averager.angular_velocity())
picked_up_object = null
Expand Down
1 change: 1 addition & 0 deletions addons/godot-xr-tools/functions/function_pickup.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@

[node name="FunctionPickup" type="Node3D"]
script = ExtResource("1")
grab_collision_mask = 327684
4 changes: 2 additions & 2 deletions addons/godot-xr-tools/interactables/interactable_handle.gd
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ func pick_up(by, with_controller) -> void:


# Called when the handle is dropped
func let_go(_p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void:
func let_go(by: Node3D, _p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void:
# Call the base-class to perform the drop, but with no velocity
super(Vector3.ZERO, Vector3.ZERO)
super(by, Vector3.ZERO, Vector3.ZERO)

# Disable the process function as no-longer held
set_process(false)
Expand Down
2 changes: 1 addition & 1 deletion addons/godot-xr-tools/objects/climbable.gd
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func pick_up(by: Node3D, _with_controller: XRController3D) -> void:
handle.global_transform = by.global_transform

# Called by XRToolsFunctionPickup when this is let go by a controller
func let_go(_p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void:
func let_go(_by: Node3D, _p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void:
pass

# Get the grab handle
Expand Down
45 changes: 37 additions & 8 deletions addons/godot-xr-tools/objects/pickable.gd
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ enum ReleaseMode {
FROZEN = 1, ## Release and freeze
}

enum SecondHandGrab {
IGNORE, ## Ignore second grab
SWAP ## Swap to second hand
}


# Default layer for held objects is 17:held-object
const DEFAULT_LAYER := 0b0000_0000_0000_0001_0000_0000_0000_0000
Expand All @@ -80,6 +85,9 @@ const GRIP_POSE_PRIORITY = 100
## Method used to perform a ranged grab
@export var ranged_grab_method : RangedMethod = RangedMethod.SNAP: set = _set_ranged_grab_method

## Second hand grab mode
@export var second_hand_grab : SecondHandGrab = SecondHandGrab.IGNORE

## Speed for ranged grab
@export var ranged_grab_speed : float = 20.0

Expand Down Expand Up @@ -164,8 +172,24 @@ func _exit_tree():


# Test if this object can be picked up
func can_pick_up(_by: Node3D) -> bool:
return enabled and _state == PickableState.IDLE
func can_pick_up(by: Node3D) -> bool:
# Refuse if not enabled
if not enabled:
return false

# Allow if the item is idle
if _state == PickableState.IDLE:
return true

# Allow swapping the item from one hand to the other
if _state == PickableState.HELD and \
second_hand_grab != SecondHandGrab.IGNORE and \
picked_up_by is XRToolsFunctionPickup and \
by is XRToolsFunctionPickup:
return true

# Refuse the pickup
return false


# Test if this object is picked up
Expand Down Expand Up @@ -211,12 +235,17 @@ func drop_and_free():

# Called when this object is picked up
func pick_up(by: Node3D, with_controller: XRController3D) -> void:
# Skip if disabled or already picked up
if not enabled or _state != PickableState.IDLE:
# Skip if not enabled or range-grabbing
if not enabled or _state == PickableState.GRABBING_RANGED:
return

# Skip if held and we don't support second-hand grab
if _state != PickableState.IDLE and second_hand_grab == SecondHandGrab.IGNORE:
return

# Drop if currently held
if picked_up_by:
let_go(Vector3.ZERO, Vector3.ZERO)
let_go(picked_up_by, Vector3.ZERO, Vector3.ZERO)

# remember who picked us up
picked_up_by = by
Expand Down Expand Up @@ -267,9 +296,9 @@ func pick_up(by: Node3D, with_controller: XRController3D) -> void:


# Called when this object is dropped
func let_go(p_linear_velocity: Vector3, p_angular_velocity: Vector3) -> void:
# Skip if idle
if _state == PickableState.IDLE:
func let_go(by: Node3D, p_linear_velocity: Vector3, p_angular_velocity: Vector3) -> void:
# Skip if idle or not picked up by the specified node
if _state == PickableState.IDLE or by != picked_up_by:
return

# If held then detach from holder
Expand Down
4 changes: 2 additions & 2 deletions addons/godot-xr-tools/objects/snap_zone.gd
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func pick_up(_by: Node3D, _with_controller: XRController3D) -> void:


# Pickable Method: Player never graps snap-zone
func let_go(_p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void:
func let_go(_by: Node3D, _p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void:
pass


Expand All @@ -157,7 +157,7 @@ func drop_object() -> void:
return

# let go of this object
picked_up_object.let_go(Vector3.ZERO, Vector3.ZERO)
picked_up_object.let_go(self, Vector3.ZERO, Vector3.ZERO)
picked_up_object = null
has_dropped.emit()
highlight_updated.emit(self, enabled)
Expand Down
1 change: 1 addition & 0 deletions scenes/pickable_demo/objects/grab_ball.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ albedo_color = Color(1, 1, 0, 1)
[node name="GrabBall" instance=ExtResource("1")]
collision_mask = 720903
ranged_grab_method = 2
second_hand_grab = 1

[node name="GrabPointHandLeft" parent="." index="0" instance=ExtResource("2_qhto0")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.19, 0.04, -0.065)
Expand Down
1 change: 1 addition & 0 deletions scenes/pickable_demo/objects/grab_cube.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ size = Vector3(0.1, 0.1, 0.1)
script = ExtResource("2_xxt38")
alternate_material = ExtResource("3_g1dne")
ranged_grab_method = 0
second_hand_grab = 1

[node name="CollisionShape3D" parent="." index="0"]
shape = SubResource("7")
Expand Down
1 change: 1 addition & 0 deletions scenes/pickable_demo/objects/hammer.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ size = Vector3(0.1, 0.1, 0.2)
[node name="Hammer" instance=ExtResource("1")]
collision_mask = 7
ranged_grab_method = 0
second_hand_grab = 1

[node name="GrabPointHandLeft" parent="." index="0" instance=ExtResource("2_2myoy")]
transform = Transform3D(-1, 8.74228e-08, 0, -8.58166e-08, -0.981627, 0.190809, 1.66811e-08, 0.190809, 0.981627, -0.007, 0.355, -0.071)
Expand Down
1 change: 1 addition & 0 deletions scenes/pickable_demo/objects/knife.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ points = PackedVector3Array(-0.0142231, 0.0175055, 0.00419341, -0.0142231, -0.01
[node name="Knife" instance=ExtResource("1")]
continuous_cd = true
script = ExtResource("7")
second_hand_grab = 1

[node name="Knife" type="MeshInstance3D" parent="." index="0"]
mesh = SubResource("ArrayMesh_anmh6")
Expand Down
1 change: 1 addition & 0 deletions scenes/pickable_demo/objects/saucer.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ surface_material_override/0 = ExtResource("1_ycnf3")
shape = SubResource("ConvexPolygonShape3D_v45tx")

[node name="SnapZoneTeacup" parent="." instance=ExtResource("1")]
grab_distance = 0.1
snap_mode = 1
snap_require = "Teacup"
1 change: 1 addition & 0 deletions scenes/pickable_demo/objects/teacup.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ open_pose = ExtResource("7_m23hc")
closed_pose = ExtResource("7_m23hc")

[node name="Teacup" groups=["Teacup"] instance=ExtResource("1_q232w")]
second_hand_grab = 1

[node name="Teacup" type="MeshInstance3D" parent="." index="0"]
gi_mode = 0
Expand Down

0 comments on commit 8baa4e7

Please sign in to comment.