moved godot repo to its own codeberg repo to submit as godot extension
This commit is contained in:
		
							parent
							
								
									4b8e0695b2
								
							
						
					
					
						commit
						5cb79147c3
					
				
					 17 changed files with 11 additions and 1786 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
[submodule "example/godot"]
 | 
			
		||||
	path = example/godot
 | 
			
		||||
	url = https://codeberg.org/coderofsalvation/xrfragment-godot.git
 | 
			
		||||
							
								
								
									
										1
									
								
								example/godot
									
										
									
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								example/godot
									
										
									
									
									
										Submodule
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Subproject commit 4354ca93987dde9a20efb880b0be9e17b3761a3e
 | 
			
		||||
							
								
								
									
										2
									
								
								example/godot/.gitattributes
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								example/godot/.gitattributes
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
# Normalize EOL for all files that Git considers text files.
 | 
			
		||||
* text=auto eol=lf
 | 
			
		||||
							
								
								
									
										2
									
								
								example/godot/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								example/godot/.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
# Godot 4+ specific ignores
 | 
			
		||||
.godot/
 | 
			
		||||
| 
						 | 
				
			
			@ -1,250 +0,0 @@
 | 
			
		|||
# GDScriptAudioImport v0.1
 | 
			
		||||
# https://github.com/Gianclgar/GDScriptAudioImport/pull/20
 | 
			
		||||
# MIT License
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2020 Gianclgar (Giannino Clemente) gianclgar@gmail.com
 | 
			
		||||
#
 | 
			
		||||
#Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
#of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
#in the Software without restriction, including without limitation the rights
 | 
			
		||||
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
#copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
#furnished to do so, subject to the following conditions:
 | 
			
		||||
#
 | 
			
		||||
#The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
#copies or substantial portions of the Software.
 | 
			
		||||
#
 | 
			
		||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
#SOFTWARE.
 | 
			
		||||
 | 
			
		||||
#I honestly don't care that much, Kopimi ftw, but it's my little baby and I want it to look nice :3
 | 
			
		||||
 | 
			
		||||
class_name AudioLoader
 | 
			
		||||
 | 
			
		||||
func report_errors(err, filepath):
 | 
			
		||||
	# See: https://docs.godotengine.org/en/latest/classes/class_@globalscope.html#enum-globalscope-error
 | 
			
		||||
	var result_hash = {
 | 
			
		||||
		ERR_FILE_NOT_FOUND: "File: not found",
 | 
			
		||||
		ERR_FILE_BAD_DRIVE: "File: Bad drive error",
 | 
			
		||||
		ERR_FILE_BAD_PATH: "File: Bad path error.",
 | 
			
		||||
		ERR_FILE_NO_PERMISSION: "File: No permission error.",
 | 
			
		||||
		ERR_FILE_ALREADY_IN_USE: "File: Already in use error.",
 | 
			
		||||
		ERR_FILE_CANT_OPEN: "File: Can't open error.",
 | 
			
		||||
		ERR_FILE_CANT_WRITE: "File: Can't write error.",
 | 
			
		||||
		ERR_FILE_CANT_READ: "File: Can't read error.",
 | 
			
		||||
		ERR_FILE_UNRECOGNIZED: "File: Unrecognized error.",
 | 
			
		||||
		ERR_FILE_CORRUPT: "File: Corrupt error.",
 | 
			
		||||
		ERR_FILE_MISSING_DEPENDENCIES: "File: Missing dependencies error.",
 | 
			
		||||
		ERR_FILE_EOF: "File: End of file (EOF) error."
 | 
			
		||||
	}
 | 
			
		||||
	if err in result_hash:
 | 
			
		||||
		print("Error: ", result_hash[err], " ", filepath)
 | 
			
		||||
	else:
 | 
			
		||||
		print("Unknown error with file ", filepath, " error code: ", err)
 | 
			
		||||
 | 
			
		||||
func loadfile(filepath, bytes = null):
 | 
			
		||||
	var file = null
 | 
			
		||||
	if bytes == null:
 | 
			
		||||
		file = FileAccess.open(filepath, FileAccess.READ)
 | 
			
		||||
		var err = file.get_error()
 | 
			
		||||
		if err != OK:
 | 
			
		||||
			report_errors(err, filepath)
 | 
			
		||||
			file.close()
 | 
			
		||||
			return AudioStreamWAV.new()
 | 
			
		||||
		bytes = file.get_buffer(file.get_length())
 | 
			
		||||
		
 | 
			
		||||
	# if File is wav
 | 
			
		||||
	if filepath.ends_with(".wav"):
 | 
			
		||||
		var newstream = AudioStreamWAV.new()
 | 
			
		||||
 | 
			
		||||
		#---------------------------
 | 
			
		||||
		#parrrrseeeeee!!! :D
 | 
			
		||||
		
 | 
			
		||||
		var bits_per_sample = 0
 | 
			
		||||
		
 | 
			
		||||
		for i in range(0, 100):
 | 
			
		||||
			var those4bytes = str(char(bytes[i])+char(bytes[i+1])+char(bytes[i+2])+char(bytes[i+3]))
 | 
			
		||||
			
 | 
			
		||||
			if those4bytes == "RIFF": 
 | 
			
		||||
				print ("RIFF OK at bytes " + str(i) + "-" + str(i+3))
 | 
			
		||||
				#RIP bytes 4-7 integer for now
 | 
			
		||||
			if those4bytes == "WAVE": 
 | 
			
		||||
				print ("WAVE OK at bytes " + str(i) + "-" + str(i+3))
 | 
			
		||||
 | 
			
		||||
			if those4bytes == "fmt ":
 | 
			
		||||
				print ("fmt OK at bytes " + str(i) + "-" + str(i+3))
 | 
			
		||||
				
 | 
			
		||||
				#get format subchunk size, 4 bytes next to "fmt " are an int32
 | 
			
		||||
				var formatsubchunksize = bytes[i+4] + (bytes[i+5] << 8) + (bytes[i+6] << 16) + (bytes[i+7] << 24)
 | 
			
		||||
				print ("Format subchunk size: " + str(formatsubchunksize))
 | 
			
		||||
				
 | 
			
		||||
				#using formatsubchunk index so it's easier to understand what's going on
 | 
			
		||||
				var fsc0 = i+8 #fsc0 is byte 8 after start of "fmt "
 | 
			
		||||
 | 
			
		||||
				#get format code [Bytes 0-1]
 | 
			
		||||
				var format_code = bytes[fsc0] + (bytes[fsc0+1] << 8)
 | 
			
		||||
				var format_name
 | 
			
		||||
				if format_code == 0: format_name = "8_BITS"
 | 
			
		||||
				elif format_code == 1: format_name = "16_BITS"
 | 
			
		||||
				elif format_code == 2: format_name = "IMA_ADPCM"
 | 
			
		||||
				else: 
 | 
			
		||||
					format_name = "UNKNOWN (trying to interpret as 16_BITS)"
 | 
			
		||||
					format_code = 1
 | 
			
		||||
				print ("Format: " + str(format_code) + " " + format_name)
 | 
			
		||||
				#assign format to our AudioStreamSample
 | 
			
		||||
				newstream.format = format_code
 | 
			
		||||
				
 | 
			
		||||
				#get channel num [Bytes 2-3]
 | 
			
		||||
				var channel_num = bytes[fsc0+2] + (bytes[fsc0+3] << 8)
 | 
			
		||||
				print ("Number of channels: " + str(channel_num))
 | 
			
		||||
				#set our AudioStreamSample to stereo if needed
 | 
			
		||||
				if channel_num == 2: newstream.stereo = true
 | 
			
		||||
				
 | 
			
		||||
				#get sample rate [Bytes 4-7]
 | 
			
		||||
				var sample_rate = bytes[fsc0+4] + (bytes[fsc0+5] << 8) + (bytes[fsc0+6] << 16) + (bytes[fsc0+7] << 24)
 | 
			
		||||
				print ("Sample rate: " + str(sample_rate))
 | 
			
		||||
				#set our AudioStreamSample mixrate
 | 
			
		||||
				newstream.mix_rate = sample_rate
 | 
			
		||||
				
 | 
			
		||||
				#get byte_rate [Bytes 8-11] because we can
 | 
			
		||||
				var byte_rate = bytes[fsc0+8] + (bytes[fsc0+9] << 8) + (bytes[fsc0+10] << 16) + (bytes[fsc0+11] << 24)
 | 
			
		||||
				print ("Byte rate: " + str(byte_rate))
 | 
			
		||||
				
 | 
			
		||||
				#same with bits*sample*channel [Bytes 12-13]
 | 
			
		||||
				var bits_sample_channel = bytes[fsc0+12] + (bytes[fsc0+13] << 8)
 | 
			
		||||
				print ("BitsPerSample * Channel / 8: " + str(bits_sample_channel))
 | 
			
		||||
				
 | 
			
		||||
				#aaaand bits per sample/bitrate [Bytes 14-15]
 | 
			
		||||
				bits_per_sample = bytes[fsc0+14] + (bytes[fsc0+15] << 8)
 | 
			
		||||
				print ("Bits per sample: " + str(bits_per_sample))
 | 
			
		||||
				
 | 
			
		||||
			if those4bytes == "data":
 | 
			
		||||
				assert(bits_per_sample != 0)
 | 
			
		||||
				
 | 
			
		||||
				var audio_data_size = bytes[i+4] + (bytes[i+5] << 8) + (bytes[i+6] << 16) + (bytes[i+7] << 24)
 | 
			
		||||
				print ("Audio data/stream size is " + str(audio_data_size) + " bytes")
 | 
			
		||||
 | 
			
		||||
				var data_entry_point = (i+8)
 | 
			
		||||
				print ("Audio data starts at byte " + str(data_entry_point))
 | 
			
		||||
				
 | 
			
		||||
				var data = bytes.slice(data_entry_point, data_entry_point + audio_data_size)
 | 
			
		||||
				
 | 
			
		||||
				if bits_per_sample in [24, 32]:
 | 
			
		||||
					newstream.data = convert_to_16bit(data, bits_per_sample)
 | 
			
		||||
				else:
 | 
			
		||||
					newstream.data = data
 | 
			
		||||
			# end of parsing
 | 
			
		||||
			#---------------------------
 | 
			
		||||
		
 | 
			
		||||
		#Calculate the size of each sample based on bits_per_sample
 | 
			
		||||
		var sample_size = bits_per_sample / 8
 | 
			
		||||
		#get samples and set loop end
 | 
			
		||||
		var samplenum = newstream.data.size() / sample_size
 | 
			
		||||
		newstream.loop_end = samplenum
 | 
			
		||||
		newstream.loop_mode = 0 #change to 0 or delete this line if you don't want loop, also check out modes 2 and 3 in the docs
 | 
			
		||||
		return newstream  #:D
 | 
			
		||||
 | 
			
		||||
	#if file is ogg
 | 
			
		||||
	elif filepath.ends_with(".ogg"):
 | 
			
		||||
		var newstream = AudioStreamOggVorbis.load_from_buffer(bytes)
 | 
			
		||||
		newstream.loop = true #set to false or delete this line if you don't want to loop
 | 
			
		||||
		return newstream
 | 
			
		||||
 | 
			
		||||
	#if file is mp3
 | 
			
		||||
	elif filepath.ends_with(".mp3"):
 | 
			
		||||
		var newstream = AudioStreamMP3.new()
 | 
			
		||||
		newstream.loop = true #set to false or delete this line if you don't want to loop
 | 
			
		||||
		newstream.data = bytes
 | 
			
		||||
		return newstream
 | 
			
		||||
 | 
			
		||||
	else:
 | 
			
		||||
		print ("ERROR: Wrong filetype or format")
 | 
			
		||||
	if file != null:
 | 
			
		||||
		file.close()
 | 
			
		||||
 | 
			
		||||
