105 lines
2.3 KiB
GDScript
105 lines
2.3 KiB
GDScript
extends Resource
|
|
class_name TerrainData
|
|
|
|
const UNIT_PER_PIXEL = 30
|
|
|
|
@export var image : Image
|
|
@export var image_size : Vector2i
|
|
|
|
func _init(terrain_size : Vector2):
|
|
image_size = terrain_size / UNIT_PER_PIXEL
|
|
image = Image.create(
|
|
image_size.x,
|
|
image_size.y,
|
|
false,
|
|
Image.Format.FORMAT_L8
|
|
)
|
|
|
|
func draw_random_zone(
|
|
zone_max_surface : float,
|
|
zone_position : Vector2i
|
|
):
|
|
var noise: Noise = FastNoiseLite.new()
|
|
noise.seed = randi()
|
|
noise.noise_type = FastNoiseLite.TYPE_CELLULAR
|
|
noise.frequency = 0.01
|
|
|
|
var noise_image_size : Vector2i = Vector2i.ONE * (image_size)
|
|
var noise_image_center = noise_image_size / 2
|
|
|
|
var noise_image = noise.get_image(
|
|
noise_image_size.x,
|
|
noise_image_size.y,
|
|
1.0,
|
|
)
|
|
|
|
ImageTools.flatten(noise_image, 0.5)
|
|
|
|
ImageTools.draw_circle(
|
|
noise_image,
|
|
noise_image_center,
|
|
80/UNIT_PER_PIXEL,
|
|
Color.WHITE,
|
|
)
|
|
|
|
var random_step = 1
|
|
var zone_radius = noise_image_size.x - random_step
|
|
while get_value_surface(noise_image) > zone_max_surface:
|
|
zone_radius -= random_step
|
|
ImageTools.draw_circle(
|
|
noise_image,
|
|
noise_image_center,
|
|
zone_radius,
|
|
Color.BLACK,
|
|
true
|
|
)
|
|
|
|
image.blit_rect(
|
|
noise_image,
|
|
Rect2i(
|
|
Vector2i.ZERO,
|
|
noise_image_size
|
|
),
|
|
Vector2i(zone_position / UNIT_PER_PIXEL) - noise_image_size/2
|
|
)
|
|
|
|
func draw_circle(position : Vector2, impact_radius : float, to_value : float = 1.):
|
|
ImageTools.draw_circle(
|
|
image,
|
|
position / UNIT_PER_PIXEL,
|
|
roundi(impact_radius / UNIT_PER_PIXEL),
|
|
Color(1., 1., 1., to_value)
|
|
)
|
|
|
|
func is_in_image(pixel_point : Vector2i):
|
|
return (
|
|
pixel_point.x > 0
|
|
and pixel_point.y > 0
|
|
and pixel_point.x < image.get_width()
|
|
and pixel_point.y < image.get_height())
|
|
|
|
func is_in_terrain(point : Vector2):
|
|
return is_in_image(get_pixel_point(point))
|
|
|
|
func get_value(point : Vector2) -> float:
|
|
var pixel_point : Vector2i = get_pixel_point(point)
|
|
if (is_in_image(pixel_point)):
|
|
return image.get_pixel(
|
|
pixel_point.x,
|
|
pixel_point.y
|
|
).r
|
|
return 0
|
|
|
|
func get_value_coverage(i : Image = image) -> float:
|
|
return ImageTools.get_color_coverage(i)
|
|
|
|
func get_value_surface(i : Image = image) -> float:
|
|
return float(ImageTools.get_color_pixel_count(i)) * UNIT_PER_PIXEL
|
|
|
|
func get_pixel_point(point : Vector2) -> Vector2i:
|
|
var vec : Vector2 = Vector2(point) / UNIT_PER_PIXEL - Vector2.ONE
|
|
return Vector2i(
|
|
roundi(vec.x + 0.5),
|
|
roundi(vec.y + 0.5)
|
|
)
|