diff --git a/Tools/make_roompack.py b/Tools/make_roompack.py new file mode 100755 index 00000000000..6747ab1a84b --- /dev/null +++ b/Tools/make_roompack.py @@ -0,0 +1,104 @@ +#!/usr/bin/python +# Analyze the rectangular bounding boxes in a greyscale bitmap to create +# dungeon room pack configs. + +import argparse +import cv2 +from dataclasses import dataclass + + +SUBDIVISIONS = 128 +MIN_VALUE = 1 +MAX_VALUE = 256 + +assert(MAX_VALUE % SUBDIVISIONS == 0) + +@dataclass +class Box2: + left: int + bottom: int + right: int + top: int + +@dataclass +class RoomPackBitmap: + width: int + height: int + rooms: list + + +def analyze_bitmap(fname, centered = False, offset_x = 0, offset_y = 0): + image = cv2.imread(fname, cv2.IMREAD_GRAYSCALE) + + contours = [] + + for i in range(0, 1 + SUBDIVISIONS): + lower = MAX_VALUE / SUBDIVISIONS * (i - 1) + upper = MAX_VALUE / SUBDIVISIONS * i - 1 + + lower = max(MIN_VALUE, lower) + upper = min(MAX_VALUE - 1, upper) + + image_slice = cv2.inRange(image, lower, upper) + image_mask = cv2.threshold(image_slice, 0, 255, cv2.THRESH_TOZERO)[1] + new_contours = cv2.findContours(image_mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) + + if len(new_contours[0]) == 0: + continue + + contours += new_contours[0:-1] + + image_height = len(image) + image_width = len(image[0]) + rooms = [] + + if centered: + offset_x -= image_width // 2 + offset_y -= image_height // 2 + + for contour in contours: + for subcontour in contour: + x, y, w, h = cv2.boundingRect(subcontour) + + box = Box2(offset_x + x, + offset_y + y, + offset_x + x + w, + offset_y + y + h) + + rooms.append(box) + + return RoomPackBitmap(image_width, image_height, rooms) + + +def main(): + parser = argparse.ArgumentParser(description='Calculate rooms from a greyscale bitmap') + + parser.add_argument('file', type=str, + help='a greyscale bitmap') + + parser.add_argument('--center', action=argparse.BooleanOptionalAction, + default=False, + help='center the output coordinates') + + parser.add_argument('--offset', type=int, + nargs=2, + default=[0, 0], + help='offset the output coordinates') + + args = parser.parse_args() + + result = analyze_bitmap(args.file, args.center, args.offset[0], args.offset[1]) + + + print(f" size: {result.width},{result.height}") + print(" rooms:") + + for room in result.rooms: + print(f" - {room.left},{room.bottom},{room.right},{room.top}") + + print("") + print(f"Generated {len(result.rooms)} rooms.") + +if __name__ == "__main__": + main() +