Created
May 27, 2020 16:16
-
-
Save devinacker/c1d222a8e49dc1e450b03200201de510 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
Doom map rect-to-polar "circularizer" - by Revenant | |
Inspired by a blog post by Ribbiks: | |
https://rbkz.blogspot.com/2020/05/circularizer-lua.html | |
""" | |
from sys import argv | |
from omg import * | |
from math import pi, sin, cos, floor | |
from copy import deepcopy | |
def polar(map): | |
ed = MapEditor(map) | |
x_min = min([v.x for v in ed.vertexes]) | |
x_max = max([v.x for v in ed.vertexes]) | |
y_min = min([v.y for v in ed.vertexes]) | |
y_max = max([v.y for v in ed.vertexes]) | |
cx = (x_min + x_max) / 2 | |
cy = (y_min + y_max) / 2 | |
r_scale = 1.0 # radius scale factor | |
r_off = 256 # radius offset (inner "hole") in map units | |
length_max = 128 # split linedefs that are longer than this | |
def split(line): | |
vx_a = ed.vertexes[line.vx_a] | |
vx_b = ed.vertexes[line.vx_b] | |
dy = vx_b.y - vx_a.y | |
dx = vx_b.x - vx_a.x | |
length = ((dy * dy) + (dx * dx)) ** 0.5 | |
if length > length_max: | |
vx_c = Vertex((vx_a.x + vx_b.x) / 2, (vx_a.y + vx_b.y) / 2) | |
line2 = deepcopy(line) | |
line.vx_a = line2.vx_b = len(ed.vertexes) | |
ed.vertexes.append(vx_c) | |
ed.linedefs.append(line2) | |
if length > (2 * length_max): | |
split(line) | |
split(line2) | |
def transform(x, y): | |
r = r_scale * (y - y_min) + r_off | |
theta = -(2 * pi * (x - x_min)) / (x_max - x_min) - (pi / 2) | |
x_new = round(r * cos(theta) + cx) | |
y_new = round(r * sin(theta) + cy) | |
return x_new, y_new, theta | |
for l in ed.linedefs: | |
split(l) | |
for v in ed.vertexes: | |
v.x, v.y, _ = transform(v.x, v.y) | |
for t in ed.things: | |
t.x, t.y, theta = transform(t.x, t.y) | |
t.angle = floor(t.angle + (theta * 360)/(2 * pi) - 90) % 360 | |
ed.nodes = [] | |
return ed.to_lumps() | |
def main(args): | |
if (len(args) < 2): | |
print(" Omgifol script: polar transform maps\n") | |
print(" Usage:") | |
print(" omgpolar.py input.wad output.wad [pattern]\n") | |
print(" Transform all maps or those whose name match the given pattern") | |
print(" (eg E?M4 or MAP*).") | |
print(" Note: nodes will have to be rebuilt externally.\n") | |
else: | |
print("Loading %s..." % args[0]) | |
inwad = WAD() | |
outwad = WAD() | |
inwad.from_file(args[0]) | |
pattern = "*" | |
if (len(args) == 3): | |
pattern = args[2] | |
for name in inwad.maps.find(pattern): | |
print("Transforming %s" % name) | |
outwad.maps[name] = polar(inwad.maps[name]) | |
print("Saving %s..." % args[1]) | |
outwad.to_file(args[1]) | |
if __name__ == "__main__": main(argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment