diff --git a/car.gd b/car.gd new file mode 100644 index 0000000..83dfb17 --- /dev/null +++ b/car.gd @@ -0,0 +1,8 @@ +class_name Car +extends RigidBody3D + +@export var wheels: Array[Wheel] + +func _physics_process(_delta: float) -> void: + for wheel: Wheel in wheels: + wheel.apply_forces(self) diff --git a/car.gd.uid b/car.gd.uid new file mode 100644 index 0000000..702134c --- /dev/null +++ b/car.gd.uid @@ -0,0 +1 @@ +uid://brdagffuckrxo diff --git a/car.tscn b/car.tscn index 274bec5..df353ca 100644 --- a/car.tscn +++ b/car.tscn @@ -1,12 +1,16 @@ -[gd_scene load_steps=3 format=3 uid="uid://dklnyvh2pawj1"] +[gd_scene load_steps=5 format=3 uid="uid://dklnyvh2pawj1"] [ext_resource type="PackedScene" uid="uid://b4q25yxjds0hu" path="res://RX-Car.glb" id="1_7822p"] +[ext_resource type="Script" uid="uid://brdagffuckrxo" path="res://car.gd" id="1_uoj53"] +[ext_resource type="PackedScene" uid="uid://cqcmml6o1x724" path="res://wheel.tscn" id="3_k61xc"] [sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_7822p"] points = PackedVector3Array(2.639865, -0.93180054, 2.1575794, 2.5861135, 1.1470379, -1.4858942, 2.3804116, 0.5341828, 5.2797356, 2.3804116, 0.18806255, 5.32922, 2.3804116, -0.8661753, 4.864291, 2.3804116, -1.0148906, 4.0564213, 2.6011019, -0.9791671, 0.85025597, 2.590765, -0.8667045, -2.7230182, 2.590765, -0.28533888, -2.7966702, 1.4661236, 1.6421381, -0.30746174, 1.4661236, 1.6421381, 1.965394, 2.2072706, 0.77604365, 5.2682266, 2.4093547, -0.27607727, -5.989025, 2.3804116, 0.40134466, -4.392848, 2.2186413, 0.11079419, -5.824459, 1.82481, 0.6985105, -5.445842, 2.3230424, -0.08025998, 5.6525984, 2.212439, -0.45231283, 5.6169233, 0.3802452, -0.5354029, 5.61232, -2.3812249, -0.8661753, 4.864291, -2.3812249, -1.0148906, 4.0564213, 2.3804116, -1.0148906, -4.7944813, 2.3804116, -0.9804902, -5.7243385, 0.8805454, 1.6670123, -0.30746174, 1.7379808, 0.72020924, -5.445842, 1.0908988, 0.8818908, -5.445842, 0.8805454, 1.6670123, 1.965394, 0.9823625, 1.0935851, 5.340728, 1.5581212, 1.056274, 5.295847, 2.2506852, -0.2766065, -5.998232, 1.3152068, -0.28031117, -6.0511694, 0.3802452, -0.28401583, -6.102956, 0.3802452, -0.05273974, 5.649146, -2.310418, -0.08025998, 5.6537495, -0.38105845, -0.5354029, 5.61232, -2.1574335, -0.42452794, 5.6169233, -2.3812249, 0.18806255, 5.32922, -2.640161, -0.93180054, 2.1575794, -2.601915, -0.9791671, 0.85025597, -2.3812249, -1.0148906, -4.7944813, -2.3812249, -0.9804902, -5.7243385, 0.3802452, -0.4711007, -6.001684, 0.3802452, 1.6881818, -0.30746174, -1.0917118, 0.8818908, -5.445842, -0.38105845, 1.6884462, -0.30746174, 0.3802452, 1.6881818, 1.965394, -0.98317564, 1.0935851, 5.340728, -0.38105845, 1.6884462, 1.965394, -0.38105845, -0.28401583, -6.102956, -0.38105845, -0.05273974, 5.649146, -2.3812249, 0.5341828, 5.2797356, -2.3812249, 0.4148401, 5.296997, -1.559451, 1.056274, 5.295847, -2.2086005, 0.77604365, 5.2682266, -2.5869267, 1.1470379, -1.4858942, -2.5920951, -0.28533888, -2.7966702, -2.5920951, -0.8667045, -2.7230182, -2.415853, -0.28401583, -6.0488677, -2.390011, -0.7981685, -5.8094983, -1.3129189, -0.28401583, -6.0787888, -0.38105845, -0.4711007, -6.001684, -2.3176537, -0.08661085, -5.9372387, -2.2194543, 0.11079419, -5.824459, -1.739311, 0.72020924, -5.445842, -1.4669368, 1.6421381, -0.30746174, -1.4669368, 1.6421381, 1.965394, -1.825623, 0.6985105, -5.445842, -2.3812249, 0.40134466, -4.392848) -[node name="Car" type="RigidBody3D"] -mass = 1000.0 +[node name="Car" type="RigidBody3D" node_paths=PackedStringArray("wheels")] +mass = 10000.0 +script = ExtResource("1_uoj53") +wheels = [NodePath("WheelRR"), NodePath("WheelFR"), NodePath("WheelFL"), NodePath("WheelRL")] [node name="CollisionShape3D" type="CollisionShape3D" parent="."] transform = Transform3D(0.36002815, 0, 0, 0, 0.36002856, 0, 0, 0, 0.36002815, -0.010458469, 0.12041265, -0.23569715) @@ -14,3 +18,15 @@ shape = SubResource("ConvexPolygonShape3D_7822p") [node name="RX-Car" parent="." instance=ExtResource("1_7822p")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5505377, 0.29083502, -2.049065) + +[node name="WheelRR" parent="." instance=ExtResource("3_k61xc")] +transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0.883119, -0.15691829, 0.9406) + +[node name="WheelFR" parent="." instance=ExtResource("3_k61xc")] +transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0.883119, -0.13746506, -1.6053799) + +[node name="WheelFL" parent="." instance=ExtResource("3_k61xc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.9021299, -0.15691829, -1.6053799) + +[node name="WheelRL" parent="." instance=ExtResource("3_k61xc")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.9021299, -0.13746506, 0.9405999) diff --git a/main.tscn b/main.tscn index 364f0c0..dfa458e 100644 --- a/main.tscn +++ b/main.tscn @@ -32,13 +32,13 @@ shadow_enabled = true environment = SubResource("Environment_0xm2m") [node name="Camera3D" type="Camera3D" parent="."] -transform = Transform3D(-0.20387852, -0.07608818, 0.97603494, -0.07710266, 0.9951264, 0.061470944, -0.9759553, -0.06272231, -0.20875147, 4.482925, 0.8071947, -35.488564) +transform = Transform3D(0.25682604, -0.12386126, 0.95848775, 0.032057658, 0.99229956, 0.11964079, -0.9659258, 0, 0.25881907, 4.482925, 4.2054358, -35.488564) [node name="CSGBox3D2" type="CSGBox3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.7605286, 1.616055, -35.098152) +transform = Transform3D(-1.0000001, 0, 0, 0, -1.0000001, 0, 0, 0, 1, -5.7605286, 1.5558312, -35.098152) material_override = SubResource("StandardMaterial3D_0xm2m") use_collision = true -size = Vector3(0.3, 2, 0.3) +size = Vector3(0.5, 2, 0.5) [node name="CSGBox3D" type="CSGBox3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.041906357, 0.010412216, -0.36748695) @@ -47,4 +47,4 @@ use_collision = true size = Vector3(178.75879, 1, 233.49219) [node name="Car" parent="." instance=ExtResource("1_ig7tw")] -transform = Transform3D(0.79928625, -0.407864, 0.4413484, 0.6009505, 0.54247415, -0.5870096, 0, 0.73441726, 0.6786982, -3.1980705, 9.413963, -35.90589) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.1980705, 3.2689552, -35.90589) diff --git a/project.godot b/project.godot index 56fca0b..ea0b38b 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,10 @@ run/main_scene="res://main.tscn" config/features=PackedStringArray("4.5", "Forward Plus") config/icon="res://icon.svg" +[display] + +window/stretch/mode="viewport" + [physics] 3d/physics_engine="Jolt Physics" diff --git a/wheel.gd b/wheel.gd new file mode 100644 index 0000000..d296dd5 --- /dev/null +++ b/wheel.gd @@ -0,0 +1,32 @@ +class_name Wheel +extends RayCast3D + +@export var wheel_radius: float = 0.316 +@export var suspension_rest_length: float = 0.1 +@export var suspension_stiffness: float = 250_000 + +func _ready() -> void: + target_position *= suspension_rest_length + wheel_radius + +func apply_forces(car: Car) -> void: + force_raycast_update() + + var force: Vector3 = get_suspension_force() + car.apply_force(force, car.to_local(get_collision_point())) + +func get_suspension_force() -> Vector3: + var up: Vector3 = global_basis.y + if not is_colliding(): + $"RX-Wheel".position = -up * suspension_rest_length + return Vector3.ZERO + + var collision_point: Vector3 = to_local(get_collision_point()) + var wheel_center: Vector3 = collision_point + (up * wheel_radius) + $"RX-Wheel".position = wheel_center + var suspension_length: float = -up.dot(wheel_center) + var suspension_displacement: float = suspension_rest_length - suspension_length + #https://en.wikipedia.org/wiki/Hookes_law + var y_force_scalar: float = suspension_stiffness * suspension_displacement + var force: Vector3 = Vector3.UP * y_force_scalar + + return force diff --git a/wheel.gd.uid b/wheel.gd.uid new file mode 100644 index 0000000..80fdaa2 --- /dev/null +++ b/wheel.gd.uid @@ -0,0 +1 @@ +uid://dnxetgki0ga2q diff --git a/wheel.tscn b/wheel.tscn index f64bb3c..3e57660 100644 --- a/wheel.tscn +++ b/wheel.tscn @@ -1,8 +1,11 @@ -[gd_scene load_steps=2 format=3 uid="uid://cqcmml6o1x724"] +[gd_scene load_steps=3 format=3 uid="uid://cqcmml6o1x724"] [ext_resource type="PackedScene" uid="uid://ceia8k20k378e" path="res://RX-Wheel.glb" id="1_8m8ww"] +[ext_resource type="Script" uid="uid://dnxetgki0ga2q" path="res://wheel.gd" id="1_e0ure"] [node name="Wheel" type="RayCast3D"] -transform = Transform3D(-4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 0, 0, 1, 0, 0, 0) +enabled = false +script = ExtResource("1_e0ure") [node name="RX-Wheel" parent="." instance=ExtResource("1_8m8ww")] +transform = Transform3D(-4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0, 1, 0, 0, 0)