# Converts .wav data from 24 or 32 bits to 16
 | 
			
		||||
#
 | 
			
		||||
# These conversions are SLOW in GDScript
 | 
			
		||||
# on my one test song, 32 -> 16 was around 3x slower than 24 -> 16
 | 
			
		||||
#
 | 
			
		||||
# I couldn't get threads to help very much
 | 
			
		||||
# They made the 24bit case about 2x faster in my test file
 | 
			
		||||
# And the 32bit case abour 50% slower
 | 
			
		||||
# I don't wanna risk it always being slower on other files
 | 
			
		||||
# And really, the solution would be to handle it in a low-level language
 | 
			
		||||
func convert_to_16bit(data: PackedByteArray, from: int) -> PackedByteArray:
 | 
			
		||||
	print("converting to 16-bit from %d" % from)
 | 
			
		||||
	var time = Time.get_ticks_msec()
 | 
			
		||||
	if from == 24:
 | 
			
		||||
		var j = 0
 | 
			
		||||
		for i in range(0, data.size(), 3):
 | 
			
		||||
			data[j] = data[i+1]
 | 
			
		||||
			data[j+1] = data[i+2]
 | 
			
		||||
			j += 2
 | 
			
		||||
		data.resize(data.size() * 2 / 3)
 | 
			
		||||
	if from == 32:
 | 
			
		||||
		var spb := StreamPeerBuffer.new()
 | 
			
		||||
		var single_float: float
 | 
			
		||||
		var value: int
 | 
			
		||||
		for i in range(0, data.size(), 4):
 | 
			
		||||
			var sub_array = data.slice(i, i+4)
 | 
			
		||||
			spb.data_array = PackedByteArray(sub_array)
 | 
			
		||||
			single_float = spb.get_float()
 | 
			
		||||
			value = single_float * 32768
 | 
			
		||||
			data[i/2] = value
 | 
			
		||||
			data[i/2+1] = value >> 8
 | 
			
		||||
		data.resize(data.size() / 2)
 | 
			
		||||
	print("Took %f seconds for slow conversion" % ((Time.get_ticks_msec() - time) / 1000.0))
 | 
			
		||||
	return data
 | 
			
		||||
 | 
			
		||||
# ---------- REFERENCE ---------------
 | 
			
		||||
# note: typical values doesn't always match
 | 
			
		||||
 | 
			
		||||
#Positions  Typical Value Description
 | 
			
		||||
#
 | 
			
		||||
#1 - 4      "RIFF"        Marks the file as a RIFF multimedia file.
 | 
			
		||||
#                         Characters are each 1 byte long.
 | 
			
		||||
#
 | 
			
		||||
#5 - 8      (integer)     The overall file size in bytes (32-bit integer)
 | 
			
		||||
#                         minus 8 bytes. Typically, you'd fill this in after
 | 
			
		||||
#                         file creation is complete.
 | 
			
		||||
#
 | 
			
		||||
#9 - 12     "WAVE"        RIFF file format header. For our purposes, it
 | 
			
		||||
#                         always equals "WAVE".
 | 
			
		||||
#
 | 
			
		||||
#13-16      "fmt "        Format sub-chunk marker. Includes trailing null.
 | 
			
		||||
#
 | 
			
		||||
#17-20      16            Length of the rest of the format sub-chunk below.
 | 
			
		||||
#
 | 
			
		||||
#21-22      1             Audio format code, a 2 byte (16 bit) integer. 
 | 
			
		||||
#                         1 = PCM (pulse code modulation).
 | 
			
		||||
#
 | 
			
		||||
#23-24      2             Number of channels as a 2 byte (16 bit) integer.
 | 
			
		||||
#                         1 = mono, 2 = stereo, etc.
 | 
			
		||||
#
 | 
			
		||||
#25-28      44100         Sample rate as a 4 byte (32 bit) integer. Common
 | 
			
		||||
#                         values are 44100 (CD), 48000 (DAT). Sample rate =
 | 
			
		||||
#                         number of samples per second, or Hertz.
 | 
			
		||||
#
 | 
			
		||||
#29-32      176400        (SampleRate * BitsPerSample * Channels) / 8
 | 
			
		||||
#                         This is the Byte rate.
 | 
			
		||||
#
 | 
			
		||||
#33-34      4             (BitsPerSample * Channels) / 8
 | 
			
		||||
#                         1 = 8 bit mono, 2 = 8 bit stereo or 16 bit mono, 4
 | 
			
		||||
#                         = 16 bit stereo.
 | 
			
		||||
#
 | 
			
		||||
#35-36      16            Bits per sample. 
 | 
			
		||||
#
 | 
			
		||||
#37-40      "data"        Data sub-chunk header. Marks the beginning of the
 | 
			
		||||
#                         raw data section.
 | 
			
		||||
#
 | 
			
		||||
#41-44      (integer)     The number of bytes of the data section below this
 | 
			
		||||
#                         point. Also equal to (#ofSamples * #ofChannels *
 | 
			
		||||
#                         BitsPerSample) / 8
 | 
			
		||||
#
 | 
			
		||||
#45+                      The raw audio data.            
 | 
			
		||||
| 
						 | 
				
			
			@ -1,43 +0,0 @@
 | 
			
		|||
[preset.0]
 | 
			
		||||
 | 
			
		||||
name="Web"
 | 
			
		||||
platform="Web"
 | 
			
		||||
runnable=true
 | 
			
		||||
dedicated_server=false
 | 
			
		||||
custom_features=""
 | 
			
		||||
export_filter="all_resources"
 | 
			
		||||
include_filter=""
 | 
			
		||||
exclude_filter=""
 | 
			
		||||
export_path="dist/webxr/index.html"
 | 
			
		||||
encryption_include_filters=""
 | 
			
		||||
encryption_exclude_filters=""
 | 
			
		||||
encrypt_pck=false
 | 
			
		||||
encrypt_directory=false
 | 
			
		||||
 | 
			
		||||
[preset.0.options]
 | 
			
		||||
 | 
			
		||||
custom_template/debug=""
 | 
			
		||||
custom_template/release=""
 | 
			
		||||
variant/extensions_support=false
 | 
			
		||||
variant/thread_support=true
 | 
			
		||||
vram_texture_compression/for_desktop=true
 | 
			
		||||
vram_texture_compression/for_mobile=true
 | 
			
		||||
html/export_icon=true
 | 
			
		||||
html/custom_html_shell=""
 | 
			
		||||
html/head_include="<!--
 | 
			
		||||
<script src=\"https://cdn.jsdelivr.net/npm/webxr-polyfill@latest/build/webxr-polyfill.min.js\"></script>
 | 
			
		||||
<script>
 | 
			
		||||
var polyfill = new WebXRPolyfill();
 | 
			
		||||
</script>
 | 
			
		||||
-->"
 | 
			
		||||
html/canvas_resize_policy=2
 | 
			
		||||
html/focus_canvas_on_start=true
 | 
			
		||||
html/experimental_virtual_keyboard=false
 | 
			
		||||
progressive_web_app/enabled=false
 | 
			
		||||
progressive_web_app/offline_page=""
 | 
			
		||||
progressive_web_app/display=1
 | 
			
		||||
progressive_web_app/orientation=0
 | 
			
		||||
progressive_web_app/icon_144x144=""
 | 
			
		||||
progressive_web_app/icon_180x180=""
 | 
			
		||||
progressive_web_app/icon_512x512=""
 | 
			
		||||
