├── .gitattributes ├── .gitignore ├── LICENSE ├── addons ├── godot-openvr │ ├── OpenVRConfig.gdns │ ├── OpenVROverlay.gdns │ ├── OpenVRRenderModel.gdns │ ├── bin │ │ ├── LICENSE │ │ └── win64 │ │ │ ├── libgodot_openvr.dll │ │ │ └── openvr_api.dll │ ├── godot_openvr.gdnlib │ ├── icon.png │ ├── icon.png.import │ └── scenes │ │ ├── framecounter_in_3d.tscn │ │ ├── ovr_controller.gd │ │ ├── ovr_controller.tscn │ │ └── ovr_first_person.tscn └── vr-common │ ├── VERSIONS.md │ ├── functions │ ├── Function_Direct_movement.gd │ ├── Function_Direct_movement.tscn │ ├── Function_Pickup.gd │ ├── Function_Pickup.tscn │ ├── Function_Teleport.gd │ ├── Function_Teleport.tscn │ ├── Function_pointer.gd │ └── Function_pointer.tscn │ ├── images │ ├── icon.png │ ├── icon.png.import │ ├── teleport_arrow.png │ ├── teleport_arrow.png.import │ ├── teleport_target.png │ └── teleport_target.png.import │ ├── materials │ ├── capule.tres │ ├── pointer.tres │ ├── target.tres │ ├── teleport.shader │ └── teleport.tres │ ├── misc │ ├── VR_Common_Shader_Cache.gd │ └── VR_Common_Shader_Cache.tscn │ └── objects │ ├── Object_pickable.gd │ └── Object_pickable.tscn ├── assets ├── fonts │ ├── OFL.txt │ ├── PT_Sans-Web-Bold.ttf │ └── pt_sans.tres └── textures │ ├── Godot │ ├── splash.png │ └── splash.png.import │ └── Scene │ ├── grid.png │ └── grid.png.import ├── default_env.tres ├── icon.png ├── icon.png.import ├── main.gd ├── main.tscn ├── misc ├── effects │ ├── FadeToBlack.gd │ └── FadeToBlack.tscn └── resource_queue.gd ├── player └── player.gd ├── project.godot └── scenes ├── base_scene.gd ├── base_scene.tscn ├── loading └── Loading_scene.tscn ├── selection ├── Screen.gd ├── Screen.tscn ├── ScreenBody.gd ├── border.png ├── border.png.import ├── center_screen_2d.gd ├── center_screen_2d.tscn ├── fade.shader ├── font_24.tres ├── font_48.tres ├── left_screen_2d.tscn ├── right_screen_2d.tscn ├── selection.gd └── selection.tscn └── test_scene ├── Box.tscn └── test_scene.tscn /.gitattributes: -------------------------------------------------------------------------------- 1 | *.gd eol=lf 2 | *.tscn eol=lf 3 | *.cfg eol=lf 4 | *.godot eol=lf 5 | *.tres eol=lf 6 | *.import eol=lf 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.os 3 | *.so 4 | *.dylib 5 | .import/ 6 | *.dblite 7 | *.exp 8 | *.lib 9 | *.obj 10 | *.TMP 11 | logs 12 | Thumbs.db 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Bastiaan Olij 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /addons/godot-openvr/OpenVRConfig.gdns: -------------------------------------------------------------------------------- 1 | [gd_resource type="NativeScript" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/godot-openvr/godot_openvr.gdnlib" type="GDNativeLibrary" id=1] 4 | 5 | [resource] 6 | resource_name = "OpenVRConfig" 7 | class_name = "OpenVRConfig" 8 | library = ExtResource( 1 ) 9 | -------------------------------------------------------------------------------- /addons/godot-openvr/OpenVROverlay.gdns: -------------------------------------------------------------------------------- 1 | [gd_resource type="NativeScript" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/godot-openvr/godot_openvr.gdnlib" type="GDNativeLibrary" id=1] 4 | 5 | [resource] 6 | resource_name = "OpenVROverlay" 7 | class_name = "OpenVROverlay" 8 | library = ExtResource( 1 ) 9 | -------------------------------------------------------------------------------- /addons/godot-openvr/OpenVRRenderModel.gdns: -------------------------------------------------------------------------------- 1 | [gd_resource type="NativeScript" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/godot-openvr/godot_openvr.gdnlib" type="GDNativeLibrary" id=1] 4 | 5 | [resource] 6 | 7 | resource_name = "OpenVRRenderModel" 8 | class_name = "OpenVRRenderModel" 9 | library = ExtResource( 1 ) 10 | _sections_unfolded = [ "Resource" ] 11 | 12 | -------------------------------------------------------------------------------- /addons/godot-openvr/bin/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Valve Corporation 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /addons/godot-openvr/bin/win64/libgodot_openvr.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/addons/godot-openvr/bin/win64/libgodot_openvr.dll -------------------------------------------------------------------------------- /addons/godot-openvr/bin/win64/openvr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/addons/godot-openvr/bin/win64/openvr_api.dll -------------------------------------------------------------------------------- /addons/godot-openvr/godot_openvr.gdnlib: -------------------------------------------------------------------------------- 1 | [general] 2 | 3 | singleton=true 4 | load_once=true 5 | symbol_prefix="godot_openvr_" 6 | reloadable=false 7 | 8 | [entry] 9 | 10 | X11.64="res://addons/godot-openvr/bin/x11/libgodot_openvr.so" 11 | Windows.32="res://addons/godot-openvr/bin/win32/libgodot_openvr.dll" 12 | Windows.64="res://addons/godot-openvr/bin/win64/libgodot_openvr.dll" 13 | OSX.64="res://addons/godot-openvr/bin/osx/libgodot_openvr.dylib" 14 | 15 | [dependencies] 16 | 17 | X11.64=[ "res://addons/godot-openvr/bin/x11/libopenvr_api.so" ] 18 | Windows.32=[ "res://addons/godot-openvr/bin/win32/openvr_api.dll" ] 19 | Windows.64=[ "res://addons/godot-openvr/bin/win64/openvr_api.dll" ] 20 | OSX.64=[ "res://addons/godot-openvr/bin/osx/libopenvr_api.dylib" ] 21 | -------------------------------------------------------------------------------- /addons/godot-openvr/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/addons/godot-openvr/icon.png -------------------------------------------------------------------------------- /addons/godot-openvr/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-a89ecb8be28ea6c50eeae0c3cb0cd271.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/godot-openvr/icon.png" 13 | dest_files=[ "res://.import/icon.png-a89ecb8be28ea6c50eeae0c3cb0cd271.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /addons/godot-openvr/scenes/framecounter_in_3d.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [sub_resource type="PlaneMesh" id=1] 4 | 5 | size = Vector2( 0.3, 0.15 ) 6 | subdivide_width = 10 7 | subdivide_depth = 10 8 | 9 | [sub_resource type="Shader" id=2] 10 | 11 | code = "shader_type spatial; 12 | render_mode unshaded; 13 | 14 | uniform sampler2D viewport_texture : hint_albedo; 15 | 16 | void vertex() { 17 | VERTEX.y = 1.0 - cos(VERTEX.x + 0.3) * 0.5 - cos(VERTEX.z + 0.15) * 0.5; 18 | } 19 | 20 | void fragment() { 21 | vec4 col = texture(viewport_texture, vec2(1.0-UV.x, UV.y)); 22 | ALBEDO = col.rgb; 23 | ALPHA = col.a; 24 | }" 25 | 26 | [sub_resource type="ShaderMaterial" id=3] 27 | 28 | render_priority = 0 29 | shader = SubResource( 2 ) 30 | _sections_unfolded = [ "Resource", "shader_param" ] 31 | 32 | [sub_resource type="GDScript" id=4] 33 | 34 | script/source = "extends MeshInstance 35 | 36 | func _ready(): 37 | get_surface_material(0).set_shader_param(\"viewport_texture\", $Viewport.get_texture()) 38 | 39 | func _process(delta): 40 | $Viewport/World/Label.text = str(Engine.get_frames_per_second()) + \" FPS\"" 41 | 42 | [node name="FPS" type="MeshInstance" index="0"] 43 | 44 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 ) 45 | layers = 1 46 | material_override = null 47 | cast_shadow = 1 48 | extra_cull_margin = 0.0 49 | use_in_baked_light = false 50 | lod_min_distance = 0.0 51 | lod_min_hysteresis = 0.0 52 | lod_max_distance = 0.0 53 | lod_max_hysteresis = 0.0 54 | mesh = SubResource( 1 ) 55 | skeleton = NodePath("..") 56 | material/0 = SubResource( 3 ) 57 | script = SubResource( 4 ) 58 | _sections_unfolded = [ "Transform", "material" ] 59 | 60 | [node name="Viewport" type="Viewport" parent="." index="0"] 61 | 62 | arvr = false 63 | size = Vector2( 200, 100 ) 64 | own_world = false 65 | world = null 66 | transparent_bg = true 67 | msaa = 0 68 | hdr = false 69 | disable_3d = false 70 | usage = 0 71 | debug_draw = 0 72 | render_target_v_flip = false 73 | render_target_clear_mode = 0 74 | render_target_update_mode = 3 75 | audio_listener_enable_2d = false 76 | audio_listener_enable_3d = false 77 | physics_object_picking = false 78 | gui_disable_input = false 79 | gui_snap_controls_to_pixels = true 80 | shadow_atlas_size = 0 81 | shadow_atlas_quad_0 = 2 82 | shadow_atlas_quad_1 = 2 83 | shadow_atlas_quad_2 = 3 84 | shadow_atlas_quad_3 = 4 85 | _sections_unfolded = [ "Render Target", "Rendering" ] 86 | 87 | [node name="World" type="Node2D" parent="Viewport" index="0"] 88 | 89 | _sections_unfolded = [ "Transform", "Z" ] 90 | 91 | [node name="Label" type="Label" parent="Viewport/World" index="0"] 92 | 93 | anchor_left = 0.0 94 | anchor_top = 0.0 95 | anchor_right = 0.0 96 | anchor_bottom = 0.0 97 | margin_right = 200.0 98 | margin_bottom = 100.0 99 | rect_scale = Vector2( 3, 3 ) 100 | rect_pivot_offset = Vector2( 0, 0 ) 101 | mouse_filter = 2 102 | size_flags_horizontal = 1 103 | size_flags_vertical = 4 104 | custom_colors/font_color = Color( 1, 1, 1, 1 ) 105 | custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) 106 | text = "FPS" 107 | percent_visible = 1.0 108 | lines_skipped = 0 109 | max_lines_visible = -1 110 | _sections_unfolded = [ "Anchor", "Grow Direction", "Margin", "Material", "Rect", "Visibility", "custom_colors" ] 111 | 112 | 113 | -------------------------------------------------------------------------------- /addons/godot-openvr/scenes/ovr_controller.gd: -------------------------------------------------------------------------------- 1 | extends ARVRController 2 | 3 | signal controller_activated(controller) 4 | 5 | export var show_controller_mesh = true setget set_show_controller_mesh, get_show_controller_mesh 6 | 7 | func set_show_controller_mesh(p_show): 8 | show_controller_mesh = p_show 9 | if $Controller_mesh: 10 | $Controller_mesh.visible = p_show 11 | 12 | func get_show_controller_mesh(): 13 | return show_controller_mesh 14 | 15 | var ovr_render_model 16 | var components = Array() 17 | var ws = 0 18 | 19 | func _ready(): 20 | # instance our render model object 21 | ovr_render_model = preload("res://addons/godot-openvr/OpenVRRenderModel.gdns").new() 22 | 23 | # set our starting vaule 24 | $Controller_mesh.visible = show_controller_mesh 25 | 26 | # hide to begin with 27 | visible = false 28 | 29 | func apply_world_scale(): 30 | var new_ws = ARVRServer.world_scale 31 | if (ws != new_ws): 32 | ws = new_ws 33 | $Controller_mesh.scale = Vector3(ws, ws, ws) 34 | 35 | func load_controller_mesh(controller_name): 36 | if ovr_render_model.load_model(controller_name.substr(0, controller_name.length()-2)): 37 | return ovr_render_model 38 | 39 | if ovr_render_model.load_model("generic_controller"): 40 | return ovr_render_model 41 | 42 | return Mesh.new() 43 | 44 | func _process(delta): 45 | if !get_is_active(): 46 | visible = false 47 | return 48 | 49 | # always set our world scale, user may end up changing this 50 | apply_world_scale() 51 | 52 | if visible: 53 | return 54 | 55 | # became active? lets handle it... 56 | var controller_name = get_controller_name() 57 | print("Controller " + controller_name + " became active") 58 | 59 | # attempt to load a mesh for this 60 | $Controller_mesh.mesh = load_controller_mesh(controller_name) 61 | 62 | # make it visible 63 | visible = true 64 | emit_signal("controller_activated", self) 65 | -------------------------------------------------------------------------------- /addons/godot-openvr/scenes/ovr_controller.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/godot-openvr/scenes/ovr_controller.gd" type="Script" id=1] 4 | 5 | [node name="OVRController" type="ARVRController"] 6 | script = ExtResource( 1 ) 7 | 8 | [node name="Controller_mesh" type="MeshInstance" parent="."] 9 | -------------------------------------------------------------------------------- /addons/godot-openvr/scenes/ovr_first_person.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/misc/VR_Common_Shader_Cache.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://addons/godot-openvr/scenes/ovr_controller.tscn" type="PackedScene" id=2] 5 | 6 | [sub_resource type="PlaneMesh" id=1] 7 | size = Vector2( 0.001, 0.001 ) 8 | 9 | [sub_resource type="SpatialMaterial" id=2] 10 | 11 | [sub_resource type="GDScript" id=3] 12 | script/source = "extends Spatial 13 | 14 | func _physics_process(delta): 15 | # we keep this in line with our camera but we remove the tilt 16 | var new_transform = get_node(\"../ARVRCamera\").transform 17 | 18 | var new_basis = Basis() 19 | new_basis.z = Vector3(new_transform.basis.z.x, 0.0, new_transform.basis.z.z).normalized() 20 | if new_basis.z.length() > 0.5: 21 | new_basis.y - Vector3(0.0, 1.0, 0.0) 22 | new_basis.x = new_basis.y.cross(new_basis.z) 23 | new_transform.basis = new_basis 24 | 25 | transform = new_transform 26 | else: 27 | # we're looking straight up or down, ignore this 28 | pass" 29 | 30 | [node name="OVRFirstPerson" type="ARVROrigin"] 31 | 32 | [node name="ARVRCamera" type="ARVRCamera" parent="."] 33 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.85, 0 ) 34 | fov = 65.0 35 | near = 0.01 36 | far = 1000.01 37 | 38 | [node name="shader_cache" parent="ARVRCamera" instance=ExtResource( 1 )] 39 | 40 | [node name="Controller" type="MeshInstance" parent="ARVRCamera/shader_cache"] 41 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ) 42 | mesh = SubResource( 1 ) 43 | material/0 = SubResource( 2 ) 44 | 45 | [node name="HUD_Anchor" type="Spatial" parent="."] 46 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.85, 0 ) 47 | script = SubResource( 3 ) 48 | 49 | [node name="Left_Hand" parent="." instance=ExtResource( 2 )] 50 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1.25, 0 ) 51 | 52 | [node name="Right_Hand" parent="." instance=ExtResource( 2 )] 53 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 1.25, 0 ) 54 | controller_id = 2 55 | -------------------------------------------------------------------------------- /addons/vr-common/VERSIONS.md: -------------------------------------------------------------------------------- 1 | 1.2 (in progress) 2 | === 3 | - Assign button to teleport function and no longer need to set origin 4 | - Added pickable object support 5 | - Fixed positioning of direct movement collision shape 6 | - Added strafe and fly mode for directional 7 | - Added ability to enable/disable the movement functions 8 | 9 | 1.1* 10 | ==== 11 | - previous versions were not tracked 12 | 13 | * Note that version history before 1.2 was not kept and is thus incomplete 14 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_Direct_movement.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | enum MOVEMENT_TYPE { MOVE_AND_ROTATE, MOVE_AND_STRAFE } 4 | 5 | # Is this active? 6 | export var enabled = true setget set_enabled, get_enabled 7 | 8 | # We don't know the name of the camera node... 9 | export (NodePath) var camera = null 10 | 11 | # size of our player 12 | export var player_radius = 0.4 setget set_player_radius, get_player_radius 13 | 14 | # to combat motion sickness we'll 'step' our left/right turning 15 | export var turn_delay = 0.2 16 | export var turn_angle = 20.0 17 | export var max_speed = 5.0 18 | export var drag_factor = 0.1 19 | 20 | # fly mode and strafe movement management 21 | export (MOVEMENT_TYPE) var move_type = MOVEMENT_TYPE.MOVE_AND_ROTATE 22 | export var canFly = true 23 | export var fly_move_button_id = 15 24 | export var fly_activate_button_id = 2 25 | var isflying = false 26 | 27 | var turn_step = 0.0 28 | var origin_node = null 29 | var camera_node = null 30 | var velocity = Vector3(0.0, 0.0, 0.0) 31 | var gravity = -30.0 32 | onready var collision_shape: CollisionShape = get_node("KinematicBody/CollisionShape") 33 | onready var tail : RayCast = get_node("KinematicBody/Tail") 34 | 35 | func set_enabled(new_value): 36 | enabled = new_value 37 | if collision_shape: 38 | collision_shape.disabled = !enabled 39 | if tail: 40 | tail.enabled = enabled 41 | if enabled: 42 | # make sure our physics process is on 43 | set_physics_process(true) 44 | else: 45 | # we turn this off in physics process just in case we want to do some cleanup 46 | pass 47 | 48 | func get_enabled(): 49 | return enabled 50 | 51 | func get_player_radius(): 52 | return player_radius 53 | 54 | func set_player_radius(p_radius): 55 | player_radius = p_radius 56 | 57 | func _ready(): 58 | # origin node should always be the parent of our parent 59 | origin_node = get_node("../..") 60 | 61 | if camera: 62 | camera_node = get_node(camera) 63 | else: 64 | # see if we can find our default 65 | camera_node = origin_node.get_node('ARVRCamera') 66 | 67 | set_player_radius(player_radius) 68 | 69 | collision_shape.disabled = !enabled 70 | tail.enabled = enabled 71 | 72 | func _physics_process(delta): 73 | if !origin_node: 74 | return 75 | 76 | if !camera_node: 77 | return 78 | 79 | if !enabled: 80 | set_physics_process(false) 81 | return 82 | 83 | # Adjust the height of our player according to our camera position 84 | var player_height = camera_node.transform.origin.y + player_radius 85 | if player_height < player_radius: 86 | # not smaller than this 87 | player_height = player_radius 88 | 89 | collision_shape.shape.radius = player_radius 90 | collision_shape.shape.height = player_height - (player_radius * 2.0) 91 | collision_shape.transform.origin.y = (player_height / 2.0) 92 | 93 | # We should be the child or the controller on which the teleport is implemented 94 | var controller = get_parent() 95 | if controller.get_is_active(): 96 | var left_right = controller.get_joystick_axis(0) 97 | var forwards_backwards = controller.get_joystick_axis(1) 98 | 99 | # if fly_action_button_id is pressed it activates the FLY MODE 100 | # if fly_action_button_id is released it deactivates the FLY MODE 101 | if controller.is_button_pressed(fly_activate_button_id) && canFly: 102 | isflying = true 103 | else: 104 | isflying = false 105 | 106 | # if player is flying, he moves following the controller's orientation 107 | if isflying: 108 | if controller.is_button_pressed(fly_move_button_id): 109 | # is flying, so we will use the controller's transform to move the VR capsule follow its orientation 110 | var curr_transform = $KinematicBody.global_transform 111 | velocity = controller.global_transform.basis.z.normalized() * -delta * max_speed * ARVRServer.world_scale 112 | velocity = $KinematicBody.move_and_slide(velocity) 113 | var movement = ($KinematicBody.global_transform.origin - curr_transform.origin) 114 | origin_node.global_transform.origin += movement 115 | 116 | ################################################################ 117 | # first process turning, no problems there :) 118 | # move_type == MOVEMENT_TYPE.move_and_strafe 119 | else: 120 | if(move_type == MOVEMENT_TYPE.MOVE_AND_ROTATE && abs(left_right) > 0.1): 121 | if left_right > 0.0: 122 | if turn_step < 0.0: 123 | # reset step 124 | turn_step = 0 125 | 126 | turn_step += left_right * delta 127 | else: 128 | if turn_step > 0.0: 129 | # reset step 130 | turn_step = 0 131 | 132 | turn_step += left_right * delta 133 | 134 | if abs(turn_step) > turn_delay: 135 | # we rotate around our Camera, but we adjust our origin, so we need a little bit of trickery 136 | var t1 = Transform() 137 | var t2 = Transform() 138 | var rot = Transform() 139 | 140 | t1.origin = -camera_node.transform.origin 141 | t2.origin = camera_node.transform.origin 142 | 143 | # Rotating 144 | while abs(turn_step) > turn_delay: 145 | if (turn_step > 0.0): 146 | rot = rot.rotated(Vector3(0.0,-1.0,0.0),turn_angle * PI / 180.0) 147 | turn_step -= turn_delay 148 | else: 149 | rot = rot.rotated(Vector3(0.0,1.0,0.0),turn_angle * PI / 180.0) 150 | turn_step += turn_delay 151 | 152 | origin_node.transform *= t2 * rot * t1 153 | else: 154 | turn_step = 0.0 155 | 156 | ################################################################ 157 | # now we do our movement 158 | # We start with placing our KinematicBody in the right place 159 | # by centering it on the camera but placing it on the ground 160 | var curr_transform = $KinematicBody.global_transform 161 | var camera_transform = camera_node.global_transform 162 | curr_transform.origin = camera_transform.origin 163 | curr_transform.origin.y = origin_node.global_transform.origin.y 164 | $KinematicBody.global_transform = curr_transform 165 | 166 | # we'll handle gravity separately 167 | var gravity_velocity = Vector3(0.0, velocity.y, 0.0) 168 | velocity.y = 0.0 169 | 170 | # Apply our drag 171 | velocity *= (1.0 - drag_factor) 172 | 173 | if move_type == MOVEMENT_TYPE.MOVE_AND_ROTATE: 174 | if (abs(forwards_backwards) > 0.1 and tail.is_colliding()): 175 | var dir = camera_transform.basis.z 176 | dir.y = 0.0 177 | velocity = dir.normalized() * -forwards_backwards * delta * max_speed * ARVRServer.world_scale 178 | #velocity = velocity.linear_interpolate(dir, delta * 100.0) 179 | elif move_type == MOVEMENT_TYPE.MOVE_AND_STRAFE: 180 | if ((abs(forwards_backwards) > 0.1 || abs(left_right) > 0.1) and tail.is_colliding()): 181 | var dir_forward = camera_transform.basis.z 182 | dir_forward.y = 0.0 183 | # VR Capsule will strafe left and right 184 | var dir_right = camera_transform.basis.x; 185 | dir_right.y = 0.0 186 | velocity = (dir_forward * -forwards_backwards + dir_right * left_right).normalized() * delta * max_speed * ARVRServer.world_scale 187 | 188 | # apply move and slide to our kinematic body 189 | velocity = $KinematicBody.move_and_slide(velocity, Vector3(0.0, 1.0, 0.0)) 190 | 191 | # apply our gravity 192 | gravity_velocity.y += gravity * delta 193 | gravity_velocity = $KinematicBody.move_and_slide(gravity_velocity, Vector3(0.0, 1.0, 0.0)) 194 | velocity.y = gravity_velocity.y 195 | 196 | # now use our new position to move our origin point 197 | var movement = ($KinematicBody.global_transform.origin - curr_transform.origin) 198 | origin_node.global_transform.origin += movement 199 | 200 | # Return this back to where it was so we can use its collision shape for other things too 201 | # $KinematicBody.global_transform.origin = curr_transform.origin 202 | 203 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_Direct_movement.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/functions/Function_Direct_movement.gd" type="Script" id=1] 4 | 5 | [sub_resource type="CapsuleShape" id=1] 6 | radius = 0.3 7 | height = 1.2 8 | 9 | [node name="Function_Direct_movement" type="Node"] 10 | script = ExtResource( 1 ) 11 | max_speed = 500.0 12 | 13 | [node name="KinematicBody" type="KinematicBody" parent="."] 14 | collision_mask = 1048574 15 | 16 | [node name="CollisionShape" type="CollisionShape" parent="KinematicBody"] 17 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.9, 0 ) 18 | shape = SubResource( 1 ) 19 | 20 | [node name="Tail" type="RayCast" parent="KinematicBody"] 21 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0 ) 22 | enabled = true 23 | cast_to = Vector3( 0, -0.6, 0 ) 24 | collision_mask = 1048574 25 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_Pickup.gd: -------------------------------------------------------------------------------- 1 | extends Area 2 | 3 | signal has_picked_up(what) 4 | signal has_dropped 5 | 6 | export var impulse_factor = 1.0 7 | export var pickup_button_id = 2 8 | export var action_button_id = 15 9 | 10 | var object_in_area = Array() 11 | var closest_object = null 12 | var picked_up_object = null 13 | 14 | var last_position = Vector3(0.0, 0.0, 0.0) 15 | var velocity = Vector3(0.0, 0.0, 0.0) 16 | 17 | func _on_Function_Pickup_body_entered(body): 18 | # add our object to our array if required 19 | if body.has_method('pick_up') and object_in_area.find(body) == -1: 20 | object_in_area.push_back(body) 21 | _update_closest_object() 22 | 23 | func _on_Function_Pickup_body_exited(body): 24 | # remove our object from our array 25 | if object_in_area.find(body) != -1: 26 | object_in_area.erase(body) 27 | _update_closest_object() 28 | 29 | func _update_closest_object(): 30 | var new_closest_obj = null 31 | if !picked_up_object: 32 | var new_closest_distance = 1000 33 | for o in object_in_area: 34 | # only check objects that aren't already picked up 35 | if o.is_picked_up() == false: 36 | var delta_pos = o.global_transform.origin - global_transform.origin 37 | var distance = delta_pos.length() 38 | if distance < new_closest_distance: 39 | new_closest_obj = o 40 | new_closest_distance = distance 41 | 42 | if closest_object != new_closest_obj: 43 | # remove highlight on old object 44 | if closest_object: 45 | closest_object.decrease_is_closest() 46 | 47 | # add highlight to new object 48 | closest_object = new_closest_obj 49 | if closest_object: 50 | closest_object.increase_is_closest() 51 | 52 | func drop_object(): 53 | if picked_up_object: 54 | # let go of this object 55 | picked_up_object.let_go(velocity * impulse_factor) 56 | picked_up_object = null 57 | emit_signal("has_dropped") 58 | 59 | func _pick_up_object(p_object): 60 | # already holding this object, nothing to do 61 | if picked_up_object == p_object: 62 | return 63 | 64 | # holding something else? drop it 65 | if picked_up_object: 66 | drop_object() 67 | 68 | # and pick up our new object 69 | if p_object: 70 | picked_up_object = p_object 71 | picked_up_object.pick_up(self, get_parent()) 72 | emit_signal("has_picked_up", picked_up_object) 73 | 74 | func _on_button_pressed(p_button): 75 | if p_button == pickup_button_id: 76 | if picked_up_object and !picked_up_object.press_to_hold: 77 | drop_object() 78 | elif closest_object: 79 | _pick_up_object(closest_object) 80 | elif p_button == action_button_id: 81 | if picked_up_object and picked_up_object.has_method("action"): 82 | picked_up_object.action() 83 | 84 | func _on_button_release(p_button): 85 | if p_button == pickup_button_id: 86 | if picked_up_object and picked_up_object.press_to_hold: 87 | drop_object() 88 | 89 | func _ready(): 90 | get_parent().connect("button_pressed", self, "_on_button_pressed") 91 | get_parent().connect("button_release", self, "_on_button_release") 92 | last_position = global_transform.origin 93 | 94 | func _process(delta): 95 | velocity = (global_transform.origin - last_position) / delta 96 | last_position = global_transform.origin 97 | _update_closest_object() 98 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_Pickup.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/functions/Function_Pickup.gd" type="Script" id=1] 4 | 5 | [sub_resource type="SphereShape" id=1] 6 | radius = 0.5 7 | 8 | [node name="Function_Pickup" type="Area"] 9 | collision_mask = 2 10 | script = ExtResource( 1 ) 11 | 12 | [node name="CollisionShape" type="CollisionShape" parent="."] 13 | shape = SubResource( 1 ) 14 | [connection signal="body_entered" from="." to="." method="_on_Function_Pickup_body_entered"] 15 | [connection signal="body_exited" from="." to="." method="_on_Function_Pickup_body_exited"] 16 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_Teleport.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody 2 | # should really change this to Spatial once #17401 is resolved 3 | 4 | # Add this scene as a sub scene of your ARVRController node to implement a teleport function on that controller. 5 | 6 | # Is this active? 7 | export var enabled = true setget set_enabled, get_enabled 8 | 9 | # button 15 is mapped to our trigger 10 | export var teleport_button = 15 11 | export (Color) var can_teleport_color = Color(0.0, 1.0, 0.0, 1.0) 12 | export (Color) var cant_teleport_color = Color(1.0, 0.0, 0.0, 1.0) 13 | export (Color) var no_collision_color = Color(45.0 / 255.0, 80.0 / 255.0, 220.0 / 255.0, 1.0) 14 | export var player_height = 1.8 setget set_player_height, get_player_height 15 | export var player_radius = 0.4 setget set_player_radius, get_player_radius 16 | export var strength = 5.0 17 | # once this is no longer a kinematic body, we'll need this.. 18 | # export var collision_mask = 1 19 | 20 | # We don't know the name of the camera node... 21 | export (NodePath) var camera = null 22 | 23 | onready var ws = ARVRServer.world_scale 24 | var origin_node = null 25 | var camera_node = null 26 | var is_on_floor = true 27 | var is_teleporting = false 28 | var can_teleport = true 29 | var teleport_rotation = 0.0; 30 | var floor_normal = Vector3(0.0, 1.0, 0.0) 31 | var last_target_transform = Transform() 32 | var collision_shape = null 33 | var step_size = 0.5 34 | 35 | # By default we show a capsule to indicate where the player lands. 36 | # Turn on editable children, 37 | # hide the capsule, 38 | # and add your own player character as child. 39 | onready var capsule = get_node("Target/Player_figure/Capsule") 40 | 41 | func set_enabled(new_value): 42 | enabled = new_value 43 | if enabled: 44 | # make sure our physics process is on 45 | set_physics_process(true) 46 | else: 47 | # we turn this off in physics process just in case we want to do some cleanup 48 | pass 49 | 50 | func get_enabled(): 51 | return enabled 52 | 53 | func get_player_height(): 54 | return player_height 55 | 56 | func set_player_height(p_height): 57 | player_height = p_height 58 | 59 | if collision_shape: 60 | # for some reason collision shape height measurement is half up, half down from center 61 | collision_shape.height = (player_height / 2.0) + 0.1 62 | 63 | if capsule: 64 | capsule.mesh.mid_height = player_height - (2.0 * player_radius) 65 | capsule.translation = Vector3(0.0, player_height/2.0, 0.0) 66 | 67 | func get_player_radius(): 68 | return player_radius 69 | 70 | func set_player_radius(p_radius): 71 | player_radius = p_radius 72 | 73 | if collision_shape: 74 | collision_shape.radius = player_radius 75 | 76 | if capsule: 77 | capsule.mesh.mid_height = player_height - (2.0 * player_radius) 78 | capsule.mesh.radius = player_radius 79 | 80 | func _ready(): 81 | # We should be a child of an ARVRController and it should be a child or our ARVROrigin 82 | origin_node = get_node("../..") 83 | 84 | # It's inactive when we start 85 | $Teleport.visible = false 86 | $Target.visible = false 87 | 88 | # Scale to our world scale 89 | $Teleport.mesh.size = Vector2(0.05 * ws, 1.0) 90 | $Target.mesh.size = Vector2(ws, ws) 91 | $Target/Player_figure.scale = Vector3(ws, ws, ws) 92 | 93 | if camera: 94 | camera_node = get_node(camera) 95 | else: 96 | # see if we can find our default 97 | camera_node = origin_node.get_node('ARVRCamera') 98 | 99 | # create shape object 100 | collision_shape = CapsuleShape.new() 101 | 102 | # call set player to ensure our collision shape is sized 103 | set_player_height(player_height) 104 | set_player_radius(player_radius) 105 | 106 | func _physics_process(delta): 107 | # We should be the child or the controller on which the teleport is implemented 108 | var controller = get_parent() 109 | 110 | if !origin_node: 111 | return 112 | 113 | if !camera_node: 114 | return 115 | 116 | # if we're not enabled no point in doing mode 117 | if !enabled: 118 | # reset these 119 | is_teleporting = false; 120 | $Teleport.visible = false 121 | $Target.visible = false 122 | 123 | # and stop this from running until we enable again 124 | set_physics_process(false) 125 | return 126 | 127 | # check if our world scale has changed.. 128 | var new_ws = ARVRServer.world_scale 129 | if ws != new_ws: 130 | ws = new_ws 131 | $Teleport.mesh.size = Vector2(0.05 * ws, 1.0) 132 | $Target.mesh.size = Vector2(ws, ws) 133 | $Target/Player_figure.scale = Vector3(ws, ws, ws) 134 | 135 | if controller and controller.get_is_active() and controller.is_button_pressed(teleport_button): 136 | if !is_teleporting: 137 | is_teleporting = true 138 | $Teleport.visible = true 139 | $Target.visible = true 140 | teleport_rotation = 0.0 141 | 142 | # get our physics engine state 143 | var space = PhysicsServer.body_get_space(self.get_rid()) 144 | var state = PhysicsServer.space_get_direct_state(space) 145 | var query = PhysicsShapeQueryParameters.new() 146 | 147 | # init stuff about our query that doesn't change (note that safe margin and collision_mask need to change once we no longer use kinematic body) 148 | query.collision_mask = collision_mask 149 | query.margin = get_safe_margin() 150 | query.shape_rid = collision_shape.get_rid() 151 | 152 | # make a transform for rotating and offseting our shape, it's always lying on its side by default... 153 | var shape_transform = Transform(Basis(Vector3(1.0, 0.0, 0.0), deg2rad(90.0)), Vector3(0.0, player_height / 2.0, 0.0)) 154 | 155 | # update location 156 | var teleport_global_transform = $Teleport.global_transform 157 | var target_global_origin = teleport_global_transform.origin 158 | var down = Vector3(0.0, -1.0 / ws, 0.0) 159 | 160 | ############################################################ 161 | # New teleport logic 162 | # We're going to use test move in steps to find out where we hit something... 163 | # This can be optimised loads by determining the lenght based on the angle between sections extending the length when we're in a flat part of the arch 164 | # Where we do get a collission we may want to fine tune the collision 165 | var cast_length = 0.0 166 | var fine_tune = 1.0 167 | var hit_something = false 168 | for i in range(1,26): 169 | var new_cast_length = cast_length + (step_size / fine_tune) 170 | var global_target = Vector3(0.0, 0.0, -new_cast_length) 171 | 172 | # our quadratic values 173 | var t = global_target.z / strength 174 | var t2 = t * t 175 | 176 | # target to world space 177 | global_target = teleport_global_transform.xform(global_target) 178 | 179 | # adjust for gravity 180 | global_target += down * t2 181 | 182 | # test our new location for collisions 183 | query.transform = Transform(Basis(), global_target) * shape_transform 184 | var cast_result = state.collide_shape(query, 10) 185 | if cast_result.empty(): 186 | # we didn't collide with anything so check our next section... 187 | cast_length = new_cast_length 188 | target_global_origin = global_target 189 | elif (fine_tune <= 16.0): 190 | # try again with a small step size 191 | fine_tune *= 2.0 192 | else: 193 | var collided_at = target_global_origin 194 | if global_target.y > target_global_origin.y: 195 | # if we're moving up, we hit the ceiling of something, we don't really care what 196 | is_on_floor = false 197 | else: 198 | # now we cast a ray downwards to see if we're on a surface 199 | var up = Vector3(0.0, 1.0, 0.0) 200 | var start_pos = target_global_origin + up 201 | var end_pos = target_global_origin - (up * 0.1) 202 | var intersects = state.intersect_ray(start_pos, end_pos) 203 | if intersects.empty(): 204 | is_on_floor = false 205 | else: 206 | # did we collide with a floor or a wall? 207 | floor_normal = intersects["normal"] 208 | var dot = floor_normal.dot(up) 209 | if dot > 0.9: 210 | is_on_floor = true 211 | else: 212 | is_on_floor = false 213 | 214 | # and return the position at which we intersected 215 | collided_at = intersects["position"] 216 | 217 | # we are colliding, find our if we're colliding on a wall or floor, one we can do, the other nope... 218 | cast_length += (collided_at - target_global_origin).length() 219 | target_global_origin = collided_at 220 | hit_something = true 221 | break 222 | 223 | # and just update our shader 224 | $Teleport.get_surface_material(0).set_shader_param("scale_t", 1.0 / strength) 225 | $Teleport.get_surface_material(0).set_shader_param("ws", ws) 226 | $Teleport.get_surface_material(0).set_shader_param("length", cast_length) 227 | if hit_something: 228 | var color = can_teleport_color 229 | var normal = Vector3(0.0, 1.0, 0.0) 230 | if is_on_floor: 231 | # if we're on the floor we'll reorientate our target to match. 232 | normal = floor_normal 233 | can_teleport = true 234 | else: 235 | can_teleport = false 236 | color = cant_teleport_color 237 | 238 | # check our axis to see if we need to rotate 239 | teleport_rotation += (delta * controller.get_joystick_axis(0) * -4.0) 240 | 241 | # update target and colour 242 | var target_basis = Basis() 243 | target_basis.z = Vector3(teleport_global_transform.basis.z.x, 0.0, teleport_global_transform.basis.z.z).normalized() 244 | target_basis.y = normal 245 | target_basis.x = target_basis.y.cross(target_basis.z) 246 | target_basis.z = target_basis.x.cross(target_basis.y) 247 | 248 | target_basis = target_basis.rotated(normal, teleport_rotation) 249 | last_target_transform.basis = target_basis 250 | last_target_transform.origin = target_global_origin + Vector3(0.0, 0.02, 0.0) 251 | $Target.global_transform = last_target_transform 252 | 253 | $Teleport.get_surface_material(0).set_shader_param("mix_color", color) 254 | $Target.get_surface_material(0).albedo_color = color 255 | $Target.visible = can_teleport 256 | else: 257 | can_teleport = false 258 | $Target.visible = false 259 | $Teleport.get_surface_material(0).set_shader_param("mix_color", no_collision_color) 260 | elif is_teleporting: 261 | if can_teleport: 262 | 263 | # make our target horizontal again 264 | var new_transform = last_target_transform 265 | new_transform.basis.y = Vector3(0.0, 1.0, 0.0) 266 | new_transform.basis.x = new_transform.basis.y.cross(new_transform.basis.z).normalized() 267 | new_transform.basis.z = new_transform.basis.x.cross(new_transform.basis.y).normalized() 268 | 269 | # find out our user's feet's transformation 270 | var cam_transform = camera_node.transform 271 | var user_feet_transform = Transform() 272 | user_feet_transform.origin = cam_transform.origin 273 | user_feet_transform.origin.y = 0 # the feet are on the ground, but have the same X,Z as the camera 274 | 275 | # ensure this transform is upright 276 | user_feet_transform.basis.y = Vector3(0.0, 1.0, 0.0) 277 | user_feet_transform.basis.x = user_feet_transform.basis.y.cross(cam_transform.basis.z).normalized() 278 | user_feet_transform.basis.z = user_feet_transform.basis.x.cross(user_feet_transform.basis.y).normalized() 279 | 280 | # now move the origin such that the new global user_feet_transform would be == new_transform 281 | origin_node.global_transform = new_transform * user_feet_transform.inverse() 282 | 283 | # and disable 284 | is_teleporting = false; 285 | $Teleport.visible = false 286 | $Target.visible = false 287 | 288 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_Teleport.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/functions/Function_Teleport.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/vr-common/materials/teleport.tres" type="Material" id=2] 5 | [ext_resource path="res://addons/vr-common/materials/target.tres" type="Material" id=3] 6 | [ext_resource path="res://addons/vr-common/materials/capule.tres" type="Material" id=4] 7 | 8 | [sub_resource type="PlaneMesh" id=1] 9 | size = Vector2( 0.05, 1 ) 10 | subdivide_depth = 40 11 | 12 | [sub_resource type="PlaneMesh" id=2] 13 | size = Vector2( 1, 1 ) 14 | 15 | [sub_resource type="CapsuleMesh" id=3] 16 | radius = 0.3 17 | mid_height = 1.2 18 | 19 | [node name="Function_Teleport" type="KinematicBody"] 20 | input_ray_pickable = false 21 | collision/safe_margin = 0.01 22 | script = ExtResource( 1 ) 23 | no_collision_color = Color( 0.176471, 0.313726, 0.862745, 1 ) 24 | 25 | [node name="Teleport" type="MeshInstance" parent="."] 26 | mesh = SubResource( 1 ) 27 | material/0 = ExtResource( 2 ) 28 | 29 | [node name="Target" type="MeshInstance" parent="."] 30 | mesh = SubResource( 2 ) 31 | material/0 = ExtResource( 3 ) 32 | 33 | [node name="Player_figure" type="Position3D" parent="Target"] 34 | 35 | [node name="Capsule" type="MeshInstance" parent="Target/Player_figure"] 36 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.9, 0 ) 37 | mesh = SubResource( 3 ) 38 | material/0 = ExtResource( 4 ) 39 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_pointer.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | signal pointer_pressed(on, at) 4 | signal pointer_released(on, at) 5 | signal pointer_moved(on, from, to) 6 | 7 | signal pointer_entered(body) 8 | signal pointer_exited(body) 9 | 10 | export var enabled = true setget set_enabled, get_enabled 11 | export var active_button = 15 12 | export var distance = 10 setget set_distance, get_distance 13 | 14 | # Need to replace this with proper solution once support for layer selection has been added 15 | export (int, FLAGS, "Layer 1", "Layer 2", "Layer 3", "Layer 4", "Layer 5", "Layer 6", "Layer 7", "Layer 8", "Layer 9", "Layer 10", "Layer 11", "Layer 12", "Layer 13", "Layer 14", "Layer 15", "Layer 16", "Layer 17", "Layer 18", "Layer 19", "Layer 20") var collision_mask = 15 setget set_collision_mask, get_collision_mask 16 | 17 | var target = null 18 | var last_target = null 19 | var last_collided_at = Vector3(0, 0, 0) 20 | var laser_y = -0.05 21 | 22 | onready var ws = ARVRServer.world_scale 23 | 24 | func set_enabled(p_enabled): 25 | enabled = p_enabled 26 | 27 | # this gets called before our scene is ready, we'll call this again in _ready to enable this 28 | if $Laser: 29 | $Laser.visible = p_enabled 30 | 31 | $Laser/RayCast.enabled = p_enabled 32 | 33 | func get_enabled(): 34 | return enabled 35 | 36 | func set_collision_mask(p_new_mask): 37 | collision_mask = p_new_mask 38 | 39 | if $Laser: 40 | $Laser/RayCast.collision_mask = collision_mask 41 | 42 | func get_collision_mask(): 43 | return collision_mask 44 | 45 | func set_distance(p_new_value): 46 | distance = p_new_value 47 | if $Laser: 48 | $Laser.mesh.size.z = distance 49 | $Laser.translation.z = distance * -0.5 50 | $Laser/RayCast.translation.z = distance * 0.5 51 | $Laser/RayCast.cast_to.z = -distance 52 | 53 | func get_distance(): 54 | return distance 55 | 56 | func _on_button_pressed(p_button): 57 | if p_button == active_button and enabled: 58 | if $Laser/RayCast.is_colliding(): 59 | target = $Laser/RayCast.get_collider() 60 | last_collided_at = $Laser/RayCast.get_collision_point() 61 | 62 | emit_signal("pointer_pressed", target, last_collided_at) 63 | 64 | func _on_button_release(p_button): 65 | if p_button == active_button and target: 66 | emit_signal("pointer_released", target, last_collided_at) 67 | 68 | # unset target 69 | target = null 70 | last_collided_at = Vector3(0, 0, 0) 71 | 72 | func _ready(): 73 | # Get button press feedback from our parent (should be an ARVRController) 74 | get_parent().connect("button_pressed", self, "_on_button_pressed") 75 | get_parent().connect("button_release", self, "_on_button_release") 76 | 77 | # apply our world scale to our laser position 78 | $Laser.translation.y = laser_y * ws 79 | 80 | # init our state 81 | set_distance(distance) 82 | set_collision_mask(collision_mask) 83 | set_enabled(enabled) 84 | 85 | func _process(delta): 86 | var new_ws = ARVRServer.world_scale 87 | if (ws != new_ws): 88 | ws = new_ws 89 | $Laser.translation.y = laser_y * ws 90 | 91 | if enabled and $Laser/RayCast.is_colliding(): 92 | var new_at = $Laser/RayCast.get_collision_point() 93 | 94 | if target: 95 | # if target is set our mouse must be down, we keep "focus" on our target 96 | if new_at != last_collided_at: 97 | emit_signal("pointer_moved", target, last_collided_at, new_at) 98 | else: 99 | var new_target = $Laser/RayCast.get_collider() 100 | 101 | # are we pointing to a new target? 102 | if new_target != last_target: 103 | # exit the old 104 | if last_target: 105 | emit_signal("pointer_exited", last_target) 106 | 107 | # enter the new 108 | if new_target: 109 | emit_signal("pointer_entered", new_target) 110 | 111 | last_target = new_target 112 | 113 | if new_at != last_collided_at: 114 | emit_signal("pointer_moved", new_target, last_collided_at, new_at) 115 | 116 | # remember our new position 117 | last_collided_at = new_at 118 | elif last_target: 119 | emit_signal("pointer_exited", last_target) 120 | last_target = null 121 | 122 | -------------------------------------------------------------------------------- /addons/vr-common/functions/Function_pointer.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/materials/pointer.tres" type="Material" id=1] 4 | [ext_resource path="res://addons/vr-common/functions/Function_pointer.gd" type="Script" id=2] 5 | 6 | [sub_resource type="CubeMesh" id=1] 7 | resource_local_to_scene = true 8 | material = ExtResource( 1 ) 9 | size = Vector3( 0.002, 0.002, 10 ) 10 | subdivide_depth = 20 11 | 12 | [node name="Function_pointer" type="Spatial"] 13 | transform = Transform( 1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 0, 0 ) 14 | script = ExtResource( 2 ) 15 | collision_mask = 1048575 16 | 17 | [node name="Laser" type="MeshInstance" parent="."] 18 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, -5 ) 19 | cast_shadow = 0 20 | mesh = SubResource( 1 ) 21 | material/0 = null 22 | 23 | [node name="RayCast" type="RayCast" parent="Laser"] 24 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5 ) 25 | enabled = true 26 | cast_to = Vector3( 0, 0, -10 ) 27 | collision_mask = 1048575 28 | -------------------------------------------------------------------------------- /addons/vr-common/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/addons/vr-common/images/icon.png -------------------------------------------------------------------------------- /addons/vr-common/images/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-fb3b2ecb55ac1327d82f6710eba4f8b4.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/vr-common/images/icon.png" 13 | dest_files=[ "res://.import/icon.png-fb3b2ecb55ac1327d82f6710eba4f8b4.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /addons/vr-common/images/teleport_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/addons/vr-common/images/teleport_arrow.png -------------------------------------------------------------------------------- /addons/vr-common/images/teleport_arrow.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path.s3tc="res://.import/teleport_arrow.png-9ee8732a3d27e6e53f97efad743b9f9b.s3tc.stex" 6 | path.etc2="res://.import/teleport_arrow.png-9ee8732a3d27e6e53f97efad743b9f9b.etc2.stex" 7 | metadata={ 8 | "imported_formats": [ "s3tc", "etc2" ], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://addons/vr-common/images/teleport_arrow.png" 15 | dest_files=[ "res://.import/teleport_arrow.png-9ee8732a3d27e6e53f97efad743b9f9b.s3tc.stex", "res://.import/teleport_arrow.png-9ee8732a3d27e6e53f97efad743b9f9b.etc2.stex" ] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/lossy_quality=0.7 21 | compress/hdr_mode=0 22 | compress/bptc_ldr=0 23 | compress/normal_map=0 24 | flags/repeat=true 25 | flags/filter=true 26 | flags/mipmaps=true 27 | flags/anisotropic=false 28 | flags/srgb=1 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/HDR_as_SRGB=false 32 | process/invert_color=false 33 | stream=false 34 | size_limit=0 35 | detect_3d=false 36 | svg/scale=1.0 37 | -------------------------------------------------------------------------------- /addons/vr-common/images/teleport_target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/addons/vr-common/images/teleport_target.png -------------------------------------------------------------------------------- /addons/vr-common/images/teleport_target.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path.s3tc="res://.import/teleport_target.png-779f853f62e0e2207f5821dfbc8b780c.s3tc.stex" 6 | path.etc2="res://.import/teleport_target.png-779f853f62e0e2207f5821dfbc8b780c.etc2.stex" 7 | metadata={ 8 | "imported_formats": [ "s3tc", "etc2" ], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://addons/vr-common/images/teleport_target.png" 15 | dest_files=[ "res://.import/teleport_target.png-779f853f62e0e2207f5821dfbc8b780c.s3tc.stex", "res://.import/teleport_target.png-779f853f62e0e2207f5821dfbc8b780c.etc2.stex" ] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/lossy_quality=0.7 21 | compress/hdr_mode=0 22 | compress/bptc_ldr=0 23 | compress/normal_map=0 24 | flags/repeat=true 25 | flags/filter=true 26 | flags/mipmaps=true 27 | flags/anisotropic=false 28 | flags/srgb=1 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/HDR_as_SRGB=false 32 | process/invert_color=false 33 | stream=false 34 | size_limit=0 35 | detect_3d=false 36 | svg/scale=1.0 37 | -------------------------------------------------------------------------------- /addons/vr-common/materials/capule.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="SpatialMaterial" format=2] 2 | 3 | [resource] 4 | flags_transparent = true 5 | albedo_color = Color( 0.0337219, 0.241112, 0.863281, 0.497255 ) 6 | roughness = 0.0 7 | 8 | -------------------------------------------------------------------------------- /addons/vr-common/materials/pointer.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="SpatialMaterial" format=2] 2 | 3 | [resource] 4 | flags_unshaded = true 5 | params_diffuse_mode = 1 6 | albedo_color = Color( 1, 0.15625, 0.15625, 0.740314 ) 7 | 8 | -------------------------------------------------------------------------------- /addons/vr-common/materials/target.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="SpatialMaterial" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/images/teleport_target.png" type="Texture" id=1] 4 | 5 | [resource] 6 | flags_transparent = true 7 | flags_unshaded = true 8 | params_diffuse_mode = 1 9 | params_cull_mode = 2 10 | albedo_color = Color( 0.176471, 0.313726, 0.862745, 1 ) 11 | albedo_texture = ExtResource( 1 ) 12 | 13 | -------------------------------------------------------------------------------- /addons/vr-common/materials/teleport.shader: -------------------------------------------------------------------------------- 1 | shader_type spatial; 2 | render_mode unshaded, cull_disabled, skip_vertex_transform; 3 | 4 | uniform float scale_t = 0.2; 5 | uniform float length = 20.0; 6 | uniform float ws = 1.0; 7 | uniform vec4 mix_color : hint_color; 8 | uniform sampler2D arrow_texture : hint_albedo; 9 | 10 | void vertex() { 11 | vec3 down = vec3(0.0, -1.0 / ws, 0.0); 12 | 13 | // offset our Z so we're projecting from our origin point 14 | VERTEX.z -= 0.5; 15 | VERTEX.z *= length; 16 | 17 | // now use that to create our arch 18 | float t = VERTEX.z * scale_t; 19 | float t2 = t * t; 20 | 21 | // translate to our world vector 22 | VERTEX = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz; 23 | 24 | // and now create our arch 25 | VERTEX += down * t2; 26 | 27 | // and apply our camera matrix 28 | VERTEX = (INV_CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; 29 | } 30 | 31 | void fragment() { 32 | // and do our color 33 | float offset = (TIME * 2.0); 34 | vec4 col = texture(arrow_texture, vec2(UV.x, (UV.y * length * 4.0) + offset )).rgba; 35 | ALBEDO = col.rgb * mix_color.rgb; 36 | 37 | // need to fix up our image and add an alpha channel 38 | ALPHA = col.a; 39 | } 40 | -------------------------------------------------------------------------------- /addons/vr-common/materials/teleport.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="ShaderMaterial" load_steps=3 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/materials/teleport.shader" type="Shader" id=1] 4 | [ext_resource path="res://addons/vr-common/images/teleport_arrow.png" type="Texture" id=2] 5 | 6 | [resource] 7 | shader = ExtResource( 1 ) 8 | shader_param/scale_t = 0.2 9 | shader_param/length = 30.0 10 | shader_param/ws = 1.0 11 | shader_param/mix_color = Color( 0.176471, 0.313726, 0.862745, 1 ) 12 | shader_param/arrow_texture = ExtResource( 2 ) 13 | 14 | -------------------------------------------------------------------------------- /addons/vr-common/misc/VR_Common_Shader_Cache.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | var countdown = 2 4 | 5 | # Called every frame. 'delta' is the elapsed time since the previous frame. 6 | func _process(delta): 7 | countdown = countdown - 1 8 | if countdown == 0: 9 | visible = false 10 | set_process(false) 11 | -------------------------------------------------------------------------------- /addons/vr-common/misc/VR_Common_Shader_Cache.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/misc/VR_Common_Shader_Cache.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/vr-common/materials/teleport.tres" type="Material" id=2] 5 | [ext_resource path="res://addons/vr-common/materials/target.tres" type="Material" id=3] 6 | [ext_resource path="res://addons/vr-common/materials/capule.tres" type="Material" id=4] 7 | [ext_resource path="res://addons/vr-common/materials/pointer.tres" type="Material" id=5] 8 | 9 | [sub_resource type="PlaneMesh" id=2] 10 | size = Vector2( 0.001, 0.001 ) 11 | 12 | [node name="vr_common_shader_cache" type="Spatial"] 13 | script = ExtResource( 1 ) 14 | 15 | [node name="teleport" type="MeshInstance" parent="."] 16 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ) 17 | mesh = SubResource( 2 ) 18 | material/0 = ExtResource( 2 ) 19 | 20 | [node name="target" type="MeshInstance" parent="."] 21 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ) 22 | mesh = SubResource( 2 ) 23 | material/0 = ExtResource( 3 ) 24 | 25 | [node name="capsule" type="MeshInstance" parent="."] 26 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ) 27 | mesh = SubResource( 2 ) 28 | material/0 = ExtResource( 4 ) 29 | 30 | [node name="pointer" type="MeshInstance" parent="."] 31 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ) 32 | mesh = SubResource( 2 ) 33 | material/0 = ExtResource( 5 ) 34 | 35 | -------------------------------------------------------------------------------- /addons/vr-common/objects/Object_pickable.gd: -------------------------------------------------------------------------------- 1 | extends RigidBody 2 | 3 | # Set hold mode 4 | export (bool) var press_to_hold = true 5 | export (int, FLAGS, "layer_1", "layer_2", "layer_3", "layer_4", "layer_5") var picked_up_layer = 0 6 | 7 | # Remember some state so we can return to it when the user drops the object 8 | onready var original_parent = get_parent() 9 | onready var original_collision_mask = collision_mask 10 | onready var original_collision_layer = collision_layer 11 | 12 | # Who picked us up? 13 | var picked_up_by = null 14 | var by_controller : ARVRController = null 15 | var closest_count = 0 16 | 17 | # have we been picked up? 18 | func is_picked_up(): 19 | if picked_up_by: 20 | return true 21 | 22 | return false 23 | 24 | func _update_highlight(): 25 | # should probably implement this in our subclass 26 | pass 27 | 28 | func increase_is_closest(): 29 | closest_count += 1 30 | _update_highlight() 31 | 32 | func decrease_is_closest(): 33 | closest_count -= 1 34 | _update_highlight() 35 | 36 | func drop_and_free(): 37 | if picked_up_by: 38 | picked_up_by.drop_object() 39 | 40 | queue_free() 41 | 42 | # we are being picked up by... 43 | func pick_up(by, with_controller): 44 | if picked_up_by == by: 45 | return 46 | 47 | if picked_up_by: 48 | let_go() 49 | 50 | # remember who picked us up 51 | picked_up_by = by 52 | by_controller = with_controller 53 | 54 | # turn off physics on our pickable object 55 | mode = RigidBody.MODE_STATIC 56 | collision_layer = picked_up_layer 57 | collision_mask = 0 58 | 59 | # now reparent it 60 | original_parent.remove_child(self) 61 | picked_up_by.add_child(self) 62 | 63 | # reset our transform 64 | transform = Transform() 65 | 66 | # we are being let go 67 | func let_go(impulse = Vector3(0.0, 0.0, 0.0)): 68 | if picked_up_by: 69 | # get our current global transform 70 | var t = global_transform 71 | 72 | # reparent it 73 | picked_up_by.remove_child(self) 74 | original_parent.add_child(self) 75 | 76 | # reposition it and apply impulse 77 | global_transform = t 78 | mode = RigidBody.MODE_RIGID 79 | collision_mask = original_collision_mask 80 | collision_layer = original_collision_layer 81 | apply_impulse(Vector3(0.0, 0.0, 0.0), impulse) 82 | 83 | # we are no longer picked up 84 | picked_up_by = null 85 | by_controller = null 86 | -------------------------------------------------------------------------------- /addons/vr-common/objects/Object_pickable.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/vr-common/objects/Object_pickable.gd" type="Script" id=1] 4 | 5 | [node name="PickableObject" type="RigidBody"] 6 | collision_layer = 6 7 | collision_mask = 6 8 | script = ExtResource( 1 ) 9 | 10 | [node name="CollisionShape" type="CollisionShape" parent="."] 11 | -------------------------------------------------------------------------------- /assets/fonts/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, ParaType Ltd. (http://www.paratype.com/public), 2 | with Reserved Font Names "PT Sans" and "ParaType". 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /assets/fonts/PT_Sans-Web-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/assets/fonts/PT_Sans-Web-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/pt_sans.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFontData" format=2] 2 | 3 | [resource] 4 | font_path = "res://assets/fonts/PT_Sans-Web-Bold.ttf" 5 | -------------------------------------------------------------------------------- /assets/textures/Godot/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/assets/textures/Godot/splash.png -------------------------------------------------------------------------------- /assets/textures/Godot/splash.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path.s3tc="res://.import/splash.png-4c5f840d4665a2d33ec8f1db79c5957b.s3tc.stex" 6 | path.etc2="res://.import/splash.png-4c5f840d4665a2d33ec8f1db79c5957b.etc2.stex" 7 | metadata={ 8 | "imported_formats": [ "s3tc", "etc2" ], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://assets/textures/Godot/splash.png" 15 | dest_files=[ "res://.import/splash.png-4c5f840d4665a2d33ec8f1db79c5957b.s3tc.stex", "res://.import/splash.png-4c5f840d4665a2d33ec8f1db79c5957b.etc2.stex" ] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/lossy_quality=0.7 21 | compress/hdr_mode=0 22 | compress/bptc_ldr=0 23 | compress/normal_map=0 24 | flags/repeat=true 25 | flags/filter=true 26 | flags/mipmaps=true 27 | flags/anisotropic=false 28 | flags/srgb=1 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/HDR_as_SRGB=false 32 | process/invert_color=false 33 | stream=false 34 | size_limit=0 35 | detect_3d=false 36 | svg/scale=1.0 37 | -------------------------------------------------------------------------------- /assets/textures/Scene/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/assets/textures/Scene/grid.png -------------------------------------------------------------------------------- /assets/textures/Scene/grid.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path.s3tc="res://.import/grid.png-03d673ffffaab7b59c3db8e41bf236d5.s3tc.stex" 6 | path.etc2="res://.import/grid.png-03d673ffffaab7b59c3db8e41bf236d5.etc2.stex" 7 | metadata={ 8 | "imported_formats": [ "s3tc", "etc2" ], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://assets/textures/Scene/grid.png" 15 | dest_files=[ "res://.import/grid.png-03d673ffffaab7b59c3db8e41bf236d5.s3tc.stex", "res://.import/grid.png-03d673ffffaab7b59c3db8e41bf236d5.etc2.stex" ] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/lossy_quality=0.7 21 | compress/hdr_mode=0 22 | compress/bptc_ldr=0 23 | compress/normal_map=0 24 | flags/repeat=true 25 | flags/filter=true 26 | flags/mipmaps=true 27 | flags/anisotropic=false 28 | flags/srgb=1 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/HDR_as_SRGB=false 32 | process/invert_color=false 33 | stream=false 34 | size_limit=0 35 | detect_3d=false 36 | svg/scale=1.0 37 | -------------------------------------------------------------------------------- /default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | 5 | [resource] 6 | background_mode = 1 7 | background_sky = SubResource( 1 ) 8 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/icon.png -------------------------------------------------------------------------------- /icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://icon.png" 13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /main.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | onready var resource_queue = get_node('/root/resource_queue') 4 | 5 | enum LoadingStates { 6 | FADE_TO_BLACK_1, 7 | FADE_TO_LOADING, 8 | LOADING, 9 | FADE_TO_BLACK_2, 10 | FADE_TO_WORLD, 11 | PLAYING 12 | } 13 | 14 | var loading_state = LoadingStates.PLAYING 15 | var current_world = null 16 | var loading_world = null 17 | 18 | func load_world(scene_to_load): 19 | # remember which scene we're loading 20 | loading_world = scene_to_load 21 | 22 | # start loading 23 | resource_queue.queue_resource(loading_world) 24 | 25 | # fade to black, if we've already faded to black (startup) we get our signal immediately 26 | loading_state = LoadingStates.FADE_TO_BLACK_1 27 | $FadeToBlack.is_faded = true 28 | 29 | # Called when the node enters the scene tree for the first time. 30 | func _ready(): 31 | resource_queue.start() 32 | 33 | # load our first scene 34 | #load_world('res://scenes/test_scene/test_scene.tscn') 35 | load_world('res://scenes/selection/selection.tscn') 36 | 37 | func _on_FadeToBlack_finished_fading(): 38 | match loading_state: 39 | LoadingStates.FADE_TO_BLACK_1: 40 | # hide our world scene 41 | $World_scene.visible = false 42 | 43 | # remove our current world 44 | if current_world: 45 | current_world.disconnect("load_world", self, "load_world") 46 | $World_scene.remove_child(current_world) 47 | current_world.queue_free() 48 | current_world = null 49 | 50 | # Position our player in the center 51 | $OVRFirstPerson.position_player(Transform()) 52 | 53 | # Disable our functions 54 | $OVRFirstPerson.enable_locomotion = false 55 | $OVRFirstPerson.enable_pointer = false 56 | 57 | # unhide our loading scene 58 | $Loading_scene.visible = true 59 | 60 | # fade to transparent 61 | loading_state = LoadingStates.FADE_TO_LOADING 62 | $FadeToBlack.is_faded = false 63 | LoadingStates.FADE_TO_LOADING: 64 | # simply change the state to loading 65 | loading_state = LoadingStates.LOADING 66 | set_process(true) 67 | LoadingStates.FADE_TO_BLACK_2: 68 | # hide our loading scene 69 | $Loading_scene.visible = false 70 | 71 | # add our new scene 72 | $World_scene.add_child(current_world) 73 | current_world.init_world($OVRFirstPerson) 74 | current_world.connect("load_world", self, "load_world") 75 | $World_scene.visible = true 76 | 77 | # fade to transparent 78 | loading_state = LoadingStates.FADE_TO_WORLD 79 | $FadeToBlack.is_faded = false 80 | LoadingStates.FADE_TO_WORLD: 81 | # simply set the state to playing 82 | loading_state = LoadingStates.PLAYING 83 | _: 84 | # nothing to do in all other states 85 | pass 86 | 87 | func _process(delta): 88 | if loading_state == LoadingStates.LOADING: 89 | # we could do something with a progress bar here 90 | 91 | # check if our resource is available 92 | var new_world = resource_queue.get_resource(loading_world) 93 | if new_world: 94 | # if we're finished create a new instance 95 | current_world = new_world.instance() 96 | 97 | # fade to black 98 | loading_state = LoadingStates.FADE_TO_BLACK_2 99 | $FadeToBlack.is_faded = true 100 | set_process(false) 101 | -------------------------------------------------------------------------------- /main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=10 format=2] 2 | 3 | [ext_resource path="res://main.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/godot-openvr/scenes/ovr_first_person.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://player/player.gd" type="Script" id=3] 6 | [ext_resource path="res://scenes/loading/Loading_scene.tscn" type="PackedScene" id=4] 7 | [ext_resource path="res://misc/effects/FadeToBlack.tscn" type="PackedScene" id=5] 8 | [ext_resource path="res://addons/vr-common/functions/Function_Direct_movement.tscn" type="PackedScene" id=6] 9 | [ext_resource path="res://addons/vr-common/functions/Function_Teleport.tscn" type="PackedScene" id=7] 10 | [ext_resource path="res://addons/vr-common/functions/Function_pointer.tscn" type="PackedScene" id=8] 11 | [ext_resource path="res://addons/vr-common/misc/VR_Common_Shader_Cache.tscn" type="PackedScene" id=9] 12 | 13 | [node name="Main" type="Spatial"] 14 | script = ExtResource( 1 ) 15 | 16 | [node name="FadeToBlack" parent="." instance=ExtResource( 5 )] 17 | 18 | [node name="OVRFirstPerson" parent="." instance=ExtResource( 2 )] 19 | script = ExtResource( 3 ) 20 | 21 | [node name="vr_common_shader_cache" parent="OVRFirstPerson/ARVRCamera/shader_cache" index="5" instance=ExtResource( 9 )] 22 | 23 | [node name="Function_Teleport" parent="OVRFirstPerson/Left_Hand" index="1" instance=ExtResource( 7 )] 24 | collision_layer = 0 25 | collision_mask = 1048574 26 | enabled = false 27 | camera = NodePath("../../ARVRCamera") 28 | 29 | [node name="Function_pointer" parent="OVRFirstPerson/Left_Hand" index="2" instance=ExtResource( 8 )] 30 | enabled = false 31 | collision_mask = 1048574 32 | 33 | [node name="Function_Direct_movement" parent="OVRFirstPerson/Right_Hand" index="1" instance=ExtResource( 6 )] 34 | enabled = false 35 | camera = NodePath("../../ARVRCamera") 36 | 37 | [node name="Function_pointer" parent="OVRFirstPerson/Right_Hand" index="2" instance=ExtResource( 8 )] 38 | enabled = false 39 | collision_mask = 1048574 40 | 41 | [node name="Loading_scene" parent="." instance=ExtResource( 4 )] 42 | 43 | [node name="World_scene" type="Spatial" parent="."] 44 | visible = false 45 | [connection signal="finished_fading" from="FadeToBlack" to="." method="_on_FadeToBlack_finished_fading"] 46 | [connection signal="button_pressed" from="OVRFirstPerson/Left_Hand" to="OVRFirstPerson" method="_on_Left_Hand_button_pressed"] 47 | [connection signal="pointer_moved" from="OVRFirstPerson/Left_Hand/Function_pointer" to="OVRFirstPerson" method="_on_Function_pointer_pointer_moved"] 48 | [connection signal="pointer_pressed" from="OVRFirstPerson/Left_Hand/Function_pointer" to="OVRFirstPerson" method="_on_Function_pointer_pointer_pressed"] 49 | [connection signal="pointer_released" from="OVRFirstPerson/Left_Hand/Function_pointer" to="OVRFirstPerson" method="_on_Function_pointer_pointer_released"] 50 | [connection signal="button_pressed" from="OVRFirstPerson/Right_Hand" to="OVRFirstPerson" method="_on_Right_Hand_button_pressed"] 51 | [connection signal="pointer_moved" from="OVRFirstPerson/Right_Hand/Function_pointer" to="OVRFirstPerson" method="_on_Function_pointer_pointer_moved"] 52 | [connection signal="pointer_pressed" from="OVRFirstPerson/Right_Hand/Function_pointer" to="OVRFirstPerson" method="_on_Function_pointer_pointer_pressed"] 53 | [connection signal="pointer_released" from="OVRFirstPerson/Right_Hand/Function_pointer" to="OVRFirstPerson" method="_on_Function_pointer_pointer_released"] 54 | 55 | [editable path="OVRFirstPerson"] 56 | -------------------------------------------------------------------------------- /misc/effects/FadeToBlack.gd: -------------------------------------------------------------------------------- 1 | extends ColorRect 2 | 3 | signal finished_fading 4 | 5 | export var is_faded = true setget set_is_faded, get_is_faded 6 | export var duration = 1.0 7 | var alpha = 1.0 8 | 9 | func set_is_faded(new_value: bool): 10 | is_faded = new_value 11 | set_process(true) 12 | 13 | func get_is_faded(): 14 | return is_faded 15 | 16 | func _process(delta): 17 | # either fade in or out 18 | if is_faded: 19 | if alpha < 1.0: 20 | alpha = clamp(alpha + (delta / duration), 0.0, 1.0) 21 | else: 22 | set_process(false) 23 | emit_signal("finished_fading") 24 | else: 25 | if alpha > 0.0: 26 | alpha = clamp(alpha - (delta / duration), 0.0, 1.0) 27 | else: 28 | set_process(false) 29 | emit_signal("finished_fading") 30 | 31 | # update our color 32 | color = Color(0.0, 0.0, 0.0, alpha) 33 | 34 | # until we're fully transparent, keep this visible 35 | visible = alpha > 0.0 36 | 37 | -------------------------------------------------------------------------------- /misc/effects/FadeToBlack.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://misc/effects/FadeToBlack.gd" type="Script" id=1] 4 | 5 | [node name="FadeToBlack" type="ColorRect"] 6 | margin_right = 5000.0 7 | margin_bottom = 5000.0 8 | color = Color( 0, 0, 0, 1 ) 9 | script = ExtResource( 1 ) 10 | __meta__ = { 11 | "_edit_use_anchors_": false 12 | } 13 | -------------------------------------------------------------------------------- /misc/resource_queue.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | # From https://docs.godotengine.org/en/3.1/tutorials/io/background_loading.html#using-multiple-threads 4 | # I guess written by Punto? 5 | # Few small improvements by Mux213 6 | 7 | var thread = null 8 | var mutex = null 9 | var sem = null 10 | 11 | var time_max = 100 # msec 12 | var running = false # have we started our thread? 13 | 14 | var queue = [] 15 | var pending = {} 16 | 17 | func _lock(caller): 18 | mutex.lock() 19 | 20 | func _unlock(caller): 21 | mutex.unlock() 22 | 23 | func _post(caller): 24 | sem.post() 25 | 26 | func _wait(caller): 27 | sem.wait() 28 | 29 | func queue_resource(path, p_in_front = false): 30 | _lock("queue_resource") 31 | if path in pending: 32 | _unlock("queue_resource") 33 | return 34 | 35 | elif ResourceLoader.has(path): 36 | var res = ResourceLoader.load(path) 37 | pending[path] = res 38 | _unlock("queue_resource") 39 | return 40 | else: 41 | var res = ResourceLoader.load_interactive(path) 42 | res.set_meta("path", path) 43 | if p_in_front: 44 | queue.insert(0, res) 45 | else: 46 | queue.push_back(res) 47 | pending[path] = res 48 | _post("queue_resource") 49 | _unlock("queue_resource") 50 | return 51 | 52 | func cancel_resource(path): 53 | _lock("cancel_resource") 54 | if path in pending: 55 | if pending[path] is ResourceInteractiveLoader: 56 | queue.erase(pending[path]) 57 | pending.erase(path) 58 | _unlock("cancel_resource") 59 | 60 | func get_progress(path): 61 | _lock("get_progress") 62 | var ret = -1 63 | if path in pending: 64 | if pending[path] is ResourceInteractiveLoader: 65 | ret = float(pending[path].get_stage()) / float(pending[path].get_stage_count()) 66 | else: 67 | ret = 1.0 68 | _unlock("get_progress") 69 | 70 | return ret 71 | 72 | func is_ready(path): 73 | var ret 74 | _lock("is_ready") 75 | if path in pending: 76 | ret = !(pending[path] is ResourceInteractiveLoader) 77 | else: 78 | ret = false 79 | 80 | _unlock("is_ready") 81 | 82 | return ret 83 | 84 | func _wait_for_resource(res, path): 85 | _unlock("wait_for_resource") 86 | while true: 87 | VisualServer.sync() 88 | OS.delay_usec(16000) # wait 1 frame 89 | _lock("wait_for_resource") 90 | if queue.size() == 0 || queue[0] != res: 91 | return pending[path] 92 | _unlock("wait_for_resource") 93 | 94 | 95 | func get_resource(path): 96 | _lock("get_resource") 97 | if path in pending: 98 | if pending[path] is ResourceInteractiveLoader: 99 | var res = pending[path] 100 | if res != queue[0]: 101 | var pos = queue.find(res) 102 | queue.remove(pos) 103 | queue.insert(0, res) 104 | 105 | res = _wait_for_resource(res, path) 106 | 107 | pending.erase(path) 108 | _unlock("return") 109 | return res 110 | 111 | else: 112 | var res = pending[path] 113 | pending.erase(path) 114 | _unlock("return") 115 | return res 116 | else: 117 | _unlock("return") 118 | return ResourceLoader.load(path) 119 | 120 | func thread_process(): 121 | _wait("thread_process") 122 | 123 | _lock("process") 124 | 125 | while queue.size() > 0: 126 | 127 | var res = queue[0] 128 | 129 | _unlock("process_poll") 130 | var ret = res.poll() 131 | _lock("process_check_queue") 132 | 133 | if ret == ERR_FILE_EOF || ret != OK: 134 | var path = res.get_meta("path") 135 | if path in pending: # else it was already retrieved 136 | pending[res.get_meta("path")] = res.get_resource() 137 | 138 | queue.erase(res) # something might have been put at the front of the queue while we polled, so use erase instead of remove 139 | 140 | _unlock("process") 141 | 142 | 143 | func thread_func(u): 144 | running = true 145 | while running: 146 | thread_process() 147 | 148 | # Should we clean up our pending resource loaders? 149 | # I don't think it matters 150 | 151 | func _is_running(): 152 | _lock("is_running") 153 | 154 | var res = running 155 | 156 | _unlock("is_running") 157 | 158 | return res 159 | 160 | func start(): 161 | if !mutex: 162 | mutex = Mutex.new() 163 | if !sem: 164 | sem = Semaphore.new() 165 | if !thread: 166 | thread = Thread.new() 167 | 168 | if !_is_running(): 169 | thread.start(self, "thread_func", 0) 170 | 171 | func stop(): 172 | if _is_running(): 173 | # cause our thread loop to exit 174 | _lock("stop_running") 175 | running = false 176 | _unlock("stop_running") 177 | 178 | # and wait for our thread to exit cleanly.. 179 | thread.wait_to_finish(); 180 | -------------------------------------------------------------------------------- /player/player.gd: -------------------------------------------------------------------------------- 1 | extends ARVROrigin 2 | 3 | export var enable_locomotion = false setget set_enable_locomotion, get_enable_locomotion 4 | export var enable_pointer = false setget set_enable_pointer, get_enable_pointer 5 | 6 | onready var teleport_function = $Left_Hand/Function_Teleport 7 | onready var direct_function = $Right_Hand/Function_Direct_movement 8 | onready var left_pointer = $Left_Hand/Function_pointer 9 | onready var right_pointer = $Right_Hand/Function_pointer 10 | 11 | # left = 0, right = 1 12 | var pointer_on_hand = 1 13 | 14 | func set_enable_locomotion(new_value): 15 | enable_locomotion = new_value 16 | 17 | if teleport_function: 18 | teleport_function.enabled = enable_locomotion 19 | 20 | if direct_function: 21 | direct_function.enabled = enable_locomotion 22 | 23 | func get_enable_locomotion(): 24 | return enable_locomotion 25 | 26 | func set_enable_pointer(new_value): 27 | enable_pointer = new_value 28 | 29 | if left_pointer: 30 | left_pointer.enabled = enable_pointer and pointer_on_hand == 0 31 | 32 | if right_pointer: 33 | right_pointer.enabled = enable_pointer and pointer_on_hand == 1 34 | 35 | func get_enable_pointer(): 36 | return enable_pointer 37 | 38 | func get_camera_transform(): 39 | return $ARVRCamera.global_transform 40 | 41 | # position our player at a given location and orientation 42 | func position_player(new_transform : Transform): 43 | var t : Transform = $ARVRCamera.transform 44 | 45 | # ignore the height of our camera 46 | t.origin.y = 0.0 47 | 48 | # remove the tilt of our camera 49 | t.basis.y = Vector3(0.0, 1.0, 0.0) # up 50 | t.basis.z.y = 0.0 51 | if t.basis.z.length() == 0.0: 52 | # we're looking straight up or down 53 | t.basis.x = Vector3(1.0, 0.0, 0.0) 54 | t.basis.z = Vector3(0.0, 0.0, 1.0) 55 | else: 56 | t.basis.z = t.basis.z.normalized() 57 | t.basis.x = t.basis.y.cross(t.basis.z).normalized() 58 | 59 | # inverse the camera matrix 60 | t = t.inverse() 61 | 62 | # and combine it with the transform we want the player at 63 | global_transform = new_transform * t 64 | 65 | # Called when the node enters the scene tree for the first time. 66 | func _ready(): 67 | var interface = ARVRServer.find_interface('OpenVR') 68 | if interface and interface.initialize(): 69 | var vp = get_viewport() 70 | 71 | # turn our arvr mode on for our viewport 72 | vp.arvr = true 73 | 74 | # set 3d linear, colors will look correct in the headset but darker on screen. 75 | # vp.keep_3d_linear = true 76 | 77 | # turn off vsync, our HMD renders at a higher refresh rate 78 | OS.vsync_enabled = false 79 | 80 | # set target FPS to 90 81 | Engine.target_fps = 90 82 | 83 | # reassign this as they are originally called before our scene is ready 84 | set_enable_locomotion(enable_locomotion) 85 | set_enable_pointer(enable_pointer) 86 | 87 | func _on_Left_Hand_button_pressed(button): 88 | if button == left_pointer.active_button and enable_pointer and pointer_on_hand == 1: 89 | pointer_on_hand = 0 90 | 91 | # reenable to switch hands 92 | set_enable_pointer(enable_pointer) 93 | 94 | func _on_Right_Hand_button_pressed(button): 95 | if button == right_pointer.active_button and enable_pointer and pointer_on_hand == 0: 96 | pointer_on_hand = 1 97 | 98 | # reenable to switch hands 99 | set_enable_pointer(enable_pointer) 100 | 101 | func _on_Function_pointer_pointer_moved(on, from, to): 102 | if on.has_method('pointer_moved'): 103 | on.pointer_moved(from, to) 104 | 105 | func _on_Function_pointer_pointer_pressed(on, at): 106 | if on.has_method('pointer_pressed'): 107 | on.pointer_pressed(at) 108 | 109 | func _on_Function_pointer_pointer_released(on, at): 110 | if on.has_method('pointer_released'): 111 | on.pointer_released(at) 112 | -------------------------------------------------------------------------------- /project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | _global_script_classes=[ ] 12 | _global_script_class_icons={ 13 | 14 | } 15 | 16 | [application] 17 | 18 | config/name="Godot Background Loading" 19 | run/main_scene="res://main.tscn" 20 | config/icon="res://icon.png" 21 | 22 | [autoload] 23 | 24 | resource_queue="*res://misc/resource_queue.gd" 25 | 26 | [gdnative] 27 | 28 | singletons=[ "res://addons/godot-openvr/godot_openvr.gdnlib" ] 29 | 30 | [layer_names] 31 | 32 | 3d_physics/layer_1="Player" 33 | 3d_physics/layer_2="Environment" 34 | 35 | [rendering] 36 | 37 | environment/default_clear_color=Color( 0.301961, 0.301961, 0.301961, 1 ) 38 | environment/default_environment="res://default_env.tres" 39 | -------------------------------------------------------------------------------- /scenes/base_scene.gd: -------------------------------------------------------------------------------- 1 | extends Spatial 2 | 3 | signal load_world(scene) 4 | 5 | export var enable_locomotion = false setget set_enable_locomotion, get_enable_locomotion 6 | export var enable_pointer = false setget set_enable_pointer, get_enable_pointer 7 | 8 | var player_node : ARVROrigin 9 | 10 | func set_enable_locomotion(new_value): 11 | enable_locomotion = new_value 12 | 13 | if player_node: 14 | player_node.enable_locomotion = enable_locomotion 15 | 16 | func get_enable_locomotion(): 17 | return enable_locomotion 18 | 19 | func set_enable_pointer(new_value): 20 | enable_pointer = new_value 21 | 22 | if player_node: 23 | player_node.enable_pointer = enable_pointer 24 | 25 | func get_enable_pointer(): 26 | return enable_pointer 27 | 28 | func init_world(new_player_node : ARVROrigin): 29 | # remember our player node 30 | player_node = new_player_node 31 | 32 | # update our functions 33 | set_enable_locomotion(enable_locomotion) 34 | set_enable_pointer(enable_pointer) 35 | 36 | # and use our spawn point to set our player position 37 | player_node.position_player($PlayerSpawnPoint.global_transform) 38 | 39 | # Called when the node enters the scene tree for the first time. 40 | func _ready(): 41 | pass # Replace with function body. 42 | 43 | -------------------------------------------------------------------------------- /scenes/base_scene.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://scenes/base_scene.gd" type="Script" id=1] 4 | 5 | [node name="Scene" type="Spatial"] 6 | script = ExtResource( 1 ) 7 | 8 | [node name="PlayerSpawnPoint" type="Position3D" parent="."] 9 | 10 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."] 11 | -------------------------------------------------------------------------------- /scenes/loading/Loading_scene.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://assets/textures/Godot/splash.png" type="Texture" id=1] 4 | 5 | [sub_resource type="SpatialMaterial" id=1] 6 | flags_transparent = true 7 | flags_unshaded = true 8 | albedo_texture = ExtResource( 1 ) 9 | 10 | [sub_resource type="QuadMesh" id=2] 11 | material = SubResource( 1 ) 12 | size = Vector2( 200, 150 ) 13 | 14 | [node name="Loading_scene" type="Spatial"] 15 | 16 | [node name="Godot logo" type="MeshInstance" parent="."] 17 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -200 ) 18 | mesh = SubResource( 2 ) 19 | material/0 = null 20 | -------------------------------------------------------------------------------- /scenes/selection/Screen.gd: -------------------------------------------------------------------------------- 1 | extends MeshInstance 2 | 3 | # Called when the node enters the scene tree for the first time. 4 | func _ready(): 5 | # create a unique material for our viewport 6 | var material : SpatialMaterial = SpatialMaterial.new() 7 | 8 | material.flags_unshaded = true 9 | material.flags_transparent = true 10 | material.albedo_texture = $Viewport.get_texture() 11 | 12 | set_surface_material(0, material) 13 | 14 | $Body.screen_size = Vector2(mesh.size.x, mesh.size.y) 15 | -------------------------------------------------------------------------------- /scenes/selection/Screen.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://scenes/selection/Screen.gd" type="Script" id=1] 4 | [ext_resource path="res://scenes/selection/ScreenBody.gd" type="Script" id=2] 5 | 6 | [sub_resource type="QuadMesh" id=1] 7 | size = Vector2( 3, 2 ) 8 | 9 | [sub_resource type="BoxShape" id=2] 10 | extents = Vector3( 1.5, 1, 0.01 ) 11 | 12 | [node name="Screen" type="MeshInstance"] 13 | mesh = SubResource( 1 ) 14 | material/0 = null 15 | script = ExtResource( 1 ) 16 | 17 | [node name="Viewport" type="Viewport" parent="."] 18 | size = Vector2( 600, 400 ) 19 | transparent_bg = true 20 | hdr = false 21 | disable_3d = true 22 | usage = 0 23 | render_target_v_flip = true 24 | render_target_update_mode = 3 25 | 26 | [node name="Body" type="StaticBody" parent="."] 27 | collision_layer = 2 28 | script = ExtResource( 2 ) 29 | viewport = NodePath("../Viewport") 30 | 31 | [node name="CollisionShape" type="CollisionShape" parent="Body"] 32 | shape = SubResource( 2 ) 33 | -------------------------------------------------------------------------------- /scenes/selection/ScreenBody.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody 2 | 3 | export (NodePath) var viewport = null setget set_viewport, get_viewport 4 | export var screen_size = Vector2(100.0, 100.0) 5 | 6 | func set_viewport(path): 7 | viewport = path 8 | if is_ready: 9 | if viewport: 10 | vp = get_node(viewport) 11 | else: 12 | vp = null 13 | 14 | if vp: 15 | viewport_size = vp.size 16 | else: 17 | viewport_size = Vector2(100.0, 100.0) 18 | 19 | func get_viewport(): 20 | return viewport 21 | 22 | var is_ready = false 23 | var vp = null 24 | var viewport_size = Vector2(100.0, 100.0) 25 | var mouse_mask = 0 26 | 27 | # Convert intersection point to screen coordinate 28 | func global_to_viewport(p_at): 29 | var t = $CollisionShape.global_transform 30 | var at = t.xform_inv(p_at) 31 | 32 | # Convert to screen space 33 | at.x = ((at.x / screen_size.x) + 0.5) * viewport_size.x 34 | at.y = (0.5 - (at.y / screen_size.y)) * viewport_size.y 35 | 36 | return Vector2(at.x, at.y) 37 | 38 | func pointer_moved(from, to): 39 | var local_from = global_to_viewport(from) 40 | var local_to = global_to_viewport(to) 41 | 42 | # Let's mimic a mouse 43 | var event = InputEventMouseMotion.new() 44 | event.set_position(local_to) 45 | event.set_global_position(local_to) 46 | event.set_relative(local_to - local_from) # should this be scaled/warped? 47 | event.set_button_mask(mouse_mask) 48 | 49 | if vp: 50 | vp.input(event) 51 | 52 | func pointer_pressed(at): 53 | var local_at = global_to_viewport(at) 54 | 55 | # Let's mimic a mouse 56 | mouse_mask = 1 57 | var event = InputEventMouseButton.new() 58 | event.set_button_index(1) 59 | event.set_pressed(true) 60 | event.set_position(local_at) 61 | event.set_global_position(local_at) 62 | event.set_button_mask(mouse_mask) 63 | 64 | if vp: 65 | vp.input(event) 66 | 67 | func pointer_released(at): 68 | var local_at = global_to_viewport(at) 69 | 70 | # Let's mimic a mouse 71 | mouse_mask = 0 72 | var event = InputEventMouseButton.new() 73 | event.set_button_index(1) 74 | event.set_pressed(false) 75 | event.set_position(local_at) 76 | event.set_global_position(local_at) 77 | event.set_button_mask(mouse_mask) 78 | 79 | if vp: 80 | vp.input(event) 81 | 82 | # Called when the node enters the scene tree for the first time. 83 | func _ready(): 84 | is_ready = true 85 | 86 | set_viewport(viewport) 87 | -------------------------------------------------------------------------------- /scenes/selection/border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BastiaanOlij/godot_background_loading/2926bea88d4bb979975211dbbf879cf86d7ea8d2/scenes/selection/border.png -------------------------------------------------------------------------------- /scenes/selection/border.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/border.png-614fec1a5118cf0318fad1decf903305.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://scenes/selection/border.png" 13 | dest_files=[ "res://.import/border.png-614fec1a5118cf0318fad1decf903305.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /scenes/selection/center_screen_2d.gd: -------------------------------------------------------------------------------- 1 | extends CanvasLayer 2 | 3 | signal load_world(scene) 4 | 5 | # Called when the node enters the scene tree for the first time. 6 | func _ready(): 7 | pass # Replace with function body. 8 | 9 | func _on_Button08_pressed(): 10 | emit_signal("load_world", "res://scenes/test_scene/test_scene.tscn") 11 | -------------------------------------------------------------------------------- /scenes/selection/center_screen_2d.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://scenes/selection/border.png" type="Texture" id=1] 4 | [ext_resource path="res://scenes/selection/center_screen_2d.gd" type="Script" id=2] 5 | [ext_resource path="res://scenes/selection/font_24.tres" type="DynamicFont" id=3] 6 | 7 | [sub_resource type="StyleBoxFlat" id=1] 8 | bg_color = Color( 0.854902, 0.0627451, 0.0627451, 1 ) 9 | corner_radius_top_left = 5 10 | corner_radius_top_right = 5 11 | corner_radius_bottom_right = 5 12 | corner_radius_bottom_left = 5 13 | 14 | [sub_resource type="StyleBoxFlat" id=2] 15 | bg_color = Color( 0.6, 0.6, 0.6, 0 ) 16 | 17 | [node name="CanvasLayer" type="CanvasLayer"] 18 | script = ExtResource( 2 ) 19 | 20 | [node name="Border" type="TextureRect" parent="."] 21 | margin_right = 600.0 22 | margin_bottom = 400.0 23 | texture = ExtResource( 1 ) 24 | __meta__ = { 25 | "_edit_use_anchors_": false 26 | } 27 | 28 | [node name="VBoxContainer" type="VBoxContainer" parent="."] 29 | margin_left = 141.0 30 | margin_top = 21.0 31 | margin_right = 464.0 32 | margin_bottom = 377.0 33 | custom_constants/separation = 10 34 | __meta__ = { 35 | "_edit_use_anchors_": false 36 | } 37 | 38 | [node name="Button01" type="Button" parent="VBoxContainer"] 39 | margin_right = 323.0 40 | margin_bottom = 32.0 41 | custom_styles/hover = SubResource( 1 ) 42 | custom_styles/normal = SubResource( 2 ) 43 | custom_fonts/font = ExtResource( 3 ) 44 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 45 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 46 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 47 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 48 | text = "Our first button" 49 | __meta__ = { 50 | "_edit_use_anchors_": false 51 | } 52 | 53 | [node name="Button02" type="Button" parent="VBoxContainer"] 54 | margin_top = 42.0 55 | margin_right = 323.0 56 | margin_bottom = 74.0 57 | custom_styles/hover = SubResource( 1 ) 58 | custom_styles/normal = SubResource( 2 ) 59 | custom_fonts/font = ExtResource( 3 ) 60 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 61 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 62 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 63 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 64 | text = "And our second button" 65 | __meta__ = { 66 | "_edit_use_anchors_": false 67 | } 68 | 69 | [node name="Button03" type="Button" parent="VBoxContainer"] 70 | margin_top = 84.0 71 | margin_right = 323.0 72 | margin_bottom = 116.0 73 | custom_styles/hover = SubResource( 1 ) 74 | custom_styles/normal = SubResource( 2 ) 75 | custom_fonts/font = ExtResource( 3 ) 76 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 77 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 78 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 79 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 80 | text = "A third button" 81 | __meta__ = { 82 | "_edit_use_anchors_": false 83 | } 84 | 85 | [node name="Button04" type="Button" parent="VBoxContainer"] 86 | margin_top = 126.0 87 | margin_right = 323.0 88 | margin_bottom = 158.0 89 | custom_styles/hover = SubResource( 1 ) 90 | custom_styles/normal = SubResource( 2 ) 91 | custom_fonts/font = ExtResource( 3 ) 92 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 93 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 94 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 95 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 96 | text = "Our fourth button" 97 | __meta__ = { 98 | "_edit_use_anchors_": false 99 | } 100 | 101 | [node name="Button05" type="Button" parent="VBoxContainer"] 102 | margin_top = 168.0 103 | margin_right = 323.0 104 | margin_bottom = 200.0 105 | custom_styles/hover = SubResource( 1 ) 106 | custom_styles/normal = SubResource( 2 ) 107 | custom_fonts/font = ExtResource( 3 ) 108 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 109 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 110 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 111 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 112 | text = "How many buttons do we have?" 113 | __meta__ = { 114 | "_edit_use_anchors_": false 115 | } 116 | 117 | [node name="Button06" type="Button" parent="VBoxContainer"] 118 | margin_top = 210.0 119 | margin_right = 323.0 120 | margin_bottom = 242.0 121 | custom_styles/hover = SubResource( 1 ) 122 | custom_styles/normal = SubResource( 2 ) 123 | custom_fonts/font = ExtResource( 3 ) 124 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 125 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 126 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 127 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 128 | text = "Seriously? More buttons?" 129 | __meta__ = { 130 | "_edit_use_anchors_": false 131 | } 132 | 133 | [node name="Button07" type="Button" parent="VBoxContainer"] 134 | margin_top = 252.0 135 | margin_right = 323.0 136 | margin_bottom = 284.0 137 | custom_styles/hover = SubResource( 1 ) 138 | custom_styles/normal = SubResource( 2 ) 139 | custom_fonts/font = ExtResource( 3 ) 140 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 141 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 142 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 143 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 144 | text = "Yup one more" 145 | __meta__ = { 146 | "_edit_use_anchors_": false 147 | } 148 | 149 | [node name="Button08" type="Button" parent="VBoxContainer"] 150 | margin_top = 294.0 151 | margin_right = 323.0 152 | margin_bottom = 326.0 153 | custom_styles/hover = SubResource( 1 ) 154 | custom_styles/normal = SubResource( 2 ) 155 | custom_fonts/font = ExtResource( 3 ) 156 | custom_colors/font_color_disabled = Color( 0.435294, 0.435294, 0.435294, 1 ) 157 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 158 | custom_colors/font_color_hover = Color( 1, 1, 1, 1 ) 159 | custom_colors/font_color_pressed = Color( 0.996094, 0.0429687, 0, 1 ) 160 | text = "Last one I promise" 161 | __meta__ = { 162 | "_edit_use_anchors_": false 163 | } 164 | [connection signal="pressed" from="VBoxContainer/Button08" to="." method="_on_Button08_pressed"] 165 | -------------------------------------------------------------------------------- /scenes/selection/fade.shader: -------------------------------------------------------------------------------- 1 | shader_type spatial; 2 | render_mode unshaded; 3 | 4 | uniform vec4 fade_color : hint_color = vec4(0.2, 0.2, 0.2, 1.0); 5 | uniform sampler2D texture_map : hint_albedo; 6 | uniform vec2 scale = vec2(10.0, 10.0); 7 | uniform float circle_size = 15.0; 8 | uniform float fade_size = 19.0; 9 | 10 | varying vec3 coord; 11 | 12 | void vertex() { 13 | coord = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz; 14 | } 15 | 16 | void fragment() { 17 | float dist = length(coord); 18 | float val = clamp((dist - circle_size) / fade_size, 0.0, 1.0); 19 | 20 | ALBEDO = mix(texture(texture_map, UV * scale).rgb, fade_color.rgb, val); 21 | } -------------------------------------------------------------------------------- /scenes/selection/font_24.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://assets/fonts/PT_Sans-Web-Bold.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 24 7 | outline_size = 1 8 | outline_color = Color( 1, 0, 0, 0.305882 ) 9 | font_data = ExtResource( 1 ) 10 | -------------------------------------------------------------------------------- /scenes/selection/font_48.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://assets/fonts/PT_Sans-Web-Bold.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 48 7 | outline_size = 2 8 | outline_color = Color( 1, 0, 0, 0.501961 ) 9 | font_data = ExtResource( 1 ) 10 | -------------------------------------------------------------------------------- /scenes/selection/left_screen_2d.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://scenes/selection/border.png" type="Texture" id=1] 4 | [ext_resource path="res://scenes/selection/font_48.tres" type="DynamicFont" id=2] 5 | 6 | [node name="CanvasLayer" type="CanvasLayer"] 7 | 8 | [node name="TextureRect" type="TextureRect" parent="."] 9 | margin_right = 600.0 10 | margin_bottom = 400.0 11 | texture = ExtResource( 1 ) 12 | __meta__ = { 13 | "_edit_use_anchors_": false 14 | } 15 | 16 | [node name="Label" type="Label" parent="."] 17 | margin_right = 600.0 18 | margin_bottom = 400.0 19 | custom_fonts/font = ExtResource( 2 ) 20 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 21 | text = "This is our left screen test" 22 | align = 1 23 | valign = 1 24 | __meta__ = { 25 | "_edit_use_anchors_": false 26 | } 27 | -------------------------------------------------------------------------------- /scenes/selection/right_screen_2d.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://scenes/selection/border.png" type="Texture" id=1] 4 | [ext_resource path="res://scenes/selection/font_48.tres" type="DynamicFont" id=2] 5 | 6 | [node name="CanvasLayer" type="CanvasLayer"] 7 | 8 | [node name="TextureRect" type="TextureRect" parent="."] 9 | margin_right = 600.0 10 | margin_bottom = 400.0 11 | texture = ExtResource( 1 ) 12 | __meta__ = { 13 | "_edit_use_anchors_": false 14 | } 15 | 16 | [node name="Label" type="Label" parent="."] 17 | margin_right = 600.0 18 | margin_bottom = 400.0 19 | custom_fonts/font = ExtResource( 2 ) 20 | custom_colors/font_color = Color( 1, 0, 0, 1 ) 21 | text = "This is our right screen test" 22 | align = 1 23 | valign = 1 24 | __meta__ = { 25 | "_edit_use_anchors_": false 26 | } 27 | -------------------------------------------------------------------------------- /scenes/selection/selection.gd: -------------------------------------------------------------------------------- 1 | extends "res://scenes/base_scene.gd" 2 | 3 | func init_world(new_player_node : ARVROrigin): 4 | .init_world(new_player_node) 5 | 6 | if player_node: 7 | $Height.global_transform.origin.y = player_node.get_camera_transform().origin.y 8 | 9 | # Called every frame. 'delta' is the elapsed time since the previous frame. 10 | func _process(delta): 11 | if player_node: 12 | $Height.global_transform.origin.y = lerp($Height.global_transform.origin.y, player_node.get_camera_transform().origin.y, delta) 13 | pass 14 | 15 | func _on_CanvasLayer_load_world(scene): 16 | emit_signal("load_world", scene) 17 | 18 | -------------------------------------------------------------------------------- /scenes/selection/selection.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=16 format=2] 2 | 3 | [ext_resource path="res://scenes/base_scene.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://scenes/selection/selection.gd" type="Script" id=2] 5 | [ext_resource path="res://scenes/selection/Screen.tscn" type="PackedScene" id=3] 6 | [ext_resource path="res://scenes/selection/center_screen_2d.tscn" type="PackedScene" id=4] 7 | [ext_resource path="res://scenes/selection/right_screen_2d.tscn" type="PackedScene" id=5] 8 | [ext_resource path="res://scenes/selection/left_screen_2d.tscn" type="PackedScene" id=6] 9 | [ext_resource path="res://assets/textures/Scene/grid.png" type="Texture" id=7] 10 | [ext_resource path="res://scenes/selection/fade.shader" type="Shader" id=8] 11 | 12 | [sub_resource type="Environment" id=1] 13 | background_mode = 1 14 | background_color = Color( 0.215686, 0.215686, 0.215686, 1 ) 15 | 16 | [sub_resource type="ViewportTexture" id=2] 17 | viewport_path = NodePath("Viewport") 18 | 19 | [sub_resource type="SpatialMaterial" id=3] 20 | resource_local_to_scene = true 21 | flags_transparent = true 22 | flags_unshaded = true 23 | albedo_texture = SubResource( 2 ) 24 | 25 | [sub_resource type="PlaneMesh" id=4] 26 | size = Vector2( 100, 100 ) 27 | 28 | [sub_resource type="ShaderMaterial" id=5] 29 | shader = ExtResource( 8 ) 30 | shader_param/fade_color = Color( 0.215686, 0.215686, 0.215686, 1 ) 31 | shader_param/scale = Vector2( 50, 50 ) 32 | shader_param/circle_size = 15.0 33 | shader_param/fade_size = 20.0 34 | shader_param/texture_map = ExtResource( 7 ) 35 | 36 | [sub_resource type="CubeMesh" id=6] 37 | size = Vector3( 2, 75, 2 ) 38 | 39 | [sub_resource type="ShaderMaterial" id=7] 40 | shader = ExtResource( 8 ) 41 | shader_param/fade_color = Color( 0.215686, 0.215686, 0.215686, 1 ) 42 | shader_param/scale = Vector2( 2, 45 ) 43 | shader_param/circle_size = 15.0 44 | shader_param/fade_size = 20.0 45 | shader_param/texture_map = ExtResource( 7 ) 46 | 47 | [node name="Scene" index="0" instance=ExtResource( 1 )] 48 | script = ExtResource( 2 ) 49 | enable_pointer = true 50 | 51 | [node name="WorldEnvironment" parent="." index="1"] 52 | environment = SubResource( 1 ) 53 | 54 | [node name="Height" type="Spatial" parent="." index="2"] 55 | 56 | [node name="Center screen" parent="Height" index="0" instance=ExtResource( 3 )] 57 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -3 ) 58 | material/0 = SubResource( 3 ) 59 | 60 | [node name="CanvasLayer" parent="Height/Center screen/Viewport" index="0" instance=ExtResource( 4 )] 61 | 62 | [node name="Left screen" parent="Height" index="1" instance=ExtResource( 3 )] 63 | transform = Transform( 0.5, 0, 0.866025, 0, 1, 0, -0.866025, 0, 0.5, -2.59808, 0, -1.5 ) 64 | material/0 = SubResource( 3 ) 65 | 66 | [node name="CanvasLayer" parent="Height/Left screen/Viewport" index="0" instance=ExtResource( 6 )] 67 | 68 | [node name="Right screen" parent="Height" index="2" instance=ExtResource( 3 )] 69 | transform = Transform( 0.5, 0, -0.866025, 0, 1, 0, 0.866025, 0, 0.5, 2.59808, 0, -1.5 ) 70 | material/0 = SubResource( 3 ) 71 | 72 | [node name="CanvasLayer" parent="Height/Right screen/Viewport" index="0" instance=ExtResource( 5 )] 73 | 74 | [node name="Floor" type="MeshInstance" parent="Height" index="3"] 75 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -4.39591, 0 ) 76 | mesh = SubResource( 4 ) 77 | material/0 = SubResource( 5 ) 78 | 79 | [node name="Beam01" type="MeshInstance" parent="Height/Floor" index="0"] 80 | transform = Transform( 0.899512, -0.301711, 0.315988, 0, 0.723256, 0.69058, -0.436896, -0.621185, 0.650578, 5.48937, 15.2259, -7.77054 ) 81 | mesh = SubResource( 6 ) 82 | material/0 = SubResource( 7 ) 83 | 84 | [node name="Beam02" type="MeshInstance" parent="Height/Floor" index="1"] 85 | transform = Transform( 0.849534, 0.364304, -0.381542, 0, 0.723256, 0.69058, 0.527534, -0.586671, 0.614431, -11.6097, 15.5661, -7.77054 ) 86 | mesh = SubResource( 6 ) 87 | material/0 = SubResource( 7 ) 88 | 89 | [node name="Beam03" type="MeshInstance" parent="Height/Floor" index="2"] 90 | transform = Transform( -0.42376, -0.497978, 0.756601, 0.0697123, 0.8149, 0.575394, -0.903088, 0.296573, -0.310606, 14.3403, 18.2133, -6.5844 ) 91 | mesh = SubResource( 6 ) 92 | material/0 = SubResource( 7 ) 93 | 94 | [node name="Beam04" type="MeshInstance" parent="Height/Floor" index="3"] 95 | transform = Transform( -0.103435, -0.686875, 0.719377, 0, 0.723256, 0.69058, -0.994636, 0.0714301, -0.07481, -5.02361, 15.2699, 15.6376 ) 96 | mesh = SubResource( 6 ) 97 | material/0 = SubResource( 7 ) 98 | 99 | [node name="Beam05" type="MeshInstance" parent="Height/Floor" index="4"] 100 | transform = Transform( 0.838423, 0.376379, -0.394189, 0, 0.723256, 0.69058, 0.54502, -0.578998, 0.606395, -0.112758, 15.2699, 12.7368 ) 101 | mesh = SubResource( 6 ) 102 | material/0 = SubResource( 7 ) 103 | 104 | [node name="Beam06" type="MeshInstance" parent="Height/Floor" index="5"] 105 | transform = Transform( -0.701743, 0.49199, -0.51527, 0, 0.723256, 0.69058, 0.71243, 0.484609, -0.50754, -30.2167, 15.2699, 8.50339 ) 106 | mesh = SubResource( 6 ) 107 | material/0 = SubResource( 7 ) 108 | 109 | [node name="Beam07" type="MeshInstance" parent="Height/Floor" index="6"] 110 | transform = Transform( -0.450884, 0.698701, -0.555446, 0.00574851, 0.624551, 0.780963, 0.892564, 0.348931, -0.285617, -3.39578, 15.2699, -28.6274 ) 111 | mesh = SubResource( 6 ) 112 | material/0 = SubResource( 7 ) 113 | [connection signal="load_world" from="Height/Center screen/Viewport/CanvasLayer" to="." method="_on_CanvasLayer_load_world"] 114 | 115 | [editable path="Height/Center screen"] 116 | 117 | [editable path="Height/Left screen"] 118 | 119 | [editable path="Height/Right screen"] 120 | -------------------------------------------------------------------------------- /scenes/test_scene/Box.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [sub_resource type="CubeMesh" id=1] 4 | size = Vector3( 1, 1, 1 ) 5 | 6 | [sub_resource type="BoxShape" id=2] 7 | extents = Vector3( 0.5, 0.5, 0.5 ) 8 | 9 | [node name="Box" type="RigidBody"] 10 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.684231, 0 ) 11 | collision_layer = 2 12 | collision_mask = 2 13 | 14 | [node name="MeshInstance" type="MeshInstance" parent="."] 15 | mesh = SubResource( 1 ) 16 | material/0 = null 17 | 18 | [node name="CollisionShape" type="CollisionShape" parent="."] 19 | shape = SubResource( 2 ) 20 | -------------------------------------------------------------------------------- /scenes/test_scene/test_scene.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=2] 2 | 3 | [ext_resource path="res://scenes/base_scene.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://assets/textures/Scene/grid.png" type="Texture" id=2] 5 | [ext_resource path="res://scenes/test_scene/Box.tscn" type="PackedScene" id=3] 6 | 7 | [sub_resource type="ProceduralSky" id=1] 8 | 9 | [sub_resource type="Environment" id=2] 10 | background_mode = 2 11 | background_sky = SubResource( 1 ) 12 | ambient_light_sky_contribution = 0.45 13 | 14 | [sub_resource type="PlaneMesh" id=3] 15 | size = Vector2( 2048, 2048 ) 16 | subdivide_width = 16 17 | subdivide_depth = 16 18 | 19 | [sub_resource type="SpatialMaterial" id=4] 20 | albedo_texture = ExtResource( 2 ) 21 | uv1_scale = Vector3( 1000, 1000, 1000 ) 22 | 23 | [sub_resource type="BoxShape" id=5] 24 | extents = Vector3( 1024, 1, 1024 ) 25 | 26 | [node name="Scene" instance=ExtResource( 1 )] 27 | enable_locomotion = true 28 | 29 | [node name="PlayerSpawnPoint" parent="." index="0"] 30 | transform = Transform( -0.173648, 0, -0.984808, 0, 1, 0, 0.984808, 0, -0.173648, -3, 0, 0 ) 31 | 32 | [node name="WorldEnvironment" parent="." index="1"] 33 | environment = SubResource( 2 ) 34 | 35 | [node name="DirectionalLight" type="DirectionalLight" parent="." index="2"] 36 | transform = Transform( 1, 0, 0, 0, -0.872138, 0.48926, 0, -0.48926, -0.872138, 0, 1.43808, 0 ) 37 | shadow_enabled = true 38 | 39 | [node name="Floor" type="StaticBody" parent="." index="3"] 40 | collision_layer = 2 41 | collision_mask = 0 42 | 43 | [node name="MeshInstance" type="MeshInstance" parent="Floor" index="0"] 44 | mesh = SubResource( 3 ) 45 | material/0 = SubResource( 4 ) 46 | 47 | [node name="CollisionShape" type="CollisionShape" parent="Floor" index="1"] 48 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.99, 0 ) 49 | shape = SubResource( 5 ) 50 | 51 | [node name="Box01" parent="." index="4" instance=ExtResource( 3 )] 52 | 53 | [node name="Box02" parent="." index="5" instance=ExtResource( 3 )] 54 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.87529, 0 ) 55 | 56 | [node name="Box03" parent="." index="6" instance=ExtResource( 3 )] 57 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.03505, 0 ) 58 | 59 | [node name="Box04" parent="." index="7" instance=ExtResource( 3 )] 60 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.684231, 3.42923 ) 61 | --------------------------------------------------------------------------------