meat_madness_redux/godot/addons/smoothing/smoothing.gd

204 lines
4.6 KiB
GDScript3
Raw Normal View History

2022-11-27 13:31:09 -07:00
# Copyright (c) 2019 Lawnjelly
#
# 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.
extends Spatial
export(NodePath) var target : NodePath setget set_target, get_target
var _m_Target : Spatial
var _m_trCurr : Transform
var _m_trPrev : Transform
const SF_ENABLED = 1 << 0
const SF_TRANSLATE = 1 << 1
const SF_BASIS = 1 << 2
const SF_SLERP = 1 << 3
const SF_DIRTY = 1 << 4
const SF_INVISIBLE = 1 << 5
export (int, FLAGS, "enabled", "translate", "basis", "slerp") var flags : int = SF_ENABLED | SF_TRANSLATE | SF_BASIS setget _set_flags, _get_flags
##########################################################################################
# USER FUNCS
# call this on e.g. starting a level, AFTER moving the target
# so we can update both the previous and current values
func teleport():
var temp_flags = flags
_SetFlags(SF_TRANSLATE | SF_BASIS)
_RefreshTransform()
_m_trPrev = _m_trCurr
# do one frame update to make sure all components are updated
_process(0)
# resume old flags
flags = temp_flags
func set_enabled(var bEnable : bool):
_ChangeFlags(SF_ENABLED, bEnable)
_SetProcessing()
func is_enabled():
return _TestFlags(SF_ENABLED)
##########################################################################################
func _ready():
_m_trCurr = Transform()
_m_trPrev = Transform()
func set_target(new_value):
target = new_value
if is_inside_tree():
_FindTarget()
func get_target():
return target
func _set_flags(new_value):
flags = new_value
# we may have enabled or disabled
_SetProcessing()
func _get_flags():
return flags
func _SetProcessing():
var bEnable = _TestFlags(SF_ENABLED)
if _TestFlags(SF_INVISIBLE):
bEnable = false
set_process(bEnable);
set_physics_process(bEnable);
pass
func _enter_tree():
# might have been moved
_FindTarget()
pass
func _notification(what):
match what:
# invisible turns off processing
NOTIFICATION_VISIBILITY_CHANGED:
_ChangeFlags(SF_INVISIBLE, is_visible_in_tree() == false)
_SetProcessing()
func _RefreshTransform():
_ClearFlags(SF_DIRTY);
if _HasTarget() == false:
return
_m_trPrev = _m_trCurr
_m_trCurr = _m_Target.transform
func _FindTarget():
_m_Target = null
if target.is_empty():
return
_m_Target = get_node(target)
if _m_Target is Spatial:
return
_m_Target = null
#return false
func _HasTarget()->bool:
if _m_Target == null:
return false
# has not been deleted?
if is_instance_valid(_m_Target):
return true
_m_Target = null
return false
func _process(_delta):
if _TestFlags(SF_DIRTY):
_RefreshTransform()
var f = Engine.get_physics_interpolation_fraction()
var tr : Transform = Transform()
# translate
if _TestFlags(SF_TRANSLATE):
var ptDiff = _m_trCurr.origin - _m_trPrev.origin
tr.origin = _m_trPrev.origin + (ptDiff * f)
# rotate
if _TestFlags(SF_BASIS):
if _TestFlags(SF_SLERP):
tr.basis = _m_trPrev.basis.slerp(_m_trCurr.basis, f)
else:
tr.basis = _LerpBasis(_m_trPrev.basis, _m_trCurr.basis, f)
transform = tr
pass
func _physics_process(_delta):
# take care of the special case where multiple physics ticks
# occur before a frame .. the data must flow!
if _TestFlags(SF_DIRTY):
_RefreshTransform()
_SetFlags(SF_DIRTY)
pass
func _LerpBasis(var from : Basis, var to : Basis, var f : float)->Basis:
var res : Basis = Basis()
res.x = from.x.linear_interpolate(to.x, f)
res.y = from.y.linear_interpolate(to.y, f)
res.z = from.z.linear_interpolate(to.z, f)
return res
func _SetFlags(var f):
flags |= f
func _ClearFlags(var f):
flags &= ~f
func _TestFlags(var f):
return (flags & f) == f
func _ChangeFlags(var f, var bSet):
if bSet:
_SetFlags(f)
else:
_ClearFlags(f)