progressive_web_app/background_color=Color(0, 0, 0, 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 950 B  | 
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
[remap]
 | 
			
		||||
 | 
			
		||||
importer="texture"
 | 
			
		||||
type="CompressedTexture2D"
 | 
			
		||||
uid="uid://ckn6pn505bam5"
 | 
			
		||||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
 | 
			
		||||
metadata={
 | 
			
		||||
"vram_texture": false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[deps]
 | 
			
		||||
 | 
			
		||||
source_file="res://icon.svg"
 | 
			
		||||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
 | 
			
		||||
 | 
			
		||||
[params]
 | 
			
		||||
 | 
			
		||||
compress/mode=0
 | 
			
		||||
compress/high_quality=false
 | 
			
		||||
compress/lossy_quality=0.7
 | 
			
		||||
compress/hdr_compression=1
 | 
			
		||||
compress/normal_map=0
 | 
			
		||||
compress/channel_pack=0
 | 
			
		||||
mipmaps/generate=false
 | 
			
		||||
mipmaps/limit=-1
 | 
			
		||||
roughness/mode=0
 | 
			
		||||
roughness/src_normal=""
 | 
			
		||||
process/fix_alpha_border=true
 | 
			
		||||
process/premult_alpha=false
 | 
			
		||||
process/normal_map_invert_y=false
 | 
			
		||||
process/hdr_as_srgb=false
 | 
			
		||||
process/hdr_clamp_exposure=false
 | 
			
		||||
process/size_limit=0
 | 
			
		||||
detect_3d/compress_to=1
 | 
			
		||||
svg/scale=1.0
 | 
			
		||||
editor/scale_with_editor_scale=false
 | 
			
		||||
editor/convert_colors_with_editor_theme=false
 | 
			
		||||
| 
						 | 
				
			
			@ -1,71 +0,0 @@
 | 
			
		|||
extends Node3D
 | 
			
		||||
 | 
			
		||||
var xr_interface: XRInterface
 | 
			
		||||
var xrf
 | 
			
		||||
var scene
 | 
			
		||||
var player:CharacterBody3D
 | 
			
		||||
 | 
			
		||||
func _ready():
 | 
			
		||||
	xrf = preload("res://xrfragment.gd").new()
 | 
			
		||||
 | 
			
		||||
	# browser extensions       src regex   handler func
 | 
			
		||||
	#                          ----------  -------------
 | 
			
		||||
	xrf.src.addExtension.call("^#",        xrf.src.model ) # enable internal embeds
 | 
			
		||||
	xrf.src.addExtension.call(".*\\.glb",  xrf.src.model ) # enable external embeds
 | 
			
		||||
	xrf.src.addExtension.call(".*\\.gltf", xrf.src.model ) # 
 | 
			
		||||
	xrf.src.addExtension.call(".*\\.wav$", xrf.src.audio ) # 
 | 
			
		||||
	xrf.src.addExtension.call(".*\\.ogg$", xrf.src.audio ) # 
 | 
			
		||||
	xrf.src.addExtension.call(".*\\.mp3$", xrf.src.audio ) # 
 | 
			
		||||
	
 | 
			
		||||
	add_child(xrf)
 | 
			
		||||
	xrf.to("https://xrfragment.org/other.glb", _onXRF )
 | 
			
		||||
	player = find_child("PlayerBody")  # optional: use PlayerBody from godot-xr-tools
 | 
			
		||||
	player.enabled = false             # optional: turn off gravity
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _onXRF(event:String,data ):
 | 
			
		||||
	if event == "scene_loaded":
 | 
			
		||||
		scene = data
 | 
			
		||||
	if event == 'href':
 | 
			
		||||
		print(data)
 | 
			
		||||
	if event == 'src':
 | 
			
		||||
		print(data)	
 | 
			
		||||
	if event == 'teleport':
 | 
			
		||||
		print("teleport!")
 | 
			
		||||
		#player.teleport( data )    # optional: use PlayerBody
 | 
			
		||||
		find_child("XROrigin3D").position = data.origin
 | 
			
		||||
 | 
			
		||||
	# update URL bar
 | 
			
		||||
	# spec 4 @ https://xrfragment.org/doc/RFC_XR_Fragments.html#navigating-content-href-portals
 | 
			
		||||
	var URLbar:RichTextLabel = find_child("URLbar")
 | 
			
		||||
	URLbar.text = xrf.URI.string
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func _input(event):  		
 | 
			
		||||
	var cam = find_child("XRCamera3D")
 | 
			
		||||
	if event is InputEventMouseMotion:
 | 
			
		||||
		var mouse_sens = 0.3
 | 
			
		||||
		cam.rotate_y(deg_to_rad(-event.relative.x*mouse_sens))
 | 
			
		||||
	if event is InputEventMouseButton and event.pressed:
 | 
			
		||||
		if event.button_index == 2:
 | 
			
		||||
			xrf.back()
 | 
			
		||||
			
 | 
			
		||||
		if event.button_index == 3:
 | 
			
		||||
			xrf.forward()
 | 
			
		||||
			
 | 
			
		||||
		if event.button_index == 1:
 | 
			
		||||
			# raycast to detect clicked item
 | 
			
		||||
			var mouse_pos = get_viewport().get_mouse_position()
 | 
			
		||||
			var from = cam.project_ray_origin(mouse_pos)
 | 
			
		||||
			var to = from + cam.project_ray_normal(mouse_pos) * 20000 #200
 | 
			
		||||
			var space_state = get_world_3d().direct_space_state
 | 
			
		||||
			var handle_query = PhysicsRayQueryParameters3D.create(from, to)
 | 
			
		||||
			handle_query.collide_with_areas = true
 | 
			
		||||
			var mesh_query = PhysicsRayQueryParameters3D.create(from, to)
 | 
			
		||||
			mesh_query.collide_with_areas = true
 | 
			
		||||
			var intersectMesh   = space_state.intersect_ray(mesh_query)
 | 
			
		||||
			var intersectHandle = space_state.intersect_ray(handle_query)
 | 
			
		||||
			if intersectMesh.has('collider'):
 | 
			
		||||
				xrf.traverse( intersectMesh.collider, xrf.href.click )	
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			@ -1,57 +0,0 @@
 | 
			
		|||
[gd_scene load_steps=8 format=3 uid="uid://cgjxim2x47n6g"]
 | 
			
		||||
 | 
			
		||||
[ext_resource type="Script" path="res://main.gd" id="1_oabt8"]
 | 
			
		||||
[ext_resource type="PackedScene" uid="uid://bq86r4yll8po" path="res://addons/godot-xr-tools/hands/scenes/lowpoly/left_fullglove_low.tscn" id="2_nv01r"]
 | 
			
		||||
[ext_resource type="PackedScene" uid="uid://bl2nuu3qhlb5k" path="res://addons/godot-xr-tools/functions/movement_direct.tscn" id="3_xxgqa"]
 | 
			
		||||
[ext_resource type="PackedScene" uid="uid://xqimcf20s2jp" path="res://addons/godot-xr-tools/hands/scenes/lowpoly/right_fullglove_low.tscn" id="4_i4b8r"]
 | 
			
		||||
[ext_resource type="PackedScene" uid="uid://b6bk2pj8vbj28" path="res://addons/godot-xr-tools/functions/movement_turn.tscn" id="5_pyrq4"]
 | 
			
		||||
[ext_resource type="PackedScene" uid="uid://diyu06cw06syv" path="res://addons/godot-xr-tools/player/player_body.tscn" id="6_kfmth"]
 | 
			
		||||
[ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="8_htpay"]
 | 
			
		||||
 | 
			
		||||
[node name="Main" type="Node3D"]
 | 
			
		||||
script = ExtResource("1_oabt8")
 | 
			
		||||
 | 
			
		||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
 | 
			
		||||
transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
 | 
			
		||||
shadow_enabled = true
 | 
			
		||||
 | 
			
		||||
[node name="XROrigin3D" type="XROrigin3D" parent="."]
 | 
			
		||||
 | 
			
		||||
[node name="XRCamera3D" type="XRCamera3D" parent="XROrigin3D"]
 | 
			
		||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.7, 0)
 | 
			
		||||
 | 
			
		||||
[node name="URLbar" type="RichTextLabel" parent="XROrigin3D/XRCamera3D"]
 | 
			
		||||
modulate = Color(0, 0, 0, 1)
 | 
			
		||||
offset_left = 20.0
 | 
			
		||||
offset_top = 20.0
 | 
			
		||||
offset_right = 1171.0
 | 
			
		||||
offset_bottom = 136.0
 | 
			
		||||
scale = Vector2(1.2, 1.2)
 | 
			
		||||
scroll_active = false
 | 
			
		||||
 | 
			
		||||
[node name="LeftHand" type="XRController3D" parent="XROrigin3D"]
 | 
			
		||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0, 0)
 | 
			
		||||
tracker = &"left_hand"
 | 
			
		||||
 | 
			
		||||
[node name="LeftHand" parent="XROrigin3D/LeftHand" instance=ExtResource("2_nv01r")]
 | 
			
		||||
 | 
			
		||||
[node name="MovementDirect" parent="XROrigin3D/LeftHand" instance=ExtResource("3_xxgqa")]
 | 
			
		||||
strafe = true
 | 
			
		||||
input_action = "thumbstick"
 | 
			
		||||
 | 
			
		||||
[node name="RightHand" type="XRController3D" parent="XROrigin3D"]
 | 
			
		||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0)
 | 
			
		||||
tracker = &"right_hand"
 | 
			
		||||
 | 
			
		||||
[node name="RightHand" parent="XROrigin3D/RightHand" instance=ExtResource("4_i4b8r")]
 | 
			
		||||
 | 
			
		||||
[node name="MovementDirect" parent="XROrigin3D/RightHand" instance=ExtResource("3_xxgqa")]
 | 
			
		||||
input_action = "thumbstick"
 | 
			
		||||
 | 
			
		||||
[node name="MovementTurn" parent="XROrigin3D/RightHand" instance=ExtResource("5_pyrq4")]
 | 
			
		||||
input_action = "thumbstick"
 | 
			
		||||
 | 
			
		||||
[node name="PlayerBody" parent="XROrigin3D" instance=ExtResource("6_kfmth")]
 | 
			
		||||
visible = false
 | 
			
		||||
 | 
			
		||||
[node name="StartXR" parent="." instance=ExtResource("8_htpay")]
 | 
			
		||||
| 
						 | 
				
			
			@ -1,885 +0,0 @@
 | 
			
		|||
[gd_resource type="OpenXRActionMap" load_steps=210 format=3 uid="uid://dsj24l7qnotcy"]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_p1qbu"]
 | 
			
		||||
resource_name = "trigger"
 | 
			
		||||
localized_name = "Trigger"
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_h1q76"]
 | 
			
		||||
resource_name = "trigger_click"
 | 
			
		||||
localized_name = "Trigger click"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_40uyl"]
 | 
			
		||||
resource_name = "trigger_touch"
 | 
			
		||||
localized_name = "Trigger touching"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_fi72f"]
 | 
			
		||||
resource_name = "grip"
 | 
			
		||||
localized_name = "Grip"
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_txhvr"]
 | 
			
		||||
resource_name = "grip_click"
 | 
			
		||||
localized_name = "Grip click"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_jx75s"]
 | 
			
		||||
resource_name = "grip_force"
 | 
			
		||||
localized_name = "Grip force"
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_ukvk2"]
 | 
			
		||||
resource_name = "primary"
 | 
			
		||||
localized_name = "Primary joystick/thumbstick/trackpad"
 | 
			
		||||
