Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions scenes/vehicle/tire_mark_decal.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extends Decal

var active := false:
set(value):
active = value
visible = value
if value:
$TireMarkTimer.start()


func _on_tire_mark_timer_timeout() -> void:
active = false
29 changes: 29 additions & 0 deletions scenes/vehicle/tire_mark_decal.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[gd_scene load_steps=5 format=3 uid="uid://0nh338l8d7ai"]

[ext_resource type="Script" path="res://scenes/vehicle/tire_mark_decal.gd" id="1_pr6ks"]

[sub_resource type="Gradient" id="Gradient_3xgt7"]
colors = PackedColorArray(0, 0, 0, 1, 0.180005, 0.180005, 0.180005, 1)

[sub_resource type="FastNoiseLite" id="FastNoiseLite_usc7i"]

[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_wvypd"]
color_ramp = SubResource("Gradient_3xgt7")
noise = SubResource("FastNoiseLite_usc7i")

[node name="TireMarkDecal" type="Decal"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.8, -0.134349, 1.5)
layers = 4
size = Vector3(0.2, 1, 0.2)
texture_albedo = SubResource("NoiseTexture2D_wvypd")
upper_fade = 1e-05
lower_fade = 1e-05
distance_fade_enabled = true
cull_mask = 1048572
script = ExtResource("1_pr6ks")

[node name="TireMarkTimer" type="Timer" parent="."]
wait_time = 3.0
one_shot = true

[connection signal="timeout" from="TireMarkTimer" to="." method="_on_tire_mark_timer_timeout"]
45 changes: 35 additions & 10 deletions scenes/vehicle/wheel_suspension.gd
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var rolling_resistance_coefficient := 0.02
var y_force := 0.0

var wheel_inertia := 0.0
var spin := 0.0 :
var spin := 0.0:
set = set_spin, get = get_spin

var z_vel := 0.0
Expand All @@ -50,6 +50,9 @@ var prev_spin := 0.0
var prev_compress := 0.0
var spring_curr_length := spring_length

var tire_mark_pool := []
var max_tire_mark_count := 500
var prev_mark_pos := Vector3.ZERO

@onready var car = get_parent() as BaseCar
@onready var wheelmesh = $MeshInstance3D
Expand All @@ -64,18 +67,19 @@ func _ready() -> void:
set_target_position(Vector3.DOWN * (spring_length + tire_radius))

# Some sensible peak slip values just in case tire model fails to have them
peak_slip.x = 0.12
peak_slip.y = 0.09
peak_slip.x = 0.12
peak_slip.y = 0.09

tire_mark_pool.resize(max_tire_mark_count)

for i in range(max_tire_mark_count):
tire_mark_pool[i] = load("res://scenes/vehicle/tire_mark_decal.tscn").instantiate()
tire_mark_pool[i].active = false
get_tree().root.add_child(tire_mark_pool[i])


func _process(delta: float) -> void:
$TireMarks.emitting = false
if abs(slip_vec.x) >= peak_slip.x or abs(slip_vec.y) >= peak_slip.y:
if local_vel.length() > 2.0:
$TireMarks.emitting = self.is_colliding()

_update_tire_squeal()

wheelmesh.position.y = -spring_curr_length
wheelmesh.rotate_x(wrapf(-spin * delta, 0, TAU))

Expand All @@ -93,6 +97,7 @@ func _physics_process(delta: float) -> void:
if is_finite(friction_power):
tire_wear = tire_model.update_tire_wear(tire_wear, friction_power, delta)
tire_temp = tire_model.update_tire_temps(tire_temp, friction_power, z_vel, delta)
_update_tire_marks()


func set_params(params: WheelSuspensionParameters):
Expand Down Expand Up @@ -136,10 +141,30 @@ func _update_tire_squeal():
var y := absf(slip_vec.y)
var avg := (x + y) * 0.5
var pitch := clampf(avg, 0.65, 1.00)

$TireSqueal.pitch_scale = pitch


func _update_tire_marks():
if local_vel.length() < 2.0:
return
if not is_colliding():
return

if abs(slip_vec.x) >= peak_slip.x or abs(slip_vec.y) >= peak_slip.y:
for mark in tire_mark_pool:
if mark.active:
continue

if global_position.distance_to(prev_mark_pos) < 0.15:
break

mark.global_position = global_position
mark.global_rotation = global_rotation.rotated(global_transform.basis.y, prev_mark_pos.angle_to(global_position))
prev_mark_pos = mark.global_position
mark.active = true
break


func apply_forces(opposite_comp, delta):
############# Local forward velocity #############
local_vel = (global_transform.origin - prev_pos) / delta * global_transform.basis
Expand Down
22 changes: 2 additions & 20 deletions scenes/vehicle/wheel_suspension.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://nelgdfamj8jh"]
[gd_scene load_steps=5 format=3 uid="uid://nelgdfamj8jh"]

[ext_resource type="Material" path="res://resources/materials/tire.tres" id="1"]
[ext_resource type="Script" path="res://scenes/vehicle/wheel_suspension.gd" id="2"]
Expand All @@ -11,34 +11,16 @@ bottom_radius = 0.3
height = 0.2
radial_segments = 16

[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_3a5fp"]
gravity = Vector3(0, 0, 0)

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ry7we"]
albedo_color = Color(0.176471, 0.176471, 0.176471, 1)

[sub_resource type="PlaneMesh" id="PlaneMesh_8qb03"]
material = SubResource("StandardMaterial3D_ry7we")
size = Vector2(0.2, 0.2)

[node name="Wheel_br" type="RayCast3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.8, 0, 1.5)
script = ExtResource("2")

[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0)
layers = 2
mesh = SubResource("10")
skeleton = NodePath("")

[node name="TireMarks" type="GPUParticles3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.3, 0)
emitting = false
amount = 10000
lifetime = 10.0
visibility_aabb = AABB(-0.503298, -0.233458, -0.487277, 1.0066, 0.466916, 0.974553)
process_material = SubResource("ParticleProcessMaterial_3a5fp")
draw_pass_1 = SubResource("PlaneMesh_8qb03")

[node name="TireSqueal" type="AudioStreamPlayer3D" parent="."]
stream = ExtResource("3_2n5q2")
bus = &"Car_Bus"