From c1426ddcc0e89ea67d9f41aed78911dfdda888f0 Mon Sep 17 00:00:00 2001 From: Wheelbarrow Date: Sat, 26 Jul 2025 15:29:11 -0400 Subject: [PATCH] changed to use max static friction --- car.gd | 2 +- wheel.gd | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/car.gd b/car.gd index 11dfa16..147ef46 100644 --- a/car.gd +++ b/car.gd @@ -53,7 +53,7 @@ func steer(delta: float) -> void: front_left.rotation.y = -outer_angle func apply_air_resistance() -> void: - var force: Vector3 = air_resistance * linear_velocity * linear_velocity.length() + var force: Vector3 = -air_resistance * linear_velocity * linear_velocity.length() apply_force(force, center_of_mass) DebugDraw3D.draw_arrow( to_global(center_of_mass), diff --git a/wheel.gd b/wheel.gd index c270006..9d0fef5 100644 --- a/wheel.gd +++ b/wheel.gd @@ -9,25 +9,31 @@ extends RayCast3D @export var suspension_rest_length: float = 0.1 @export var suspension_stiffness: float = 30_000 @export var suspension_damping: float = 2000 +@export_group("Friction") +@export var static_friction: float = 1.1 var car: Car +var acceleration: Vector3 var _last_velocity: Vector3 func _ready() -> void: target_position *= suspension_rest_length + wheel_radius - $"RX-Wheel".rotate_y(PI if flipped else 0.0) + if flipped: $"RX-Wheel".rotate_y(PI) func set_new_car(new_car: Car) -> void: car = new_car # Little bit freaky but we put up with it _last_velocity = car.get_velocity_at_point(get_collision_point()) -func _physics_process(_delta: float) -> void: +func _physics_process(delta: float) -> void: + var velocity: Vector3 = car.get_velocity_at_point(get_collision_point()) + acceleration = velocity - _last_velocity / delta force_raycast_update() apply_suspension_force() apply_rolling_resistance() - apply_engine_force() + apply_friction_force() + _last_velocity = car.get_velocity_at_point(get_collision_point()) func apply_suspension_force() -> void: @@ -71,25 +77,46 @@ func apply_rolling_resistance() -> void: car.apply_force(force, car.to_local(get_collision_point())) DebugDraw3D.draw_arrow( arrow_tail, - arrow_tail + force, + arrow_tail + force / 250, Color.ORANGE, .2 ) -func apply_engine_force() -> void: +func apply_friction_force() -> void: if not on_drivetrain: return if not is_colliding(): return var forwards: Vector3 = -global_basis.z + var backwards: Vector3 = global_basis.z + var normal: Vector3 = get_collision_normal() + + var total_weight: Vector3 = car.mass * car.get_gravity() + var wheel_to_com: float = abs( + forwards.dot(car.center_of_mass) - \ + forwards.dot(car.to_local(get_collision_point())) + ) + var weight: Vector3 = wheel_to_com / car.wheelbase * total_weight + var normal_force: Vector3 = -weight + + # Intern please fix + var surface_static_friction: float = 1 + var static_friction_coeff: float = static_friction * surface_static_friction + var maximum_static_friction: float = static_friction_coeff * normal_force.length() var torque: float = car.get_torque_per_wheel() - var force: Vector3 = forwards * torque / wheel_radius + var applied_force: Vector3 = backwards * torque / wheel_radius + #Restricts applied force to plane parralel to surface + applied_force -= normal * applied_force.dot(normal) + + var friction_force: Vector3 = Vector3.ZERO + if applied_force.length() <= maximum_static_friction: + friction_force = -applied_force var arrow_tail: Vector3 = to_global(get_wheel_center()) - car.apply_force(force, car.to_local(get_collision_point())) + car.apply_force(friction_force, car.to_local(get_collision_point())) DebugDraw3D.draw_arrow( arrow_tail, - arrow_tail + force / 250, + arrow_tail + friction_force / 250, Color.BLUE, .2 )