From 31b585f1d7cf2a2c89e9661a146a037219934f7c Mon Sep 17 00:00:00 2001 From: Alain STARK Date: Fri, 19 Aug 2022 22:44:48 +0200 Subject: [PATCH 1/2] Voronoi class VoronoiCenter, VoronoiCorner and VoronoiEdge --- utils/terrain/Terrain.gd | 140 +++++++++++++++++++++++++++++++++++++++ world/game.gd | 26 +++++++- 2 files changed, 165 insertions(+), 1 deletion(-) diff --git a/utils/terrain/Terrain.gd b/utils/terrain/Terrain.gd index ba4c050..522c524 100644 --- a/utils/terrain/Terrain.gd +++ b/utils/terrain/Terrain.gd @@ -3,6 +3,140 @@ extends Reference # Build terrain from delaunay graph class_name Terrain +# Voronoi Center iterator +class VoronoiCenters: + var _terrain + var _curr + var _end + + func _init(terrain): + self._terrain = terrain + self._curr = 0 + self._end = _terrain._points.size() + + func _should_continue(): + return (_curr < _end) + + func _iter_init(_arg): + _curr = 0 + return _should_continue() + + func _iter_next(_arg): + _curr += 1 + return _should_continue() + + func _iter_get(_arg): + var point = Point.new(_curr,_terrain) + return point + + func size(): + return _end + +# Voronoi Center object +class VoronoiCenter: + var _idx + var _terrain + + func _init(idx, terrain): + self._idx = idx + self._terrain = terrain + + func to_point(): + return Point.new(_idx, _terrain) + + func get_index(): + return _idx + + func has_key(key): + return _terrain._points_data[_idx].has(key) + + func set_data(key,value): + var data = _terrain._points_data[_idx] + data[key] = value + + func get_data(key): + var data = _terrain._points_data[_idx] + if data.has(key): + return data[key] + + func point3d(): + return _terrain._points[_idx] + + func point2d(): + var point3d:Vector3 = _terrain._points[_idx] + var point2d:Vector2 = Vector2(point3d.x, point3d.z) + return(point2d) + + func set_elevation(elevation:float): + _terrain._points[_idx].y = elevation + + func get_elevation(): + return(_terrain._points[_idx].y) + + func neighbors(): + var list_centers = [] + + for point in to_point().points_around(): + list_centers.append(point.to_center()) + return list_centers + + func borders(): + var list_edges = [] + for edge in to_point().edges_around(): + var center_start = edge.start().to_center() + var center_end = edge.end().to_center() + var corner_start = VoronoiCorner.new(edge.triangle()) + var corner_end = VoronoiCorner.new(edge.opposite().triangle()) + list_edges.append(VoronoiEdge.new(corner_start,corner_end,center_start,center_end)) + return list_edges + + + func corners(): + var list_corners = [] + + for triangle in to_point().triangles_around(): + var corner = VoronoiCorner.new(triangle) + list_corners.append(corner) + return list_corners + +# Voronoi Corner object +class VoronoiCorner: + var _triangle + + func _init(triangle): + self._triangle = triangle + + func point3d(): + return _triangle.center3d() + + func point2d(): + return _triangle.center2d() + +# Voronoi Edge object +class VoronoiEdge: + var _start_corner + var _end_corner + var _start_center + var _end_center + + func _init(start_corner, end_corner, start_center, end_center): + self._start_corner = end_corner + self._end_corner = start_corner + self._start_center = end_center + self._end_center = start_center + + func start_corner(): + return _start_corner + + func end_corner(): + return _end_corner + + func start_center(): + return _start_center + + func end_center(): + return _end_center + # Triangles iterator class Triangles: var _terrain @@ -124,6 +258,9 @@ class Point: func _init(idx, terrain): self._idx = idx self._terrain = terrain + + func to_center(): + return VoronoiCenter.new(_idx, _terrain) func get_index(): return _idx @@ -391,6 +528,9 @@ func get_points(): func get_point(idx): return Point.new(idx, self) +func get_center(idx): + return VoronoiCenter.new(idx, self) + func get_edge(idx): return Edge.new(idx, self) diff --git a/world/game.gd b/world/game.gd index 824a37a..6ed5629 100644 --- a/world/game.gd +++ b/world/game.gd @@ -24,7 +24,7 @@ func _ready(): noise.octaves = octaves # terrain = Terrain.new(width,height,spacing,false) - var terrain_name="bonjour" + var terrain_name="bonjour01" terrain = Terrain.new() print(terrain.list()) @@ -35,6 +35,30 @@ func _ready(): terrain.create(width,height,spacing,terrain_name) if terrain.is_created() or terrain.is_loaded(): + + var center = terrain.get_center(43) + for edge in center.borders(): + Global.print_debug("Corner start :") + Global.print_debug(edge.start_corner().point2d()) + Global.print_debug("Corner end :") + Global.print_debug(edge.end_corner().point2d()) + Global.print_debug("Center start :") + Global.print_debug(edge.start_center().point2d()) + Global.print_debug("Center end :") + Global.print_debug(edge.end_center().point2d()) + + """ + Global.print_debug("Corners of center :") + for corner in center.corners(): + Global.print_debug(corner.point2d()) + + Global.print_debug("Find neighbors") + for neighbor in center.neighbors(): + Global.print_debug("Corners of neighbor :") + for corner in neighbor.corners(): + Global.print_debug(corner.point2d()) + """ + init_data() add_trees() emit_signal("world_loaded", terrain) -- 2.36.2 From 797f4efcd1664f1dc990ff7868a49e49f512979a Mon Sep 17 00:00:00 2001 From: Alain STARK Date: Mon, 22 Aug 2022 22:19:01 +0200 Subject: [PATCH 2/2] Debug Terrain.gd --- utils/terrain/Terrain.gd | 59 ++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/utils/terrain/Terrain.gd b/utils/terrain/Terrain.gd index 522c524..a2a7f76 100644 --- a/utils/terrain/Terrain.gd +++ b/utils/terrain/Terrain.gd @@ -26,8 +26,8 @@ class VoronoiCenters: return _should_continue() func _iter_get(_arg): - var point = Point.new(_curr,_terrain) - return point + var center = VoronoiCenter.new(_curr,_terrain) + return center func size(): return _end @@ -98,6 +98,12 @@ class VoronoiCenter: var corner = VoronoiCorner.new(triangle) list_corners.append(corner) return list_corners + + func polygon(): + var polygon = [] + for corner in corners(): + polygon.append(corner.point2d()) + return polygon # Voronoi Corner object class VoronoiCorner: @@ -111,6 +117,28 @@ class VoronoiCorner: func point2d(): return _triangle.center2d() + + func touches(): + var list_centers = [] + for point in _triangle.points(): + list_centers.append(point.to_center()) + return list_centers + + func protudes(): + var list_edges = [] + for edge in _triangle.edges(): + var center_start = edge.start().to_center() + var center_end = edge.end().to_center() + var corner_start = VoronoiCorner.new(edge.triangle()) + var corner_end = VoronoiCorner.new(edge.opposite().triangle()) + list_edges.append(VoronoiEdge.new(corner_start,corner_end,center_start,center_end)) + return list_edges + + func adjacents(): + var list_corners = [] + for triangle in _triangle.adjacents(): + list_corners.append(VoronoiCorner.new(triangle)) + return list_corners # Voronoi Edge object class VoronoiEdge: @@ -136,6 +164,12 @@ class VoronoiEdge: func end_center(): return _end_center + + func line(): + var line = [] + line.append(start_corner().point2d()) + line.append(end_corner().point2d()) + return line # Triangles iterator class Triangles: @@ -199,7 +233,7 @@ class Triangle: list_points.append(Point.new(_terrain._triangles[edge._idx], _terrain)) return list_points - func triangles_adjacent(): + func adjacents(): var list_triangles = [] for edge in edges(): var opposite = Edge.new(_terrain._halfedges[edge._idx], _terrain) @@ -293,13 +327,14 @@ class Point: func edges_around(): var list_edges = [] - var incoming_edge = Edge.new(_idx, _terrain) + var incoming = _terrain._points_to_halfedges.get(_idx) + var incoming_edge = Edge.new(incoming, _terrain) var outgoing_edge while true: list_edges.append(incoming_edge); outgoing_edge = incoming_edge.next_half() incoming_edge = Edge.new(_terrain._halfedges[outgoing_edge._idx], _terrain); - if not (incoming_edge._idx != -1 and incoming_edge._idx != _idx): + if not (incoming_edge._idx != -1 and incoming_edge._idx != incoming): break return list_edges @@ -320,6 +355,7 @@ class Point: var list_triangles = [] for edge in edges_around(): list_triangles.append(edge.triangle()) +# list_triangles.append(edge.opposite().triangle()) return list_triangles # Edges iterator @@ -356,7 +392,7 @@ class Edge: var _idx var _terrain - func _init(idx, terrain): + func _init(idx:int, terrain): self._idx = idx self._terrain = terrain @@ -527,6 +563,10 @@ func get_points(): func get_point(idx): return Point.new(idx, self) + +func get_centers(): + var centers = VoronoiCenters.new(self) + return centers func get_center(idx): return VoronoiCenter.new(idx, self) @@ -698,10 +738,7 @@ func get_voronoi_edges_as_line(): func get_voronoi_cells_as_polygon(): var list_polygon = [] - for point in get_points(): - var polygon = [] - for edge in point.edges_around(): - polygon.append(edge.triangle().center2d()) - list_polygon.append(polygon) + for center in get_centers(): + list_polygon.append(center.polygon()) return(list_polygon) -- 2.36.2