You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
societer/utils/camera/CameraInput.gd

158 lines
4.9 KiB

extends Node
export(float,0.001,1.0) var screen_edge_size : float = 0.3
export(float) var mouse_wheel_damping = 0.9
#USED TO CALCULATE RAW MOVEMENT WHILE PUSHING AN EDGE
var horizontal : float = 0.0
var vertical : float = 0.0
#USED TO STORE MOUSE WHEEL INERTIA TO ENABLE SMOOTH STOPPING
var mouse_wheel : float = 0.0
signal on_change_velocity(velocity)
signal on_rotate_view(relative)
signal on_change_action(new_state)
signal on_zoom(value)
var current_action
#TOUCH VARIABLE FOR MOBILE
var touch_count : int = 0
var swipe_start : Vector2
func _ready():
connect("on_change_action",self,"change_action")
emit_signal("on_change_action",CameraController.CAMERA_ACTIONS.MOVING)
func change_action(action):
current_action = action
func toggle_action():
current_action = 1 - current_action
func start_swipe(position : Vector2):
swipe_start = position
func move_swipe(position : Vector2):
if blocked_movement:
return
var delta = (position - swipe_start)*-1
var direction_x = sign(delta.x)
var direction_y = sign(delta.y)
var view_size = get_viewport().get_visible_rect().size - Vector2.ONE
horizontal = range_lerp(abs(delta.x),0,view_size.x,0.0,1.0)
vertical = range_lerp(abs(delta.y),0,view_size.y,0.0,1.0)
#Applies direction
horizontal *= direction_x
vertical *= direction_y
var touches = [ Vector2.ZERO, Vector2.ZERO ]
var start_pinch_distance : float
var last_pinch_distance : float
var pinching : float
var blocked_movement : bool = false
func _input(event):
if OS.get_name() == "Android" or OS.get_name() == "iOS":
#MOBILE##############
if event is InputEventScreenTouch:
#SET TOUCH STARTING POSTIION
touches[event.index] = event.position
if event.pressed:
touch_count += 1
start_swipe(event.position)
else:
touch_count -= 1
#RENABLE SWIPE MOVEMENT BECAUSE EVERY TOUCH WAS LIFTED
if blocked_movement and touch_count <= 0:
blocked_movement = false
#RESET PINCHING VALUE WHEN A NEW TOUCH IS DETECTED OR HAS BEEN LIFTED
pinching = 0.0
if touch_count == 2:
#STARTED ZOOMING, BLOCK MOVEMENT UNTIL EVERY TOUCH IS LIFTED
blocked_movement = true
start_pinch_distance = (touches[1] - touches[0]).length()
if event is InputEventScreenDrag:
if touch_count == 2:
#UPDATE TOUCHES POSITIONS
touches[event.index] = event.position
#CALCULATE DISTANCE BETWEEN TOUCHES
var pinch_distance = (touches[1] - touches[0]).length()
var pinch_direction = 1 if pinch_distance > last_pinch_distance else -1
#CALCULATE PINCH DELTA
pinching = abs(start_pinch_distance - pinch_distance) * pinch_direction
#USE MOUSE WHEEL BUFFER TO ENABLE SMOOTHING
mouse_wheel += pinching * get_process_delta_time()
last_pinch_distance = pinch_distance
else:
if current_action == CameraController.CAMERA_ACTIONS.MOVING:
move_swipe(event.position)
elif current_action == CameraController.CAMERA_ACTIONS.ROTATING_VIEW:
emit_signal("on_rotate_view",event.relative)
###############MOBILE
else:
#PC##################
#Camera edge pushing
if event is InputEventMouseMotion:
#ROTATE VIEW
if current_action == CameraController.CAMERA_ACTIONS.ROTATING_VIEW:
emit_signal("on_rotate_view",event.relative)
#Gets screen size
var view_size = get_viewport().get_visible_rect().size - Vector2.ONE
#Get mouse position in percentage values relative to the screen
var delta = (event.position) / view_size
#Convert it to a range between [-1,1]
delta = (delta * 2) - Vector2.ONE
if current_action == CameraController.CAMERA_ACTIONS.MOVING:
#Store it an buffer to use it on _process
#Calculates delta based on percentage between the edge size and the actual edge
horizontal = max(abs(delta.x) - (1.0 - screen_edge_size),0)
vertical = max(abs(delta.y) - (1.0 - screen_edge_size),0)
#Converts it to an [0.0,1.0] range
horizontal = range_lerp(horizontal,0.0,screen_edge_size,0.0,1.0)
vertical = range_lerp(vertical,0.0,screen_edge_size,0.0,1.0)
#Applies direction
horizontal *= sign(delta.x)
vertical *= sign(delta.y)
elif current_action == CameraController.CAMERA_ACTIONS.ROTATING_VIEW:
horizontal = delta.x
vertical = delta.y
pass
if event is InputEventMouseButton:
#WHEEL SCROLL
if event.button_index == BUTTON_WHEEL_UP or event.button_index == BUTTON_WHEEL_DOWN:
if event.pressed and not event.is_echo():
var direction = (-1 if event.button_index == BUTTON_WHEEL_UP else 0) + (1 if event.button_index == BUTTON_WHEEL_DOWN else 0)
mouse_wheel += direction * get_process_delta_time() * 1000
###################PC
func _process(delta):
#PC######
match(current_action):
CameraController.CAMERA_ACTIONS.MOVING:
#RESIDUAL MOVEMENT
if horizontal != 0 or vertical != 0:
emit_signal("on_change_velocity",Vector2(horizontal, vertical))
#MOUSE WHEEL
if mouse_wheel != 0:
mouse_wheel = mouse_wheel * mouse_wheel_damping
emit_signal("on_zoom",mouse_wheel)
#######PC