action_type = 2
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_6dqlo"]
 | 
			
		||||
resource_name = "primary_click"
 | 
			
		||||
localized_name = "Primary joystick/thumbstick/trackpad click"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_vyrot"]
 | 
			
		||||
resource_name = "primary_touch"
 | 
			
		||||
localized_name = "Primary joystick/thumbstick/trackpad touching"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_mavp1"]
 | 
			
		||||
resource_name = "secondary"
 | 
			
		||||
localized_name = "Secondary joystick/thumbstick/trackpad"
 | 
			
		||||
action_type = 2
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_0tp8j"]
 | 
			
		||||
resource_name = "secondary_click"
 | 
			
		||||
localized_name = "Secondary joystick/thumbstick/trackpad click"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_doiqt"]
 | 
			
		||||
resource_name = "secondary_touch"
 | 
			
		||||
localized_name = "Secondary joystick/thumbstick/trackpad touching"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_w7yf6"]
 | 
			
		||||
resource_name = "menu_button"
 | 
			
		||||
localized_name = "Menu button"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_wgxqk"]
 | 
			
		||||
resource_name = "select_button"
 | 
			
		||||
localized_name = "Select button"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_pnd64"]
 | 
			
		||||
resource_name = "ax_button"
 | 
			
		||||
localized_name = "A/X button"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_do38y"]
 | 
			
		||||
resource_name = "ax_touch"
 | 
			
		||||
localized_name = "A/X touching"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_uwjrj"]
 | 
			
		||||
resource_name = "by_button"
 | 
			
		||||
localized_name = "B/Y button"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_shsmx"]
 | 
			
		||||
resource_name = "by_touch"
 | 
			
		||||
localized_name = "B/Y touching"
 | 
			
		||||
action_type = 0
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_7fi81"]
 | 
			
		||||
resource_name = "default_pose"
 | 
			
		||||
localized_name = "Default pose"
 | 
			
		||||
action_type = 3
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right", "/user/vive_tracker_htcx/role/left_foot", "/user/vive_tracker_htcx/role/right_foot", "/user/vive_tracker_htcx/role/left_shoulder", "/user/vive_tracker_htcx/role/right_shoulder", "/user/vive_tracker_htcx/role/left_elbow", "/user/vive_tracker_htcx/role/right_elbow", "/user/vive_tracker_htcx/role/left_knee", "/user/vive_tracker_htcx/role/right_knee", "/user/vive_tracker_htcx/role/waist", "/user/vive_tracker_htcx/role/chest", "/user/vive_tracker_htcx/role/camera", "/user/vive_tracker_htcx/role/keyboard", "/user/eyes_ext")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_ft0mk"]
 | 
			
		||||
resource_name = "aim_pose"
 | 
			
		||||
localized_name = "Aim pose"
 | 
			
		||||
action_type = 3
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_itk60"]
 | 
			
		||||
resource_name = "grip_pose"
 | 
			
		||||
localized_name = "Grip pose"
 | 
			
		||||
action_type = 3
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_fi2yi"]
 | 
			
		||||
resource_name = "palm_pose"
 | 
			
		||||
localized_name = "Palm pose"
 | 
			
		||||
action_type = 3
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRAction" id="OpenXRAction_ks6w8"]
 | 
			
		||||
resource_name = "haptic"
 | 
			
		||||
localized_name = "Haptic"
 | 
			
		||||
action_type = 4
 | 
			
		||||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right", "/user/vive_tracker_htcx/role/left_foot", "/user/vive_tracker_htcx/role/right_foot", "/user/vive_tracker_htcx/role/left_shoulder", "/user/vive_tracker_htcx/role/right_shoulder", "/user/vive_tracker_htcx/role/left_elbow", "/user/vive_tracker_htcx/role/right_elbow", "/user/vive_tracker_htcx/role/left_knee", "/user/vive_tracker_htcx/role/right_knee", "/user/vive_tracker_htcx/role/waist", "/user/vive_tracker_htcx/role/chest", "/user/vive_tracker_htcx/role/camera", "/user/vive_tracker_htcx/role/keyboard")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRActionSet" id="OpenXRActionSet_0o34d"]
 | 
			
		||||
resource_name = "godot"
 | 
			
		||||
localized_name = "Godot action set"
 | 
			
		||||
actions = [SubResource("OpenXRAction_p1qbu"), SubResource("OpenXRAction_h1q76"), SubResource("OpenXRAction_40uyl"), SubResource("OpenXRAction_fi72f"), SubResource("OpenXRAction_txhvr"), SubResource("OpenXRAction_jx75s"), SubResource("OpenXRAction_ukvk2"), SubResource("OpenXRAction_6dqlo"), SubResource("OpenXRAction_vyrot"), SubResource("OpenXRAction_mavp1"), SubResource("OpenXRAction_0tp8j"), SubResource("OpenXRAction_doiqt"), SubResource("OpenXRAction_w7yf6"), SubResource("OpenXRAction_wgxqk"), SubResource("OpenXRAction_pnd64"), SubResource("OpenXRAction_do38y"), SubResource("OpenXRAction_uwjrj"), SubResource("OpenXRAction_shsmx"), SubResource("OpenXRAction_7fi81"), SubResource("OpenXRAction_ft0mk"), SubResource("OpenXRAction_itk60"), SubResource("OpenXRAction_fi2yi"), SubResource("OpenXRAction_ks6w8")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_k5fcj"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ey06d"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1oumt"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_rjohw"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fl58m"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_bm1u6"]
 | 
			
		||||
action = SubResource("OpenXRAction_wgxqk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/select/click", "/user/hand/right/input/select/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4xtk0"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_iyv21"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/khr/simple_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_k5fcj"), SubResource("OpenXRIPBinding_ey06d"), SubResource("OpenXRIPBinding_1oumt"), SubResource("OpenXRIPBinding_rjohw"), SubResource("OpenXRIPBinding_fl58m"), SubResource("OpenXRIPBinding_bm1u6"), SubResource("OpenXRIPBinding_4xtk0")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_a1bbd"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jygrk"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ytxa7"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jq563"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_rucv7"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_574s5"]
 | 
			
		||||
action = SubResource("OpenXRAction_wgxqk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/system/click", "/user/hand/right/input/system/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_abvxo"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_44kn7"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_mlnp3"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_xkx17"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_rdhyh"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4yn8i"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/click", "/user/hand/right/input/trackpad/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ns68t"]
 | 
			
		||||
action = SubResource("OpenXRAction_vyrot")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5am2b"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_jyjt5"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/htc/vive_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_a1bbd"), SubResource("OpenXRIPBinding_jygrk"), SubResource("OpenXRIPBinding_ytxa7"), SubResource("OpenXRIPBinding_jq563"), SubResource("OpenXRIPBinding_rucv7"), SubResource("OpenXRIPBinding_574s5"), SubResource("OpenXRIPBinding_abvxo"), SubResource("OpenXRIPBinding_44kn7"), SubResource("OpenXRIPBinding_mlnp3"), SubResource("OpenXRIPBinding_xkx17"), SubResource("OpenXRIPBinding_rdhyh"), SubResource("OpenXRIPBinding_4yn8i"), SubResource("OpenXRIPBinding_ns68t"), SubResource("OpenXRIPBinding_5am2b")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_spkfk"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_cc1ht"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_300ah"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_6olt8"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nmird"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ntp2l"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_2qefk"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_m1qhd"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_6o3ow"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_u2bvt"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qksqt"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fgkr4"]
 | 
			
		||||
action = SubResource("OpenXRAction_mavp1")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_441qa"]
 | 
			
		||||
action = SubResource("OpenXRAction_0tp8j")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/click", "/user/hand/right/input/trackpad/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_dmu24"]
 | 
			
		||||
action = SubResource("OpenXRAction_doiqt")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ttkyt"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_jlls3"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/microsoft/motion_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_spkfk"), SubResource("OpenXRIPBinding_cc1ht"), SubResource("OpenXRIPBinding_300ah"), SubResource("OpenXRIPBinding_6olt8"), SubResource("OpenXRIPBinding_nmird"), SubResource("OpenXRIPBinding_ntp2l"), SubResource("OpenXRIPBinding_2qefk"), SubResource("OpenXRIPBinding_m1qhd"), SubResource("OpenXRIPBinding_6o3ow"), SubResource("OpenXRIPBinding_u2bvt"), SubResource("OpenXRIPBinding_qksqt"), SubResource("OpenXRIPBinding_fgkr4"), SubResource("OpenXRIPBinding_441qa"), SubResource("OpenXRIPBinding_dmu24"), SubResource("OpenXRIPBinding_ttkyt")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_0aylh"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4ftgx"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1cj81"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fwdkc"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_d31r8"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/system/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_64nbn"]
 | 
			
		||||
action = SubResource("OpenXRAction_pnd64")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_js0u8"]
 | 
			
		||||
action = SubResource("OpenXRAction_do38y")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/x/touch", "/user/hand/right/input/a/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_v5te4"]
 | 
			
		||||
action = SubResource("OpenXRAction_uwjrj")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_yt2f7"]
 | 
			
		||||
action = SubResource("OpenXRAction_shsmx")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/y/touch", "/user/hand/right/input/b/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_n1a64"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_p1odw"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_imvcy"]
 | 
			
		||||
action = SubResource("OpenXRAction_40uyl")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_uem2u"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_16xmt"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_hj2qy"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_kdl7p"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7o3u7"]
 | 
			
		||||
action = SubResource("OpenXRAction_vyrot")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qvxpc"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_272e4"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/oculus/touch_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_0aylh"), SubResource("OpenXRIPBinding_4ftgx"), SubResource("OpenXRIPBinding_1cj81"), SubResource("OpenXRIPBinding_fwdkc"), SubResource("OpenXRIPBinding_d31r8"), SubResource("OpenXRIPBinding_64nbn"), SubResource("OpenXRIPBinding_js0u8"), SubResource("OpenXRIPBinding_v5te4"), SubResource("OpenXRIPBinding_yt2f7"), SubResource("OpenXRIPBinding_n1a64"), SubResource("OpenXRIPBinding_p1odw"), SubResource("OpenXRIPBinding_imvcy"), SubResource("OpenXRIPBinding_uem2u"), SubResource("OpenXRIPBinding_16xmt"), SubResource("OpenXRIPBinding_hj2qy"), SubResource("OpenXRIPBinding_kdl7p"), SubResource("OpenXRIPBinding_7o3u7"), SubResource("OpenXRIPBinding_qvxpc")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7d8kg"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pdpqc"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_vrx1l"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_exs0w"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_sc1qa"]
 | 
			
		||||
