Initial commit
Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
		
						commit
						91ce62f680
					
				
							
								
								
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
# Normalize EOL for all files that Git considers text files.
 | 
			
		||||
* text=auto eol=lf
 | 
			
		||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
export/
 | 
			
		||||
.godot/
 | 
			
		||||
.godot/
 | 
			
		||||
*.translation
 | 
			
		||||
							
								
								
									
										167
									
								
								OSCReceiver.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								OSCReceiver.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,167 @@
 | 
			
		||||
extends Node
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@export var default_address:String = "0.0.0.0"
 | 
			
		||||
@export var default_port: int = 9001
 | 
			
		||||
@export var poll_interval: float = 0.05
 | 
			
		||||
@export var debug: bool = false
 | 
			
		||||
var _server: UDPServer
 | 
			
		||||
var _observers: Dictionary
 | 
			
		||||
var _timer: Timer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _init():
 | 
			
		||||
	_observers = {}
 | 
			
		||||
 | 
			
		||||
	_timer = Timer.new()
 | 
			
		||||
	_timer.autostart = false
 | 
			
		||||
	_timer.one_shot = false
 | 
			
		||||
	_timer.timeout.connect(self._poll)
 | 
			
		||||
	add_child(_timer)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _exit_tree():
 | 
			
		||||
	stop_server()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func register_callback(oscaddress, argtypes, callback):
 | 
			
		||||
	if not _observers.has([oscaddress, argtypes]):
 | 
			
		||||
		_observers[[oscaddress, argtypes]] = []
 | 
			
		||||
 | 
			
		||||
	_observers[[oscaddress, argtypes]].append(callback)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func start_server(address:String = default_address, port:int = default_port):
 | 
			
		||||
	_server = UDPServer.new()
 | 
			
		||||
 | 
			
		||||
	if _server.listen(port, address) != OK:
 | 
			
		||||
		_debug("OSCReceiver could not bind to port: %s" % port)
 | 
			
		||||
	else:
 | 
			
		||||
		_debug("OSCReceiver listening on port: %s" % port)
 | 
			
		||||
 | 
			
		||||
	_timer.start(poll_interval)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func stop_server():
 | 
			
		||||
	_timer.stop()
 | 
			
		||||
	remove_child(_timer)
 | 
			
		||||
	_timer.free()
 | 
			
		||||
 | 
			
		||||
	if _server:
 | 
			
		||||
		_server.stop()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _poll():
 | 
			
		||||
	if not _server.is_listening():
 | 
			
		||||
		return
 | 
			
		||||
 | 
			
		||||
	_server.poll()
 | 
			
		||||
 | 
			
		||||
	if _server.is_connection_available():
 | 
			
		||||
		var peer: PacketPeerUDP = _server.take_connection()
 | 
			
		||||
		var packet = peer.get_packet()
 | 
			
		||||
		var sender_ip = peer.get_packet_ip()
 | 
			
		||||
		var sender_port = peer.get_packet_port()
 | 
			
		||||
 | 
			
		||||
		_debug("Accepted peer: %s:%s" % [sender_ip, sender_port])
 | 
			
		||||
 | 
			
		||||
		var result = _parse_osc_addr_and_types(packet)
 | 
			
		||||
		var address = result[0]
 | 
			
		||||
		var types = result[1]
 | 
			
		||||
		var offset = result[2]
 | 
			
		||||
 | 
			
		||||
		_debug("OSC address: %s" % address)
 | 
			
		||||
		_debug("OSC arg types: %s" % types)
 | 
			
		||||
 | 
			
		||||
		if _observers.has([address, types]):
 | 
			
		||||
			var values = _parse_osc_values(packet, types, offset)
 | 
			
		||||
 | 
			
		||||
			if values == null:
 | 
			
		||||
				_debug("Invalid/Unsupported OSC message.")
 | 
			
		||||
			elif values.size() != types.length():
 | 
			
		||||
				_debug("Mismatch between expected / received number of OSC arguments.")
 | 
			
		||||
			else:
 | 
			
		||||
				values.append({
 | 
			
		||||
					"ip": sender_ip,
 | 
			
		||||
					"port": sender_port,
 | 
			
		||||
					"address": address,
 | 
			
		||||
					"types": types
 | 
			
		||||
				})
 | 
			
		||||
 | 
			
		||||
				for callback in _observers[[address, types]]:
 | 
			
		||||
					callback.callv(values)
 | 
			
		||||
 | 
			
		||||
