This commit is contained in:
parent
c7c3cd4d97
commit
7ffaa30f6d
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_name = "cake"
|
resource_name = "cake"
|
||||||
cull_mode = 2
|
|
||||||
vertex_color_use_as_albedo = true
|
vertex_color_use_as_albedo = true
|
||||||
albedo_texture = ExtResource("1_jefwg")
|
albedo_texture = ExtResource("1_jefwg")
|
||||||
roughness = 0.5
|
roughness = 0.5
|
||||||
|
|
|
@ -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)
|
"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
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue