mesh files use game space (right-handed, y up): obj/gltf import and export no longer mirror models, per-mesh handedness keeps meshes of old projects as they were, python tools follow (--export-space for the old files)
This commit is contained in:
1 parent
c4fa500198
commit
4a58910fba
26 files changed
+525
-96
No files matched your search
+18
-11
@@ -11,7 +11,9 @@ Writes to outdir:
|
||||
objects.obj (--objects) static STPC object models side by side
|
||||
preview_top.png, preview_persp.png textured software renderings for checking
|
||||
|
||||
Coordinates: export space = MAP floats (y up, right-handed, z < 0). Game space = (x, y, -z).
|
||||
Coordinates: OBJ file space = game space (x, y, z_game): right-handed, y up, z > 0 in the grid, as
|
||||
Blender shows the level the same way round as the game (geomlib.to_file). --export-space writes
|
||||
the raw export space (MAP floats, z < 0; mirrored in other tools), the convention before 2026-11-07.
|
||||
Format: notes/geometry.md
|
||||
"""
|
||||
import argparse
|
||||
@@ -61,7 +63,7 @@ def flat_color(t):
|
||||
return (t['u0'] / 255, t['u1'] / 255, t['v0'] / 255)
|
||||
|
||||
|
||||
def write_obj(path, tris, texs, mtlname):
|
||||
def write_obj(path, tris, texs, mtlname, raw=False):
|
||||
with open(path, 'w') as fo:
|
||||
fo.write('# Ein Koenigreich fuer ein Lama - world geometry (geom_export.py)\n')
|
||||
fo.write(f'mtllib {mtlname}\n')
|
||||
@@ -77,10 +79,11 @@ def write_obj(path, tris, texs, mtlname):
|
||||
if mat != cur_mat:
|
||||
fo.write(f'usemtl {mat}\n')
|
||||
cur_mat = mat
|
||||
for p, c in zip(P, C):
|
||||
fo.write('v %.5f %.5f %.5f %.3f %.3f %.3f\n' % (*p, *c))
|
||||
for u, v in uv:
|
||||
fo.write('vt %.6f %.6f\n' % (u, 1 - v))
|
||||
order = [0, 1, 2] if raw else G.file_order(range(3))
|
||||
for k in order:
|
||||
fo.write('v %.5f %.5f %.5f %.3f %.3f %.3f\n' % (*(P[k] if raw else G.to_file(P[k])), *C[k]))
|
||||
for k in order:
|
||||
fo.write('vt %.6f %.6f\n' % (uv[k][0], 1 - uv[k][1]))
|
||||
fo.write(f'f {vi}/{vi} {vi + 1}/{vi + 1} {vi + 2}/{vi + 2}\n')
|
||||
vi += 3
|
||||
|
||||
@@ -168,12 +171,16 @@ def main():
|
||||
ap.add_argument('--objects', action='store_true')
|
||||
ap.add_argument('--no-png', action='store_true', help='no page PNGs/previews')
|
||||
ap.add_argument('--size', default='1200x900')
|
||||
ap.add_argument('--export-space', action='store_true',
|
||||
help='raw export space (z < 0, mirrored in Blender) instead of game space')
|
||||
a = ap.parse_args()
|
||||
out = (lambda p: p) if a.export_space else G.to_file
|
||||
order = (lambda s: list(s)) if a.export_space else G.file_order
|
||||
os.makedirs(a.outdir, exist_ok=True)
|
||||
ch, wf, trak, mp = G.load_level(a.wad)
|
||||
pages, texs = G.parse_text(G.wad_get(ch, 'TEXT'))
|
||||
tris = world_tris(trak, mp, texs)
|
||||
write_obj(os.path.join(a.outdir, 'level.obj'), tris, texs, 'level.mtl')
|
||||
write_obj(os.path.join(a.outdir, 'level.obj'), tris, texs, 'level.mtl', a.export_space)
|
||||
write_mtl(os.path.join(a.outdir, 'level.mtl'), tris, texs, len(pages))
|
||||
print(f'{a.wad}: WFPC={wf:#x} TRAK models={len(trak)} tiles={mp["N"]} grid={mp["W"]}x{mp["H"]} '
|
||||
f'triangles={len(tris)} textures={len(texs)} pages={len(pages)}')
|
||||
@@ -194,8 +201,8 @@ def main():
|
||||
if nrm @ np.array(c['plane'][:3]) < 0:
|
||||
pts = pts[::-1]
|
||||
fo.write(f'g mat{c["mat"]:02d}_grp{g}\n')
|
||||
for p in pts:
|
||||
fo.write('v %.5f %.5f %.5f\n' % f(*p))
|
||||
for p in order(pts):
|
||||
fo.write('v %.5f %.5f %.5f\n' % out(f(*p)))
|
||||
fo.write('f ' + ' '.join(str(vi + k) for k in range(len(pts))) + '\n')
|
||||
vi += len(pts)
|
||||
|
||||
@@ -211,7 +218,7 @@ def main():
|
||||
dx = ox - min(xs)
|
||||
fo.write(f'o stpc_model_{k:03d}\n')
|
||||
for v in m.verts:
|
||||
fo.write('v %.5f %.5f %.5f\n' % (v[0] + dx, v[1], v[2]))
|
||||
fo.write('v %.5f %.5f %.5f\n' % out((v[0] + dx, v[1], v[2])))
|
||||
for fc in m.faces:
|
||||
t = texs[fc['tex']] if fc['tex'] < len(texs) else None
|
||||
if t and not (t['flags'] & 1) and t['page'] >= 0:
|
||||
@@ -220,7 +227,7 @@ def main():
|
||||
uv = [(0, 0)] * 3; fo.write(f'usemtl flat_{fc["tex"]}\n')
|
||||
for u, v in uv:
|
||||
fo.write('vt %.6f %.6f\n' % (u, 1 - v))
|
||||
fo.write('f ' + ' '.join(f'{vi + fc["v"][j]}/{vt + j}' for j in range(3)) + '\n')
|
||||
fo.write('f ' + ' '.join(f'{vi + fc["v"][j]}/{vt + j}' for j in order(range(3))) + '\n')
|
||||
vt += 3
|
||||
vi += len(m.verts)
|
||||
ox += max(xs) - min(xs) + 0.5
|
||||
|
||||
Reference in new issue
Block a user