first commit
This commit is contained in:
140
addons/zylann.hterrain/tools/minimap/minimap.gd
Executable file
140
addons/zylann.hterrain/tools/minimap/minimap.gd
Executable file
@@ -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)
|
||||
1
addons/zylann.hterrain/tools/minimap/minimap.gd.uid
Normal file
1
addons/zylann.hterrain/tools/minimap/minimap.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://1wyqr28qcn6e
|
||||
56
addons/zylann.hterrain/tools/minimap/minimap.tscn
Normal file
56
addons/zylann.hterrain/tools/minimap/minimap.tscn
Normal file
@@ -0,0 +1,56 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://cba6k3hrwhrke"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://1wyqr28qcn6e" path="res://addons/zylann.hterrain/tools/minimap/minimap.gd" id="1"]
|
||||
[ext_resource type="Shader" uid="uid://dtptqfyprdl7o" path="res://addons/zylann.hterrain/tools/minimap/minimap_normal.gdshader" id="2"]
|
||||
[ext_resource type="Script" uid="uid://dfodtk8qo0qqg" path="res://addons/zylann.hterrain/tools/minimap/minimap_overlay.gd" id="3"]
|
||||
[ext_resource type="Texture2D" uid="uid://c1el0dmyvaaij" path="res://addons/zylann.hterrain/tools/icons/icon_minimap_position.svg" id="4"]
|
||||
[ext_resource type="Texture2D" uid="uid://cc47smy24m368" path="res://addons/zylann.hterrain/tools/icons/icon_minimap_out_of_range_position.svg" id="5"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="1"]
|
||||
shader = ExtResource("2")
|
||||
shader_parameter/u_light_direction = Vector3(0.5, -0.7, 0.2)
|
||||
|
||||
[node name="Minimap" type="Control"]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 100.0
|
||||
offset_bottom = 100.0
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="PopupMenu" type="PopupMenu" parent="."]
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
material = SubResource("1")
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="X" type="ColorRect" parent="."]
|
||||
layout_mode = 0
|
||||
mouse_filter = 2
|
||||
color = Color(0.929412, 0.290196, 0.290196, 0.627451)
|
||||
|
||||
[node name="Z" type="ColorRect" parent="."]
|
||||
layout_mode = 0
|
||||
mouse_filter = 2
|
||||
color = Color(0.0784314, 0.501961, 1, 0.627451)
|
||||
|
||||
[node name="Y" type="ColorRect" parent="."]
|
||||
layout_mode = 0
|
||||
mouse_filter = 2
|
||||
color = Color(0.207843, 0.835294, 0.152941, 0.627451)
|
||||
|
||||
[node name="Overlay" type="Control" parent="."]
|
||||
anchors_preset = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
mouse_filter = 2
|
||||
script = ExtResource("3")
|
||||
cursor_texture = ExtResource("4")
|
||||
out_of_range_texture = ExtResource("5")
|
||||
|
||||
[node name="Cursor" type="Sprite2D" parent="Overlay"]
|
||||
|
||||
[connection signal="id_pressed" from="PopupMenu" to="." method="_on_PopupMenu_id_pressed"]
|
||||
24
addons/zylann.hterrain/tools/minimap/minimap_normal.gdshader
Executable file
24
addons/zylann.hterrain/tools/minimap/minimap_normal.gdshader
Executable file
@@ -0,0 +1,24 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D u_normalmap;
|
||||
uniform sampler2D u_globalmap;
|
||||
uniform vec3 u_light_direction = vec3(0.5, -0.7, 0.2);
|
||||
|
||||
vec3 unpack_normal(vec4 rgba) {
|
||||
return rgba.xzy * 2.0 - vec3(1.0);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec3 albedo = texture(u_globalmap, UV).rgb;
|
||||
// Undo sRGB
|
||||
// TODO I don't know what is correct tbh, this didn't work well
|
||||
//albedo *= pow(albedo, vec3(0.4545));
|
||||
//albedo *= pow(albedo, vec3(1.0 / 0.4545));
|
||||
albedo = sqrt(albedo);
|
||||
|
||||
vec3 normal = unpack_normal(texture(u_normalmap, UV));
|
||||
float g = max(-dot(u_light_direction, normal), 0.0);
|
||||
|
||||
COLOR = vec4(albedo * g, 1.0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dtptqfyprdl7o
|
||||
24
addons/zylann.hterrain/tools/minimap/minimap_overlay.gd
Executable file
24
addons/zylann.hterrain/tools/minimap/minimap_overlay.gd
Executable file
@@ -0,0 +1,24 @@
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
|
||||
@export var cursor_texture : Texture
|
||||
@export var out_of_range_texture : Texture
|
||||
|
||||
@onready var _sprite : Sprite2D = $Cursor
|
||||
|
||||
var _pos := Vector2()
|
||||
var _rot := 0.0
|
||||
|
||||
|
||||
func set_cursor_position_normalized(pos_norm: Vector2, dir: Vector2):
|
||||
if Rect2(0, 0, 1, 1).has_point(pos_norm):
|
||||
_sprite.texture = cursor_texture
|
||||
else:
|
||||
pos_norm.x = clampf(pos_norm.x, 0.0, 1.0)
|
||||
pos_norm.y = clampf(pos_norm.y, 0.0, 1.0)
|
||||
_sprite.texture = out_of_range_texture
|
||||
|
||||
_sprite.position = pos_norm * size
|
||||
_sprite.rotation = dir.angle()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dfodtk8qo0qqg
|
||||
32
addons/zylann.hterrain/tools/minimap/ratio_container.gd
Executable file
32
addons/zylann.hterrain/tools/minimap/ratio_container.gd
Executable file
@@ -0,0 +1,32 @@
|
||||
# Simple container keeping its children under the same aspect ratio
|
||||
|
||||
@tool
|
||||
extends Container
|
||||
|
||||
|
||||
@export var ratio := 1.0
|
||||
|
||||
|
||||
func _notification(what: int):
|
||||
if what == NOTIFICATION_SORT_CHILDREN:
|
||||
_sort_children2()
|
||||
|
||||
|
||||
# TODO Function with ugly name to workaround a Godot 3.1 issue
|
||||
# See https://github.com/godotengine/godot/pull/38396
|
||||
func _sort_children2():
|
||||
for i in get_child_count():
|
||||
var child = get_child(i)
|
||||
if not (child is Control):
|
||||
continue
|
||||
var w := size.x
|
||||
var h := size.x / ratio
|
||||
|
||||
if h > size.y:
|
||||
h = size.y
|
||||
w = h * ratio
|
||||
|
||||
var rect := Rect2(0, 0, w, h)
|
||||
|
||||
fit_child_in_rect(child, rect)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dohopfy4boqy2
|
||||
Reference in New Issue
Block a user