Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up objects in demo scenes. #202

Merged
merged 1 commit into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 195 additions & 80 deletions addons/godot-xr-tools/functions/function_pointer.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@ tool
class_name XRToolsFunctionPointer, "res://addons/godot-xr-tools/editor/icons/function.svg"
extends Spatial


##
## Pointer Function Script
##
## @desc:
## This script implements a pointer function for a players controller. The
## pointer supports sending signals to XRToolsInteractableArea or
## XRToolsInteractableBody objects.
##
## The following signals are sent to these objects:
## - pointer_pressed(at) with the pointer location
## - pointer_released(at) with the pointer location
## - pointer_moved(from, to) with the pointer movement
## - pointer_entered()
## - pointer_exited()
##


# enum our buttons, should find a way to put this more central
enum Buttons {
VR_BUTTON_BY = 1,
Expand All @@ -22,124 +40,94 @@ enum Buttons {
VR_ACTION = 255
}

export var enabled = true setget set_enabled
export var show_laser = true setget set_show_laser
export var show_target = false
export (Buttons) var active_button = Buttons.VR_TRIGGER
export var action = ""
export var y_offset = -0.05 setget set_y_offset
export var distance = 10 setget set_distance
export (int, LAYERS_3D_PHYSICS) var collision_mask = 15 setget set_collision_mask
export var collide_with_bodies = true setget set_collide_with_bodies
export var collide_with_areas = false setget set_collide_with_areas

var target = null
var last_target = null
var last_collided_at = Vector3(0, 0, 0)
## Pointer enabled property
export var enabled : bool = true setget set_enabled

var ws = 1.0
## Show laser property
export var show_laser : bool = true setget set_show_laser

func set_enabled(p_enabled):
enabled = p_enabled
## Show laser target
export var show_target : bool = false

# this gets called before our scene is ready, we'll call this again in _ready to enable this
if is_inside_tree():
$Laser.visible = p_enabled and show_laser
$RayCast.enabled = p_enabled
## Y Offset for pointer
export var y_offset : float = -0.05 setget set_y_offset

func set_show_laser(p_show):
show_laser = p_show
if is_inside_tree():
$Laser.visible = enabled and show_laser
## Pointer distance
export var distance : float = 10 setget set_distance

func set_y_offset(p_offset):
y_offset = p_offset
if is_inside_tree():
$Laser.translation.y = y_offset * ws
$RayCast.translation.y = y_offset * ws
## Pointer collision mask
export (int, LAYERS_3D_PHYSICS) var collision_mask : int = 15 setget set_collision_mask

func set_collision_mask(p_new_mask):
collision_mask = p_new_mask
if is_inside_tree():
$RayCast.collision_mask = collision_mask
## Enable pointer collision with bodies
export var collide_with_bodies : bool = true setget set_collide_with_bodies

func set_distance(p_new_value):
distance = p_new_value
if is_inside_tree():
$Laser.mesh.size.z = distance
$Laser.translation.z = distance * -0.5
$RayCast.cast_to.z = -distance
## Enable pointer collision with areas
export var collide_with_areas : bool = false setget set_collide_with_areas

func set_collide_with_bodies(p_new_value : bool):
collide_with_bodies = p_new_value
if is_inside_tree():
$RayCast.collide_with_bodies = collide_with_bodies
## Active button
export (Buttons) var active_button : int = Buttons.VR_TRIGGER

func set_collide_with_areas(p_new_value : bool):
collide_with_areas = p_new_value
if is_inside_tree():
$RayCast.collide_with_areas = collide_with_areas
## Action to monitor (if button set to VR_ACTION)
export var action = ""

func _button_pressed():
if $RayCast.is_colliding():
target = $RayCast.get_collider()
last_collided_at = $RayCast.get_collision_point()

if target.has_signal("pointer_pressed"):
target.emit_signal("pointer_pressed", last_collided_at)
elif target.has_method("pointer_pressed"):
target.pointer_pressed(last_collided_at)
# Current target
var target : Spatial

func _button_released():
if target:
if target.has_signal("pointer_released"):
target.emit_signal("pointer_released", last_collided_at)
elif target.has_method("pointer_released"):
target.pointer_released(last_collided_at)
# Last target
var last_target : Spatial

# unset target
target = null
last_collided_at = Vector3(0, 0, 0)
# Last collision point
var last_collided_at : Vector3 = Vector3.ZERO

func _on_button_pressed(p_button):
if p_button == active_button and enabled:
_button_pressed()
# World scale
var ws : float = 1.0

func _on_button_release(p_button):
if p_button == active_button and target:
_button_released()

# Called when the node enters the scene tree for the first time.
func _ready():
# Do not initialise if in the editor
if Engine.editor_hint:
return

# Read the initial world-scale
ws = ARVRServer.world_scale

# If pointer-trigger is a button then subscribe to button signals
if active_button != Buttons.VR_ACTION:
# Get button press feedback from our parent (should be an ARVRController)
get_parent().connect("button_pressed", self, "_on_button_pressed")
get_parent().connect("button_release", self, "_on_button_release")

# init our state
set_y_offset(y_offset)
set_distance(distance)
set_collision_mask(collision_mask)
set_show_laser(show_laser)
set_collide_with_bodies(collide_with_bodies)
set_collide_with_areas(collide_with_areas)
set_enabled(enabled)
_update_y_offset()
_update_distance()
_update_collision_mask()
_update_show_laser()
_update_collide_with_bodies()
_update_collide_with_areas()
_update_set_enabled()


# Called on each frame to update the pickup
func _process(_delta):
if !is_inside_tree():
# Do not process if in the editor
if Engine.editor_hint or !is_inside_tree():
return

# If pointer-trigger is an action then check for action
if active_button == Buttons.VR_ACTION and action != "":
if Input.is_action_just_pressed(action):
_button_pressed()
elif !Input.is_action_pressed(action) and target:
_button_released()

var new_ws = ARVRServer.world_scale
# Handle world-scale changes
var new_ws := ARVRServer.world_scale
if (ws != new_ws):
ws = new_ws
set_y_offset(y_offset)
_update_y_offset()

if enabled and $RayCast.is_colliding():
var new_at = $RayCast.get_collision_point()
Expand Down Expand Up @@ -193,3 +181,130 @@ func _process(_delta):

last_target = null
$Target.visible = false


# Set pointer enabled property
func set_enabled(p_enabled : bool) -> void:
enabled = p_enabled

# this gets called before our scene is ready, we'll call this again in _ready to enable this
if is_inside_tree():
_update_set_enabled()


# Set show-laser property
func set_show_laser(p_show : bool) -> void:
show_laser = p_show
if is_inside_tree():
_update_show_laser()


# Set pointer Y offset property
func set_y_offset(p_offset : float) -> void:
y_offset = p_offset
if is_inside_tree():
_update_y_offset()


# Set pointer distance property
func set_distance(p_new_value : float) -> void:
distance = p_new_value
if is_inside_tree():
_update_distance()


# Set pointer collision mask property
func set_collision_mask(p_new_mask : int) -> void:
collision_mask = p_new_mask
if is_inside_tree():
_update_collision_mask()


# Set pointer collide-with-bodies property
func set_collide_with_bodies(p_new_value : bool) -> void:
collide_with_bodies = p_new_value
if is_inside_tree():
_update_collide_with_bodies()


# Set pointer collide-with-areas property
func set_collide_with_areas(p_new_value : bool) -> void:
collide_with_areas = p_new_value
if is_inside_tree():
_update_collide_with_areas()


# Pointer enabled update handler
func _update_set_enabled() -> void:
$Laser.visible = enabled and show_laser
$RayCast.enabled = enabled


# Pointer show-laser update handler
func _update_show_laser() -> void:
$Laser.visible = enabled and show_laser


# Pointer Y offset update handler
func _update_y_offset() -> void:
$Laser.translation.y = y_offset * ws
$RayCast.translation.y = y_offset * ws


# Pointer distance update handler
func _update_distance() -> void:
$Laser.mesh.size.z = distance
$Laser.translation.z = distance * -0.5
$RayCast.cast_to.z = -distance


# Pointer collision mask update handler
func _update_collision_mask() -> void:
$RayCast.collision_mask = collision_mask


# Pointer collide-with-bodies update handler
func _update_collide_with_bodies() -> void:
$RayCast.collide_with_bodies = collide_with_bodies


# Pointer collide-with-areas update handler
func _update_collide_with_areas() -> void:
$RayCast.collide_with_areas = collide_with_areas


# Pointer-activation button pressed handler
func _button_pressed() -> void:
if $RayCast.is_colliding():
target = $RayCast.get_collider()
last_collided_at = $RayCast.get_collision_point()

if target.has_signal("pointer_pressed"):
target.emit_signal("pointer_pressed", last_collided_at)
elif target.has_method("pointer_pressed"):
target.pointer_pressed(last_collided_at)


# Pointer-activation button released handler
func _button_released() -> void:
if target:
if target.has_signal("pointer_released"):
target.emit_signal("pointer_released", last_collided_at)
elif target.has_method("pointer_released"):
target.pointer_released(last_collided_at)

# unset target
target = null
last_collided_at = Vector3(0, 0, 0)


# Button pressed handler
func _on_button_pressed(p_button : int) -> void:
if p_button == active_button and enabled:
_button_pressed()


# Button released handler
func _on_button_release(p_button : int) -> void:
if p_button == active_button and target:
_button_released()
Loading