func _parse_osc_addr_and_types(packet):
 | 
			
		||||
	var asep = packet.find(0)
 | 
			
		||||
	var address = packet.slice(0, asep).get_string_from_ascii() 
 | 
			
		||||
	
 | 
			
		||||
	var toffset = asep + (4 - asep % 4)
 | 
			
		||||
	assert(char(packet.decode_u8(toffset)) == ",")
 | 
			
		||||
	var tsep = packet.find(0, toffset)
 | 
			
		||||
	var types = packet.slice(toffset + 1, tsep).get_string_from_ascii() 
 | 
			
		||||
 | 
			
		||||
	return [address, types, tsep + (4 - tsep % 4)]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _parse_osc_values(packet, types, offset):
 | 
			
		||||
	var values = []
 | 
			
		||||
	var stream = StreamPeerBuffer.new()
 | 
			
		||||
	stream.set_data_array(packet.slice(offset))
 | 
			
		||||
	stream.set_big_endian(true)
 | 
			
		||||
 | 
			
		||||
	for type_id in types:
 | 
			
		||||
		match type_id:
 | 
			
		||||
			"i":
 | 
			
		||||
				values.append(stream.get_32())
 | 
			
		||||
			"h":
 | 
			
		||||
				values.append(stream.get_62())
 | 
			
		||||
			"f":
 | 
			
		||||
				values.append(stream.get_float())
 | 
			
		||||
			"d":
 | 
			
		||||
				values.append(stream.get_double())
 | 
			
		||||
			"c":
 | 
			
		||||
				values.append(char(stream.get_32()))
 | 
			
		||||
			"s", "S":
 | 
			
		||||
				var value = PackedStringArray()
 | 
			
		||||
				var null_found = false
 | 
			
		||||
 | 
			
		||||
				while not null_found:
 | 
			
		||||
					for _i in range(4):
 | 
			
		||||
						var ch = stream.get_u8()
 | 
			
		||||
						if not null_found and ch != 0:
 | 
			
		||||
							value.append(char(ch))
 | 
			
		||||
						else:
 | 
			
		||||
							null_found = true
 | 
			
		||||
 | 
			
		||||
				values.append("".join(value))
 | 
			
		||||
			"b":
 | 
			
		||||
				var count = stream.get_u32()
 | 
			
		||||
				values.append(stream.get_data(count))
 | 
			
		||||
				
 | 
			
		||||
				if count % 4:
 | 
			
		||||
					stream.seek(stream.get_position() + (count % 4))
 | 
			
		||||
			"t":
 | 
			
		||||
				values.append(stream.get_data(8))
 | 
			
		||||
			"m", "r":
 | 
			
		||||
				values.append([
 | 
			
		||||
					stream.get_u8(),
 | 
			
		||||
					stream.get_u8(),
 | 
			
		||||
					stream.get_u8(),
 | 
			
		||||
					stream.get_u8(),
 | 
			
		||||
				])
 | 
			
		||||
			"T":
 | 
			
		||||
				values.append(true)
 | 
			
		||||
			"F":
 | 
			
		||||
				values.append(false)
 | 
			
		||||
			"I", "N":
 | 
			
		||||
				values.append(null)
 | 
			
		||||
			_:
 | 
			
		||||
				_debug("Argument type '%s' not yet supported." % type_id)
 | 
			
		||||
				return
 | 
			
		||||
 | 
			
		||||
	return values
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _debug(msg):
 | 
			
		||||
	if debug:
 | 
			
		||||
		print(msg)
 | 
			
		||||
							
								
								
									
										9
									
								
								Slider.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Slider.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
