diff --git a/blends/cake.blend b/blends/cake.blend new file mode 100644 index 0000000..f703a5e --- /dev/null +++ b/blends/cake.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:215d76aa508f3e94eb4973c99817e1ddc6d3a4e29ff04552b037b75dbbb7fb2b +size 2607764 diff --git a/blends/cake_albedo.png b/blends/cake_albedo.png new file mode 100644 index 0000000..778c6a0 --- /dev/null +++ b/blends/cake_albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ff239a97b45ec9ee48fbb1e32669d0fa61d2632b5b7d17680e37c8554f5daff +size 140896 diff --git a/blends/cake_normals.png b/blends/cake_normals.png new file mode 100644 index 0000000..61577ac --- /dev/null +++ b/blends/cake_normals.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1014ae0e49e204badbaf020f346da409db435d55a9ff5443856a7dcbf6c16a7a +size 3427515 diff --git a/godot/cake.glb b/godot/cake.glb new file mode 100644 index 0000000..80f1fea --- /dev/null +++ b/godot/cake.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5e980b139d7d2f4a4c64ea569b6d6d604c649fc7b7e1277209a76462e3294ef +size 3697368 diff --git a/godot/cake.glb.import b/godot/cake.glb.import new file mode 100644 index 0000000..36da67f --- /dev/null +++ b/godot/cake.glb.import @@ -0,0 +1,53 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://djj412h1ien4o" +path="res://.godot/imported/cake.glb-e60e073e8642f273d1a78ec90c85894b.scn" + +[deps] + +source_file="res://cake.glb" +dest_files=["res://.godot/imported/cake.glb-e60e073e8642f273d1a78ec90c85894b.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="res://physics/import_billiard.gd" +_subresources={ +"materials": { +"cake": { +"use_external/enabled": true, +"use_external/path": "res://cake.tres" +}, +"candles": { +"use_external/enabled": true, +"use_external/path": "res://candles.tres" +} +}, +"nodes": { +"PATH:cake2": { +"generate/physics": true, +"physics/body_type": 1, +"physics/shape_type": 5, +"primitive/height": 0.244, +"primitive/position": Vector3(0, 0.042, 0), +"primitive/radius": 0.219 +} +} +} +gltf/embedded_image_handling=1 diff --git a/godot/cake.tres b/godot/cake.tres new file mode 100644 index 0000000..72be408 --- /dev/null +++ b/godot/cake.tres @@ -0,0 +1,12 @@ +[gd_resource type="StandardMaterial3D" load_steps=3 format=3 uid="uid://b8htfw5f1a4wf"] + +[ext_resource type="Texture2D" uid="uid://dhyh1g25bmhtf" path="res://cake_cake_albedo.png" id="1_jefwg"] +[ext_resource type="Texture2D" uid="uid://cer3pk0fspi1c" path="res://cake_cake_normals.png" id="2_55xkl"] + +[resource] +resource_name = "cake" +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("1_jefwg") +roughness = 0.5 +normal_enabled = true +normal_texture = ExtResource("2_55xkl") diff --git a/godot/cake.tscn b/godot/cake.tscn new file mode 100644 index 0000000..2e7e2a7 --- /dev/null +++ b/godot/cake.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=3 uid="uid://cx4ohbn84hmc3"] + +[ext_resource type="PackedScene" uid="uid://djj412h1ien4o" path="res://cake.glb" id="1_q3mni"] + +[node name="cake" instance=ExtResource("1_q3mni")] + +[node name="CollisionShape3D" parent="." index="4"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0367587, 0) diff --git a/godot/cake_cake_albedo.png b/godot/cake_cake_albedo.png new file mode 100644 index 0000000..04d1777 --- /dev/null +++ b/godot/cake_cake_albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f9de21d8cd93f7c4509e50d600e7ac87dbf6fed35cba7e6ef4e1c86ab1bc526 +size 152531 diff --git a/godot/cake_cake_albedo.png.import b/godot/cake_cake_albedo.png.import new file mode 100644 index 0000000..fe9550d --- /dev/null +++ b/godot/cake_cake_albedo.png.import @@ -0,0 +1,36 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dhyh1g25bmhtf" +path.bptc="res://.godot/imported/cake_cake_albedo.png-8e7e933b04d67a69b2a262d9cdfe2bb0.bptc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://cake_cake_albedo.png" +dest_files=["res://.godot/imported/cake_cake_albedo.png-8e7e933b04d67a69b2a262d9cdfe2bb0.bptc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=true +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/godot/cake_cake_normals.png b/godot/cake_cake_normals.png new file mode 100644 index 0000000..3edb4a4 --- /dev/null +++ b/godot/cake_cake_normals.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b71924b298755c0cd85bbdc6ddf6665888872e95f64b196929f2b3de768194ab +size 2281378 diff --git a/godot/cake_cake_normals.png.import b/godot/cake_cake_normals.png.import new file mode 100644 index 0000000..28a68c1 --- /dev/null +++ b/godot/cake_cake_normals.png.import @@ -0,0 +1,36 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cer3pk0fspi1c" +path.bptc="res://.godot/imported/cake_cake_normals.png-85023f0c4cf5997d4101eb078e7a1400.bptc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://cake_cake_normals.png" +dest_files=["res://.godot/imported/cake_cake_normals.png-85023f0c4cf5997d4101eb078e7a1400.bptc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=true +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=1 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=1 +roughness/src_normal="res://cake_cake_normals.png" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/godot/candles.tres b/godot/candles.tres new file mode 100644 index 0000000..653dc4c --- /dev/null +++ b/godot/candles.tres @@ -0,0 +1,8 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://li4gdaji6poj"] + +[resource] +resource_name = "candles" +cull_mode = 2 +vertex_color_use_as_albedo = true +albedo_color = Color(0.453326, 0, 0.0696221, 1) +roughness = 0.5 diff --git a/godot/control_scheme/control_target_overlay.gdshader b/godot/control_scheme/control_target_overlay.gdshader index be794fe..0eb6a41 100644 --- a/godot/control_scheme/control_target_overlay.gdshader +++ b/godot/control_scheme/control_target_overlay.gdshader @@ -11,7 +11,7 @@ void vertex() { void fragment() { float scale = 50.0; float speed = 1000.0; - float f = random2(round(UV * scale)/scale + round(TIME*speed)/speed); + float f = random2(UV + round(TIME*speed)/speed); if (f > 0.1) { discard; } diff --git a/godot/control_scheme/is_targetable.gd b/godot/control_scheme/is_targetable.gd index 17fd761..8e40c81 100644 --- a/godot/control_scheme/is_targetable.gd +++ b/godot/control_scheme/is_targetable.gd @@ -36,7 +36,7 @@ func change_all_materials(mesh: MeshInstance3D): layer2.render_priority = 30 layer0.no_depth_test = true - layer0.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS + layer0.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_HASH layer0.grow = true layer0.grow_amount = -0.001 layer0.albedo_color = layer0.albedo_color.darkened(0.5) diff --git a/godot/project.godot b/godot/project.godot index d35607e..a0f1b9f 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -43,3 +43,10 @@ charge={ "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) ] } + +[physics] + +3d/default_linear_damp=5.0 +3d/default_angular_damp=5.0 +3d/time_before_sleep=0.1 +3d/solver/solver_iterations=128 diff --git a/godot/smoother.gd b/godot/smoother.gd new file mode 100644 index 0000000..b1b2fd5 --- /dev/null +++ b/godot/smoother.gd @@ -0,0 +1,229 @@ +# MIT LICENSE +# +# Copyright 2022 Anatol Bogun +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +# associated documentation files (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, publish, distribute, +# sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all copies or +# substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +class_name Smoother extends Node + +## Smoother Node +## Version: 1.0.4 +## +## A node type that smoothes scene nodes' properties by interpolating _physics_process steps. +## +## For documentation please visit https://github.com/anatolbogun/godot-smoother-node . + +## Node properties that are interpolated. +## Defaults to ["position"], even if not displayed in the inspector. +@export var properties:Array[String] = ["position"] + +## Apply interpolation to this node's parent. +@export var smooth_parent: = true : + set (value): + if value == false: + # remove parent from _properties in case this gets toggled on and off during runtime + _properties.erase(get_parent()) + + smooth_parent = value + +## Apply interpolation to the recursive children of this node's parent. +@export var recursive: = true + +## Explicitly include node paths in addition to the nodes that are included by other Smoother +## settings. +@export var includes:Array[NodePath] = [] + +## Explicitly exclude node paths. +## This will exclude nodes that would otherwise be included by other settings. +@export var excludes:Array[NodePath] = [] + +# get an array of all currently smoothed nodes; mainly for debugging performance optimisations +var smoothed_nodes:Array[Node] : + get: + var parent: = get_parent() + return _get_physics_process_nodes(parent, !smooth_parent) if parent != null else [] as Array[Node] + +var _properties: = {} +var _physics_process_nodes:Array[Node] +var _physics_process_just_updated: = false + + +## Reset all smoothed nodes. +func reset() -> void: + _properties.clear() + + +## Reset a specific node. You may want to call this when a node gets teleported. +func reset_node(node:Node) -> void: + _properties.erase(node) + + +## Reset a specific Node by NodePath. You may want to call this when a Node gets teleported. +func reset_node_path(path:NodePath) -> void: + var node: = get_node_or_null(path) + + if node != null: + reset_node(node) + + +## Add a Node to the includes Array[NodePath]. +func add_include_node(node:Node) -> Array[NodePath]: + return add_include_path(get_path_to(node)) + + +## Add a NodePath to the includes Array[NodePath]. +func add_include_path(path:NodePath) -> Array[NodePath]: + return _add_unique_to_array(includes, path) as Array[NodePath] + + +## Remove a Node from the includes Array[NodePath]. +func remove_include_node(node:Node) -> Array[NodePath]: + return remove_include_path(get_path_to(node)) + + +## Remove a NodePath from the includes Array[NodePath]. +func remove_include_path(path:NodePath) -> Array[NodePath]: + return _remove_all_from_array(includes, path) as Array[NodePath] + + +## Add a Node to the excludes Array[NodePath]. +func add_exclude_node(node:Node) -> Array[NodePath]: + return add_exclude_path(get_path_to(node)) + + +## Add a NodePath to the excludes Array[NodePath]. +func add_exclude_path(path:NodePath) -> Array[NodePath]: + return _add_unique_to_array(excludes, path) as Array[NodePath] + + +## Remove a Node from the excludes Array[NodePath]. +func remove_exclude_node(node:Node) -> Array[NodePath]: + return remove_exclude_path(get_path_to(node)) + + +## Remove a NodePath from the excludes Array[NodePath]. +func remove_exclude_path(path:NodePath) -> Array[NodePath]: + return _remove_all_from_array(excludes, path) as Array[NodePath] + + +## Add an item to an array unless the array already contains that item. +func _add_unique_to_array(array:Array, item:Variant) -> Array: + if !array.has(item): + array.push_back(item) + + return array + + +## Remove all array items that match item. +func _remove_all_from_array(array:Array, item:Variant) -> Array: + while array.has(item): + array.erase(item) + + return array + + +## Apply interpolation to all smoothed_nodes supported properties. +func _process(_delta: float) -> void: + for node in _physics_process_nodes: + if !_properties.has(node): continue + + for property in _properties[node]: + var values = _properties[node][property] + + if values.size() == 2: + if _physics_process_just_updated: + values[1] = node[property] + + node[property] = lerp(values[0], values[1], Engine.get_physics_interpolation_fraction()) + + _physics_process_just_updated = false + + +## Store all smoothed_nodes' relevant properties of the previous (origin) and this (target) +## _physics_process frames for interpolation in the upcoming _process frames and apply the origin +## values. +func _physics_process(_delta: float) -> void: + var parent: = get_parent() + if parent == null: return + + # move this node to the top of the parent tree (typically a scene's root node) so that it is + # called before all other _physics_processes + parent.move_child(self, 0) + + if smooth_parent: + process_priority = parent.process_priority - 1 + + # update the relevant nodes once per _physics_process + _physics_process_nodes = _get_physics_process_nodes(parent, !smooth_parent) + + # clean up _properties + for key in _properties.keys(): + if !_physics_process_nodes.has(key): + _properties.erase(key) + + for node in _physics_process_nodes: + if !_properties.has(node): + # called on the first frame after a node was added to _properties + _properties[node] = {} + + # clean up _properties when a node exited the tree + node.tree_exited.connect(func (): _properties.erase(node)) + + for property in properties: + if ! property in node: continue + + if !_properties[node].has(property): + # called on the first frame after a node was added to _properties + _properties[node][property] = [node[property]] + elif _properties[node][property].size() < 2: + # called on the second frame after a node was added to _properties + _properties[node][property].push_front(_properties[node][property][0]) + _properties[node][property][1] = node[property] + else: + _properties[node][property][0] = _properties[node][property][1] + node[property] = _properties[node][property][0] + + _physics_process_just_updated = true + + +## Get the relevant nodes to be smoothed based on this node's tree position and properties. +func _get_physics_process_nodes(node: Node, ignore_node: = false, with_includes: = true) -> Array[Node]: + var nodes:Array[Node] = [] + + nodes.assign(includes.map( + get_node_or_null + ).filter( + func (_node:Node) -> bool: return _node != null && !excludes.has(get_path_to(_node)) + ) if with_includes else []) + + if ( + !ignore_node + && node != self + && !node is RigidBody2D + && !node is RigidBody3D + && !nodes.has(node) + && !excludes.has(get_path_to(node)) + && node.has_method("_physics_process") + ): + nodes.push_back(node) + + if recursive: + for child in node.get_children(): + for nested_node in _get_physics_process_nodes(child, false, false): + _add_unique_to_array(nodes, nested_node) + + return nodes diff --git a/godot/tests/control_scheme/test_basic_controls.tscn b/godot/tests/control_scheme/test_basic_controls.tscn index f7db47c..03e4dce 100644 --- a/godot/tests/control_scheme/test_basic_controls.tscn +++ b/godot/tests/control_scheme/test_basic_controls.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=6 format=3 uid="uid://70bb2yncbl"] +[gd_scene load_steps=7 format=3 uid="uid://70bb2yncbl"] [ext_resource type="PackedScene" uid="uid://bua7f25rpewkp" path="res://small_room.glb" id="1_2ticn"] [ext_resource type="PackedScene" uid="uid://drmb4sitb74fx" path="res://control_scheme/controller.tscn" id="2_dcvuq"] [ext_resource type="PackedScene" uid="uid://c43pr474qofhl" path="res://physics/grape.tscn" id="3_gijly"] [ext_resource type="PackedScene" uid="uid://b1uf31ed6h0ir" path="res://UI/TAS UI/TAS UI.tscn" id="4_8yatx"] +[ext_resource type="PackedScene" uid="uid://cx4ohbn84hmc3" path="res://cake.tscn" id="5_udc7s"] [sub_resource type="Environment" id="Environment_f0m14"] ambient_light_source = 2 @@ -32,3 +33,6 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.115958, 1.77839, -0.189013) [node name="Camera3D" type="Camera3D" parent="." index="7"] current = true + +[node name="cake" parent="." index="8" instance=ExtResource("5_udc7s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.45077, 0)