diff --git a/src/equipment/balls/debug_ball/debug_ball.gd b/src/equipment/balls/debug_ball/debug_ball.gd index f3300a1..7c1e6f9 100644 --- a/src/equipment/balls/debug_ball/debug_ball.gd +++ b/src/equipment/balls/debug_ball/debug_ball.gd @@ -1,6 +1,6 @@ extends GameBall -const INFO_FMT := "speed: {0} m/s\nlin.damp: {1}\nang.spd: {2}\nang.damp: {3}\ntime: {4} s\nsurface decay: {5}" +const INFO_FMT := "speed: {0} m/s\nang.spd: {1}\nsurface: {2}\ntime: {3} s" @onready var debug_info: Label3D = %DebugInfo @@ -11,10 +11,8 @@ func _physics_process(delta: float) -> void: debug_info.text = INFO_FMT.format( [ linear_velocity.length(), - linear_damp, angular_velocity.length(), - angular_damp, - _shot_time_s, - terrain_physics.get_decay_factor(_surface_time_s) + Terrain.Type.keys()[_surface_terrain], + _shot_time_s ] ) diff --git a/src/equipment/balls/debug_ball/debug_ball.tscn b/src/equipment/balls/debug_ball/debug_ball.tscn index a5a2573..c54d864 100644 --- a/src/equipment/balls/debug_ball/debug_ball.tscn +++ b/src/equipment/balls/debug_ball/debug_ball.tscn @@ -19,6 +19,7 @@ size = Vector2(0.05, 0.05) [sub_resource type="SystemFont" id="SystemFont_td87w"] font_names = PackedStringArray("Monospace") +subpixel_positioning = 0 [node name="DebugBall" instance=ExtResource("1_gcsxs")] script = ExtResource("2_edye5") diff --git a/src/equipment/balls/physics_ball/game_ball.gd b/src/equipment/balls/physics_ball/game_ball.gd index f6442b8..91e170a 100644 --- a/src/equipment/balls/physics_ball/game_ball.gd +++ b/src/equipment/balls/physics_ball/game_ball.gd @@ -14,18 +14,12 @@ enum Type { POWER, } -const TERRAIN_DAMPING_EPSILON := 1e-6 -const MAGNUS_EPSILON := 1e-3 +const VELOCITY_SQ_EPSILON := 1e-4 +const MAGNUS_SQ_EPSILON := 1e-3 ## If enabled, ball ability cooldown is only reset at end of shot. @export var once_per_shot_ability := false -## Linear damping while in the air. -@export var aerial_linear_damping := 0.0 - -## Angular damping while in the air. -@export var aerial_angular_damping := 0.0 - ## Material physics configuration for this ball. @export var terrain_physics: TerrainPhysics @@ -64,6 +58,7 @@ var _ability_triggered := false var _zones: Array[BallZone] = [] var _shot_time_s := 0.0 var _surface_time_s := 0.0 +var _surface_terrain: Terrain.Type @onready var ability_cooldown: Timer = %AbilityCooldown @onready var manual_sleep_timer: Timer = %ManualSleepTimer @@ -74,9 +69,6 @@ var _surface_time_s := 0.0 "res://src/equipment/balls/physics_ball/normal_physics.tres" ) -@onready var default_surface_linear_damping := linear_damp -@onready var default_surface_angular_damping := angular_damp - ## Should this ball stick to surfaces, rather than bounce? func is_sticky() -> bool: @@ -131,43 +123,45 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void: # We want the contact normal which minimizes the angle to the up vector var min_dot := -1.0 + var primary_body: Node for i: int in range(state.get_contact_count()): var norm := state.get_contact_local_normal(i) var dot := norm.dot(Vector3.UP) if dot > min_dot: min_dot = dot _last_contact_normal = norm + primary_body = state.get_contact_collider_object(i) - # Use first contact to determine terrain properties - var primary_body: Node = state.get_contact_collider_object(0) - - var terrain := Terrain.from_collision(global_position, primary_body) - var params := terrain_physics.get_params(terrain) - if params: - linear_damp = params.linear_damping - angular_damp = params.angular_damping - else: - linear_damp = default_surface_linear_damping - angular_damp = default_surface_angular_damping - - var decay := 1.0 + terrain_physics.get_decay_factor(_surface_time_s) - #linear_damp *= decay - #angular_damp *= decay - + _surface_terrain = Terrain.from_collision(global_position, primary_body) _surface_time_s += state.step else: # Ball is in the air - linear_damp = aerial_linear_damping - angular_damp = aerial_angular_damping + _surface_terrain = Terrain.Type.NONE _surface_time_s = 0.0 func _physics_process(delta: float) -> void: # Simulate magnus effect var magnus := _magnus_force() - if magnus.length_squared() > MAGNUS_EPSILON: + 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 diff --git a/src/equipment/balls/physics_ball/physics_ball.tscn b/src/equipment/balls/physics_ball/physics_ball.tscn index 0bdbfec..d538672 100644 --- a/src/equipment/balls/physics_ball/physics_ball.tscn +++ b/src/equipment/balls/physics_ball/physics_ball.tscn @@ -19,58 +19,56 @@ [sub_resource type="Resource" id="Resource_casfi"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 0.5 +linear_drag = 0.0 +angular_drag = 1.0 [sub_resource type="Resource" id="Resource_3k63c"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 8.0 +linear_drag = 0.0 +angular_drag = 0.0 [sub_resource type="Resource" id="Resource_xf73q"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 2.0 +linear_drag = 0.0 +angular_drag = 1.0 [sub_resource type="Resource" id="Resource_nhn3l"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 0.1 +linear_drag = 0.0 +angular_drag = 1.0 [sub_resource type="Resource" id="Resource_m3wjo"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 1.0 +linear_drag = 0.0 +angular_drag = 1.0 [sub_resource type="Resource" id="Resource_h4rld"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 0.1 +linear_drag = 0.0 +angular_drag = 1.0 [sub_resource type="Resource" id="Resource_j6lib"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 2.0 +linear_drag = 0.0 +angular_drag = 1.0 [sub_resource type="Resource" id="Resource_7f7ql"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 8.0 +linear_drag = 0.0 +angular_drag = 3.0 [sub_resource type="Resource" id="Resource_pusmf"] script = ExtResource("4_onl6o") -linear_damping = 1.0 -angular_damping = 24.0 +linear_drag = 1.0 +angular_drag = 10.0 [sub_resource type="Resource" id="Resource_edkxb"] script = ExtResource("4_onl6o") -linear_damping = 0.0 -angular_damping = 1.0 +linear_drag = 0.0 +angular_drag = 1.0 [sub_resource type="Resource" id="Resource_3ngau"] script = ExtResource("3_52hui") -damping_decay_curve = 12.0 -damping_decay_scale = 8.0 default = SubResource("Resource_3k63c") rough = SubResource("Resource_7f7ql") fairway = SubResource("Resource_xf73q") 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 7558b32..e65949c 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_damping := 0.0 -@export var angular_damping := 0.0 +@export var linear_drag := 0.0 +@export var angular_drag := 0.0 diff --git a/src/equipment/balls/physics_ball/terrain_physics/terrain_physics.gd b/src/equipment/balls/physics_ball/terrain_physics/terrain_physics.gd index 4c07b81..0517a59 100644 --- a/src/equipment/balls/physics_ball/terrain_physics/terrain_physics.gd +++ b/src/equipment/balls/physics_ball/terrain_physics/terrain_physics.gd @@ -1,9 +1,6 @@ class_name TerrainPhysics extends Resource ## Container for ball behavior parameters when in contact with different terrain types -@export_exp_easing() var damping_decay_curve := 1.0 -@export var damping_decay_scale := 8.0 - @export var default: TerrainParameters @export var rough: TerrainParameters @@ -41,10 +38,3 @@ func get_params(type: Terrain.Type) -> TerrainParameters: return glass _: return default - - -func get_decay_factor(time: float) -> float: - var x := time / damping_decay_scale - if damping_decay_curve < 1.0: - return 1.0 - pow(1.0 - x, 1.0 / damping_decay_curve) - return pow(x, damping_decay_curve)