Add support for tile orientation in map editor
This commit is contained in:
parent
a175b22377
commit
300f1db0d5
BIN
local_player.scn (Stored with Git LFS)
BIN
local_player.scn (Stored with Git LFS)
Binary file not shown.
BIN
map_editor.scn (Stored with Git LFS)
BIN
map_editor.scn (Stored with Git LFS)
Binary file not shown.
|
@ -8,6 +8,12 @@ enum Kind {
|
||||||
WALL,
|
WALL,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
@export
|
||||||
|
var fixed_orientation := false
|
||||||
|
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
|
|
|
@ -4,21 +4,37 @@ const _CHUNK_SIZE := 32
|
||||||
|
|
||||||
const _GRID_ORIGIN := Vector2(0.5, 0.5)
|
const _GRID_ORIGIN := Vector2(0.5, 0.5)
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##
|
||||||
|
enum Orientation {
|
||||||
|
NORTH,
|
||||||
|
EAST,
|
||||||
|
SOUTH,
|
||||||
|
WEST,
|
||||||
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
## Baked block of meshes making up a segment of the grid.
|
## Baked block of meshes making up a segment of the grid.
|
||||||
##
|
##
|
||||||
class Chunk:
|
class Chunk:
|
||||||
var _floor_meshes: Array[Mesh] = []
|
var _floor_meshes: Array[Mesh] = []
|
||||||
|
|
||||||
|
var _floor_orientation := PackedInt32Array()
|
||||||
|
|
||||||
var _multimesh_instances: Array[MultiMeshInstance] = []
|
var _multimesh_instances: Array[MultiMeshInstance] = []
|
||||||
|
|
||||||
var _wall_meshes: Array[Mesh] = []
|
var _wall_meshes: Array[Mesh] = []
|
||||||
|
|
||||||
|
var _wall_orientation := PackedInt32Array()
|
||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
var buffer_size := _CHUNK_SIZE * _CHUNK_SIZE
|
var buffer_size := _CHUNK_SIZE * _CHUNK_SIZE
|
||||||
|
|
||||||
_floor_meshes.resize(buffer_size)
|
_floor_meshes.resize(buffer_size)
|
||||||
|
_floor_orientation.resize(buffer_size)
|
||||||
_wall_meshes.resize(buffer_size)
|
_wall_meshes.resize(buffer_size)
|
||||||
|
_wall_orientation.resize(buffer_size)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Invalidates the mesh block, re-baking its contents from the current mesh data set.
|
## Invalidates the mesh block, re-baking its contents from the current mesh data set.
|
||||||
|
@ -34,6 +50,7 @@ class Chunk:
|
||||||
# Normalize mesh instance data for the chunk.
|
# Normalize mesh instance data for the chunk.
|
||||||
var transforms_by_mesh := {}
|
var transforms_by_mesh := {}
|
||||||
var grid_size := tile_grid.size
|
var grid_size := tile_grid.size
|
||||||
|
var half_pi := PI / 2
|
||||||
|
|
||||||
for i in _floor_meshes.size():
|
for i in _floor_meshes.size():
|
||||||
var mesh := _floor_meshes[i]
|
var mesh := _floor_meshes[i]
|
||||||
|
@ -42,11 +59,12 @@ class Chunk:
|
||||||
if not(mesh in transforms_by_mesh):
|
if not(mesh in transforms_by_mesh):
|
||||||
transforms_by_mesh[mesh] = []
|
transforms_by_mesh[mesh] = []
|
||||||
|
|
||||||
transforms_by_mesh[mesh].append(Transform3D(Basis.IDENTITY, Vector3(
|
transforms_by_mesh[mesh].append(Transform3D(
|
||||||
(float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) -
|
Basis.IDENTITY.rotated(Vector3.UP, half_pi * _floor_orientation[i]), Vector3(
|
||||||
(float(grid_size.x) * _GRID_ORIGIN.x), 0.0,
|
(float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) -
|
||||||
(float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) -
|
(float(grid_size.x) * _GRID_ORIGIN.x), 0.0,
|
||||||
(float(grid_size.y) * _GRID_ORIGIN.y))))
|
(float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) -
|
||||||
|
(float(grid_size.y) * _GRID_ORIGIN.y))))
|
||||||
|
|
||||||
for i in _wall_meshes.size():
|
for i in _wall_meshes.size():
|
||||||
var mesh := _wall_meshes[i]
|
var mesh := _wall_meshes[i]
|
||||||
|
@ -55,11 +73,12 @@ class Chunk:
|
||||||
if not(mesh in transforms_by_mesh):
|
if not(mesh in transforms_by_mesh):
|
||||||
transforms_by_mesh[mesh] = []
|
transforms_by_mesh[mesh] = []
|
||||||
|
|
||||||
transforms_by_mesh[mesh].append(Transform3D(Basis.IDENTITY, Vector3(
|
transforms_by_mesh[mesh].append(Transform3D(
|
||||||
(float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) -
|
Basis.IDENTITY.rotated(Vector3.UP, half_pi * _wall_orientation[i]), Vector3(
|
||||||
(float(grid_size.x) * _GRID_ORIGIN.x), 0.0,
|
(float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) -
|
||||||
(float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) -
|
(float(grid_size.x) * _GRID_ORIGIN.x), 0.0,
|
||||||
(float(grid_size.y) * _GRID_ORIGIN.y))))
|
(float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) -
|
||||||
|
(float(grid_size.y) * _GRID_ORIGIN.y))))
|
||||||
|
|
||||||
# (Re)-bake into multimesh instances for the chunk.
|
# (Re)-bake into multimesh instances for the chunk.
|
||||||
var scenario_rid := tile_grid.get_world_3d().scenario
|
var scenario_rid := tile_grid.get_world_3d().scenario
|
||||||
|
@ -79,8 +98,11 @@ class Chunk:
|
||||||
## *Note* that [method Chunk.invalidate] must be called at some point after to visually update
|
## *Note* that [method Chunk.invalidate] must be called at some point after to visually update
|
||||||
## the chunk.
|
## the chunk.
|
||||||
##
|
##
|
||||||
func set_floor_mesh(coordinates: Vector2i, mesh: Mesh) -> void:
|
func set_floor_mesh(coordinates: Vector2i, orientation: Orientation, mesh: Mesh) -> void:
|
||||||
_floor_meshes[(_CHUNK_SIZE * coordinates.y) + coordinates.x] = mesh
|
var index := (_CHUNK_SIZE * coordinates.y) + coordinates.x
|
||||||
|
|
||||||
|
_floor_orientation[index] = orientation
|
||||||
|
_floor_meshes[index] = mesh
|
||||||
|
|
||||||
##
|
##
|
||||||
## Sets the wall mesh in the chunk at the location relative [code]coordinatess[/code] to
|
## Sets the wall mesh in the chunk at the location relative [code]coordinatess[/code] to
|
||||||
|
@ -89,8 +111,11 @@ class Chunk:
|
||||||
## *Note* that [method Chunk.invalidate] must be called at some point after to visually update
|
## *Note* that [method Chunk.invalidate] must be called at some point after to visually update
|
||||||
## the chunk.
|
## the chunk.
|
||||||
##
|
##
|
||||||
func set_wall_mesh(coordinates: Vector2i, mesh: Mesh) -> void:
|
func set_wall_mesh(coordinates: Vector2i, orientation: Orientation, mesh: Mesh) -> void:
|
||||||
_wall_meshes[(_CHUNK_SIZE * coordinates.y) + coordinates.x] = mesh
|
var index := (_CHUNK_SIZE * coordinates.y) + coordinates.x
|
||||||
|
|
||||||
|
_wall_orientation[index] = orientation
|
||||||
|
_wall_meshes[index] = mesh
|
||||||
|
|
||||||
##
|
##
|
||||||
## Specialized multi-mesh instance convenience for use within the tile grid and its chunks.
|
## Specialized multi-mesh instance convenience for use within the tile grid and its chunks.
|
||||||
|
@ -155,7 +180,7 @@ func _notification(what: int) -> void:
|
||||||
##
|
##
|
||||||
## For clearing a specific region of the mesh grid, see [method fill_mesh].
|
## For clearing a specific region of the mesh grid, see [method fill_mesh].
|
||||||
##
|
##
|
||||||
func clear_tiles(tile: Tile) -> void:
|
func clear_tiles(orientation: Orientation, tile: Tile) -> void:
|
||||||
if tile == null:
|
if tile == null:
|
||||||
for y in size.y:
|
for y in size.y:
|
||||||
for x in size.x:
|
for x in size.x:
|
||||||
|
@ -163,8 +188,8 @@ func clear_tiles(tile: Tile) -> void:
|
||||||
var chunk := _get_chunk(coordinates / _CHUNK_SIZE)
|
var chunk := _get_chunk(coordinates / _CHUNK_SIZE)
|
||||||
var chunk_coordinates := coordinates % _CHUNK_SIZE
|
var chunk_coordinates := coordinates % _CHUNK_SIZE
|
||||||
|
|
||||||
chunk.set_floor_mesh(chunk_coordinates, null)
|
chunk.set_floor_mesh(chunk_coordinates, orientation, null)
|
||||||
chunk.set_wall_mesh(chunk_coordinates, null)
|
chunk.set_wall_mesh(chunk_coordinates, orientation, null)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var mesh := tile.mesh
|
var mesh := tile.mesh
|
||||||
|
@ -176,7 +201,7 @@ func clear_tiles(tile: Tile) -> void:
|
||||||
var coordinate := Vector2i(x, y)
|
var coordinate := Vector2i(x, y)
|
||||||
|
|
||||||
_get_chunk(coordinate / _CHUNK_SIZE).\
|
_get_chunk(coordinate / _CHUNK_SIZE).\
|
||||||
set_floor_mesh(coordinate % _CHUNK_SIZE, mesh)
|
set_floor_mesh(coordinate % _CHUNK_SIZE, orientation, mesh)
|
||||||
|
|
||||||
Tile.Kind.WALL:
|
Tile.Kind.WALL:
|
||||||
for y in size.y:
|
for y in size.y:
|
||||||
|
@ -184,7 +209,7 @@ func clear_tiles(tile: Tile) -> void:
|
||||||
var coordinate := Vector2i(x, y)
|
var coordinate := Vector2i(x, y)
|
||||||
|
|
||||||
_get_chunk(coordinate / _CHUNK_SIZE).\
|
_get_chunk(coordinate / _CHUNK_SIZE).\
|
||||||
set_floor_mesh(coordinate % _CHUNK_SIZE, mesh)
|
set_floor_mesh(coordinate % _CHUNK_SIZE, orientation, mesh)
|
||||||
|
|
||||||
for y in _chunks_size.y:
|
for y in _chunks_size.y:
|
||||||
for x in _chunks_size.x:
|
for x in _chunks_size.x:
|
||||||
|
@ -201,7 +226,7 @@ func clear_tiles(tile: Tile) -> void:
|
||||||
##
|
##
|
||||||
## For clearing the whole of the mesh grid, see [method clear_mesh].
|
## For clearing the whole of the mesh grid, see [method clear_mesh].
|
||||||
##
|
##
|
||||||
func fill_tiles(area: Rect2i, tile: Tile) -> void:
|
func fill_tiles(area: Rect2i, orientation: Orientation, tile: Tile) -> void:
|
||||||
assert(get_area().encloses(area), "area must be within grid")
|
assert(get_area().encloses(area), "area must be within grid")
|
||||||
|
|
||||||
var filled_chunks := BitMap.new()
|
var filled_chunks := BitMap.new()
|
||||||
|
@ -216,13 +241,16 @@ func fill_tiles(area: Rect2i, tile: Tile) -> void:
|
||||||
var chunk := _get_chunk(coordinates / _CHUNK_SIZE)
|
var chunk := _get_chunk(coordinates / _CHUNK_SIZE)
|
||||||
var local_coordinates := coordinates % _CHUNK_SIZE
|
var local_coordinates := coordinates % _CHUNK_SIZE
|
||||||
|
|
||||||
chunk.set_floor_mesh(local_coordinates, null)
|
chunk.set_floor_mesh(local_coordinates, orientation, null)
|
||||||
chunk.set_wall_mesh(local_coordinates, null)
|
chunk.set_wall_mesh(local_coordinates, orientation, null)
|
||||||
filled_chunks.set_bitv(chunk_coordinates, true)
|
filled_chunks.set_bitv(chunk_coordinates, true)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var mesh := tile.mesh
|
var mesh := tile.mesh
|
||||||
|
|
||||||
|
if tile.fixed_orientation:
|
||||||
|
orientation = Orientation.NORTH
|
||||||
|
|
||||||
match tile.kind:
|
match tile.kind:
|
||||||
Tile.Kind.FLOOR:
|
Tile.Kind.FLOOR:
|
||||||
for y in range(area.position.y, area.end.y):
|
for y in range(area.position.y, area.end.y):
|
||||||
|
@ -230,7 +258,9 @@ func fill_tiles(area: Rect2i, tile: Tile) -> void:
|
||||||
var coordinate := Vector2i(x, y)
|
var coordinate := Vector2i(x, y)
|
||||||
var chunk_coordinate := coordinate / _CHUNK_SIZE
|
var chunk_coordinate := coordinate / _CHUNK_SIZE
|
||||||
|
|
||||||
_get_chunk(chunk_coordinate).set_floor_mesh(coordinate % _CHUNK_SIZE, mesh)
|
_get_chunk(chunk_coordinate).set_floor_mesh(
|
||||||
|
coordinate % _CHUNK_SIZE, orientation, mesh)
|
||||||
|
|
||||||
filled_chunks.set_bitv(chunk_coordinate, true)
|
filled_chunks.set_bitv(chunk_coordinate, true)
|
||||||
|
|
||||||
Tile.Kind.WALL:
|
Tile.Kind.WALL:
|
||||||
|
@ -239,7 +269,9 @@ func fill_tiles(area: Rect2i, tile: Tile) -> void:
|
||||||
var coordinate := Vector2i(x, y)
|
var coordinate := Vector2i(x, y)
|
||||||
var chunk_coordinate := coordinate / _CHUNK_SIZE
|
var chunk_coordinate := coordinate / _CHUNK_SIZE
|
||||||
|
|
||||||
_get_chunk(chunk_coordinate).set_wall_mesh(coordinate % _CHUNK_SIZE, mesh)
|
_get_chunk(chunk_coordinate).set_wall_mesh(
|
||||||
|
coordinate % _CHUNK_SIZE, orientation, mesh)
|
||||||
|
|
||||||
filled_chunks.set_bitv(chunk_coordinate, true)
|
filled_chunks.set_bitv(chunk_coordinate, true)
|
||||||
|
|
||||||
for y in _chunks_size.y:
|
for y in _chunks_size.y:
|
||||||
|
@ -265,7 +297,7 @@ func get_area() -> Rect2i:
|
||||||
##
|
##
|
||||||
## For bulk-setting many meshes at once, see [method fill_mesh] and [method clear_mesh].
|
## For bulk-setting many meshes at once, see [method fill_mesh] and [method clear_mesh].
|
||||||
##
|
##
|
||||||
func plot_tile(coordinates: Vector2i, tile: Tile) -> void:
|
func plot_tile(coordinates: Vector2i, orientation: Orientation, tile: Tile) -> void:
|
||||||
assert(get_area().has_point(coordinates), "coordinate must be within grid")
|
assert(get_area().has_point(coordinates), "coordinate must be within grid")
|
||||||
|
|
||||||
var chunk_coordinates := coordinates / _CHUNK_SIZE
|
var chunk_coordinates := coordinates / _CHUNK_SIZE
|
||||||
|
@ -274,18 +306,21 @@ func plot_tile(coordinates: Vector2i, tile: Tile) -> void:
|
||||||
if tile == null:
|
if tile == null:
|
||||||
var local_coordinates := coordinates % _CHUNK_SIZE
|
var local_coordinates := coordinates % _CHUNK_SIZE
|
||||||
|
|
||||||
chunk.set_floor_mesh(local_coordinates, null)
|
chunk.set_floor_mesh(local_coordinates, orientation, null)
|
||||||
chunk.set_wall_mesh(local_coordinates, null)
|
chunk.set_wall_mesh(local_coordinates, orientation, null)
|
||||||
chunk.invalidate(self, chunk_coordinates)
|
chunk.invalidate(self, chunk_coordinates)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var mesh := tile.mesh
|
var mesh := tile.mesh
|
||||||
|
|
||||||
|
if tile.fixed_orientation:
|
||||||
|
orientation = Orientation.NORTH
|
||||||
|
|
||||||
match tile.kind:
|
match tile.kind:
|
||||||
Tile.Kind.FLOOR:
|
Tile.Kind.FLOOR:
|
||||||
chunk.set_floor_mesh(coordinates % _CHUNK_SIZE, mesh)
|
chunk.set_floor_mesh(coordinates % _CHUNK_SIZE, orientation, mesh)
|
||||||
chunk.invalidate(self, chunk_coordinates)
|
chunk.invalidate(self, chunk_coordinates)
|
||||||
|
|
||||||
Tile.Kind.WALL:
|
Tile.Kind.WALL:
|
||||||
chunk.set_wall_mesh(coordinates % _CHUNK_SIZE, mesh)
|
chunk.set_wall_mesh(coordinates % _CHUNK_SIZE, orientation, mesh)
|
||||||
chunk.invalidate(self, chunk_coordinates)
|
chunk.invalidate(self, chunk_coordinates)
|
||||||
|
|
BIN
tiling/tiles/dungeon_01_tiling_tile.res (Stored with Git LFS)
BIN
tiling/tiles/dungeon_01_tiling_tile.res (Stored with Git LFS)
Binary file not shown.
Loading…
Reference in New Issue