# Hurry Curry! - a game about cooking # Copyright (C) 2025 Hurry Curry! contributors # # 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 . # class_name FloorMesher extends Object const H := 0.25 const RECTANGLE: Array[Vector3] = [ Vector3.ZERO, Vector3.RIGHT, Vector3.BACK + Vector3.RIGHT, Vector3.BACK, Vector3.ZERO, Vector3.BACK + Vector3.RIGHT, ] const UV: Array[Vector2] = [ Vector2.ZERO, Vector2.RIGHT, Vector2.DOWN + Vector2.RIGHT, Vector2.DOWN, Vector2.ZERO, Vector2.DOWN + Vector2.RIGHT, ] 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 func remove_tile(pos: Vector2i): tiles.erase(str(pos)) func flush() -> void: if tiles.is_empty(): mesh_instance.mesh = null return var tiles_queue = tiles.duplicate() var st := SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) while not tiles_queue.is_empty(): var key: String = tiles_queue.keys()[0] var tile_position: Vector2i = tiles_queue[key] var shift := Vector2i.ZERO # move the origin of the rectangle to the upper left corner while true: #if tiles_queue.has(str(tile_position + shift + Vector2i.UP + Vector2i.LEFT)): # shift += Vector2i.UP + Vector2i.LEFT if tiles_queue.has(str(tile_position + shift + Vector2i.UP)): shift += Vector2i.UP elif tiles_queue.has(str(tile_position + shift + Vector2i.LEFT)): shift += Vector2i.LEFT else: break var rectangle_origin := tile_position + shift var rectangle := Vector2i.ONE # go down as long as possible while tiles_queue.has(str(rectangle_origin + Vector2i(0, rectangle.y))): rectangle.y += 1 # try to go right as long as possible by checking if whole columns are long enough while true: var column_possible := true for i in range(0, rectangle.y): column_possible = tiles_queue.has(str(rectangle_origin + Vector2i(rectangle.x, i))) if not column_possible: break if column_possible: rectangle.x += 1 else: break # floor for i in range(UV.size()): st.set_normal(Vector3.UP) st.set_uv(UV[i] * Vector2(rectangle)) st.add_vertex(RECTANGLE[i] * Vector3(rectangle.x, 0., rectangle.y) + Vector3(rectangle_origin.x, 0., rectangle_origin.y)) # the faces on the side (should be improved...) # back for i in range(UV.size()): st.set_normal(Vector3.BACK) st.set_uv(UV[i] * Vector2(rectangle.x, H)) st.add_vertex((RECTANGLE[i] * Vector3(rectangle.x, 0., -H)).rotated(Vector3.RIGHT, 0.5 * PI) + Vector3(rectangle_origin.x, -H, rectangle_origin.y)) # right for i in range(UV.size()): st.set_normal(Vector3.RIGHT) st.set_uv(UV[i] * Vector2(H, rectangle.y)) st.add_vertex((RECTANGLE[i] * Vector3(H, 0., rectangle.y)).rotated(Vector3.BACK, 0.5 * PI) + Vector3(rectangle_origin.x, -H, rectangle_origin.y)) # left for i in range(UV.size()): st.set_normal(Vector3.LEFT) st.set_uv(UV[i] * Vector2(H, rectangle.y)) st.add_vertex((RECTANGLE[i] * Vector3(H, 0., -rectangle.y)).rotated(Vector3.BACK, 0.5 * PI) + Vector3(rectangle_origin.x + rectangle.x, -H, rectangle_origin.y + rectangle.y)) # back for i in range(UV.size()): st.set_normal(Vector3.BACK) st.set_uv(UV[i] * Vector2(rectangle.x, H)) st.add_vertex((RECTANGLE[i] * Vector3(-rectangle.x, 0., -H)).rotated(Vector3.RIGHT, 0.5 * PI) + Vector3(rectangle_origin.x + rectangle.x, -H, rectangle_origin.y + rectangle.y)) # remove the rectangle from the "queue" for x in range(rectangle_origin.x, rectangle_origin.x + rectangle.x): for y in range(rectangle_origin.y, rectangle_origin.y + rectangle.y): tiles_queue.erase(str(Vector2i(x, y))) st.index() st.optimize_indices_for_cache() mesh_instance.mesh = st.commit()