Skip to content

Instantly share code, notes, and snippets.

@devinacker
Created May 27, 2020 16:16
Show Gist options
  • Save devinacker/c1d222a8e49dc1e450b03200201de510 to your computer and use it in GitHub Desktop.
Save devinacker/c1d222a8e49dc1e450b03200201de510 to your computer and use it in GitHub Desktop.
#!/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