From da8749568fd2bc67a1ae2af82e58ba3891434762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veeti=20V=C3=A4is=C3=A4nen?= Date: Wed, 24 Jan 2024 17:13:04 +0200 Subject: [PATCH 1/2] Use decal pool for tire marks --- scenes/vehicle/tire_mark_decal.gd | 12 ++++++++ scenes/vehicle/tire_mark_decal.tscn | 29 ++++++++++++++++++ scenes/vehicle/wheel_suspension.gd | 44 ++++++++++++++++++++++------ scenes/vehicle/wheel_suspension.tscn | 16 ++++++---- 4 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 scenes/vehicle/tire_mark_decal.gd create mode 100644 scenes/vehicle/tire_mark_decal.tscn diff --git a/scenes/vehicle/tire_mark_decal.gd b/scenes/vehicle/tire_mark_decal.gd new file mode 100644 index 0000000..40049c4 --- /dev/null +++ b/scenes/vehicle/tire_mark_decal.gd @@ -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 diff --git a/scenes/vehicle/tire_mark_decal.tscn b/scenes/vehicle/tire_mark_decal.tscn new file mode 100644 index 0000000..d5029ba --- /dev/null +++ b/scenes/vehicle/tire_mark_decal.tscn @@ -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"] diff --git a/scenes/vehicle/wheel_suspension.gd b/scenes/vehicle/wheel_suspension.gd index 88c5b6b..7e1854d 100644 --- a/scenes/vehicle/wheel_suspension.gd +++ b/scenes/vehicle/wheel_suspension.gd @@ -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 @@ -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 @@ -64,18 +67,20 @@ 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() - + _update_tire_marks() wheelmesh.position.y = -spring_curr_length wheelmesh.rotate_x(wrapf(-spin * delta, 0, TAU)) @@ -140,6 +145,27 @@ func _update_tire_squeal(): $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.2: + break + + mark.global_position = global_position + mark.global_rotation = global_rotation + 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 diff --git a/scenes/vehicle/wheel_suspension.tscn b/scenes/vehicle/wheel_suspension.tscn index 2b906db..2e597b6 100644 --- a/scenes/vehicle/wheel_suspension.tscn +++ b/scenes/vehicle/wheel_suspension.tscn @@ -17,9 +17,12 @@ 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"] +[sub_resource type="RibbonTrailMesh" id="RibbonTrailMesh_nahxj"] material = SubResource("StandardMaterial3D_ry7we") -size = Vector2(0.2, 0.2) +shape = 0 +size = 0.2 +sections = 2 +section_length = 0.1 [node name="Wheel_br" type="RayCast3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.8, 0, 1.5) @@ -27,17 +30,18 @@ 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 +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, -0.3, 0) +visible = false +amount = 100 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") +draw_pass_1 = SubResource("RibbonTrailMesh_nahxj") [node name="TireSqueal" type="AudioStreamPlayer3D" parent="."] stream = ExtResource("3_2n5q2") From d06f87ffcb55f1f50d8296cef4824a8b169d9f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veeti=20V=C3=A4is=C3=A4nen?= Date: Thu, 8 Feb 2024 19:00:52 +0200 Subject: [PATCH 2/2] Update mark rotation when adding it --- scenes/vehicle/wheel_suspension.gd | 7 +++---- scenes/vehicle/wheel_suspension.tscn | 24 +----------------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/scenes/vehicle/wheel_suspension.gd b/scenes/vehicle/wheel_suspension.gd index 7e1854d..eb22957 100644 --- a/scenes/vehicle/wheel_suspension.gd +++ b/scenes/vehicle/wheel_suspension.gd @@ -80,7 +80,6 @@ func _ready() -> void: func _process(delta: float) -> void: _update_tire_squeal() - _update_tire_marks() wheelmesh.position.y = -spring_curr_length wheelmesh.rotate_x(wrapf(-spin * delta, 0, TAU)) @@ -98,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): @@ -141,7 +141,6 @@ 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 @@ -156,11 +155,11 @@ func _update_tire_marks(): if mark.active: continue - if global_position.distance_to(prev_mark_pos) < 0.2: + if global_position.distance_to(prev_mark_pos) < 0.15: break mark.global_position = global_position - mark.global_rotation = global_rotation + 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 diff --git a/scenes/vehicle/wheel_suspension.tscn b/scenes/vehicle/wheel_suspension.tscn index 2e597b6..f312214 100644 --- a/scenes/vehicle/wheel_suspension.tscn +++ b/scenes/vehicle/wheel_suspension.tscn @@ -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"] @@ -11,19 +11,6 @@ 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="RibbonTrailMesh" id="RibbonTrailMesh_nahxj"] -material = SubResource("StandardMaterial3D_ry7we") -shape = 0 -size = 0.2 -sections = 2 -section_length = 0.1 - [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") @@ -34,15 +21,6 @@ layers = 2 mesh = SubResource("10") skeleton = NodePath("") -[node name="TireMarks" type="GPUParticles3D" parent="."] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, -0.3, 0) -visible = false -amount = 100 -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("RibbonTrailMesh_nahxj") - [node name="TireSqueal" type="AudioStreamPlayer3D" parent="."] stream = ExtResource("3_2n5q2") bus = &"Car_Bus"