2023-01-16 19:25:35 +01:00
|
|
|
class_name TerrainInstance3D extends GeometryInstance3D
|
|
|
|
|
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
## Identifier constant for a paint slot channel.
|
2023-01-16 19:25:35 +01:00
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
enum PaintSlot {
|
|
|
|
ERASE,
|
|
|
|
RED,
|
|
|
|
GREEN,
|
|
|
|
BLUE,
|
|
|
|
}
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
const _DETAIL := 2
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
var _albedo_map_textures: Array[Texture2D] = [null, null, null, null]
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
var _material := ShaderMaterial.new()
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
var _normal_map_textures: Array[Texture2D] = [null, null, null, null]
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
var _mesh := PlaneMesh.new()
|
2023-01-16 19:25:35 +01:00
|
|
|
|
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
## The height scale range that is used to determine the minimums and maximums of the terrain map.
|
2023-01-16 19:25:35 +01:00
|
|
|
##
|
|
|
|
@export
|
2023-01-18 18:15:41 +01:00
|
|
|
var height_scale := 100.0:
|
2023-01-16 19:25:35 +01:00
|
|
|
get:
|
2023-01-18 18:15:41 +01:00
|
|
|
return height_scale
|
2023-01-16 19:25:35 +01:00
|
|
|
|
|
|
|
set(value):
|
2023-01-18 18:15:41 +01:00
|
|
|
_material.set_shader_parameter("MAX_HEIGHT", value)
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
height_scale = max(value, 0.0)
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
var _size := Vector2i.ZERO
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
func _init() -> void:
|
|
|
|
_material.shader = preload("res://terrain/terrain.gdshader")
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
RenderingServer.instance_set_base(get_instance(), _mesh)
|
|
|
|
_mesh.surface_set_material(0, _material)
|
2023-01-16 19:25:35 +01:00
|
|
|
|
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
## Returns the size of the terrain mesh (as in-engine units).
|
2023-01-16 19:25:35 +01:00
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
func get_size() -> Vector2i:
|
|
|
|
return _size
|
2023-01-16 19:25:35 +01:00
|
|
|
|
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
## Attempts to resize the terrain to be equal to [code]size[/code] (in-engine units), with
|
|
|
|
## [code]Vector2i.ONE[/code] as the minimum size.
|
2023-01-16 19:25:35 +01:00
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
func resize(size: Vector2i) -> void:
|
|
|
|
var width := maxi(size.x, 1)
|
|
|
|
var height := maxi(size.y, 1)
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
if (width != _size.x) or (height != _size.y):
|
|
|
|
_mesh.subdivide_width = width * _DETAIL
|
|
|
|
_mesh.subdivide_depth = height * _DETAIL
|
|
|
|
_mesh.size = size
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
_material.set_shader_parameter("SIZE", Vector2(size))
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
_size = size
|
2023-01-16 19:25:35 +01:00
|
|
|
|
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
## Updates the paint used by the paint channel identified by [code]paint_slot[/code] to
|
|
|
|
## [code]terrain_paint[/code].
|
2023-01-16 19:25:35 +01:00
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
func update_paint(paint_slot: PaintSlot, paint: TerrainPaint) -> void:
|
|
|
|
if paint == null:
|
|
|
|
_albedo_map_textures[paint_slot] = null
|
|
|
|
_normal_map_textures[paint_slot] = null
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
else:
|
|
|
|
_albedo_map_textures[paint_slot] = paint.albedo_map
|
|
|
|
_normal_map_textures[paint_slot] = paint.normal_map
|
2023-01-16 19:25:35 +01:00
|
|
|
|
2023-01-18 18:15:41 +01:00
|
|
|
_material.set_shader_parameter("ALBEDO_MAPS", _albedo_map_textures)
|
|
|
|
_material.set_shader_parameter("NORMAL_MAPS", _normal_map_textures)
|
2023-01-16 19:25:35 +01:00
|
|
|
|
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
## Updates the terrain map to [code]terrain_map[/code].
|
2023-01-16 19:25:35 +01:00
|
|
|
##
|
2023-01-18 18:15:41 +01:00
|
|
|
func update_terrain(terrain_map: Texture2D) -> void:
|
|
|
|
_material.set_shader_parameter("TERRAIN_MAP", terrain_map)
|