Make some test with terrain generator
This commit is contained in:
110
proc-terrain/terrain_control_layers.gd
Normal file
110
proc-terrain/terrain_control_layers.gd
Normal file
@@ -0,0 +1,110 @@
|
||||
@tool
|
||||
class_name TerrainControlLayers
|
||||
extends Resource
|
||||
|
||||
## Resource containing artist-controlled terrain layers for procedural generation.
|
||||
## Includes biome maps, height profiles, masks, and slope limits.
|
||||
|
||||
signal layers_changed
|
||||
|
||||
@export var resolution: Vector2i = Vector2i(512, 512):
|
||||
set(value):
|
||||
resolution = value
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
@export_group("Biome Control")
|
||||
@export var biome_map: Texture2D:
|
||||
set(value):
|
||||
biome_map = value
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
@export var height_profile: Curve:
|
||||
set(value):
|
||||
if height_profile and height_profile.changed.is_connected(_on_curve_changed):
|
||||
height_profile.changed.disconnect(_on_curve_changed)
|
||||
height_profile = value
|
||||
if height_profile:
|
||||
height_profile.changed.connect(_on_curve_changed)
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
@export_group("Slope Control")
|
||||
@export var slope_limit_map: Texture2D:
|
||||
set(value):
|
||||
slope_limit_map = value
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
@export_range(0.0, 90.0) var default_slope_limit: float = 45.0:
|
||||
set(value):
|
||||
default_slope_limit = value
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
@export_group("Mask Layers")
|
||||
@export var mask_layers: Array[Texture2D] = []:
|
||||
set(value):
|
||||
mask_layers = value
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
@export var mask_names: Array[String] = []:
|
||||
set(value):
|
||||
mask_names = value
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
|
||||
func _on_curve_changed() -> void:
|
||||
emit_changed()
|
||||
layers_changed.emit()
|
||||
|
||||
|
||||
func get_biome_value(uv: Vector2) -> Color:
|
||||
if not biome_map:
|
||||
return Color.WHITE
|
||||
var img := biome_map.get_image()
|
||||
if not img:
|
||||
return Color.WHITE
|
||||
var px := clampi(int(uv.x * img.get_width()), 0, img.get_width() - 1)
|
||||
var py := clampi(int(uv.y * img.get_height()), 0, img.get_height() - 1)
|
||||
return img.get_pixel(px, py)
|
||||
|
||||
|
||||
func get_slope_limit(uv: Vector2) -> float:
|
||||
if not slope_limit_map:
|
||||
return default_slope_limit
|
||||
var img := slope_limit_map.get_image()
|
||||
if not img:
|
||||
return default_slope_limit
|
||||
var px := clampi(int(uv.x * img.get_width()), 0, img.get_width() - 1)
|
||||
var py := clampi(int(uv.y * img.get_height()), 0, img.get_height() - 1)
|
||||
return img.get_pixel(px, py).r * 90.0
|
||||
|
||||
|
||||
func get_height_profile_value(normalized_height: float) -> float:
|
||||
if not height_profile:
|
||||
return normalized_height
|
||||
return height_profile.sample(clampf(normalized_height, 0.0, 1.0))
|
||||
|
||||
|
||||
func get_mask_value(mask_index: int, uv: Vector2) -> float:
|
||||
if mask_index < 0 or mask_index >= mask_layers.size():
|
||||
return 0.0
|
||||
var tex := mask_layers[mask_index]
|
||||
if not tex:
|
||||
return 0.0
|
||||
var img := tex.get_image()
|
||||
if not img:
|
||||
return 0.0
|
||||
var px := clampi(int(uv.x * img.get_width()), 0, img.get_width() - 1)
|
||||
var py := clampi(int(uv.y * img.get_height()), 0, img.get_height() - 1)
|
||||
return img.get_pixel(px, py).r
|
||||
|
||||
|
||||
func get_mask_name(mask_index: int) -> String:
|
||||
if mask_index < 0 or mask_index >= mask_names.size():
|
||||
return "mask_%d" % mask_index
|
||||
return mask_names[mask_index]
|
||||
Reference in New Issue
Block a user