diff options
author | nokoe <nokoe@mailbox.org> | 2025-06-21 01:52:33 +0200 |
---|---|---|
committer | nokoe <nokoe@mailbox.org> | 2025-06-21 01:52:33 +0200 |
commit | 16f72d038c37a2f5dd60a960f034ee2c3ff53f5b (patch) | |
tree | 9af64de6fe8b2b47a5e46b87adabde94ccd8b88b /client/map | |
parent | 44ca1fe3780b76c73e03070fc20189607c414860 (diff) | |
download | hurrycurry-16f72d038c37a2f5dd60a960f034ee2c3ff53f5b.tar hurrycurry-16f72d038c37a2f5dd60a960f034ee2c3ff53f5b.tar.bz2 hurrycurry-16f72d038c37a2f5dd60a960f034ee2c3ff53f5b.tar.zst |
generalize floor meshing; fixes #278
Diffstat (limited to 'client/map')
-rw-r--r-- | client/map/map.gd | 16 | ||||
-rw-r--r-- | client/map/tile_factory.gd | 13 | ||||
-rw-r--r-- | client/map/tiles/floor.gd | 17 | ||||
-rw-r--r-- | client/map/tiles/floor_like.gd | 28 | ||||
-rw-r--r-- | client/map/tiles/floor_like.gd.uid | 1 | ||||
-rw-r--r-- | client/map/tiles/floor_mesher.gd | 10 | ||||
-rw-r--r-- | client/map/tiles/grass.gd | 33 | ||||
-rw-r--r-- | client/map/tiles/grass_material.tres | 8 | ||||
-rw-r--r-- | client/map/tiles/grass_mesher.gd | 42 | ||||
-rw-r--r-- | client/map/tiles/grass_mesher.gd.uid | 1 | ||||
-rw-r--r-- | client/map/tiles/path.gd | 12 | ||||
-rw-r--r-- | client/map/tiles/path_material.tres | 7 | ||||
-rw-r--r-- | client/map/tiles/street.gd | 12 | ||||
-rw-r--r-- | client/map/tiles/street_material.tres | 7 |
14 files changed, 156 insertions, 51 deletions
diff --git a/client/map/map.gd b/client/map/map.gd index fe8ddd66..5d6719e9 100644 --- a/client/map/map.gd +++ b/client/map/map.gd @@ -21,8 +21,8 @@ extends Node3D var tile_by_pos: Dictionary = {} # Dictionary[String, [Vector2i, String, Tile, Array]] var autobake = false var currently_baked = false -var floor_mesher := FloorMesher.new() var floor_node := MeshInstance3D.new() +var tile_factory = TileFactory.new() func get_tile_name(pos: Vector2i): # -> String? var e = tile_by_pos.get(str(pos)) @@ -35,7 +35,7 @@ func get_tile_instance(pos: Vector2i) -> Tile: func set_tile(pos: Vector2i, name_: String, neighbors: Array = [null,null,null,null]) -> Tile: clear_tile(pos) - var tile := TileFactory.produce(name_, pos, neighbors, floor_mesher) + var tile := tile_factory.produce(name_, pos, neighbors) add_child(tile) tile.position = Vector3(pos.x, 0, pos.y) tile_by_pos[str(pos)] = [pos, name_, tile, neighbors] @@ -45,20 +45,26 @@ func clear_tile(pos: Vector2i): var tile = get_tile_instance(pos) if tile == null: return if tile.item != null: tile.item.queue_free() + if tile is FloorLike: + var floor_mesher = tile_factory.floor_meshers.get(tile.fm_id()) + if floor_mesher != null: + floor_mesher.remove_tile(pos) + tile.queue_free() tile_by_pos.erase(str(pos)) tile.name += "_queued_free" - tile.queue_free() - floor_mesher.remove_tile(pos) @onready var voxelgi: VoxelGI = $VoxelGI func _ready(): Settings.hook_changed("graphics.gi", false, apply_gi_setting) floor_node.material_override = preload("res://map/tiles/floor_material.tres") + for fm in tile_factory.floor_meshers.values(): + add_child(fm.mesh_instance) add_child(floor_node) func flush() -> void: - if floor_mesher != null: floor_node.mesh = floor_mesher.flush() + for fm in tile_factory.floor_meshers.values(): + fm.flush() gi_bake() func apply_gi_setting(state): diff --git a/client/map/tile_factory.gd b/client/map/tile_factory.gd index 7ba575c3..ca6c0f81 100644 --- a/client/map/tile_factory.gd +++ b/client/map/tile_factory.gd @@ -20,14 +20,21 @@ class TileCC: var tile_name: String var position: Vector2i var neighbors: Array - var floor_mesher: FloorMesher + var floor_meshers: Dictionary[String, FloorMesher] -static func produce(tile_name: String, position: Vector2i, neighbors: Array, floor_mesher) -> Tile: +var floor_meshers: Dictionary[String, FloorMesher] = { + "floor": FloorMesher.new(Floor.floor_mesh()), + "path": FloorMesher.new(Path.floor_mesh()), + "grass": GrassMesher.new(Grass.floor_mesh()), + "street": FloorMesher.new(Street.floor_mesh()) +} + +func produce(tile_name: String, position: Vector2i, neighbors: Array) -> Tile: var ctx := TileCC.new() ctx.tile_name = tile_name ctx.position = position ctx.neighbors = neighbors - ctx.floor_mesher = floor_mesher + ctx.floor_meshers = floor_meshers match tile_name: "black-hole-counter": return ItemPortal.new(ctx, false) "black-hole": return PlayerPortal.new(ctx, false) diff --git a/client/map/tiles/floor.gd b/client/map/tiles/floor.gd index dd51c928..a0b54171 100644 --- a/client/map/tiles/floor.gd +++ b/client/map/tiles/floor.gd @@ -14,15 +14,12 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. # class_name Floor -extends Tile +extends FloorLike -var opt: bool +static func fm_id() -> String: + return "floor" -func _init(ctx: TileFactory.TileCC): - opt = ctx.floor_mesher != null - super(ctx) - if not base_mesh: ctx.floor_mesher.add_tile(ctx.position) - -func get_base_mesh(): - if opt: return null - else: return preload("res://map/tiles/floor.tscn").instantiate() +static func floor_mesh() -> MeshInstance3D: + var node = super() + node.material_override = preload("res://map/tiles/floor_material.tres") + return node diff --git a/client/map/tiles/floor_like.gd b/client/map/tiles/floor_like.gd new file mode 100644 index 00000000..683f6124 --- /dev/null +++ b/client/map/tiles/floor_like.gd @@ -0,0 +1,28 @@ +# Hurry Curry! - a game about cooking +# Copyright 2025 nokoe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name FloorLike +extends Tile + +func _init(ctx: TileFactory.TileCC): + super(ctx) + if not base_mesh: ctx.floor_meshers[fm_id()].add_tile(ctx.position) + +static func fm_id() -> String: + return "" + +static func floor_mesh() -> MeshInstance3D: + var node = MeshInstance3D.new() + return node diff --git a/client/map/tiles/floor_like.gd.uid b/client/map/tiles/floor_like.gd.uid new file mode 100644 index 00000000..cf2178c9 --- /dev/null +++ b/client/map/tiles/floor_like.gd.uid @@ -0,0 +1 @@ +uid://dyea0clge0o7n diff --git a/client/map/tiles/floor_mesher.gd b/client/map/tiles/floor_mesher.gd index 79521795..029ec934 100644 --- a/client/map/tiles/floor_mesher.gd +++ b/client/map/tiles/floor_mesher.gd @@ -34,7 +34,11 @@ const UV: Array[Vector2] = [ Vector2.DOWN + Vector2.RIGHT, ] -var tiles: Dictionary +var tiles: Dictionary[String, Vector2i] +var mesh_instance: MeshInstance3D + +func _init(mesh: MeshInstance3D) -> void: + mesh_instance = mesh func add_tile(pos: Vector2i): tiles[str(pos)] = pos @@ -42,7 +46,7 @@ func add_tile(pos: Vector2i): func remove_tile(pos: Vector2i): tiles.erase(str(pos)) -func flush() -> ArrayMesh: +func flush() -> void: var tiles_queue = tiles.duplicate() var st := SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) @@ -118,4 +122,4 @@ func flush() -> ArrayMesh: st.index() st.optimize_indices_for_cache() - return st.commit() + mesh_instance.mesh = st.commit() diff --git a/client/map/tiles/grass.gd b/client/map/tiles/grass.gd index 0f67174c..0d64ae2b 100644 --- a/client/map/tiles/grass.gd +++ b/client/map/tiles/grass.gd @@ -14,30 +14,15 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. # class_name Grass -extends Tile +extends FloorLike -const GRASS_MESH: Mesh = preload("res://map/tiles/grass_side.tres") - -func _init(ctx: TileFactory.TileCC): - super(ctx) - - var random = RandomNumberGenerator.new() - random.seed = str(ctx.position).hash() - - var multimesh_instance := MultiMeshInstance3D.new() - - var multimesh := MultiMesh.new() - multimesh.mesh = GRASS_MESH - multimesh.transform_format = MultiMesh.TRANSFORM_3D - multimesh.instance_count = Global.get_setting("graphics.grass_amount") - - for i in multimesh.instance_count: - var origin := Vector3(random.randf_range(-.5, .5), 0.25, random.randf_range(-.5, .5)) - var basis_ := (Basis(Vector3(0, 1, 0), random.randf_range(0, PI)) * Basis(Vector3(1, 0, 0), PI/2)).scaled(Vector3(0.75, 0.5, 0.75)) - multimesh.set_instance_transform(i, Transform3D(basis_, origin)) - - base_mesh.add_child(multimesh_instance) - multimesh_instance.multimesh = multimesh +static func fm_id() -> String: + return "grass" func get_base_mesh(): - return preload("res://map/tiles/grass.tscn").instantiate() + return null + +static func floor_mesh() -> MeshInstance3D: + var node = super() + node.material_override = preload("res://map/tiles/grass_material.tres") + return node diff --git a/client/map/tiles/grass_material.tres b/client/map/tiles/grass_material.tres new file mode 100644 index 00000000..04f97be3 --- /dev/null +++ b/client/map/tiles/grass_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://d4hlt62613rxx"] + +[resource] +resource_name = "dark" +cull_mode = 2 +albedo_color = Color(0.384912, 0.569568, 0.179726, 1) +metallic_specular = 0.0 +roughness = 0.5 diff --git a/client/map/tiles/grass_mesher.gd b/client/map/tiles/grass_mesher.gd new file mode 100644 index 00000000..8535bfe7 --- /dev/null +++ b/client/map/tiles/grass_mesher.gd @@ -0,0 +1,42 @@ +# Hurry Curry! - a game about cooking +# Copyright 2025 nokoe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name GrassMesher +extends FloorMesher + +const GRASS_MESH: Mesh = preload("res://map/tiles/grass_side.tres") +var multimesh_instance := MultiMeshInstance3D.new() + +func _init(mesh: MeshInstance3D) -> void: + super(mesh) + mesh_instance.add_child(multimesh_instance) + +func flush() -> void: + super() + var random = RandomNumberGenerator.new() + random.seed = "gr4ss".hash() + + var multimesh := MultiMesh.new() + multimesh.mesh = GRASS_MESH + multimesh.transform_format = MultiMesh.TRANSFORM_3D + multimesh.instance_count = tiles.size() * Global.get_setting("graphics.grass_amount") + var t := tiles.values() + for i in multimesh.instance_count: + var p = t[i / Global.get_setting("graphics.grass_amount")] + var origin := Vector3(random.randf_range(-.5, .5), 0.25, random.randf_range(-.5, .5)) + Vector3(p.x + 0.5, 0.0, p.y + 0.5) + var basis_ := (Basis(Vector3(0, 1, 0), random.randf_range(0, PI)) * Basis(Vector3(1, 0, 0), PI/2)).scaled(Vector3(0.75, 0.5, 0.75)) + multimesh.set_instance_transform(i, Transform3D(basis_, origin)) + + multimesh_instance.multimesh = multimesh diff --git a/client/map/tiles/grass_mesher.gd.uid b/client/map/tiles/grass_mesher.gd.uid new file mode 100644 index 00000000..ed80218e --- /dev/null +++ b/client/map/tiles/grass_mesher.gd.uid @@ -0,0 +1 @@ +uid://bhjrbs3exkrm8 diff --git a/client/map/tiles/path.gd b/client/map/tiles/path.gd index 65b7e62c..da7bb4fe 100644 --- a/client/map/tiles/path.gd +++ b/client/map/tiles/path.gd @@ -14,7 +14,13 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. # class_name Path -extends Tile +extends FloorLike -func get_base_mesh(): - return preload("res://map/tiles/path.tscn").instantiate() +static func fm_id() -> String: + return "path" + +static func floor_mesh() -> MeshInstance3D: + var node = super() + node.material_override = preload("res://map/tiles/path_material.tres") + node.position.y = -0.06 + return node diff --git a/client/map/tiles/path_material.tres b/client/map/tiles/path_material.tres new file mode 100644 index 00000000..ddb7c997 --- /dev/null +++ b/client/map/tiles/path_material.tres @@ -0,0 +1,7 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://w1vbm8i23g5h"] + +[resource] +resource_name = "top" +cull_mode = 2 +albedo_color = Color(0.909087, 0.807703, 0.681417, 1) +roughness = 0.5 diff --git a/client/map/tiles/street.gd b/client/map/tiles/street.gd index 891b27a6..39aedaa9 100644 --- a/client/map/tiles/street.gd +++ b/client/map/tiles/street.gd @@ -14,7 +14,13 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. # class_name Street -extends Tile +extends FloorLike -func get_base_mesh(): - return preload("res://map/tiles/street.tscn").instantiate() +static func fm_id() -> String: + return "street" + +static func floor_mesh() -> MeshInstance3D: + var node = super() + node.material_override = preload("res://map/tiles/street_material.tres") + node.position.y = -0.06 + return node diff --git a/client/map/tiles/street_material.tres b/client/map/tiles/street_material.tres new file mode 100644 index 00000000..6a838e59 --- /dev/null +++ b/client/map/tiles/street_material.tres @@ -0,0 +1,7 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://csn4n46o8kc5n"] + +[resource] +resource_name = "top" +cull_mode = 2 +albedo_color = Color(0.31802, 0.31802, 0.31802, 1) +roughness = 0.5 |