extends VSlider
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func recv_osc(val, msg_info):
 | 
			
		||||
	print("Sender IP: %s" % msg_info["ip"])
 | 
			
		||||
	print("Sender Port: %d" % msg_info["port"])
 | 
			
		||||
	print("Adress: %s" % msg_info["address"])
 | 
			
		||||
	print("Types: %s" % msg_info["types"])
 | 
			
		||||
	set_value(clampf(val, 0.0, 1.0))
 | 
			
		||||
							
								
								
									
										9
									
								
								ToggleButton.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								ToggleButton.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
extends Button
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func recv_osc(val, msg_info):
 | 
			
		||||
	print("Sender IP: %s" % msg_info["ip"])
 | 
			
		||||
	print("Sender Port: %d" % msg_info["port"])
 | 
			
		||||
	print("Adress: %s" % msg_info["address"])
 | 
			
		||||
	print("Types: %s" % msg_info["types"])
 | 
			
		||||
	set_pressed_no_signal(bool(val))
 | 
			
		||||
							
								
								
									
										23
									
								
								UI.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								UI.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
extends Control
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _ready():
 | 
			
		||||
	var scene = preload("res://osc_receiver.tscn")
 | 
			
		||||
	var osc_server = scene.instantiate()
 | 
			
		||||
	add_child(osc_server)
 | 
			
		||||
 | 
			
		||||
	# configure all sensors
 | 
			
		||||
	for i in range(4):
 | 
			
		||||
		var nodename = "VSlider%d" % (i + 1)
 | 
			
		||||
		var osc_addr = "/slider/%d/set" % i
 | 
			
		||||
		var slider_node = find_child(nodename)
 | 
			
		||||
		osc_server.register_callback(osc_addr, "f", slider_node.recv_osc)
 | 
			
		||||
 | 
			
		||||
	for i in range(4):
 | 
			
		||||
		var nodename = "Button%d" % (i + 1)
 | 
			
		||||
		var osc_addr = "/button/%d/set" % i
 | 
			
		||||
		var button_node = find_child(nodename)
 | 
			
		||||
		osc_server.register_callback(osc_addr, "i", button_node.recv_osc)
 | 
			
		||||
 | 
			
		||||
	# start listening for osc messages
 | 
			
		||||
	osc_server.start_server()
 | 
			
		||||
							
								
								
									
										116
									
								
								UI.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								UI.tscn
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,116 @@
 | 
			
		||||
[gd_scene load_steps=8 format=3 uid="uid://8xyprd3yldfg"]
 | 
			
		||||
 | 
			
		||||
[ext_resource type="Script" path="res://UI.gd" id="1_ft657"]
 | 
			
		||||
[ext_resource type="Script" path="res://Slider.gd" id="2_310mb"]
 | 
			
		||||
[ext_resource type="Script" path="res://ToggleButton.gd" id="3_ct66k"]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_y0b18"]
 | 
			
		||||
bg_color = Color(1, 0, 0, 1)
 | 
			
		||||
 | 
			
		||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_iu8u7"]
 | 
			
		||||
bg_color = Color(0, 1, 0, 1)
 | 
			
		||||
 | 
			
		||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7e33t"]
 | 
			
		||||
bg_color = Color(0, 0, 1, 1)
 | 
			
		||||
 | 
			
		||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eeife"]
 | 
			
		||||
bg_color = Color(1, 1, 0.0235294, 1)
 | 
			
		||||
 | 
			
		||||
[node name="UI" type="Control"]
 | 
			
		||||
layout_mode = 3
 | 
			
		||||
anchors_preset = 15
 | 
			
		||||
anchor_right = 1.0
 | 
			
		||||
anchor_bottom = 1.0
 | 
			
		||||
grow_horizontal = 2
 | 
			
		||||
grow_vertical = 2
 | 
			
		||||
script = ExtResource("1_ft657")
 | 
			
		||||
 | 
			
		||||
[node name="MarginContainer" type="MarginContainer" parent="."]
 | 
			
		||||
layout_mode = 1
 | 
			
		||||
anchors_preset = 15
 | 
			
		||||
anchor_right = 1.0
 | 
			
		||||
anchor_bottom = 1.0
 | 
			
		||||
grow_horizontal = 2
 | 
			
		||||
grow_vertical = 2
 | 
			
		||||
theme_override_constants/margin_left = 20
 | 
			
		||||
