Рефактор.
This commit is contained in:
@@ -142,16 +142,12 @@ func _on_resize() -> void:
|
||||
|
||||
|
||||
## Создаёт новую отметку из координат экрана
|
||||
func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node) -> bool:
|
||||
func add_mark_from_screen_pos(id: int, scr_xy: Vector2, mark: Node) -> bool:
|
||||
if _marks.has(id):
|
||||
return false
|
||||
var wrld_pos = screen_to_world(_xyz, x, y)
|
||||
var p = world_to_tile(wrld_pos.x, wrld_pos.y, _xyz.z)
|
||||
var tile_index = xyz_to_idx(p.x, p.y, _xyz.z)
|
||||
var dot = { 'position': wrld_pos, 'tile_index': tile_index, 'mark': mark }
|
||||
_marks[id] = dot
|
||||
var wrld_pos = screen_to_world(_xyz, scr_xy)
|
||||
_marks[id] = { 'position': wrld_pos, 'mark': mark, 'gap_size': 0.0 }
|
||||
add_child(mark)
|
||||
fix_mark_position(dot)
|
||||
return true
|
||||
|
||||
|
||||
@@ -169,9 +165,7 @@ func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size
|
||||
if _marks.has(id):
|
||||
return false
|
||||
var wrld_pos = lonlat_to_world(lon, lat)
|
||||
var scr_pos = world_to_screen(wrld_pos.x, wrld_pos.y)
|
||||
mark.set_global_position(scr_pos)
|
||||
_marks[id] = {'position': wrld_pos, 'mark': mark, 'gap_size': gap_size }
|
||||
_marks[id] = {'position': wrld_pos, 'mark': mark, 'gap_size': gap_size}
|
||||
add_child(mark)
|
||||
queue_redraw()
|
||||
return true
|
||||
@@ -189,7 +183,7 @@ func fix_mark_position(dot) -> void:
|
||||
|
||||
|
||||
func is_mark_visible(dot) -> bool:
|
||||
var screen_pos = world_to_screen(dot.position.x, dot.position.y)
|
||||
var screen_pos = world_to_screen(dot.position)
|
||||
return screen_pos.x > 0 and screen_pos.x < $canvas.size.x
|
||||
|
||||
|
||||
@@ -208,11 +202,11 @@ func _input(e) -> void:
|
||||
queue_redraw()
|
||||
if e.button_index == MOUSE_BUTTON_LEFT:
|
||||
_dragging = e.pressed
|
||||
_drag_pos = screen_to_world(_xyz, lmp.x, lmp.y)
|
||||
_drag_pos = screen_to_world(_xyz, lmp)
|
||||
|
||||
elif e is InputEventMouseMotion:
|
||||
if _dragging:
|
||||
var wp = screen_to_world(_xyz, lmp.x, lmp.y)
|
||||
var wp = screen_to_world(_xyz, lmp)
|
||||
var diff = _drag_pos - wp
|
||||
_xyz.x += diff.x
|
||||
|
||||
@@ -231,40 +225,34 @@ func _input(e) -> void:
|
||||
signaller.emmit(signaller.map_user_panning)
|
||||
|
||||
|
||||
## Возвращает true, если видна область за краем карты
|
||||
func is_border_visible():
|
||||
var z = min(max_zoom_level, _xyz.z)
|
||||
return screen_to_tile(0, 0, z).y != 0
|
||||
|
||||
|
||||
func multiply_zoom(multiplier: float, pivot: Vector2) -> void:
|
||||
var p1: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
var p1: = screen_to_world(_xyz, pivot)
|
||||
_xyz.z = clampf(_xyz.z * multiplier, min_zoom_level, max_zoom_level)
|
||||
var p2: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
var p2: = screen_to_world(_xyz, pivot)
|
||||
_xyz.x -= p2.x - p1.x
|
||||
_xyz.y -= p2.y - p1.y
|
||||
|
||||
|
||||
func increment_zoom(increment: float, pivot: Vector2) -> void:
|
||||
var p1: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
var p1: = screen_to_world(_xyz, pivot)
|
||||
_xyz.z = clampf(_xyz.z + increment, min_zoom_level, max_zoom_level)
|
||||
var p2: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
var p2: = screen_to_world(_xyz, pivot)
|
||||
_xyz.x -= p2.x - p1.x
|
||||
_xyz.y -= p2.y - p1.y
|
||||
|
||||
|
||||
func set_zoom(zoom: float, pivot: Vector2) -> void:
|
||||
var p1: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
var p1: = screen_to_world(_xyz, pivot)
|
||||
_xyz.z = clampf(zoom, max_zoom_level, min_zoom_level)
|
||||
var p2: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
var p2: = screen_to_world(_xyz, pivot)
|
||||
_xyz.x -= p2.x - p1.x
|
||||
_xyz.y -= p2.y - p1.y
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var z = min(max_zoom_level, _xyz.z)
|
||||
var t1 = screen_to_tile(0, 0, z)
|
||||
var t2 = screen_to_tile($canvas.size.x, $canvas.size.y, z) + Vector2(1, 1)
|
||||
var t1 = screen_to_tile(Vector2(0, 0), z)
|
||||
var t2 = screen_to_tile($canvas.size, z) + Vector2(1, 1)
|
||||
is_out_border1 = true
|
||||
is_out_border2 = true
|
||||
for tx in range(t1.x, t2.x):
|
||||
@@ -272,29 +260,21 @@ func _draw() -> void:
|
||||
_draw_tile(tx, ty, z)
|
||||
var n = pow(2, z)
|
||||
var dx = n * tile_width
|
||||
var c = $canvas.size / 2.0
|
||||
var r = min($canvas.size.x, $canvas.size.y) / 2.0
|
||||
var c: Vector2 = $canvas.size / 2.0
|
||||
var r = c.length()
|
||||
visible_marks_count = 0
|
||||
for dot in _marks.values():
|
||||
var pos = world_to_screen(dot.position.x, dot.position.y)
|
||||
if pos.x >= 0:
|
||||
pos.x = fmod(pos.x, dx)
|
||||
else:
|
||||
pos.x = -pos.x - 1
|
||||
pos.x = int(dx - 1) - fmod(pos.x, dx)
|
||||
dot.mark.position = pos
|
||||
dot.mark.visible = c.distance_to(pos) < (r - dot.gap_size)
|
||||
var scr_pos = world_to_screen(dot.position)
|
||||
scr_pos.x = posmod(scr_pos.x, dx)
|
||||
dot.mark.position = scr_pos
|
||||
dot.mark.visible = c.distance_to(scr_pos) < (r - dot.gap_size)
|
||||
visible_marks_count += int(dot.mark.visible)
|
||||
|
||||
|
||||
func _clean_all() -> void:
|
||||
_queue.clear()
|
||||
_cache.clear()
|
||||
_marks.clear()
|
||||
_req_count = 0
|
||||
for c in get_children().filter(func (item): return not item.is_in_group('gui_items')):
|
||||
remove_child(c)
|
||||
c.queue_free()
|
||||
|
||||
|
||||
# get the tile from queue with the newest timestamp
|
||||
@@ -449,7 +429,7 @@ func lonlat_to_world(lon: float, lat: float) -> Vector2:
|
||||
## convert lon/lat to screen coords
|
||||
func lonlat_to_screen(lon: float, lat: float) -> Vector2:
|
||||
var w = lonlat_to_world(lon, lat)
|
||||
return world_to_screen(w.x, w.y)
|
||||
return world_to_screen(w)
|
||||
|
||||
|
||||
## convert lon/lat to tile coords
|
||||
@@ -466,8 +446,8 @@ func world_to_lonlat(wx: float, wy: float) -> Vector2:
|
||||
|
||||
|
||||
## convert screen coords to lon/lat
|
||||
func screen_to_lonlat(sx: float, sy: float) -> Vector2:
|
||||
var w = screen_to_world(_xyz, sx, sy)
|
||||
func screen_to_lonlat(scr_xy: Vector2) -> Vector2:
|
||||
var w = screen_to_world(_xyz, scr_xy)
|
||||
return world_to_lonlat(w.x, w.y)
|
||||
|
||||
|
||||
@@ -478,12 +458,12 @@ func tile_to_lonlat(tx: float, ty: float, tz: float) -> Vector2:
|
||||
|
||||
|
||||
## convert screen coords to world coords
|
||||
func screen_to_world(xyz: Vector3, sx: float, sy: float) -> Vector2:
|
||||
func screen_to_world(xyz: Vector3, s: Vector2) -> Vector2:
|
||||
var n = pow(2.0, xyz.z)
|
||||
var span_w = n * tile_width
|
||||
var span_h = n * tile_height
|
||||
var px = sx - $canvas.size.x / 2 + span_w / 2
|
||||
var py = sy - $canvas.size.y / 2 + span_h / 2
|
||||
var px = s.x - $canvas.size.x / 2 + span_w / 2
|
||||
var py = s.y - $canvas.size.y / 2 + span_h / 2
|
||||
var xr = px / span_w
|
||||
var yr = py / span_h
|
||||
var x = (xr * 2.0 - 1.0) + xyz.x
|
||||
@@ -492,15 +472,15 @@ func screen_to_world(xyz: Vector3, sx: float, sy: float) -> Vector2:
|
||||
|
||||
|
||||
## convert screen coords to tile coords
|
||||
func screen_to_tile(sx: float, sy: float, z: float) -> Vector2:
|
||||
var world = screen_to_world(_xyz, sx, sy)
|
||||
func screen_to_tile(scr_xy: Vector2, z: float) -> Vector2:
|
||||
var world = screen_to_world(_xyz, scr_xy)
|
||||
return world_to_tile(world.x, world.y, z)
|
||||
|
||||
|
||||
## convert tile coords to screen coords
|
||||
func tile_to_screen(tx: float, ty: float, tz: float) -> Vector2:
|
||||
var w = tile_to_world(tx, ty, tz)
|
||||
return world_to_screen(w.x, w.y)
|
||||
return world_to_screen(w)
|
||||
|
||||
|
||||
## convert tile coords to world coords
|
||||
@@ -513,30 +493,24 @@ func tile_to_world(tx: float, ty: float, tz: float) -> Vector2:
|
||||
|
||||
## convert world coords to tile coords
|
||||
func world_to_tile(wx: float, wy: float, z: float) -> Vector2:
|
||||
var n: = pow(2.0, floor(z))
|
||||
var tx: = ((wx + 1.0) / 2.0) * n
|
||||
var ty: = ((-wy + 1.0) / 2.0) * n
|
||||
tx = floor(tx)
|
||||
ty = floor(ty)
|
||||
var n: float = pow(2.0, floor(z))
|
||||
var tx: float = floor(((wx + 1.0) / 2.0) * n)
|
||||
var ty: float = floor(((-wy + 1.0) / 2.0) * n)
|
||||
return Vector2(tx, ty)
|
||||
|
||||
|
||||
## convert world coords to screen coords
|
||||
func world_to_screen(wx: float, wy: float) -> Vector2:
|
||||
func world_to_screen(pos: Vector2) -> Vector2:
|
||||
var n: = pow(2.0, _xyz.z)
|
||||
var w: = n * tile_width
|
||||
var h: = n * tile_height
|
||||
var xr: = ((wx - _xyz.x) + 1.0) / 2.0
|
||||
var yr: = (-(wy - _xyz.y) + 1.0) / 2.0
|
||||
var x = w * xr - w / 2.0 + $canvas.size.x / 2.0
|
||||
var y = h * yr - h / 2.0 + $canvas.size.y / 2.0
|
||||
return Vector2(x, y)
|
||||
var wh: = Vector2(n * tile_width, n * tile_height)
|
||||
var rxy: = Vector2(((pos.x - _xyz.x) + 1.0) / 2.0, (-(pos.y - _xyz.y) + 1.0) / 2.0)
|
||||
return wh * rxy + ($canvas.size - wh) / 2.0
|
||||
|
||||
|
||||
## get the tile index from xyz tile coords
|
||||
func xyz_to_idx(x: float, y: float, z: float) -> int:
|
||||
var i: = (pow(4.0, z) - 1.0) / 3.0
|
||||
var n: = pow(2.0, z)
|
||||
var n: = pow(2.0, z)
|
||||
return int(i + (y * n + x))
|
||||
|
||||
|
||||
@@ -655,7 +629,7 @@ func find_at_screen_position(screen_pos: Vector2) -> Node:
|
||||
var closest_dot = null
|
||||
var closest_distance = INF
|
||||
for mark in _marks.values():
|
||||
var dot_screen_pos = world_to_screen(mark.position.x, mark.position.y)
|
||||
var dot_screen_pos = world_to_screen(mark.position)
|
||||
var distance = dot_screen_pos.distance_to(screen_pos)
|
||||
if distance < closest_distance:
|
||||
closest_distance = distance
|
||||
|
||||
Reference in New Issue
Block a user