From ae7b7226c64e7b9ce62e045991c315040563fe5a Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Sun, 9 Jul 2023 14:02:37 +0100 Subject: road simplification via Ramer–Douglas–Peucker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/road.png | Bin 0 -> 252 bytes Assets/road.png.import | 34 ++++++++++++++++++++++++++++++++++ Nodes/Level_test.tscn | 11 ++++++++--- Scripts/Road.gd | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ Scripts/drawing.gd | 3 ++- 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 Assets/road.png create mode 100644 Assets/road.png.import create mode 100644 Scripts/Road.gd diff --git a/Assets/road.png b/Assets/road.png new file mode 100644 index 0000000..5acc2e9 Binary files /dev/null and b/Assets/road.png differ diff --git a/Assets/road.png.import b/Assets/road.png.import new file mode 100644 index 0000000..59a81a8 --- /dev/null +++ b/Assets/road.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bcn7tgs6a4fm7" +path="res://.godot/imported/road.png-c3c47e2cc8c90beae2ad5c8a3bb2c3ca.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/road.png" +dest_files=["res://.godot/imported/road.png-c3c47e2cc8c90beae2ad5c8a3bb2c3ca.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Nodes/Level_test.tscn b/Nodes/Level_test.tscn index f082198..0703906 100644 --- a/Nodes/Level_test.tscn +++ b/Nodes/Level_test.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://dliou1u4o6bib"] +[gd_scene load_steps=12 format=3 uid="uid://dliou1u4o6bib"] [ext_resource type="Script" path="res://Scripts/scene_control.gd" id="1_0esj3"] [ext_resource type="Texture2D" uid="uid://5xqahgawme4m" path="res://Assets/start.png" id="1_wenkl"] @@ -6,7 +6,8 @@ [ext_resource type="Texture2D" uid="uid://dg3v488vx0oj6" path="res://Assets/checkpoint.png" id="3_cgigr"] [ext_resource type="PackedScene" uid="uid://c1mvbh2fwqtkb" path="res://Nodes/car.tscn" id="4_xvobs"] [ext_resource type="Script" path="res://Scripts/drawing.gd" id="5_x7h3g"] -[ext_resource type="PackedScene" uid="uid://wkfai2lvnp7n" path="res://Nodes/checkpoint.tscn" id="7_52mhf"] +[ext_resource type="PackedScene" path="res://Nodes/checkpoint.tscn" id="7_52mhf"] +[ext_resource type="Script" path="res://Scripts/Road.gd" id="7_nyjk7"] [ext_resource type="PackedScene" uid="uid://c8r6i3bu37ogu" path="res://Nodes/ui.tscn" id="8_8u1ba"] [sub_resource type="CircleShape2D" id="CircleShape2D_6g88q"] @@ -42,7 +43,11 @@ acceleration = 0.05 [node name="DrawNode" type="Node2D" parent="."] script = ExtResource("5_x7h3g") -[node name="TrackLine" type="Line2D" parent="DrawNode"] +[node name="Road" type="Line2D" parent="DrawNode"] +width = 100.0 +default_color = Color(0.133333, 0.133333, 0.133333, 1) +joint_mode = 2 +script = ExtResource("7_nyjk7") [node name="TrackPath" type="Path2D" parent="DrawNode"] curve = SubResource("Curve2D_0exre") diff --git a/Scripts/Road.gd b/Scripts/Road.gd new file mode 100644 index 0000000..e0b69a1 --- /dev/null +++ b/Scripts/Road.gd @@ -0,0 +1,48 @@ +extends Line2D + +var epsilon = 20 + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + +func simplify(): + points = simplify_rec(points, 5) + +func simplify_rec(pointArray: PackedVector2Array, epsilon: float): + var dmax = 0 + var index = -1 + if pointArray.size() < 3: + return pointArray + var end = pointArray.size() - 1 + for i in range(1, end-1): + var d = find_perpendicular_distance(pointArray[i], pointArray[0], pointArray[end]) + if d > dmax: + index = i + dmax = d + + if dmax > epsilon: + var recResults1 = simplify_rec(pointArray.slice(0, index), epsilon) + var recResults2 = simplify_rec(pointArray.slice(index, end), epsilon) + recResults1.append_array(recResults2) + return recResults1 + else: + return [pointArray[0], pointArray[end]] + +func find_perpendicular_distance(p: Vector2, p1: Vector2, p2: Vector2): + var result + var slope + var intercept + if p1.x == p2.x: + result = p.x - p1.x + else: + slope = (p2.y - p1.y) / (p2.x - p1.x) + intercept = p1.y - (slope * p1.x) + result = abs(slope * p.x - p.y + intercept) / sqrt(pow(slope, 2) + 1) + + return result diff --git a/Scripts/drawing.gd b/Scripts/drawing.gd index 61896f9..c45196b 100644 --- a/Scripts/drawing.gd +++ b/Scripts/drawing.gd @@ -2,7 +2,7 @@ extends Node var drawing = false -@onready var line: Line2D = $TrackLine +@onready var line = $Road @onready var path: Path2D = $TrackPath func _ready(): @@ -16,6 +16,7 @@ func start_drawing(): func _end_drawing(): drawing = false + line.simplify() owner.set_driving(true) -- cgit From b384856adeed758ce3fe395f6b973639f21fc4d8 Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Sun, 9 Jul 2023 16:21:38 +0100 Subject: add borders --- Nodes/Level_test.tscn | 16 +++++++++++++--- Scripts/Road.gd | 40 +++++++++++++++++++++++++++++++++++++--- Scripts/drawing.gd | 4 +++- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Nodes/Level_test.tscn b/Nodes/Level_test.tscn index 0703906..dd45a9f 100644 --- a/Nodes/Level_test.tscn +++ b/Nodes/Level_test.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=12 format=3 uid="uid://dliou1u4o6bib"] +[gd_scene load_steps=13 format=3 uid="uid://dliou1u4o6bib"] [ext_resource type="Script" path="res://Scripts/scene_control.gd" id="1_0esj3"] [ext_resource type="Texture2D" uid="uid://5xqahgawme4m" path="res://Assets/start.png" id="1_wenkl"] @@ -7,6 +7,7 @@ [ext_resource type="PackedScene" uid="uid://c1mvbh2fwqtkb" path="res://Nodes/car.tscn" id="4_xvobs"] [ext_resource type="Script" path="res://Scripts/drawing.gd" id="5_x7h3g"] [ext_resource type="PackedScene" path="res://Nodes/checkpoint.tscn" id="7_52mhf"] +[ext_resource type="Texture2D" uid="uid://bcn7tgs6a4fm7" path="res://Assets/road.png" id="7_mmi61"] [ext_resource type="Script" path="res://Scripts/Road.gd" id="7_nyjk7"] [ext_resource type="PackedScene" uid="uid://c8r6i3bu37ogu" path="res://Nodes/ui.tscn" id="8_8u1ba"] @@ -44,11 +45,20 @@ acceleration = 0.05 script = ExtResource("5_x7h3g") [node name="Road" type="Line2D" parent="DrawNode"] +texture_repeat = 2 width = 100.0 -default_color = Color(0.133333, 0.133333, 0.133333, 1) -joint_mode = 2 +texture = ExtResource("7_mmi61") +texture_mode = 1 +joint_mode = 1 +round_precision = 16 script = ExtResource("7_nyjk7") +[node name="LeftBorder" type="Line2D" parent="DrawNode/Road"] +width = 2.0 + +[node name="RightBorder" type="Line2D" parent="DrawNode/Road"] +width = 2.0 + [node name="TrackPath" type="Path2D" parent="DrawNode"] curve = SubResource("Curve2D_0exre") diff --git a/Scripts/Road.gd b/Scripts/Road.gd index e0b69a1..4b19c70 100644 --- a/Scripts/Road.gd +++ b/Scripts/Road.gd @@ -1,18 +1,20 @@ extends Line2D -var epsilon = 20 +var epsilon = 2 + +@onready var leftBorder = $LeftBorder +@onready var rightBorder = $RightBorder # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. - # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): pass func simplify(): - points = simplify_rec(points, 5) + points = simplify_rec(points, epsilon) func simplify_rec(pointArray: PackedVector2Array, epsilon: float): var dmax = 0 @@ -46,3 +48,35 @@ func find_perpendicular_distance(p: Vector2, p1: Vector2, p2: Vector2): result = abs(slope * p.x - p.y + intercept) / sqrt(pow(slope, 2) + 1) return result + +func get_bisector(left_side: bool, p2: Vector2, p1: Vector2 = p2, p3: Vector2 = p2): + var v1 = (p2 - p1).normalized() + var v2 = (p2 - p3).normalized() + var normal + if v1 == -v2: + normal = v2.rotated(-PI/2) + else: + normal = (v1 + v2).normalized() + if v2.rotated(-PI/2).dot(v1) < 0: + normal = -normal + + if left_side: + normal = -normal + return normal + + +func draw_borders(): + for pointIndex in range(0, points.size() - 1): + var normal + if pointIndex == 0: + continue + elif pointIndex == points.size() -1: + continue + #normal = Vector2.ZERO + else: + normal = get_bisector(true, points[pointIndex], points[pointIndex-1], points[pointIndex+1]) + + var point = points[pointIndex] + (normal*50) + leftBorder.add_point(point) + point = points[pointIndex] - (normal*50) + rightBorder.add_point(point) diff --git a/Scripts/drawing.gd b/Scripts/drawing.gd index c45196b..a8068a2 100644 --- a/Scripts/drawing.gd +++ b/Scripts/drawing.gd @@ -17,13 +17,15 @@ func start_drawing(): func _end_drawing(): drawing = false line.simplify() + line.draw_borders() + for point in line.points: + path.curve.add_point(point) owner.set_driving(true) func _input(event): if drawing and event is InputEventMouseMotion: line.add_point(event.position) - path.curve.add_point(event.position) func reset(): -- cgit