theme_override_constants/margin_top = 20
 | 
			
		||||
theme_override_constants/margin_right = 20
 | 
			
		||||
theme_override_constants/margin_bottom = 20
 | 
			
		||||
 | 
			
		||||
[node name="GridContainer" type="GridContainer" parent="MarginContainer"]
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
theme_override_constants/h_separation = 10
 | 
			
		||||
theme_override_constants/v_separation = 10
 | 
			
		||||
columns = 4
 | 
			
		||||
 | 
			
		||||
[node name="VSlider1" type="VSlider" parent="MarginContainer/GridContainer"]
 | 
			
		||||
custom_minimum_size = Vector2(50, 300)
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
size_flags_horizontal = 3
 | 
			
		||||
size_flags_vertical = 3
 | 
			
		||||
max_value = 1.0
 | 
			
		||||
step = 0.01
 | 
			
		||||
tick_count = 11
 | 
			
		||||
ticks_on_borders = true
 | 
			
		||||
script = ExtResource("2_310mb")
 | 
			
		||||
 | 
			
		||||
[node name="VSlider2" type="VSlider" parent="MarginContainer/GridContainer"]
 | 
			
		||||
custom_minimum_size = Vector2(50, 300)
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
size_flags_horizontal = 3
 | 
			
		||||
size_flags_vertical = 3
 | 
			
		||||
max_value = 1.0
 | 
			
		||||
step = 0.01
 | 
			
		||||
tick_count = 11
 | 
			
		||||
ticks_on_borders = true
 | 
			
		||||
script = ExtResource("2_310mb")
 | 
			
		||||
 | 
			
		||||
[node name="VSlider3" type="VSlider" parent="MarginContainer/GridContainer"]
 | 
			
		||||
custom_minimum_size = Vector2(50, 300)
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
size_flags_horizontal = 3
 | 
			
		||||
size_flags_vertical = 3
 | 
			
		||||
max_value = 1.0
 | 
			
		||||
step = 0.01
 | 
			
		||||
tick_count = 11
 | 
			
		||||
ticks_on_borders = true
 | 
			
		||||
script = ExtResource("2_310mb")
 | 
			
		||||
 | 
			
		||||
[node name="VSlider4" type="VSlider" parent="MarginContainer/GridContainer"]
 | 
			
		||||
custom_minimum_size = Vector2(50, 300)
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
size_flags_horizontal = 3
 | 
			
		||||
size_flags_vertical = 3
 | 
			
		||||
max_value = 1.0
 | 
			
		||||
step = 0.01
 | 
			
		||||
tick_count = 11
 | 
			
		||||
ticks_on_borders = true
 | 
			
		||||
script = ExtResource("2_310mb")
 | 
			
		||||
 | 
			
		||||
[node name="Button1" type="Button" parent="MarginContainer/GridContainer"]
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_y0b18")
 | 
			
		||||
toggle_mode = true
 | 
			
		||||
text = "1"
 | 
			
		||||
script = ExtResource("3_ct66k")
 | 
			
		||||
 | 
			
		||||
[node name="Button2" type="Button" parent="MarginContainer/GridContainer"]
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_iu8u7")
 | 
			
		||||
toggle_mode = true
 | 
			
		||||
text = "2"
 | 
			
		||||
script = ExtResource("3_ct66k")
 | 
			
		||||
 | 
			
		||||
[node name="Button3" type="Button" parent="MarginContainer/GridContainer"]
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_7e33t")
 | 
			
		||||
toggle_mode = true
 | 
			
		||||
text = "3"
 | 
			
		||||
script = ExtResource("3_ct66k")
 | 
			
		||||
 | 
			
		||||
[node name="Button4" type="Button" parent="MarginContainer/GridContainer"]
 | 
			
		||||
layout_mode = 2
 | 
			
		||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_eeife")
 | 
			
		||||
toggle_mode = true
 | 
			
		||||
text = "4	"
 | 
			
		||||
script = ExtResource("3_ct66k")
 | 
			
		||||
							
								
								
									
										4
									
								
								default_env.tres
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								default_env.tres
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
[gd_resource type="Environment" format=2]
 | 
			
		||||
 | 
			
		||||
