diff options
Diffstat (limited to 'game/addons/zylann.hterrain/tools/minimap/minimap.gd')
-rw-r--r-- | game/addons/zylann.hterrain/tools/minimap/minimap.gd | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/game/addons/zylann.hterrain/tools/minimap/minimap.gd b/game/addons/zylann.hterrain/tools/minimap/minimap.gd new file mode 100644 index 0000000..f71295a --- /dev/null +++ b/game/addons/zylann.hterrain/tools/minimap/minimap.gd @@ -0,0 +1,140 @@ +@tool +extends Control + +const HT_Util = preload("../../util/util.gd") +const HTerrain = preload("../../hterrain.gd") +const HTerrainData = preload("../../hterrain_data.gd") +const HT_MinimapOverlay = preload("./minimap_overlay.gd") + +const HT_MinimapShader = preload("./minimap_normal.gdshader") +# TODO Can't preload because it causes the plugin to fail loading if assets aren't imported +#const HT_WhiteTexture = preload("../icons/white.png") +const WHITE_TEXTURE_PATH = "res://addons/zylann.hterrain/tools/icons/white.png" + +const MODE_QUADTREE = 0 +const MODE_NORMAL = 1 + +@onready var _popup_menu : PopupMenu = $PopupMenu +@onready var _color_rect : ColorRect = $ColorRect +@onready var _overlay : HT_MinimapOverlay = $Overlay + +var _terrain : HTerrain = null +var _mode := MODE_NORMAL +var _camera_transform := Transform3D() + + +func _ready(): + if HT_Util.is_in_edited_scene(self): + return + + _set_mode(_mode) + + _popup_menu.add_item("Quadtree mode", MODE_QUADTREE) + _popup_menu.add_item("Normal mode", MODE_NORMAL) + + +func set_terrain(node: HTerrain): + if _terrain != node: + _terrain = node + set_process(_terrain != null) + + +func set_camera_transform(ct: Transform3D): + if _camera_transform == ct: + return + if _terrain == null: + return + var data = _terrain.get_data() + if data == null: + return + var to_local := _terrain.get_internal_transform().affine_inverse() + var pos := _get_xz(to_local * _camera_transform.origin) + var size := Vector2(data.get_resolution(), data.get_resolution()) + pos /= size + var dir := _get_xz(to_local.basis * (-_camera_transform.basis.z)).normalized() + _overlay.set_cursor_position_normalized(pos, dir) + _camera_transform = ct + + +static func _get_xz(v: Vector3) -> Vector2: + return Vector2(v.x, v.z) + + +func _gui_input(event: InputEvent): + if event is InputEventMouseButton: + if event.pressed: + match event.button_index: + MOUSE_BUTTON_RIGHT: + _popup_menu.position = get_screen_position() + event.position + _popup_menu.popup() + MOUSE_BUTTON_LEFT: + # Teleport there? + pass + + +func _process(delta): + if _terrain != null: + if _mode == MODE_QUADTREE: + queue_redraw() + else: + _update_normal_material() + + +func _set_mode(mode: int): + if mode == MODE_QUADTREE: + _color_rect.hide() + else: + var mat := ShaderMaterial.new() + mat.shader = HT_MinimapShader + _color_rect.material = mat + _color_rect.show() + _update_normal_material() + _mode = mode + queue_redraw() + + +func _update_normal_material(): + if _terrain == null: + return + var data : HTerrainData = _terrain.get_data() + if data == null: + return + + var normalmap = data.get_texture(HTerrainData.CHANNEL_NORMAL) + _set_if_changed(_color_rect.material, "u_normalmap", normalmap) + + var globalmap : Texture + if data.has_texture(HTerrainData.CHANNEL_GLOBAL_ALBEDO, 0): + globalmap = data.get_texture(HTerrainData.CHANNEL_GLOBAL_ALBEDO) + if globalmap == null: + globalmap = load(WHITE_TEXTURE_PATH) + _set_if_changed(_color_rect.material, "u_globalmap", globalmap) + + +# Need to check if it has changed, otherwise Godot's update spinner +# indicates that the editor keeps redrawing every frame, +# which is not intended and consumes more power. +static func _set_if_changed(sm: ShaderMaterial, param: String, v): + if sm.get_shader_parameter(param) != v: + sm.set_shader_parameter(param, v) + + +func _draw(): + if _terrain == null: + return + + if _mode == MODE_QUADTREE: + var lod_count := _terrain.get_lod_count() + + if lod_count > 0: + # Fit drawing to rect + + var qsize = 1 << (lod_count - 1) + var vsize := size + draw_set_transform(Vector2(0, 0), 0, Vector2(vsize.x / qsize, vsize.y / qsize)) + + _terrain._edit_debug_draw(self) + + +func _on_PopupMenu_id_pressed(id: int): + _set_mode(id) |