From dafd425359832236f5cdb9f186f8fe171f20c562 Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Tue, 7 Jan 2025 17:56:18 -0700 Subject: [PATCH] Ball gets culled if velocity is low after rolling for a while --- src/equipment/balls/physics_ball/game_ball.gd | 42 ++++++++++--------- .../balls/physics_ball/physics_ball.tscn | 40 +++++++++--------- .../terrain_physics/terrain_parameters.gd | 4 +- src/ui/3d/projectile_arc/projectile_arc.gd | 3 +- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/equipment/balls/physics_ball/game_ball.gd b/src/equipment/balls/physics_ball/game_ball.gd index 91e170a..a6e8887 100644 --- a/src/equipment/balls/physics_ball/game_ball.gd +++ b/src/equipment/balls/physics_ball/game_ball.gd @@ -14,7 +14,6 @@ enum Type { POWER, } -const VELOCITY_SQ_EPSILON := 1e-4 const MAGNUS_SQ_EPSILON := 1e-3 ## If enabled, ball ability cooldown is only reset at end of shot. @@ -23,6 +22,10 @@ const MAGNUS_SQ_EPSILON := 1e-3 ## Material physics configuration for this ball. @export var terrain_physics: TerrainPhysics +## Coefficient of the linear curve that determines the minimum speed at +## a given point in surface time below which the ball will be frozen. +@export var surface_cull_coefficient: float = 0.2 + #@export var fluid_density := 1.225 #@export var lift_coefficient := 0.05 #@export var radius := 0.05 @@ -116,6 +119,7 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void: _position_on_last_wake = global_position _last_contact_normal = Vector3.UP _shot_time_s = 0.0 + _surface_time_s = 0.0 # TODO something's fucky here... I think this gets called once after the ball sleeps if state.get_contact_count(): @@ -133,12 +137,19 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void: primary_body = state.get_contact_collider_object(i) _surface_terrain = Terrain.from_collision(global_position, primary_body) - _surface_time_s += state.step + + var culling_speed_sq := pow(surface_cull_coefficient * _surface_time_s, 2) - 1 + if linear_velocity.length_squared() < culling_speed_sq: + _manual_sleep() else: # Ball is in the air _surface_terrain = Terrain.Type.NONE _surface_time_s = 0.0 + var params := terrain_physics.get_params(_surface_terrain) + angular_damp = params.angular_damp + linear_damp = params.linear_damp + func _physics_process(delta: float) -> void: # Simulate magnus effect @@ -146,24 +157,9 @@ func _physics_process(delta: float) -> void: if magnus.length_squared() > MAGNUS_SQ_EPSILON: apply_central_force(magnus) - # Apply drag - var params := terrain_physics.get_params(_surface_terrain) - if linear_velocity.length() > params.linear_drag: - linear_velocity -= params.linear_drag * linear_velocity.normalized() - else: - linear_velocity = Vector3.ZERO - if angular_velocity.length() > params.angular_drag: - angular_velocity -= params.angular_drag * angular_velocity.normalized() - else: - angular_velocity = Vector3.ZERO - - if linear_velocity.length_squared() < VELOCITY_SQ_EPSILON: - linear_velocity = Vector3.ZERO - if angular_velocity.length_squared() < VELOCITY_SQ_EPSILON: - angular_velocity = Vector3.ZERO - # Keep shot time _shot_time_s += delta + _surface_time_s += delta func enter_zone(zone: BallZone) -> void: @@ -194,11 +190,17 @@ func _on_sleeping_state_changed() -> void: _awake = false +func _manual_sleep() -> void: + freeze = true + linear_velocity = Vector3.ZERO + angular_velocity = Vector3.ZERO + manual_sleep_timer.start() + + func _on_collision(body: Node) -> void: if is_sticky(): # Freeze physics as soon as we hit something - freeze = true - manual_sleep_timer.start() + _manual_sleep() var terrain := Terrain.from_collision(global_position, body) print_debug("Collision terrain: ", Terrain.Type.keys()[terrain]) diff --git a/src/equipment/balls/physics_ball/physics_ball.tscn b/src/equipment/balls/physics_ball/physics_ball.tscn index d538672..fec0619 100644 --- a/src/equipment/balls/physics_ball/physics_ball.tscn +++ b/src/equipment/balls/physics_ball/physics_ball.tscn @@ -19,53 +19,53 @@ [sub_resource type="Resource" id="Resource_casfi"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 1.0 +linear_damp = 0.2 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_3k63c"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 0.0 +linear_damp = 0.0 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_xf73q"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 1.0 +linear_damp = 0.5 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_nhn3l"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 1.0 +linear_damp = 0.1 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_m3wjo"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 1.0 +linear_damp = 0.2 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_h4rld"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 1.0 +linear_damp = 0.1 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_j6lib"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 1.0 +linear_damp = 0.5 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_7f7ql"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 3.0 +linear_damp = 1.0 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_pusmf"] script = ExtResource("4_onl6o") -linear_drag = 1.0 -angular_drag = 10.0 +linear_damp = 4.0 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_edkxb"] script = ExtResource("4_onl6o") -linear_drag = 0.0 -angular_drag = 1.0 +linear_damp = 0.2 +angular_damp = 0.0 [sub_resource type="Resource" id="Resource_3ngau"] script = ExtResource("3_52hui") diff --git a/src/equipment/balls/physics_ball/terrain_physics/terrain_parameters.gd b/src/equipment/balls/physics_ball/terrain_physics/terrain_parameters.gd index e65949c..7ed1131 100644 --- a/src/equipment/balls/physics_ball/terrain_physics/terrain_parameters.gd +++ b/src/equipment/balls/physics_ball/terrain_physics/terrain_parameters.gd @@ -1,5 +1,5 @@ class_name TerrainParameters extends Resource ## Physical parameters for an individual terrain type. -@export var linear_drag := 0.0 -@export var angular_drag := 0.0 +@export var linear_damp := 0.0 +@export var angular_damp := 0.0 diff --git a/src/ui/3d/projectile_arc/projectile_arc.gd b/src/ui/3d/projectile_arc/projectile_arc.gd index 711de18..99cd8cf 100644 --- a/src/ui/3d/projectile_arc/projectile_arc.gd +++ b/src/ui/3d/projectile_arc/projectile_arc.gd @@ -63,7 +63,8 @@ var _cached_vel: Vector3 func set_ball(ball: GameBall) -> void: global_position = ball.global_position - linear_damp = ball.linear_damp + linear_damp = ball.terrain_physics.default.linear_damp + print("using linear damp: ", linear_damp) func _process(_delta: float) -> void: