aboutsummaryrefslogtreecommitdiff
path: root/game/addons/zylann.hterrain/tools/minimap/minimap.gd
diff options
context:
space:
mode:
Diffstat (limited to 'game/addons/zylann.hterrain/tools/minimap/minimap.gd')
-rw-r--r--game/addons/zylann.hterrain/tools/minimap/minimap.gd140
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)