From 300f1db0d5add4cb0dbe689254ed539372700e07 Mon Sep 17 00:00:00 2001 From: kayomn Date: Fri, 27 Jan 2023 23:52:10 +0000 Subject: [PATCH] Add support for tile orientation in map editor --- local_player.scn | 2 +- map_editor.scn | 4 +- tiling/tile.gd | 6 ++ tiling/tile_grid.gd | 93 +++++++++++++++++-------- tiling/tiles/dungeon_01_tiling_tile.res | 4 +- 5 files changed, 75 insertions(+), 34 deletions(-) diff --git a/local_player.scn b/local_player.scn index b10cd97..6e357be 100644 --- a/local_player.scn +++ b/local_player.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdc150f7614a20d1a925aebcbba25105d3cf046f2f70deb2b68951fa6bc46dc8 +oid sha256:ee55ead59320730db7e2a7a301107fcf35900e9398f8f51e690849c51d59c295 size 679 diff --git a/map_editor.scn b/map_editor.scn index e6f4a04..72f8168 100644 --- a/map_editor.scn +++ b/map_editor.scn @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35daad0fb39d23f098b2849489292c5e5a5dccbffffb2a866e74d82d64085cdd -size 10675 +oid sha256:0ba76d6fec225724ee1822d1cceaf41eba72051c84aa03e4c0d149fdabc2a0e0 +size 10986 diff --git a/tiling/tile.gd b/tiling/tile.gd index 2b172a5..14ae89a 100644 --- a/tiling/tile.gd +++ b/tiling/tile.gd @@ -8,6 +8,12 @@ enum Kind { WALL, } +## +## +## +@export +var fixed_orientation := false + ## ## ## diff --git a/tiling/tile_grid.gd b/tiling/tile_grid.gd index f22a672..b591939 100644 --- a/tiling/tile_grid.gd +++ b/tiling/tile_grid.gd @@ -4,21 +4,37 @@ const _CHUNK_SIZE := 32 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. ## class Chunk: var _floor_meshes: Array[Mesh] = [] + var _floor_orientation := PackedInt32Array() + var _multimesh_instances: Array[MultiMeshInstance] = [] var _wall_meshes: Array[Mesh] = [] + var _wall_orientation := PackedInt32Array() + func _init() -> void: var buffer_size := _CHUNK_SIZE * _CHUNK_SIZE _floor_meshes.resize(buffer_size) + _floor_orientation.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. @@ -34,6 +50,7 @@ class Chunk: # Normalize mesh instance data for the chunk. var transforms_by_mesh := {} var grid_size := tile_grid.size + var half_pi := PI / 2 for i in _floor_meshes.size(): var mesh := _floor_meshes[i] @@ -42,11 +59,12 @@ class Chunk: if not(mesh in transforms_by_mesh): transforms_by_mesh[mesh] = [] - transforms_by_mesh[mesh].append(Transform3D(Basis.IDENTITY, Vector3( - (float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) - - (float(grid_size.x) * _GRID_ORIGIN.x), 0.0, - (float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) - - (float(grid_size.y) * _GRID_ORIGIN.y)))) + transforms_by_mesh[mesh].append(Transform3D( + Basis.IDENTITY.rotated(Vector3.UP, half_pi * _floor_orientation[i]), Vector3( + (float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) - + (float(grid_size.x) * _GRID_ORIGIN.x), 0.0, + (float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) - + (float(grid_size.y) * _GRID_ORIGIN.y)))) for i in _wall_meshes.size(): var mesh := _wall_meshes[i] @@ -55,11 +73,12 @@ class Chunk: if not(mesh in transforms_by_mesh): transforms_by_mesh[mesh] = [] - transforms_by_mesh[mesh].append(Transform3D(Basis.IDENTITY, Vector3( - (float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) - - (float(grid_size.x) * _GRID_ORIGIN.x), 0.0, - (float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) - - (float(grid_size.y) * _GRID_ORIGIN.y)))) + transforms_by_mesh[mesh].append(Transform3D( + Basis.IDENTITY.rotated(Vector3.UP, half_pi * _wall_orientation[i]), Vector3( + (float(coordinate.x * _CHUNK_SIZE) + (i % _CHUNK_SIZE)) - + (float(grid_size.x) * _GRID_ORIGIN.x), 0.0, + (float(coordinate.y * _CHUNK_SIZE) + (i / _CHUNK_SIZE)) - + (float(grid_size.y) * _GRID_ORIGIN.y)))) # (Re)-bake into multimesh instances for the chunk. 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 ## the chunk. ## - func set_floor_mesh(coordinates: Vector2i, mesh: Mesh) -> void: - _floor_meshes[(_CHUNK_SIZE * coordinates.y) + coordinates.x] = mesh + func set_floor_mesh(coordinates: Vector2i, orientation: Orientation, mesh: Mesh) -> void: + 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 @@ -89,8 +111,11 @@ class Chunk: ## *Note* that [method Chunk.invalidate] must be called at some point after to visually update ## the chunk. ## - func set_wall_mesh(coordinates: Vector2i, mesh: Mesh) -> void: - _wall_meshes[(_CHUNK_SIZE * coordinates.y) + coordinates.x] = mesh + func set_wall_mesh(coordinates: Vector2i, orientation: Orientation, mesh: Mesh) -> void: + 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. @@ -155,7 +180,7 @@ func _notification(what: int) -> void: ## ## 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: for y in size.y: for x in size.x: @@ -163,8 +188,8 @@ func clear_tiles(tile: Tile) -> void: var chunk := _get_chunk(coordinates / _CHUNK_SIZE) var chunk_coordinates := coordinates % _CHUNK_SIZE - chunk.set_floor_mesh(chunk_coordinates, null) - chunk.set_wall_mesh(chunk_coordinates, null) + chunk.set_floor_mesh(chunk_coordinates, orientation, null) + chunk.set_wall_mesh(chunk_coordinates, orientation, null) else: var mesh := tile.mesh @@ -176,7 +201,7 @@ func clear_tiles(tile: Tile) -> void: var coordinate := Vector2i(x, y) _get_chunk(coordinate / _CHUNK_SIZE).\ - set_floor_mesh(coordinate % _CHUNK_SIZE, mesh) + set_floor_mesh(coordinate % _CHUNK_SIZE, orientation, mesh) Tile.Kind.WALL: for y in size.y: @@ -184,7 +209,7 @@ func clear_tiles(tile: Tile) -> void: var coordinate := Vector2i(x, y) _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 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]. ## -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") 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 local_coordinates := coordinates % _CHUNK_SIZE - chunk.set_floor_mesh(local_coordinates, null) - chunk.set_wall_mesh(local_coordinates, null) + chunk.set_floor_mesh(local_coordinates, orientation, null) + chunk.set_wall_mesh(local_coordinates, orientation, null) filled_chunks.set_bitv(chunk_coordinates, true) else: var mesh := tile.mesh + if tile.fixed_orientation: + orientation = Orientation.NORTH + match tile.kind: Tile.Kind.FLOOR: 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 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) Tile.Kind.WALL: @@ -239,7 +269,9 @@ func fill_tiles(area: Rect2i, tile: Tile) -> void: var coordinate := Vector2i(x, y) 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) 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]. ## -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") var chunk_coordinates := coordinates / _CHUNK_SIZE @@ -274,18 +306,21 @@ func plot_tile(coordinates: Vector2i, tile: Tile) -> void: if tile == null: var local_coordinates := coordinates % _CHUNK_SIZE - chunk.set_floor_mesh(local_coordinates, null) - chunk.set_wall_mesh(local_coordinates, null) + chunk.set_floor_mesh(local_coordinates, orientation, null) + chunk.set_wall_mesh(local_coordinates, orientation, null) chunk.invalidate(self, chunk_coordinates) else: var mesh := tile.mesh + if tile.fixed_orientation: + orientation = Orientation.NORTH + match tile.kind: 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) 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) diff --git a/tiling/tiles/dungeon_01_tiling_tile.res b/tiling/tiles/dungeon_01_tiling_tile.res index 5615154..a83e0db 100644 --- a/tiling/tiles/dungeon_01_tiling_tile.res +++ b/tiling/tiles/dungeon_01_tiling_tile.res @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc799687c0d79256370e57b1b005fe4bcf989e17f88bbf72eb275b7d0f0dfd01 -size 456 +oid sha256:9025b3e769094aea76dc1638ace7338eeb3b72cfccdb1b1f2615798a160fdcdc +size 469