class Vertex: pos = xyz() normal = xyz() sh1 = 0 Weights = None #weights def __init__(self): self.Weights = list()
class Skin: Textures = None fl1 = 0. Pos = xyz() Bounds = (xyz(), xyz()) field_40 = 0 vtxCount = 0 vtxList = None numGeom = 0 GeomList = None def __init__(self): self.Textures = list() self.vtxList = list() self.GeomList = list()
def WriteLvlGeom(out, g, pos = xyz(), rot = None, vtxOff = 0): global tuID i = 0 for vtx in g.Verticies: v = vtx.TransformBy(rot) + pos #out.write("# VtxID {:d}\n".format(vtxOff + i)) out.write("v {:f} {:f} {:f}\n".format(-v.x, v.y, v.z)) i += 1 for f in g.Faces: if (f.Flags & (FFLAGS.NOTRENDER.value | FFLAGS.NOTRENDER1.value)) == 0 and f.TexID != -1: ### Do not export invisible? if (f.TexID != -1): out.write("usemtl {:s}\n".format( TexDict[g.Textures[f.TexID].lower()] )) for v in f.Vtx: out.write("vt {:f} {:f}\n".format(v.U, 1.0 - v.V)) #out.write("# Flags {:X} unk1 {:X} unk2 {:d}\n".format(f.Flags, f.unk1, f.unk2)) out.write("f ") i = 0 for v in f.Vtx: out.write(" {:d}/{:d}".format(v.ID + vtxOff, tuID + i)) i += 1 out.write("\n") tuID += len(f.Vtx) return vtxOff + len(g.Verticies)
class Face: N = xyz() D = 0. TexID = -1 Flags = 0 unk1 = -1 unk2 = -1 Vtx = None RoomID = -1 def __init__(self): self.Vtx = list()
def WriteRfcGeom(out, model, pos = xyz(), rot = None, vtxOff = 0): global tuID if len(model.Bones) > 0: for obj in model.ObjList: lod = obj.LodList[0] for vtx in lod.skin.vtxList: v = vtx.pos.TransformBy(rot) + pos out.write("v {:f} {:f} {:f}\n".format(-v.x, v.y, v.z)) for geom in lod.skin.GeomList: out.write("usemtl {:s}\n".format( TexDict[ lod.skin.Textures[ geom.TexID ].lower() ] ) ) for tr in geom.Triangles: out.write("vt {:f} {:f}\nvt {:f} {:f}\nvt {:f} {:f}\n".format(tr[0].u, 1.0 - tr[0].v, tr[1].u, 1.0 - tr[1].v, tr[2].u, 1.0 - tr[2].v)) out.write("f {0:d}/{3:d} {1:d}/{4:d} {2:d}/{5:d}\n".format(tr[0].VtxID + vtxOff, tr[1].VtxID + vtxOff, tr[2].VtxID + vtxOff, tuID, tuID + 1, tuID + 2 )) tuID += 3 vtxOff += len(lod.skin.vtxList) else: for obj in model.ObjList: lod = obj.LodList[0] for geom in lod.skin.GeomList: for vtx in geom.SimpleVertexes: v = (vtx.pos + lod.skin.Pos).TransformBy(rot) + pos out.write("v {:f} {:f} {:f}\n".format(-v.x, v.y, v.z)) out.write("usemtl {:s}\n".format( TexDict[ lod.skin.Textures[ geom.TexID ].lower() ] ) ) for tr in geom.Triangles: out.write("vt {:f} {:f}\nvt {:f} {:f}\nvt {:f} {:f}\n".format(tr[0].u, 1.0 - tr[0].v, tr[1].u, 1.0 - tr[1].v, tr[2].u, 1.0 - tr[2].v)) out.write("f {0:d}/{3:d} {1:d}/{4:d} {2:d}/{5:d}\n".format(tr[0].VtxID + vtxOff, tr[1].VtxID + vtxOff, tr[2].VtxID + vtxOff, tuID, tuID + 1, tuID + 2 )) tuID += 3 vtxOff += geom.numSimpleVertex return vtxOff
class Entity: Pos = xyz() Mt33 = [] Tp = ""
class MoverBrush: Pos = xyz() Mt33 = [] Geom = None ID = -1 Flags = 0
def main(): global MTL if (len(sys.argv) < 2): print("Usage: rfl_read.py level.rfl outName.obj") exit(0) path = os.path.dirname(sys.argv[1]) lvl = ReadRFL(sys.argv[1]) numvtx = 1 MTL = None OBJ = None if (len(sys.argv) > 2): OBJ = open(sys.argv[2], "w") MTL = open(sys.argv[2] + ".mtl", "w") OBJ.write("mtllib {:s}\n".format(sys.argv[2] + ".mtl")) else: OBJ = open("out.obj", "w") MTL = open("out.mtl", "w") OBJ.write("mtllib out.mtl\n") if not os.path.exists("outtex"): os.mkdir("outtex") texID = 0 ##Write misc-static.tga (from Permanent_data/perma.peg) MTL.write("newmtl Tex{:d}\n\tmap_Kd outtex/{:s}.png\n".format(texID, "misc-static.tga")) TexDict[ "misc-static.tga" ] = "Tex{:d}".format(texID) texID += 1 ##Missing textures! TexDict[ "mtl_122_grate2.tga" ] = TexDict[ "misc-static.tga" ] TexDict[ "building1.tga" ] = TexDict[ "misc-static.tga" ] TexDict[ "gls_smoked01_a.tga" ] = TexDict[ "misc-static.tga" ] TexDict[ "green_grime.tga" ] = TexDict[ "misc-static.tga" ] ## Write level textures if (lvl.Peg): for pg in lvl.Peg.Texturies: pg.img.save("outtex/{:s}.png".format(pg.Name)) MTL.write("newmtl Tex{:d}\n\tmap_Kd outtex/{:s}.png\n".format(texID, pg.Name)) TexDict[ pg.Name.lower() ] = "Tex{:d}".format(texID) texID += 1 #Write static mesh OBJ.write("o Lvl static\n") numvtx = WriteLvlGeom(OBJ, lvl.Geom, xyz(), None, numvtx) #Write mover mesh i = 0 for movr in lvl.Movers: OBJ.write("o Lvl Mover Brush {:d}\n".format(i)) numvtx = WriteLvlGeom(OBJ, movr.Geom, movr.Pos, movr.Mt33, numvtx) i += 1 #Write entities i = 0 for ent in lvl.Entities: if not (ent.Tp.lower() in EntityDict): print("Entity \"{:s}\" not in dict".format(ent.Tp)) continue filename = GetFileName(path, EntityDict[ent.Tp.lower()]) if filename == "" or (not os.path.isfile(filename)): print("Can't open entity object {:s}".format(filename)) continue print("Loading Entity file :", filename) model = LoadRfc(filename) ## Write Entity textures if (model.Peg): for pg in model.Peg.Texturies: if not pg.Name.lower() in TexDict: pg.img.save("outtex/{:s}.png".format(pg.Name)) MTL.write("newmtl Tex{:d}\n\tmap_Kd outtex/{:s}.png\n".format(texID, pg.Name)) TexDict[ pg.Name.lower() ] = "Tex{:d}".format(texID) texID += 1 OBJ.write("o Entity {:d}\n".format(i)) numvtx = WriteRfcGeom(OBJ, model, ent.Pos, ent.Mt33, numvtx) i += 1 OBJ.close() MTL.close()
class SimpleVertex: pos = xyz() normal = xyz()
class Bone: Name = "" field_4C = 0 pos = xyz() mtx = None
class RFC_s2: Name = "" field_40 = 0 pos = xyz() field_50 = FLT4()
class RFC_s1: Name = "" field_18 = 0 pos = xyz() field_28 = 0.