# Hurry Curry! - a game about cooking # Copyright 2024 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 . # 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 func add_tile(pos: Vector2i): tiles[str(pos)] = pos func flush() -> ArrayMesh: var st := SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) while not tiles.is_empty(): var key: String = tiles.keys()[0] var tile_position: Vector2i = tiles[key] var shift := Vector2i.ZERO # move the origin of the rectangle to the upper left corner while true: #if tiles.has(str(tile_position + shift + Vector2i.UP + Vector2i.LEFT)): # shift += Vector2i.UP + Vector2i.LEFT if tiles.has(str(tile_position + shift + Vector2i.UP)): shift += Vector2i.UP elif tiles.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.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.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.erase(str(Vector2i(x, y))) return st.commit()