diff --git a/scenes/button-flat/nine-patch-button.gd b/scenes/button-flat/nine-patch-button.gd index 750b44c7..1e190074 100644 --- a/scenes/button-flat/nine-patch-button.gd +++ b/scenes/button-flat/nine-patch-button.gd @@ -52,7 +52,6 @@ func is_toggle_mode(): return $button.is_toggle_mode() func _on_resized() -> void: $back.scale = size - func _enter_tree() -> void: $back.scale = size save_modulate = modulate diff --git a/scenes/tilemap/tilemap.gd b/scenes/tilemap/tilemap.gd index 0273b4fb..3b8838f6 100644 --- a/scenes/tilemap/tilemap.gd +++ b/scenes/tilemap/tilemap.gd @@ -11,7 +11,7 @@ enum TASK_STATE { ## Координаты для проверок [lng, lat] -var TEST_DATA: = { +const TEST_DATA: = { 'Калиниград': [ 20.51095, 54.70649 ], 'Москва': [ 37.6156, 55.7522 ], 'Нью-Йорк': [ -74.006, 40.7143 ], @@ -29,30 +29,41 @@ var TEST_DATA: = { 'Море' : [ 19.4, 54.91 ] } -var map_image: Image ## Изображение с картой -var map_tile_state: TASK_STATE ## Текущее состояние конечного автомата плитки -var map_bcs: Vector3 ## Яркость, контраст насыщенность -var map_server_addr: String ## Адрес сервера изображений карт в проекции Меркатора -var map_tile_stack: Array ## Стек для хранения плиток карты -var map_request: HTTPRequest ## Обработчик запросов http -var map_zoom: int ## Уровень детализации карты -var map_rects: Array[Rect2i] ## Занятые плиткой области изображения карты -var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки] -var prev_tiles_dic = {} ## - - const MAP_MODES: = { 0: 'application/config/map_image_size_rto', 1: 'application/config/map_image_size_rls' } +const MAP_RELATIVE_RADIUSES: = { + 0: 0.39, + 1: 0.466 +} + + +var map_image: Image ## Изображение с картой +var map_tile_state: TASK_STATE ## Текущее состояние конечного автомата плитки +var map_bcs: Vector3 ## Яркость, контраст насыщенность +var map_server_addr: String ## Адрес сервера изображений карт в проекции Меркатора +var map_tile_format: String ## +var map_tile_stack: Array ## Стек для хранения плиток карты +var map_request: HTTPRequest ## Обработчик запросов http +var map_zoom: int ## Уровень детализации карты +var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки] +var map_mode: int ## Режим карты: 0 - приоритет РТО, 1 - приоритет РЛС +var prev_tiles_dic: Dictionary ## +var lnglat: Array ## Текущие координаты +var root_rect: Rect2i + + func _ready(): + lnglat = TEST_DATA['Таганрог'] map_tile_state = TASK_STATE.DONE map_request = HTTPRequest.new() add_child(map_request) map_request.request_completed.connect(self._map_request_completed) map_bcs = ProjectSettings.get_setting('application/config/map_bcs', Vector3(1.0, 1.0, 1.0)) map_server_addr = ProjectSettings.get_setting('application/config/map_server_addr') + map_tile_format = ProjectSettings.get_setting('application/config/map_tile_format', '%s/%d/%d/%d.png') var map_image_size = ProjectSettings.get_setting(MAP_MODES[0], Vector2i(512, 512)) var map_tile_size = ProjectSettings.get_setting('application/config/map_tile_size', 256) map_image = Image.create(map_image_size.x, map_image_size.y, true, Image.FORMAT_RGB8) @@ -65,11 +76,12 @@ func _ready(): func _on_map_mode_changed(mode: int) -> void: var map_image_size = ProjectSettings.get_setting(MAP_MODES[mode]) + material.set('shader_parameter/radius', MAP_RELATIVE_RADIUSES[mode]) map_image.fill(Color(0, 0, 0, 0)) map_image.resize(map_image_size.x, map_image_size.y) map_tile_state = TASK_STATE.DONE - var ll = TEST_DATA['Хельсинки'] - var tile: = mercator.create_tile(ll[0], ll[1], map_zoom) + map_mode = mode + var tile: = mercator.create_tile(lnglat[0], lnglat[1], map_zoom) map_tile_stack.clear() map_tile_stack.append(tile) prev_tiles_dic.clear() @@ -87,18 +99,12 @@ func _on_zoom_changed(zoom: int): if map_tile_stack.size() != 0: return map_zoom = zoom - var ll = TEST_DATA['Хельсинки'] - var tile: = mercator.create_tile(ll[0], ll[1], zoom) + var tile: = mercator.create_tile(lnglat[0], lnglat[1], zoom) map_tile_stack.clear() map_tile_stack.append(tile) prev_tiles_dic.clear() -func request_tile(tile: mercator.Tile, server_addr: String, tile_format: String = '%s/%d/%d/%d.png') -> Error: - var tile_addr: = tile_format % [server_addr, tile.z, tile.x , tile.y] - return map_request.request(tile_addr) - - func img_tile_to_map_image(image: Image, dst_pos: Vector2i): image.adjust_bcs(map_bcs.x, map_bcs.y, map_bcs.z) map_image.blit_rect(image, map_tile, dst_pos) @@ -107,15 +113,16 @@ func img_tile_to_map_image(image: Image, dst_pos: Vector2i): func _process(_delta: float): if (map_tile_state == TASK_STATE.DONE) and map_tile_stack.size(): var tile: mercator.Tile = map_tile_stack[-1] - if request_tile(tile, map_server_addr) == OK: + var tile_addr: = map_tile_format % [map_server_addr, tile.z, tile.x , tile.y] + var rc = map_request.request(tile_addr) + if rc == OK: map_tile_state = TASK_STATE.WAIT else: log.error('%s: Невозможно сформировать запрос HTTP' % self) map_tile_state = TASK_STATE.ERROR elif map_tile_state == TASK_STATE.CHECK: - var root_rect: Rect2i = map_rects[0] var root_tile: = mercator.Tile.new(root_rect.size.x, root_rect.size.y, map_zoom) - var neighbors_tiles = mercator.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 1) # = mercator.neighbors(root_tile) + var neighbors_tiles = mercator.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 2) var neighbors_tiles_dic = {} for tile in neighbors_tiles: neighbors_tiles_dic[[tile.x, tile.y]] = false @@ -149,22 +156,18 @@ func _map_request_completed(result, response_code, headers, data): if tile.is_root: # Отображение корневой плитки map_image.fill(Color(0, 0, 0, 0)) - map_rects.clear() # Очистить список занятых областей изображения карты var bounds: = mercator.bounds(tile) var lng_c = (bounds.east + bounds.west) / 2.0 var lat_c = (bounds.north + bounds.south) / 2.0 - var sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2 # Cмещение в пискселях центра плитки от заданной точки по горизонтали. - var sy: float = float(map_tile.size.y) / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2 # Cмещение в пискселях центра плитки от заданной точки по вертикали. - var dst_pos: Vector2i = Vector2i(sx, -sy) + var sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2.0 # Cмещение в пискселях центра плитки от заданной точки по горизонтали. + var sy: float = float(map_tile.size.y) / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # Cмещение в пискселях центра плитки от заданной точки по вертикали. + var dst_pos: Vector2i = Vector2i(sx, -sy) + map_tile.size * map_mode img_tile_to_map_image(img_tile, dst_pos) - map_rects.append(Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y)) + root_rect = Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y) else: # Отображение соседних плиток - var root_rect: Rect2i = map_rects[0] # Получить корневую плитку - var dx: int = tile.x - root_rect.size.x # Вычислить смещение дочерней плитки относительно корневой - var dy: int = tile.y - root_rect.size.y - var dst_pos: Vector2i = root_rect.position + Vector2i(dx, dy) * map_tile.size + var delta: = Vector2i(tile.x - root_rect.size.x, tile.y - root_rect.size.y) + var dst_pos: Vector2i = root_rect.position + delta * map_tile.size img_tile_to_map_image(img_tile, dst_pos) - map_rects.append(Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y)) mark_image_center(map_image) texture = ImageTexture.create_from_image(map_image) diff --git a/scenes/tilemap/tilemap.tscn b/scenes/tilemap/tilemap.tscn index b8d8895f..406784f3 100644 --- a/scenes/tilemap/tilemap.tscn +++ b/scenes/tilemap/tilemap.tscn @@ -6,7 +6,7 @@ [sub_resource type="ShaderMaterial" id="ShaderMaterial_pmqvj"] resource_local_to_scene = true shader = ExtResource("1_tsdui") -shader_parameter/radius = 0.4 +shader_parameter/radius = 0.39 [node name="tilemap" type="Sprite2D"] material = SubResource("ShaderMaterial_pmqvj") diff --git a/scenes/работа/работа.gd b/scenes/работа/работа.gd index 5a83c1bb..f2e9327e 100644 --- a/scenes/работа/работа.gd +++ b/scenes/работа/работа.gd @@ -45,15 +45,16 @@ enum DragFSM { } -func on_button_view_toggled(toggled: bool): - $canvas.set_view_mode(int(toggled)) - signaller.emit_signal('map_mode_changed', int(toggled)) - - ## Обработчик сигнала изменения списка целей func on_threats_resized(threats: Dictionary): $count_all_pad/count_all.text = '%02d' % threats.size() +func on_threat_selected(th, ecm_btns): on_rto_threat_sel(th.id, ecm_btns) + + +func on_button_view_toggled(toggled: bool): signaller.emit_signal('map_mode_changed', int(toggled)) + + ## func _enter_tree() -> void: var timer1 = Timer.new() @@ -74,24 +75,24 @@ func _exit_tree() -> void: func _ready(): min_zoom = ProjectSettings.get_setting('application/config/map_minimum_zoom', 5) max_zoom = ProjectSettings.get_setting('application/config/map_maximum_zoom', 19) + drag_fsm = DragFSM.OFF $btn_zoom.set_meta('zoom', min_zoom - 1) $btn_strob.button_connect('pressed', Callable(self, 'on_button_strobe_pressed')) $btn_view.button_connect('toggled', Callable(self, 'on_button_view_toggled')) - drag_fsm = DragFSM.OFF var nodes: Array = get_tree().get_nodes_in_group('группа-режим-помехи') nodes.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_pressed').bind(btn, nodes))) - threats.connect('threat_new', Callable(self, 'on_threat_new')) - threats.connect('threat_lost', Callable(self, 'on_threat_lost')) - threats.connect('threats_resized', Callable(self, 'on_threats_resized')) - threats.connect('threat_update', Callable(self, 'on_threat_update')) - signaller.connect('zoom_complete', Callable(self, '_on_zoom_complete')) - signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(nodes)) + threats.connect('threat_new', Callable(self, 'on_threat_new')) + threats.connect('threat_lost', Callable(self, 'on_threat_lost')) + threats.connect('threats_resized', Callable(self, 'on_threats_resized')) + threats.connect('threat_update', Callable(self, 'on_threat_update')) + signaller.connect('zoom_complete', Callable(self, '_on_zoom_complete')) + signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(nodes)) signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel').bind(nodes)) - signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(nodes)) + signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(nodes)) signaller.connect('interfer_selected', Callable(self, 'on_interfer_selected').bind(nodes)) - signaller.connect('interfer_new', Callable(self, 'on_interfer_new')) - signaller.connect('interfer_off_all', Callable(self, 'interfer_off_all')) - interfer.connect('interfer_update', Callable(self, 'on_interfer_new')) + signaller.connect('interfer_new', Callable(self, 'on_interfer_new')) + signaller.connect('interfer_off_all', Callable(self, 'interfer_off_all')) + interfer.connect('interfer_update', Callable(self, 'on_interfer_new')) func on_enter_tree() -> void: call_deferred('_on_btn_scale_pressed') @@ -179,10 +180,6 @@ func on_rto_threat_unsel(th_id, ecm_btns): btn.set_disabled(true) -func on_threat_selected(th, ecm_btns): - on_rto_threat_sel(th.id, ecm_btns) - - ## Обработчик нажатия кнопки "Строб". Управляет отображением строба func on_button_strobe_pressed() -> void: drag_fsm = DragFSM.IDLE if $btn_strob.is_pressed() else DragFSM.OFF diff --git a/scripts/mercator.gd b/scripts/mercator.gd index d64b4169..c876d452 100644 --- a/scripts/mercator.gd +++ b/scripts/mercator.gd @@ -1,11 +1,12 @@ extends Node -## Веб-утилиты для работы с меркаторовскими XYZ-плитками. +## Утилиты для работы с меркаторовскими XYZ-плитками. const R2D: = 180.0 / PI const RE: = 6378137.0 ## Радиус Земли экваториальный в метрах const RP: = 6356752.31424518 ## Радиус Земли полярный в метрах const CE: = 2.0 * PI * RE ## Длина окружности Земли в метрах по экватору +const CP: = 2.0 * PI * RP ## Длина окружности Земли в метрах через полюсы const EPSILON: = 1e-14 const LL_EPSILON: = 1e-11 const MAX_ZOOM: = 20 @@ -28,21 +29,21 @@ class Tile: func _to_string() -> String: return '[%d, %d, %d]' % [self.x, self.y, self.z] func _init(x0: int = 0, y0: int = 0, z0: int = 0, is_root0: bool = true): - self.x = x0 - self.y = y0 - self.z = z0 - self.is_root = is_root0 + x = x0 + y = y0 + z = z0 + is_root = is_root0 func is_valid() -> bool: - if (self.z >= 0) and (self.z < MAX_ZOOM): - var mz: int = 2 ** self.z - return (self.x >= 0) and (self.x < mz) \ - and (self.y >= 0) and (self.y < mz) + if (z >= 0) and (z < MAX_ZOOM): + var mz: int = 2 ** z + return (x >= 0) and (x < mz) \ + and (y >= 0) and (y < mz) return false func _bound_index(index: int) -> int: - var mi: int = 2 ** self.z + var mi: int = 2 ** z if index < 0: index *= -1 index %= mi @@ -52,8 +53,8 @@ class Tile: return index func fix_xy(): - self.x = _bound_index(self.x) - self.y = _bound_index(self.y) + x = _bound_index(x) + y = _bound_index(y) ## Пара долготы и широты. @@ -113,13 +114,14 @@ func radians(v: float) -> float: return (v * PI) / 180.0 func rshift(val: int, n: int) -> int: return (val % 0x100000000) >> n +# Возвращает арксинус гиперболический от значения [param val] func asinh(val: float): return log(val + sqrt(val * val + 1.0)) -# To convert lon/lat/alt (lon in degrees East, lat in degrees North, alt in -# meters) to earth centered fixed coordinates (x, y, z) -func lnglat_to_ecef(lng: float, lat: float, alt: float = 0.0): - alt += RE +# Преобразует [param lon] в градусах восточной долготы, [param lat] в градусах +# северной долготы, [param alt] высоты в метрах в фиксированные координаты (x, y, z) Земли. +func lnglat_to_ecef(lng: float, lat: float, alt: float = 0.0) -> Array: + alt += (RE + RP) / 2.0 var latrad: float = radians(lat) var lonrad: float = radians(lng) var coslat: float = cos(latrad) @@ -163,9 +165,9 @@ func num2deg(x: int, y: int, zoom: int): ## Расстояние по горизонтали в метрах, представленное одним пикселем -## [paramn lat] - Широта, градусы.[br] -## [paramn zoom] - Уровень детализации.[br] -## [paramn size] - Размер плитки в пикселях.[br] +## [param lat] - Широта, градусы.[br] +## [param zoom] - Уровень детализации.[br] +## [param size] - Размер плитки в пикселях.[br] func dist_per_pixel(lat: float, zoom: int, size: int = 256) -> float: return (CE / float(size)) * cos(radians(lat)) / float(2 ** zoom) diff --git a/shaders/antenas.tres b/shaders/antenas.tres index e5252132..600570f0 100644 --- a/shaders/antenas.tres +++ b/shaders/antenas.tres @@ -65,7 +65,7 @@ void sector(inout vec4 c, vec2 uv, vec2 center, float a, float da, float r0, flo void antenas(inout vec4 c, vec2 uv, vec2 p0, int cnt, float r0, float r1, vec4 c0, vec4 c1) { - float da = 180.0f / float(cnt); + float da = 180.0 / float(cnt); for (int i = -cnt; i <= cnt; i ++) { float v = float(i & 1); @@ -85,7 +85,7 @@ void fragment() { ivec2 isz = textureSize(TEXTURE, 0); vec2 uv = UV * vec2(float(isz.x), float(isz.y)); // координаты текущей точки в пикселях - COLOR = vec4(0, 0, 0, 0.0); //texture(TEXTURE, UV); // Цвет текущей точки + COLOR = vec4(0, 0, 0, 0); //texture(TEXTURE, UV); // Цвет текущей точки // Сетка антенн antenas(COLOR, uv, pc0, ant_band_count_0, ant_band_r0_0[mode], ant_band_r1_0[mode], color1, color0); diff --git a/shaders/bip.gdshader b/shaders/bip.gdshader index 574f4359..db41b3fe 100644 --- a/shaders/bip.gdshader +++ b/shaders/bip.gdshader @@ -1,6 +1,6 @@ shader_type canvas_item; -#include "tools.gdshaderinc" +#include "res://shaders/tools.gdshaderinc" /* Закрашенная окружность */ uniform vec4 color: source_color = vec4(1, 1, 1, 1); diff --git a/shaders/sector.gdshader b/shaders/sector.gdshader index 1b2d43d5..1fd8d166 100644 --- a/shaders/sector.gdshader +++ b/shaders/sector.gdshader @@ -1,6 +1,6 @@ shader_type canvas_item; -#include "tools.gdshaderinc" +#include "res://shaders/tools.gdshaderinc" /* Закрашенный сектор окружности ограниченный угловым сектором и радиусами */ diff --git a/shaders/tilemap.gdshader b/shaders/tilemap.gdshader index 64923d2b..6bc52bd4 100644 --- a/shaders/tilemap.gdshader +++ b/shaders/tilemap.gdshader @@ -1,6 +1,6 @@ shader_type canvas_item; -#include "tools.gdshaderinc" +#include "res://shaders/tools.gdshaderinc" /* Рисует текстуру по маске в форме окружности */ @@ -11,4 +11,3 @@ void fragment() { COLOR.a *= smooth_px(length(UV - center), radius, DS); } - diff --git a/shaders/tracked.gdshader b/shaders/tracked.gdshader index 5befd89b..be96fa05 100644 --- a/shaders/tracked.gdshader +++ b/shaders/tracked.gdshader @@ -1,4 +1,7 @@ shader_type canvas_item; + +#include "res://shaders/tools.gdshaderinc" + uniform vec4 ColorFig:source_color; uniform vec2 point_1; uniform vec2 point_2; @@ -14,10 +17,6 @@ const float DSS = 0.002525; const float radius = 0.125; uniform float speed: hint_range(0.0, 1024.0) = 0.0; -float smooth_px(float r, float R, float dss) -{ - return 1.0 - smoothstep(R - dss, R + dss, r); -} float line(vec2 p1, vec2 p2, float width, vec2 uv) {