Interior Maps #13
							
								
								
									
										
											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, | ||||
| } | ||||
| 
 | ||||
| ## | ||||
| ## | ||||
| ## | ||||
| @export | ||||
| var fixed_orientation := false | ||||
| 
 | ||||
| ## | ||||
| ## | ||||
| ## | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
							
								
								
									
										
											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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user