Use spring damper for player geometry orientation.

main
Martin Felis 2024-09-08 21:11:02 +02:00
parent 01d95a145a
commit 58733064c1
2 changed files with 49 additions and 1 deletions

View File

@ -13,6 +13,7 @@ var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var inventory:Inventory = Inventory.new()
var look_direction:Vector3 = Vector3.BACK
var look_direction_damper:SpringDamper = SpringDamper.new(Vector3.ZERO)
signal trigger_message(message:String)
@ -51,9 +52,11 @@ func _physics_process(delta):
elif direction.length_squared() > 0.1 * 0.1:
look_direction = direction
var damped_look_direction = look_direction_damper.calc(geometry.global_basis.z, look_direction, delta)
animation_tree.set("parameters/conditions/running", is_moving)
animation_tree.set("parameters/conditions/idle", not is_moving)
geometry.look_at(position - look_direction, Vector3.UP)
geometry.look_at(position - damped_look_direction, Vector3.UP)
func on_item_picked_up(item:Item):

45
utils/SpringDamper.gd Normal file
View File

@ -0,0 +1,45 @@
class_name SpringDamper
extends Object
# Based on: allenchou.net/2015/04/game-math-precise-control-over-numeric-springing/
var omega
var zeta
var v:Variant = null
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
func _init(v0:Variant, osc_freq:float = 4, osc_red:float = 0.003, osc_red_h:float = 0.003):
assert (osc_red > 0.001 and osc_red < 0.999)
omega = osc_freq * 2 * PI
zeta = log(1.0 - osc_red) / (-omega * osc_red_h)
print ("omega: ", omega, " zeta: ", zeta)
v = v0
func calc(x, xt, h:float):
var f = 1.0 + 2.0 * h * zeta * omega
var oo = omega * omega
var hoo = oo * h
var hhoo = hoo * h
var det_inv = 1.0 / (f + hhoo)
var det_x = f * x + h * v + hhoo * xt
var det_v = v + hoo * (xt - x)
x = det_x * det_inv
v = det_v * det_inv
return x
func calc_clamped_speed(x, xt, h:float, s_max:float):
var x_old = x
var v_old = v
var x_new = calc(x, xt, h)
var vel_new = (x_new - x_old) / h
var speed_new = vel_new.length()
if speed_new > s_max:
vel_new = (vel_new / speed_new) * s_max
x = x_old + vel_new * h
return x