action = SubResource("OpenXRAction_wgxqk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/system/click", "/user/hand/right/input/system/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4450r"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_is30e"]
 | 
			
		||||
action = SubResource("OpenXRAction_pnd64")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_kbg0k"]
 | 
			
		||||
action = SubResource("OpenXRAction_do38y")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/x/touch", "/user/hand/right/input/a/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ink3t"]
 | 
			
		||||
action = SubResource("OpenXRAction_uwjrj")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_03gqq"]
 | 
			
		||||
action = SubResource("OpenXRAction_shsmx")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/y/touch", "/user/hand/right/input/b/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_t6po4"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_t064u"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5ppsb"]
 | 
			
		||||
action = SubResource("OpenXRAction_40uyl")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_e6ahd"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nsv78"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jcp55"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_3ols2"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5fk30"]
 | 
			
		||||
action = SubResource("OpenXRAction_vyrot")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fitxy"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_t5wvy"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/bytedance/pico4_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_7d8kg"), SubResource("OpenXRIPBinding_pdpqc"), SubResource("OpenXRIPBinding_vrx1l"), SubResource("OpenXRIPBinding_exs0w"), SubResource("OpenXRIPBinding_sc1qa"), SubResource("OpenXRIPBinding_4450r"), SubResource("OpenXRIPBinding_is30e"), SubResource("OpenXRIPBinding_kbg0k"), SubResource("OpenXRIPBinding_ink3t"), SubResource("OpenXRIPBinding_03gqq"), SubResource("OpenXRIPBinding_t6po4"), SubResource("OpenXRIPBinding_t064u"), SubResource("OpenXRIPBinding_5ppsb"), SubResource("OpenXRIPBinding_e6ahd"), SubResource("OpenXRIPBinding_nsv78"), SubResource("OpenXRIPBinding_jcp55"), SubResource("OpenXRIPBinding_3ols2"), SubResource("OpenXRIPBinding_5fk30"), SubResource("OpenXRIPBinding_fitxy")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_yfah0"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_r81sm"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jnxl5"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ggi8y"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gyvyi"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/system/click", "/user/hand/right/input/system/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ydsle"]
 | 
			
		||||
action = SubResource("OpenXRAction_pnd64")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/a/click", "/user/hand/right/input/a/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_x7dm0"]
 | 
			
		||||
action = SubResource("OpenXRAction_do38y")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/a/touch", "/user/hand/right/input/a/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_dy53c"]
 | 
			
		||||
action = SubResource("OpenXRAction_uwjrj")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/b/click", "/user/hand/right/input/b/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qiayg"]
 | 
			
		||||
action = SubResource("OpenXRAction_shsmx")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/b/touch", "/user/hand/right/input/b/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_p1t5k"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5j67o"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gr8j7"]
 | 
			
		||||
action = SubResource("OpenXRAction_40uyl")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_spqqg"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_l7kv6"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_b1vi2"]
 | 
			
		||||
action = SubResource("OpenXRAction_jx75s")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/force", "/user/hand/right/input/squeeze/force")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jkrbd"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_2th34"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jmeka"]
 | 
			
		||||
action = SubResource("OpenXRAction_vyrot")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gfsia"]
 | 
			
		||||
action = SubResource("OpenXRAction_mavp1")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_j8prd"]
 | 
			
		||||
action = SubResource("OpenXRAction_0tp8j")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/force", "/user/hand/right/input/trackpad/force")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4vquj"]
 | 
			
		||||
action = SubResource("OpenXRAction_doiqt")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4hbrf"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_qc6pb"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/valve/index_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_yfah0"), SubResource("OpenXRIPBinding_r81sm"), SubResource("OpenXRIPBinding_jnxl5"), SubResource("OpenXRIPBinding_ggi8y"), SubResource("OpenXRIPBinding_gyvyi"), SubResource("OpenXRIPBinding_ydsle"), SubResource("OpenXRIPBinding_x7dm0"), SubResource("OpenXRIPBinding_dy53c"), SubResource("OpenXRIPBinding_qiayg"), SubResource("OpenXRIPBinding_p1t5k"), SubResource("OpenXRIPBinding_5j67o"), SubResource("OpenXRIPBinding_gr8j7"), SubResource("OpenXRIPBinding_spqqg"), SubResource("OpenXRIPBinding_l7kv6"), SubResource("OpenXRIPBinding_b1vi2"), SubResource("OpenXRIPBinding_jkrbd"), SubResource("OpenXRIPBinding_2th34"), SubResource("OpenXRIPBinding_jmeka"), SubResource("OpenXRIPBinding_gfsia"), SubResource("OpenXRIPBinding_j8prd"), SubResource("OpenXRIPBinding_4vquj"), SubResource("OpenXRIPBinding_4hbrf")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_bmlpa"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_l7u44"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_cc2t1"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_f6okh"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_xjlsb"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_3pfvl"]
 | 
			
		||||
action = SubResource("OpenXRAction_pnd64")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_i1xfm"]
 | 
			
		||||
action = SubResource("OpenXRAction_uwjrj")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_r2wyp"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_6vane"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_yah5k"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1drk4"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5k8hr"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4jbot"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4lb7a"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_tlptw"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/hp/mixed_reality_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_bmlpa"), SubResource("OpenXRIPBinding_l7u44"), SubResource("OpenXRIPBinding_cc2t1"), SubResource("OpenXRIPBinding_f6okh"), SubResource("OpenXRIPBinding_xjlsb"), SubResource("OpenXRIPBinding_3pfvl"), SubResource("OpenXRIPBinding_i1xfm"), SubResource("OpenXRIPBinding_r2wyp"), SubResource("OpenXRIPBinding_6vane"), SubResource("OpenXRIPBinding_yah5k"), SubResource("OpenXRIPBinding_1drk4"), SubResource("OpenXRIPBinding_5k8hr"), SubResource("OpenXRIPBinding_4jbot"), SubResource("OpenXRIPBinding_4lb7a")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ffiu3"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_cs63x"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_lex3e"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pueu6"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_t641s"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_kkww7"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gsx12"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_bv52h"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_bwcsr"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_chf2t"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_82lhq"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fqj0f"]
 | 
			
		||||
action = SubResource("OpenXRAction_mavp1")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_2evvu"]
 | 
			
		||||
action = SubResource("OpenXRAction_0tp8j")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/click", "/user/hand/right/input/trackpad/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gt5qs"]
 | 
			
		||||
action = SubResource("OpenXRAction_doiqt")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_45ux7"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_ifqou"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/samsung/odyssey_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_ffiu3"), SubResource("OpenXRIPBinding_cs63x"), SubResource("OpenXRIPBinding_lex3e"), SubResource("OpenXRIPBinding_pueu6"), SubResource("OpenXRIPBinding_t641s"), SubResource("OpenXRIPBinding_kkww7"), SubResource("OpenXRIPBinding_gsx12"), SubResource("OpenXRIPBinding_bv52h"), SubResource("OpenXRIPBinding_bwcsr"), SubResource("OpenXRIPBinding_chf2t"), SubResource("OpenXRIPBinding_82lhq"), SubResource("OpenXRIPBinding_fqj0f"), SubResource("OpenXRIPBinding_2evvu"), SubResource("OpenXRIPBinding_gt5qs"), SubResource("OpenXRIPBinding_45ux7")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_h4qcu"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_lw1j0"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_wiafw"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_d2xjr"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_cxr63"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fjggq"]
 | 
			
		||||
action = SubResource("OpenXRAction_wgxqk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/right/input/system/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_cm6vh"]
 | 
			
		||||
action = SubResource("OpenXRAction_pnd64")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_dx68f"]
 | 
			
		||||
action = SubResource("OpenXRAction_uwjrj")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_uyw0x"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_h3xr1"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_05yod"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_c43jn"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_xlqlb"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_c27oe"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fqi1x"]
 | 
			
		||||
action = SubResource("OpenXRAction_vyrot")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ifotl"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_vq5vi"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/htc/vive_cosmos_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_h4qcu"), SubResource("OpenXRIPBinding_lw1j0"), SubResource("OpenXRIPBinding_wiafw"), SubResource("OpenXRIPBinding_d2xjr"), SubResource("OpenXRIPBinding_cxr63"), SubResource("OpenXRIPBinding_fjggq"), SubResource("OpenXRIPBinding_cm6vh"), SubResource("OpenXRIPBinding_dx68f"), SubResource("OpenXRIPBinding_uyw0x"), SubResource("OpenXRIPBinding_h3xr1"), SubResource("OpenXRIPBinding_05yod"), SubResource("OpenXRIPBinding_c43jn"), SubResource("OpenXRIPBinding_xlqlb"), SubResource("OpenXRIPBinding_c27oe"), SubResource("OpenXRIPBinding_fqi1x"), SubResource("OpenXRIPBinding_ifotl")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_e01yu"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_232it"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_642ln"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ryfrm"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_j4rhg"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/menu/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fdi6k"]
 | 
			
		||||
action = SubResource("OpenXRAction_wgxqk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/right/input/system/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ec5dv"]
 | 
			
		||||
action = SubResource("OpenXRAction_pnd64")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ac8c6"]
 | 
			
		||||
action = SubResource("OpenXRAction_uwjrj")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ovu4a"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_i14pk"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ixdk0"]
 | 
			
		||||
action = SubResource("OpenXRAction_40uyl")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_355ex"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi72f")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_80df3"]
 | 
			
		||||
action = SubResource("OpenXRAction_txhvr")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_138lw"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ti78g"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_c2f8l"]
 | 
			
		||||
action = SubResource("OpenXRAction_vyrot")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_mrsyu"]
 | 
			
		||||
