diff --git a/src/equipment/balls/physics_ball/normal_physics.tres b/src/equipment/balls/physics_ball/normal_physics.tres index 55a1901..f9372f8 100644 --- a/src/equipment/balls/physics_ball/normal_physics.tres +++ b/src/equipment/balls/physics_ball/normal_physics.tres @@ -1,5 +1,4 @@ [gd_resource type="PhysicsMaterial" format=3 uid="uid://3bih72l068ic"] [resource] -friction = 0.8 bounce = 0.5 diff --git a/src/player/shot_setup/shot_setup.gd b/src/player/shot_setup/shot_setup.gd index 55b1abc..8e9b6e7 100644 --- a/src/player/shot_setup/shot_setup.gd +++ b/src/player/shot_setup/shot_setup.gd @@ -241,13 +241,14 @@ func take_shot() -> void: var impulse := get_shot_impulse(shot_power) print_debug("Shot impulse: ", impulse, "; ", impulse.length(), " N*s") + # Curve the curve var curve := shot_ref.global_basis.x.normalized() * shot_curve # Position where the ball is hit (imparts spin) var offset := curve * 0.001 print_debug("Shot offset: ", offset, "; ", offset.length(), " m") # Rotate impulse - impulse = impulse.rotated(Vector3.UP, -shot_curve * CURVE_INFLUENCE) + impulse = impulse.rotated(Vector3.UP, -shot_curve * CURVE_INFLUENCE * shot_power) if game_ball: game_ball.iron_ball = club == Club.Type.IRON @@ -264,6 +265,7 @@ func _show_shot_projection() -> void: if not game_ball: return + shot_projection.putt_projection = club == Club.Type.PUTTER shot_projection.initial_speed = 1 shot_projection.basis = shot_ref.basis.orthonormalized() var shot_speed := get_shot_impulse(1.0).length() / game_ball.mass diff --git a/src/ui/3d/projectile_arc/projectile_arc.gd b/src/ui/3d/projectile_arc/projectile_arc.gd index 8e5d8e0..6ec7898 100644 --- a/src/ui/3d/projectile_arc/projectile_arc.gd +++ b/src/ui/3d/projectile_arc/projectile_arc.gd @@ -3,6 +3,11 @@ class_name ProjectileArc extends Node3D ## ## If this node has any children, they will be positioned wherever the projection ends. +## Constant attrition factor for putting collisions +## The actual velocity attrition is dependent on lots of factors +#const PUTT_ATTRITION := 0.75 # rough? +const PUTT_ATTRITION := 0.8325 # green? + ## Initial speed of the projectile, in m/s. ## The projectile's initial direction vector is the negative Z direction relative to this node. @export var initial_speed := 1.0 @@ -14,6 +19,8 @@ class_name ProjectileArc extends Node3D @export var max_steps := 50 ## Ticks between each projection update. 0 means update every tick. @export var ticks_per_update := 0 +## If enabled, project a linear putt instead of an arcing shot +@export var putt_projection := false @export_category("Collision") ## Enables collision checking. Projection will end at the point where a collision is detected. @@ -27,12 +34,16 @@ class_name ProjectileArc extends Node3D var _tick_counter := 0 +var _debug_points: Array[Vector3] = [] + @onready var polygon: CSGPolygon3D = %Polygon @onready var path: Path3D = %Path @onready var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") @onready var gravity_vec: Vector3 = ProjectSettings.get_setting("physics/3d/default_gravity_vector") +@onready var debug_draw: Control = %DebugDraw + func _process(_delta: float) -> void: if not visible: @@ -45,6 +56,8 @@ func _process(_delta: float) -> void: return _tick_counter = ticks_per_update + _debug_points = [] + # Rebuild path curve path.global_basis = Basis.IDENTITY path.curve.clear_points() @@ -72,10 +85,15 @@ func _process(_delta: float) -> void: var collision := space.intersect_ray(ray_params) if collision: # Set current position to collision point, so it will be added to the path - # TODO: we could project further using the surface normal here... pos = collision["position"] - # End projection! - break + _debug_points.append(pos) + if putt_projection: + var norm: Vector3 = (collision["normal"] as Vector3).normalized() + next_pos = pos + norm * 0.05 + vel = PUTT_ATTRITION * (vel - 2 * norm * vel.dot(norm)) + else: + # End projection! + break pos = next_pos @@ -89,6 +107,8 @@ func _process(_delta: float) -> void: node_3d.global_position = pos node_3d.global_basis = Basis.IDENTITY + (%DebugDraw as CanvasItem).queue_redraw() + func _on_visibility_changed() -> void: # Force update as soon as visible diff --git a/src/ui/3d/projectile_arc/projectile_arc.tscn b/src/ui/3d/projectile_arc/projectile_arc.tscn index 9f2313b..345e8c2 100644 --- a/src/ui/3d/projectile_arc/projectile_arc.tscn +++ b/src/ui/3d/projectile_arc/projectile_arc.tscn @@ -1,9 +1,9 @@ -[gd_scene load_steps=9 format=3 uid="uid://fht6j87o8ecr"] +[gd_scene load_steps=10 format=3 uid="uid://fht6j87o8ecr"] [ext_resource type="Script" path="res://src/ui/3d/projectile_arc/projectile_arc.gd" id="1_vafqi"] [ext_resource type="Shader" path="res://src/shaders/plasma.gdshader" id="2_pi36v"] -[sub_resource type="Curve3D" id="Curve3D_rfv3d"] +[sub_resource type="Curve3D" id="Curve3D_sj0rs"] [sub_resource type="Gradient" id="Gradient_28hbf"] offsets = PackedFloat32Array(0, 0.37193, 0.838596, 1) @@ -34,12 +34,31 @@ shader_parameter/pulse_speed = 0.3 shader_parameter/wave_gradient = SubResource("GradientTexture1D_l8ond") shader_parameter/pulse_gradient = SubResource("GradientTexture1D_8xhfy") +[sub_resource type="GDScript" id="GDScript_hbqgy"] +script/source = "extends Control + +const COLOR := Color(0, 1, 0) +const WIDTH := 4 +const RADIUS := 16 + +@onready var root: ProjectileArc = owner + +func _draw() -> void: + if not visible: + return + + var camera := get_viewport().get_camera_3d() + for p: Vector3 in root._debug_points: + var pos := camera.unproject_position(p) + draw_circle(pos, RADIUS, COLOR, false, WIDTH, true) +" + [node name="ProjectileArc" type="Node3D"] script = ExtResource("1_vafqi") [node name="Path" type="Path3D" parent="."] unique_name_in_owner = true -curve = SubResource("Curve3D_rfv3d") +curve = SubResource("Curve3D_sj0rs") [node name="Polygon" type="CSGPolygon3D" parent="Path"] unique_name_in_owner = true @@ -56,4 +75,13 @@ path_u_distance = 1.0 path_joined = false material = SubResource("ShaderMaterial_ahf42") +[node name="DebugDraw" type="Control" parent="."] +unique_name_in_owner = true +visible = false +layout_mode = 3 +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 +script = SubResource("GDScript_hbqgy") + [connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]