game/terrain/terrain_instance_3d.gd

88 lines
2.1 KiB
GDScript3
Raw Normal View History

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)