action = SubResource("OpenXRAction_doiqt")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/thumbrest/touch", "/user/hand/right/input/thumbrest/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7ufh4"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_mapo7"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/htc/vive_focus3_controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_e01yu"), SubResource("OpenXRIPBinding_232it"), SubResource("OpenXRIPBinding_642ln"), SubResource("OpenXRIPBinding_ryfrm"), SubResource("OpenXRIPBinding_j4rhg"), SubResource("OpenXRIPBinding_fdi6k"), SubResource("OpenXRIPBinding_ec5dv"), SubResource("OpenXRIPBinding_ac8c6"), SubResource("OpenXRIPBinding_ovu4a"), SubResource("OpenXRIPBinding_i14pk"), SubResource("OpenXRIPBinding_ixdk0"), SubResource("OpenXRIPBinding_355ex"), SubResource("OpenXRIPBinding_80df3"), SubResource("OpenXRIPBinding_138lw"), SubResource("OpenXRIPBinding_ti78g"), SubResource("OpenXRIPBinding_c2f8l"), SubResource("OpenXRIPBinding_mrsyu"), SubResource("OpenXRIPBinding_7ufh4")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nuiab"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_3afjt"]
 | 
			
		||||
action = SubResource("OpenXRAction_ft0mk")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_wg7tk"]
 | 
			
		||||
action = SubResource("OpenXRAction_itk60")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_3gya4"]
 | 
			
		||||
action = SubResource("OpenXRAction_fi2yi")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nresw"]
 | 
			
		||||
action = SubResource("OpenXRAction_w7yf6")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/home/click", "/user/hand/right/input/home/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gih0u"]
 | 
			
		||||
action = SubResource("OpenXRAction_p1qbu")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_voccd"]
 | 
			
		||||
action = SubResource("OpenXRAction_h1q76")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1tf0b"]
 | 
			
		||||
action = SubResource("OpenXRAction_ukvk2")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fvi1f"]
 | 
			
		||||
action = SubResource("OpenXRAction_6dqlo")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/click", "/user/hand/right/input/trackpad/click")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_y7qt8"]
 | 
			
		||||
action = SubResource("OpenXRAction_vyrot")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qdakj"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_1ueyw"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/huawei/controller"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_nuiab"), SubResource("OpenXRIPBinding_3afjt"), SubResource("OpenXRIPBinding_wg7tk"), SubResource("OpenXRIPBinding_3gya4"), SubResource("OpenXRIPBinding_nresw"), SubResource("OpenXRIPBinding_gih0u"), SubResource("OpenXRIPBinding_voccd"), SubResource("OpenXRIPBinding_1tf0b"), SubResource("OpenXRIPBinding_fvi1f"), SubResource("OpenXRIPBinding_y7qt8"), SubResource("OpenXRIPBinding_qdakj")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nusr4"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/vive_tracker_htcx/role/left_foot/input/grip/pose", "/user/vive_tracker_htcx/role/right_foot/input/grip/pose", "/user/vive_tracker_htcx/role/left_shoulder/input/grip/pose", "/user/vive_tracker_htcx/role/right_shoulder/input/grip/pose", "/user/vive_tracker_htcx/role/left_elbow/input/grip/pose", "/user/vive_tracker_htcx/role/right_elbow/input/grip/pose", "/user/vive_tracker_htcx/role/left_knee/input/grip/pose", "/user/vive_tracker_htcx/role/right_knee/input/grip/pose", "/user/vive_tracker_htcx/role/waist/input/grip/pose", "/user/vive_tracker_htcx/role/chest/input/grip/pose", "/user/vive_tracker_htcx/role/camera/input/grip/pose", "/user/vive_tracker_htcx/role/keyboard/input/grip/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gkfwb"]
 | 
			
		||||
action = SubResource("OpenXRAction_ks6w8")
 | 
			
		||||
paths = PackedStringArray("/user/vive_tracker_htcx/role/left_foot/output/haptic", "/user/vive_tracker_htcx/role/right_foot/output/haptic", "/user/vive_tracker_htcx/role/left_shoulder/output/haptic", "/user/vive_tracker_htcx/role/right_shoulder/output/haptic", "/user/vive_tracker_htcx/role/left_elbow/output/haptic", "/user/vive_tracker_htcx/role/right_elbow/output/haptic", "/user/vive_tracker_htcx/role/left_knee/output/haptic", "/user/vive_tracker_htcx/role/right_knee/output/haptic", "/user/vive_tracker_htcx/role/waist/output/haptic", "/user/vive_tracker_htcx/role/chest/output/haptic", "/user/vive_tracker_htcx/role/camera/output/haptic", "/user/vive_tracker_htcx/role/keyboard/output/haptic")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_5qbto"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/htc/vive_tracker_htcx"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_nusr4"), SubResource("OpenXRIPBinding_gkfwb")]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_hhjas"]
 | 
			
		||||
action = SubResource("OpenXRAction_7fi81")
 | 
			
		||||
paths = PackedStringArray("/user/eyes_ext/input/gaze_ext/pose")
 | 
			
		||||
 | 
			
		||||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_ska4h"]
 | 
			
		||||
interaction_profile_path = "/interaction_profiles/ext/eye_gaze_interaction"
 | 
			
		||||
bindings = [SubResource("OpenXRIPBinding_hhjas")]
 | 
			
		||||
 | 
			
		||||
[resource]
 | 
			
		||||
action_sets = [SubResource("OpenXRActionSet_0o34d")]
 | 
			
		||||
interaction_profiles = [SubResource("OpenXRInteractionProfile_iyv21"), SubResource("OpenXRInteractionProfile_jyjt5"), SubResource("OpenXRInteractionProfile_jlls3"), SubResource("OpenXRInteractionProfile_272e4"), SubResource("OpenXRInteractionProfile_t5wvy"), SubResource("OpenXRInteractionProfile_qc6pb"), SubResource("OpenXRInteractionProfile_tlptw"), SubResource("OpenXRInteractionProfile_ifqou"), SubResource("OpenXRInteractionProfile_vq5vi"), SubResource("OpenXRInteractionProfile_mapo7"), SubResource("OpenXRInteractionProfile_1ueyw"), SubResource("OpenXRInteractionProfile_5qbto"), SubResource("OpenXRInteractionProfile_ska4h")]
 | 
			
		||||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
; 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="XRF browser"
 | 
			
		||||
run/main_scene="res://main.tscn"
 | 
			
		||||
config/features=PackedStringArray("4.3", "GL Compatibility")
 | 
			
		||||
config/icon="res://icon.svg"
 | 
			
		||||
 | 
			
		||||
[autoload]
 | 
			
		||||
 | 
			
		||||
XRToolsUserSettings="*res://addons/godot-xr-tools/user_settings/user_settings.gd"
 | 
			
		||||
 | 
			
		||||
[editor_plugins]
 | 
			
		||||
 | 
			
		||||
enabled=PackedStringArray()
 | 
			
		||||
 | 
			
		||||
[rendering]
 | 
			
		||||
 | 
			
		||||
renderer/rendering_method="gl_compatibility"
 | 
			
		||||
renderer/rendering_method.mobile="gl_compatibility"
 | 
			
		||||
textures/vram_compression/import_etc2_astc=true
 | 
			
		||||
 | 
			
		||||
[xr]
 | 
			
		||||
 | 
			
		||||
openxr/enabled=true
 | 
			
		||||
openxr/foveation_level=3
 | 
			
		||||
openxr/foveation_dynamic=true
 | 
			
		||||
shaders/enabled=true
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1,394 +0,0 @@
 | 
			
		|||
# XR Fragment class
 | 
			
		||||
# more info: https://xrfragment.org 
 | 
			
		||||
# SPDX-License-Identifier: MPL-2.0"
 | 
			
		||||
# author: Leon van Kammen
 | 
			
		||||
# date: 16-05-2024
 | 
			
		||||
 | 
			
		||||
extends Node
 | 
			
		||||
 | 
			
		||||
class_name XRF
 | 
			
		||||
 | 
			
		||||
var scene: Node
 | 
			
		||||
var URI: Dictionary = {}
 | 
			
		||||
var history: Array
 | 
			
		||||
var animplayer: AnimationPlayer
 | 
			
		||||
var isModelLoading = false
 | 
			
		||||
var metadata
 | 
			
		||||
var _orphans = []
 | 
			
		||||
var _regex:RegEx = RegEx.new()				
 | 
			
		||||
var callback: Callable;
 | 
			
		||||
