2024-08-02 01:38:05 +00:00
|
|
|
@tool
|
2024-08-01 22:29:11 +00:00
|
|
|
extends SpaceEntity
|
|
|
|
|
2024-08-02 01:38:05 +00:00
|
|
|
## Classic 2.5D sector beauty.
|
|
|
|
##
|
2024-08-01 22:29:11 +00:00
|
|
|
|
2024-08-02 01:38:05 +00:00
|
|
|
class_name SpaceRegion
|
2024-08-01 22:29:11 +00:00
|
|
|
|
|
|
|
@export var elevation: float = 0.0
|
|
|
|
@export var height: float = 100.0
|
2024-08-02 00:11:18 +00:00
|
|
|
@export var wall_texture: Texture2D
|
|
|
|
@export var floor_texture: Texture2D
|
2024-08-02 01:47:17 +00:00
|
|
|
@export var ceiling_texture: Texture2D
|
2024-08-01 22:29:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
func generate_geometry(space: Space) -> Node3D:
|
2024-08-02 00:11:18 +00:00
|
|
|
return _generate_geometry(space, true)
|
|
|
|
|
|
|
|
|
2024-08-02 01:38:05 +00:00
|
|
|
func _process(delta):
|
|
|
|
if Engine.is_editor_hint():
|
|
|
|
self.texture = floor_texture
|
|
|
|
|
|
|
|
|
2024-08-02 00:11:18 +00:00
|
|
|
func _generate_geometry(space: Space, looked_from_inside: bool) -> Node3D:
|
2024-08-01 22:29:11 +00:00
|
|
|
var geometry := MeshInstance3D.new()
|
|
|
|
geometry.name = name
|
2024-08-02 01:38:05 +00:00
|
|
|
geometry.position = Vector3(
|
|
|
|
position.x * space.unit_scale,
|
|
|
|
0,
|
|
|
|
position.y * space.unit_scale,
|
|
|
|
)
|
2024-08-01 22:29:11 +00:00
|
|
|
|
2024-08-02 00:48:26 +00:00
|
|
|
var mesh := ArrayMesh.new()
|
|
|
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, _generate_wall_arrays(space, looked_from_inside))
|
|
|
|
|
|
|
|
var wall_material := StandardMaterial3D.new()
|
|
|
|
wall_material.albedo_texture = wall_texture
|
|
|
|
mesh.surface_set_material(0, wall_material)
|
|
|
|
|
2024-08-02 00:50:35 +00:00
|
|
|
if (looked_from_inside):
|
|
|
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, _generate_floor_arrays(space))
|
|
|
|
var floor_material := StandardMaterial3D.new()
|
|
|
|
floor_material.albedo_texture = floor_texture
|
|
|
|
mesh.surface_set_material(1, floor_material)
|
2024-08-02 00:48:26 +00:00
|
|
|
|
2024-08-02 01:47:17 +00:00
|
|
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, _generate_ceiling_arrays(space))
|
|
|
|
var ceiling_material := StandardMaterial3D.new()
|
|
|
|
ceiling_material.albedo_texture = ceiling_texture
|
|
|
|
ceiling_material.cull_mode = BaseMaterial3D.CULL_FRONT # todo: Don't require state change
|
|
|
|
mesh.surface_set_material(2, ceiling_material)
|
|
|
|
|
2024-08-02 00:48:26 +00:00
|
|
|
geometry.mesh = mesh
|
|
|
|
|
|
|
|
for child in get_children():
|
|
|
|
if child is SpaceRegion:
|
|
|
|
geometry.add_child(child._generate_geometry(space, not looked_from_inside))
|
|
|
|
|
|
|
|
return geometry
|
|
|
|
|
|
|
|
|
|
|
|
func _generate_wall_arrays(space: Space, looked_from_inside: bool) -> Array:
|
2024-08-01 22:29:11 +00:00
|
|
|
var polygon = self.polygon
|
|
|
|
var polygon_pairs = Array()
|
|
|
|
for i in range(-1, polygon.size() - 1):
|
|
|
|
polygon_pairs.append([polygon[i], polygon[i+1]])
|
|
|
|
|
|
|
|
var vertices = PackedVector3Array()
|
|
|
|
var uvs = PackedVector2Array()
|
|
|
|
for line in polygon_pairs:
|
2024-08-02 00:11:18 +00:00
|
|
|
_push_line(space, line, vertices, uvs, looked_from_inside)
|
|
|
|
|
|
|
|
var arrays := Array()
|
2024-08-01 22:29:11 +00:00
|
|
|
arrays.resize(Mesh.ARRAY_MAX)
|
|
|
|
arrays[Mesh.ARRAY_VERTEX] = vertices
|
|
|
|
arrays[Mesh.ARRAY_TEX_UV] = uvs
|
2024-08-02 00:50:35 +00:00
|
|
|
|
2024-08-02 00:48:26 +00:00
|
|
|
return arrays
|
2024-08-02 00:11:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _push_line(space: Space,
|
|
|
|
line: Array,
|
|
|
|
vertices: PackedVector3Array,
|
|
|
|
uvs: PackedVector2Array,
|
|
|
|
looked_from_inside: bool
|
|
|
|
):
|
|
|
|
var v0 := Vector3(
|
|
|
|
line[0][0] * space.unit_scale, elevation * space.unit_scale,
|
|
|
|
line[0][1] * space.unit_scale)
|
|
|
|
var v1 := Vector3(
|
|
|
|
line[1][0] * space.unit_scale, (elevation + height) * space.unit_scale,
|
|
|
|
line[1][1] * space.unit_scale)
|
|
|
|
var v2 := Vector3(
|
|
|
|
line[1][0] * space.unit_scale, elevation * space.unit_scale,
|
|
|
|
line[1][1] * space.unit_scale)
|
|
|
|
var v3 := Vector3(
|
|
|
|
line[0][0] * space.unit_scale, (elevation + height) * space.unit_scale,
|
|
|
|
line[0][1] * space.unit_scale)
|
|
|
|
|
|
|
|
if looked_from_inside:
|
|
|
|
vertices.append_array([v0, v1, v2, v1, v0, v3])
|
|
|
|
else:
|
|
|
|
vertices.append_array([v0, v2, v1, v1, v3, v0])
|
|
|
|
|
|
|
|
uvs.append(Vector2(0, 1))
|
|
|
|
uvs.append(Vector2(1, 0))
|
|
|
|
uvs.append(Vector2(1, 1))
|
|
|
|
uvs.append(Vector2(1, 0))
|
|
|
|
uvs.append(Vector2(0, 1))
|
|
|
|
uvs.append(Vector2(0, 0))
|
2024-08-02 00:48:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _generate_floor_arrays(space: Space) -> Array:
|
|
|
|
var triangulation := Geometry2D.triangulate_polygon(self.polygon)
|
|
|
|
var vertices := PackedVector3Array()
|
|
|
|
var uvs := PackedVector2Array()
|
|
|
|
vertices.resize(triangulation.size())
|
|
|
|
uvs.resize(triangulation.size())
|
|
|
|
|
|
|
|
for i in range(triangulation.size()):
|
|
|
|
vertices[i] = Vector3(
|
|
|
|
self.polygon[triangulation[i]].x * space.unit_scale,
|
|
|
|
elevation * space.unit_scale,
|
|
|
|
self.polygon[triangulation[i]].y * space.unit_scale,
|
|
|
|
)
|
|
|
|
uvs[i] = self.polygon[triangulation[i]] * space.unit_scale
|
|
|
|
|
|
|
|
var arrays := Array()
|
|
|
|
arrays.resize(Mesh.ARRAY_MAX)
|
|
|
|
arrays[Mesh.ARRAY_VERTEX] = vertices
|
|
|
|
arrays[Mesh.ARRAY_TEX_UV] = uvs
|
|
|
|
|
|
|
|
return arrays
|
2024-08-02 01:47:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
# todo: Reuse triangulation with the floor
|
|
|
|
func _generate_ceiling_arrays(space: Space) -> Array:
|
|
|
|
var triangulation := Geometry2D.triangulate_polygon(self.polygon)
|
|
|
|
var vertices := PackedVector3Array()
|
|
|
|
var uvs := PackedVector2Array()
|
|
|
|
vertices.resize(triangulation.size())
|
|
|
|
uvs.resize(triangulation.size())
|
|
|
|
|
|
|
|
for i in range(triangulation.size()):
|
|
|
|
vertices[i] = Vector3(
|
|
|
|
self.polygon[triangulation[i]].x * space.unit_scale,
|
|
|
|
(elevation + height) * space.unit_scale,
|
|
|
|
self.polygon[triangulation[i]].y * space.unit_scale,
|
|
|
|
)
|
|
|
|
uvs[i] = self.polygon[triangulation[i]] * space.unit_scale
|
|
|
|
|
|
|
|
var arrays := Array()
|
|
|
|
arrays.resize(Mesh.ARRAY_MAX)
|
|
|
|
arrays[Mesh.ARRAY_VERTEX] = vertices
|
|
|
|
arrays[Mesh.ARRAY_TEX_UV] = uvs
|
|
|
|
|
|
|
|
return arrays
|