[resource]
 | 
			
		||||
background_mode = 2
 | 
			
		||||
							
								
								
									
										39
									
								
								export_presets.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								export_presets.cfg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
[preset.0]
 | 
			
		||||
 | 
			
		||||
name="Linux/X11"
 | 
			
		||||
platform="Linux/X11"
 | 
			
		||||
runnable=true
 | 
			
		||||
dedicated_server=false
 | 
			
		||||
custom_features=""
 | 
			
		||||
export_filter="all_resources"
 | 
			
		||||
include_filter=""
 | 
			
		||||
exclude_filter=""
 | 
			
		||||
export_path="export/osc_receiver_demo.x86_64"
 | 
			
		||||
encryption_include_filters=""
 | 
			
		||||
encryption_exclude_filters=""
 | 
			
		||||
encrypt_pck=false
 | 
			
		||||
encrypt_directory=false
 | 
			
		||||
 | 
			
		||||
[preset.0.options]
 | 
			
		||||
 | 
			
		||||
custom_template/debug=""
 | 
			
		||||
custom_template/release=""
 | 
			
		||||
debug/export_console_wrapper=1
 | 
			
		||||
binary_format/embed_pck=false
 | 
			
		||||
texture_format/bptc=true
 | 
			
		||||
texture_format/s3tc=true
 | 
			
		||||
texture_format/etc=false
 | 
			
		||||
texture_format/etc2=false
 | 
			
		||||
binary_format/architecture="x86_64"
 | 
			
		||||
ssh_remote_deploy/enabled=false
 | 
			
		||||
ssh_remote_deploy/host="user@host_ip"
 | 
			
		||||
ssh_remote_deploy/port="22"
 | 
			
		||||
ssh_remote_deploy/extra_args_ssh=""
 | 
			
		||||
ssh_remote_deploy/extra_args_scp=""
 | 
			
		||||
ssh_remote_deploy/run_script="#!/usr/bin/env bash
 | 
			
		||||
export DISPLAY=:0
 | 
			
		||||
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
 | 
			
		||||
\"{temp_dir}/{exe_name}\" {cmd_args}"
 | 
			
		||||
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
 | 
			
		||||
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
 | 
			
		||||
rm -rf \"{temp_dir}\""
 | 
			
		||||
							
								
								
									
										7
									
								
								osc_receiver.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								osc_receiver.tscn
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
[gd_scene load_steps=2 format=3 uid="uid://bqci5bw1h0lh7"]
 | 
			
		||||
 | 
			
		||||
[ext_resource type="Script" path="res://OSCReceiver.gd" id="1_ujyu5"]
 | 
			
		||||
 | 
			
		||||
[node name="OSCReceiver" type="Node"]
 | 
			
		||||
script = ExtResource("1_ujyu5")
 | 
			
		||||
debug = true
 | 
			
		||||
							
								
								
									
										28
									
								
								project.godot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								project.godot
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
; Engine configuration file.
 | 
			
		||||
; It's best edited using the editor UI and not directly,
 | 
			
		||||
; since the parameters that go here are not all obvious.
 | 
			
		||||
;
 | 
			
		||||
; Format:
 | 
			
		||||
;   [section] ; section goes between []
 | 
			
		||||
;   param=value ; assign values to parameters
 | 
			
		||||
 | 
			
		||||
config_version=5
 | 
			
		||||
 | 
			
		||||
[application]
 | 
			
		||||
 | 
			
		||||
config/name="OSCReceiver Demo"
 | 
			
		||||
run/main_scene="res://UI.tscn"
 | 
			
		||||
config/features=PackedStringArray("4.1")
 | 
			
		||||
 | 
			
		||||
[debug]
 | 
			
		||||
 | 
			
		||||
settings/fps/force_fps=30
 | 
			
		||||
 | 
			
		||||
[display]
 | 
			
		||||
 | 
			
		||||
window/size/viewport_width=300
 | 
			
		||||
window/size/viewport_height=400
 | 
			
		||||
 | 
			
		||||
[rendering]
 | 
			
		||||
 | 
			
		||||
environment/default_environment="res://default_env.tres"
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user