var Type = {
 | 
			
		||||
	"isColor":  "^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$",
 | 
			
		||||
	"isInt":    "^[0-9]+$",
 | 
			
		||||
	"isFloat":  "^[0-9]+%.[0-9]+$",
 | 
			
		||||
	"isVector": "([,]+|%w)"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Called when the node enters the scene tree for the first time.
 | 
			
		||||
func _ready():
 | 
			
		||||
	pass # Replace with function body.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
 | 
			
		||||
func _process(delta):
 | 
			
		||||
	pass
 | 
			
		||||
 | 
			
		||||
####################################################################################################
 | 
			
		||||
# URI Related functions
 | 
			
		||||
# based on https://gist.github.com/coderofsalvation/b2b111a2631fbdc8e76d6cab3bea8f17
 | 
			
		||||
####################################################################################################
 | 
			
		||||
func parseURL(url: String) -> Dictionary:
 | 
			
		||||
	var URI   = {"domain":"","fragment":"","file":"","URN":""}
 | 
			
		||||
	var parts = ["string","protocol","path","query","hash"]
 | 
			
		||||
	var urlregex = RegEx.new()
 | 
			
		||||
	urlregex.compile("(\\w+:\\/\\/)?([^#\\?]+)?(\\?[^#]+)?(#.*)?")
 | 
			
		||||
	var match = urlregex.search(url)
 | 
			
		||||
	for i in range(0,parts.size()):
 | 
			
		||||
		URI[ parts[i] ] = match.strings[i] if match.strings[i] else ""
 | 
			
		||||
	if URI["path"]:
 | 
			
		||||
		var pathParts:Array = URI["path"].split("/")
 | 
			
		||||
		if pathParts.size() > 1 and (pathParts[0].find(".") != -1 || pathParts[0].find(":") != -1):
 | 
			
		||||
			URI["domain"] = pathParts.pop_front()
 | 
			
		||||
		URI["path"]   = "/".join(pathParts)
 | 
			
		||||
		pathParts = URI["path"].split("/")
 | 
			
		||||
		if pathParts[-1].find(".") != -1:
 | 
			
		||||
			URI["file"] = pathParts[-1]
 | 
			
		||||
		URI["path"]   = "/".join(pathParts)
 | 
			
		||||
	URI["protocol"] = URI["protocol"].replace("://","") if URI["protocol"] else ""
 | 
			
		||||
	URI["fragment"]	= parseArgs( URI["hash"].substr(1) ) if URI["hash"] else {}
 | 
			
		||||
	URI["query"]	= parseArgs( URI["query"].substr(1) ) if URI["query"] else {}
 | 
			
		||||
	URI["URN"]      = URI["string"].replace("\\?.*","") if URI["domain"] else ""
 | 
			
		||||
	URI["isLocal"]  = true if !URI["domain"] else false
 | 
			
		||||
	# make relative URL's absolute
 | 
			
		||||
	if URI["isLocal"]:
 | 
			
		||||
		URI["domain"]   = self.URI["domain"]
 | 
			
		||||
		URI["protocol"] = self.URI["protocol"]
 | 
			
		||||
		if URI["path"].match("\\/"):
 | 
			
		||||
			URI["path"] = self.URI["path"] + URI["path"]
 | 
			
		||||
	return URI
 | 
			
		||||
 | 
			
		||||
func parseArgs(fragment: String) -> Dictionary:
 | 
			
		||||
	var ARG = {}
 | 
			
		||||
	var items = fragment.split("&")
 | 
			
		||||
	var i = 0
 | 
			
		||||
	for item in items:
 | 
			
		||||
		var key_value = item.split("=")
 | 
			
		||||
		var exclude    = item.begins_with("-")
 | 
			
		||||
		if exclude:
 | 
			
		||||
			key_value[0] = key_value[0].substr(1)
 | 
			
		||||
		ARG[key_value[0]] = guess_type(key_value[1] if key_value.size() > 1 else "")
 | 
			
		||||
		ARG[key_value[0]].exclude = exclude
 | 
			
		||||
		ARG[key_value[0]].weight = i
 | 
			
		||||
		i=i+1
 | 
			
		||||
	return ARG
 | 
			
		||||
 | 
			
		||||
func guess_type(str: String) -> Dictionary:
 | 
			
		||||
	var v = { 
 | 
			
		||||
		"string": str,
 | 
			
		||||
		"x": null,
 | 
			
		||||
		"y": null,
 | 
			
		||||
		"color":null,
 | 
			
		||||
		"float": null,
 | 
			
		||||
		"int": null
 | 
			
		||||
	}
 | 
			
		||||
	var parts = str.split(",")
 | 
			
		||||
	if parts.size() > 1:
 | 
			
		||||
		v.x = parts[0].to_int()
 | 
			
		||||
		v.y = parts[1].to_int()
 | 
			
		||||
		if parts.size() > 2:
 | 
			
		||||
			v.z = parts[2].to_int()
 | 
			
		||||
	if str.match(Type.isColor):
 | 
			
		||||
		v.color = str
 | 
			
		||||
	if str.match(Type.isFloat):
 | 
			
		||||
		v.float = str.to_float()
 | 
			
		||||
	if str.match(Type.isInt):
 | 
			
		||||
		v.int = str.to_int()	
 | 
			
		||||
	return v
 | 
			
		||||
	
 | 
			
		||||
####################################################################################################
 | 
			
		||||
# Navigation Related functions
 | 
			
		||||
####################################################################################################
 | 
			
		||||
	
 | 
			
		||||
func back():
 | 
			
		||||
	var prev  = self.history.pop_back()
 | 
			
		||||
	if prev != null:
 | 
			
		||||
		prev.next = self.URI 
 | 
			
		||||
		self.to( prev.string, callback )
 | 
			
		||||
 | 
			
		||||
func forward():
 | 
			
		||||
	if self.URI.next != null:
 | 
			
		||||
		self.to( self.URI.next.string, callback )
 | 
			
		||||
	
 | 
			
		||||
# Download model by HTTP and run `downloadModelSuccess` if OK
 | 
			
		||||
func to(url, f:Callable ):
 | 
			
		||||
	print("navigating to "+url)
 | 
			
		||||
	cleanup()
 | 
			
		||||
	var URI = self.parseURL(url)
 | 
			
		||||
	callback = f
 | 
			
		||||
	
 | 
			
		||||
	if self.URI.has('domain') && URI.domain == self.URI.domain && URI.path == self.URI.path:
 | 
			
		||||
		URI.isLocal = true 
 | 
			
		||||
			
 | 
			
		||||
	if !URI.isLocal:
 | 
			
		||||
		fetchURL(url, downloadModelSuccess )
 | 
			
		||||
	if self.URI:
 | 
			
		||||
		self.URI.next = null
 | 
			
		||||
		self.history.push_back(self.URI )		
 | 
			
		||||
	self.URI = URI
 | 
			
		||||
	if URI.isLocal && URI.fragment.has('pos'):
 | 
			
		||||
		callback.call("teleport", self.posToTransform3D( URI.fragment.pos ) )
 | 
			
		||||
 | 
			
		||||
####################################################################################################
 | 
			
		||||
# Model Related functions
 | 
			
		||||
####################################################################################################			
 | 
			
		||||
 | 
			
		||||
func fetchURL(url:String, f:Callable) -> HTTPRequest:
 | 
			
		||||
	var http_request = HTTPRequest.new()
 | 
			
		||||
	_orphans.push_back(http_request)
 | 
			
		||||
	add_child(http_request)
 | 
			
		||||
	http_request.request_completed.connect(f)
 | 
			
		||||
	var error = http_request.request(url)
 | 
			
		||||
	if error != OK:
 | 
			
		||||
		print("could not request "+url)
 | 
			
		||||
		push_error("An error occurred in the HTTP request.")
 | 
			
		||||
	return http_request
 | 
			
		||||
	
 | 
			
		||||
func cleanup():
 | 
			
		||||
	for orphan in _orphans:
 | 
			
		||||
		remove_child(orphan)
 | 
			
		||||
 | 
			
		||||
func downloadModelSuccess(result, response_code, headers, body):
 | 
			
		||||
	# TODO: here different parsing functions should be called
 | 
			
		||||
	#       based on the filetype (glb,gltf,ade,obj e.g.)
 | 
			
		||||
	loadModelFromBufferByGLTFDocument(body)
 | 
			
		||||
	if scene == null:
 | 
			
		||||
		print('could not load GLTF from HTTP response')
 | 
			
		||||
		return
 | 
			
		||||
	_parseXRFMetadata(scene)
 | 
			
		||||
	traverse( scene, _parseXRFMetadata )
 | 
			
		||||
	# setup actions & embeds
 | 
			
		||||
	traverse( scene, href.init )
 | 
			
		||||
	traverse( scene, src.init )
 | 
			
		||||
	setPredefinedSceneView()
 | 
			
		||||
	callback.call("scene_loaded", scene)
 | 
			
		||||
 | 
			
		||||
func loadModelFromBufferByGLTFDocument(body):
 | 
			
		||||
	var doc = GLTFDocument.new()
 | 
			
		||||
	var state = GLTFState.new()
 | 
			
		||||
	#state.set_handle_binary_image(GLTFState.HANDLE_BINARY_EMBED_AS_BASISU) # Fixed in new Godot version (4.3 as I see) https://github.com/godotengine/godot/blob/17e7f85c06366b427e5068c5b3e2940e27ff5f1d/scene/resources/portable_compressed_texture.cpp#L116
 | 
			
		||||
	var error = doc.append_from_buffer(body, "", state, 8) # 8 = force ENABLE_TANGENTS since it is required for mesh compression since 4.2
 | 
			
		||||
	if error == OK:
 | 
			
		||||
		scene = doc.generate_scene(state)
 | 
			
		||||
		scene.name = "XRFscene"
 | 
			
		||||
		metadata = _parseMetadata(state,scene)
 | 
			
		||||
		add_child(scene)
 | 
			
		||||
		print("model added")
 | 
			
		||||
		_addAnimations(state, scene)
 | 
			
		||||
	else:
 | 
			
		||||
		print("Couldn't load glTF scene (error code: %s). Are you connected to internet?" % error_string(error))	
 | 
			
		||||
 | 
			
		||||
func _parseXRFMetadata(node:Node):
 | 
			
		||||
	if node.has_meta("extras"):
 | 
			
		||||
		var extras = node.get_meta("extras")
 | 
			
		||||
		var XRF = {}
 | 
			
		||||
		for i in extras:
 | 
			
		||||
			if typeof(extras[i]) == TYPE_STRING:
 | 
			
		||||
				XRF[ i ] = parseURL( extras[i] )
 | 
			
		||||
		node.set_meta("XRF", XRF)
 | 
			
		||||
 | 
			
		||||
func _addAnimations( state:GLTFState, scene:Node):
 | 
			
		||||
	self.animplayer == null
 | 
			
		||||
	for i in scene.get_child_count():
 | 
			
		||||
		var animplayer : AnimationPlayer = scene.get_child(i) as AnimationPlayer;
 | 
			
		||||
		if animplayer == null:
 | 
			
		||||
			continue;
 | 
			
		||||
		self.animplayer = animplayer
 | 
			
		||||
		print("playing animations")
 | 
			
		||||
		print(animplayer.get_animation_library_list())
 | 
			
		||||
		var anims = animplayer.get_animation_library_list()
 | 
			
		||||
		for j in anims:
 | 
			
		||||
			animplayer.play( j )
 | 
			
		||||
	
 | 
			
		||||
func traverse(node, f:Callable ):
 | 
			
		||||
	for N in node.get_children():
 | 
			
		||||
		if N.get_child_count() > 0:
 | 
			
		||||
			f.call(N)
 | 
			
		||||
			self.traverse(N,f)
 | 
			
		||||
		else:
 | 
			
		||||
			f.call(N)
 | 
			
		||||
 | 
			
		||||
func _parseMetadata(state: GLTFState, scene: Node) -> Error:
 | 
			
		||||
	#var meta = new Dictionary()
 | 
			
		||||
	
 | 
			
		||||
	# Add metadata to materials
 | 
			
		||||
	var materials_json : Array = state.json.get("materials", [])
 | 
			
		||||
	var materials : Array[Material] = state.get_materials()
 | 
			
		||||
	for i in materials_json.size():
 | 
			
		||||
		if materials_json[i].has("extras"):
 | 
			
		||||
			materials[i].set_meta("extras", materials_json[i]["extras"])
 | 
			
		||||
		
 | 
			
		||||
	# Add metadata to ImporterMeshes
 | 
			
		||||
	var meshes_json : Array = state.json.get("meshes", [])
 | 
			
		||||
	var meshes : Array[GLTFMesh] = state.get_meshes()
 | 
			
		||||
	for i in meshes_json.size():
 | 
			
		||||
		if meshes_json[i].has("extras"):
 | 
			
		||||
			meshes[i].mesh.set_meta("extras", meshes_json[i]["extras"])	
 | 
			
		||||
	
 | 
			
		||||
	# Add metadata to scene
 | 
			
		||||
	var scenes_json : Array = state.json.get("scenes", [])
 | 
			
		||||
	if scenes_json[0].has("extras"):
 | 
			
		||||
		scene.set_meta("extras", scenes_json[0]["extras"])	
 | 
			
		||||
		
 | 
			
		||||
	# Add metadata to nodes
 | 
			
		||||
	var nodes_json : Array = state.json.get("nodes", [])
 | 
			
		||||
	for i in nodes_json.size():
 | 
			
		||||
		if nodes_json[i].has("extras"):
 | 
			
		||||
			var name = nodes_json[i]["name"].replace(".","_")
 | 
			
		||||
			var node = scene.find_child(name) #state.get_scene_node(i)
 | 
			
		||||
			if node:
 | 
			
		||||
				node.set_meta( "extras", nodes_json[i]["extras"] )
 | 
			
		||||
			else:
 | 
			
		||||
				print(name+" could not be found")
 | 
			
		||||
	return OK
 | 
			
		||||
	
 | 
			
		||||
func posToTransform3D(v:Dictionary):
 | 
			
		||||
	var transform : Transform3D
 | 
			
		||||
	if !v.x:
 | 
			
		||||
		var node:Node3D = scene.find_child(v.string)
 | 
			
		||||
		if node:
 | 
			
		||||
			transform = node.global_transform
 | 
			
		||||
	else:
 | 
			
		||||
		var pos = Vector3()
 | 
			
		||||
		pos.x = v.x
 | 
			
		||||
		pos.y = v.y
 | 
			
		||||
		pos.z = v.z
 | 
			
		||||
		transform = Transform3D()
 | 
			
		||||
		transform.origin = pos
 | 
			
		||||
	return transform
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
####################################################################################################
 | 
			
		||||
# The XR Fragments
 | 
			
		||||
# spec: https://xrfragment.org/doc/RFC_XR_Fragments.html
 | 
			
		||||
####################################################################################################
 | 
			
		||||
 | 
			
		||||
# info: https://xrfragment.org/#predefined_view
 | 
			
		||||
# spec: 6-8 @ https://xrfragment.org/doc/RFC_XR_Fragments.html#navigating-3d
 | 
			
		||||
func setPredefinedSceneView():
 | 
			
		||||
	var XRF = scene.get_meta("XRF")
 | 
			
		||||
	if XRF && XRF.has("#") && XRF["#"]["fragment"]["pos"]:
 | 
			
		||||
		self.URI.fragment = XRF["#"]["fragment"]
 | 
			
		||||
		if !self.URI.string.match("#"):
 | 
			
		||||
			self.URI.string  += XRF["#"]["string"]
 | 
			
		||||
		callback.call("teleport", posToTransform3D(XRF["#"]["fragment"]["pos"]) )		
 | 
			
		||||
 | 
			
		||||
# info: https://xrfragment.org/doc/RFC_XR_Fragments.html#embedding-xr-content-using-src
 | 
			
		||||
func filterModel(XRF,node):
 | 
			
		||||
	# spec 3 @ https://xrfragment.org/doc/RFC_XR_Fragments.html#embedding-xr-content-using-src
 | 
			
		||||
	for filter in XRF:
 | 
			
		||||
		var frag = XRF[filter]
 | 
			
		||||
		# spec 4 @ https://xrfragment.org/doc/RFC_XR_Fragments.html#embedding-xr-content-using-src		
 | 
			
		||||
		if frag.exclude:
 | 
			
		||||
			var hideNode:Node = node.get_node(filter)
 | 
			
		||||
			if hideNode:
 | 
			
		||||
				hideNode.get_parent().remove_child(hideNode)		
 | 
			
		||||
		# spec 3 @ https://xrfragment.org/doc/RFC_XR_Fragments.html#embedding-xr-content-using-src		
 | 
			
		||||
		if frag.weight == 0 and !frag.exclude && frag.string == '':
 | 
			
		||||
			var newParent:Node = node.get_node(filter)
 | 
			
		||||
			if newParent:
 | 
			
		||||
				node = newParent 
 | 
			
		||||
	return node
 | 
			
		||||
		
 | 
			
		||||
func href_init(node:Node):
 | 
			
		||||
	if node.has_meta("XRF"):
 | 
			
		||||
		var XRF = node.get_meta("XRF")
 | 
			
		||||
		if XRF.has('href'):
 | 
			
		||||
			var parent = node.get_parent()
 | 
			
		||||
			var area3D = Area3D.new()
 | 
			
		||||
			var col3D  = CollisionShape3D.new()
 | 
			
		||||
			var group  = MeshInstance3D.new()
 | 
			
		||||
			parent.remove_child(node)
 | 
			
		||||
			area3D.add_child(node)
 | 
			
		||||
			area3D.add_child(col3D)
 | 
			
		||||
			col3D.make_convex_from_siblings() # generate collision from MeshInstance3D siblings	
 | 
			
		||||
			parent.add_child(area3D)
 | 
			
		||||
 | 
			
		||||
var href = {	
 | 
			
		||||
	"click": func init(node:Node):
 | 
			
		||||
		if node.has_meta("XRF"):
 | 
			
		||||
			var XRF = node.get_meta("XRF")
 | 
			
		||||
			if XRF.has('href'):
 | 
			
		||||
				print("TELEPORT")
 | 
			
		||||
				to(XRF.href.string,callback)
 | 
			
		||||
				callback.call("href", node),
 | 
			
		||||
								
 | 
			
		||||
	"init": func href_init(node:Node):
 | 
			
		||||
		if node.has_meta("XRF"):
 | 
			
		||||
			var XRF = node.get_meta("XRF")
 | 
			
		||||
			if XRF.has('href'):
 | 
			
		||||
				var parent = node.get_parent()
 | 
			
		||||
				var area3D = Area3D.new()
 | 
			
		||||
				var col3D  = CollisionShape3D.new()
 | 
			
		||||
				var group  = MeshInstance3D.new()
 | 
			
		||||
				parent.remove_child(node)
 | 
			
		||||
				area3D.add_child(node)
 | 
			
		||||
				area3D.add_child(col3D)
 | 
			
		||||
				col3D.make_convex_from_siblings() # generate collision from MeshInstance3D siblings	
 | 
			
		||||
				parent.add_child(area3D)				
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
				
 | 
			
		||||
var src = {
 | 
			
		||||
	"extension":{},
 | 
			
		||||
	
 | 
			
		||||
	"addExtension": func addExtension( extension:String, f:Callable): # flexible way for adding extension handlers
 | 
			
		||||
		src.extension[ extension ] = f,
 | 
			
		||||
	
 | 
			
		||||
	"init": func init(node:Node):
 | 
			
		||||
		if node.has_meta("XRF"):
 | 
			
		||||
			var XRF = node.get_meta("XRF")
 | 
			
		||||
			if XRF.has('src'):
 | 
			
		||||
				var mesh = node as MeshInstance3D
 | 
			
		||||
				if mesh != null:
 | 
			
		||||
					var mat = mesh.get_active_material(0) as BaseMaterial3D
 | 
			
		||||
					mat = mat.duplicate()
 | 
			
		||||
					mat.transparency = mat.TRANSPARENCY_ALPHA
 | 
			
		||||
					mat.albedo = Color(1.0,1.0,1.0, 0.3) # 0.5 sets 50% opacity
 | 
			
		||||
					mesh.set_surface_override_material(0,mat)
 | 
			
		||||
				for ext in src.extension:
 | 
			
		||||
					_regex.compile(ext)
 | 
			
		||||
					if _regex.search(XRF.src.path) or _regex.search(XRF.src.string):
 | 
			
		||||
						var url:String = XRF.src.protocol+"://"+XRF.src.domain+XRF.src.path						
 | 
			
		||||
						print("src: fetching "+url)
 | 
			
		||||
						var handler:Callable = src.extension[ext].call(node,ext)
 | 
			
		||||
						if handler != null:
 | 
			
		||||
							fetchURL(url, handler )
 | 
			
		||||
				callback.call("src", {"node":node,"XRF":XRF} ),
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	# some builtin content handlers
 | 
			
		||||
	
 | 
			
		||||
	"model": func audio(node:Node, extension:String) -> Callable:
 | 
			
		||||
		var node3D:Node3D = node as Node3D
 | 
			
		||||
		var src = node.get_meta("XRF").src
 | 
			
		||||
		if src.string.begins_with("#"): # local resource
 | 
			
		||||
			var clone:Node3D   = scene.duplicate() as Node3D
 | 
			
		||||
			clone.global_scale( node3D.scale )
 | 
			
		||||
			if src.fragment:
 | 
			
		||||
				clone = filterModel( src.fragment, clone)
 | 
			
		||||
			node.add_child(clone as Node)
 | 
			
		||||
		return func onFile(result, response_code, headers, body):
 | 
			
		||||
			print("JAAAAAA"),
 | 
			
		||||
 | 
			
		||||
	"audio": func audio(node:Node, extension:String) -> Callable:
 | 
			
		||||
		var src = node.get_meta("XRF").src
 | 
			
		||||
		return func onFile(result, response_code, headers, body):
 | 
			
		||||
			var music = AudioStreamPlayer.new()
 | 
			
		||||
			add_child(music)
 | 
			
		||||
			var audio_loader = AudioLoader.new()
 | 
			
		||||
			music.set_stream( audio_loader.loadfile( src.file, body ) )
 | 
			
		||||
			music.volume_db = 1
 | 
			
		||||
			music.pitch_scale = 1
 | 
			
		||||
			music.play()
 | 
			
		||||
			add_child(music)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								index.html
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								index.html
									
										
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		
		Reference in a new issue