Despite the distorted exports, I seem to have got the overall binary format of those files, in general. But I think Python simply can't do some vector to Unreal vertex long conversion, probably due to the way it handles ints. So I might end up needing to use some class from `ctypes`...
Either way, nerdy stuff behind, this is a simple command-line tool that takes a bunch of Wavefront .obj files inside a folder (ordered by any number in their filename), takes each of them as a frame, and converts the result into an aniv and a data file, with the format `(filename)_(type).3d`.
Copy this into a file named unreal_conv.py:
Code: Select all
import struct_helper
import glob
import sys
import struct
def unreal_vertex(vertex):
"""
Returns a long int that represents the vertex
in Unreal Engine 1 (1998/1999)'s aniv data format.
"""
(x, y, z) = vertex
return int( (int(x * 8.0) & 0x7ff)
| ((int(y * 8.0) & 0x7ff) << 11)
| ((int(z * 4.0) & 0x3ff) << 22) )
def export_unreal(obj_folder, export_name, frame_sort=sorted):
frames = [open(path) for path in frame_sort(glob.glob(obj_folder + "\*.obj"))]
vertices = []
texture_coords = []
polys = []
processed_polys = []
# Reads the mesh data.
for line in frames[0].readlines():
if line.startswith("vt "):
texture_coords.append([float(x) for x in line.split(" ")[1:3]])
elif line.startswith("f "):
polys.append(line.split(" ")[1:4])
# Reads per-frame vertex data.
for frame in frames:
vertices.append([])
for line in frame.readlines():
if line.startswith("v "):
vertices[-1].append([float(x) for x in line.split(" ")[1:4]])
# Processes the poly strings.
for poly in polys:
processed_polys.append([])
for indexes in poly:
processed_polys[-1].append([int(x) for x in indexes.split("/")[:2]])
aniv = struct_helper.BinaryFile(export_name + "_a.3d")
data = struct_helper.BinaryFile(export_name + "_d.3d")
# Write aniv file
aniv.write_binary(True, "=HL", len(frames), len(vertices[0]) * struct.calcsize("=L")) # header
for frame in vertices:
for vertex in frame:
aniv.write_binary(True, "=L", unreal_vertex(vertex))
del aniv
# Write data file
data.write_binary(True, "=4H7L12B", len(polys), len(vertices[0]), *[0] * 21) # header
for poly in processed_polys:
try:
data.write_binary(
True,
"=3H2b6B2b",
poly[0][0],
poly[1][0],
poly[2][0],
1,
127,
texture_coords[poly[0][1]][0],
texture_coords[poly[0][1]][1],
texture_coords[poly[1][1]][0],
texture_coords[poly[1][1]][1],
texture_coords[poly[2][1]][0],
texture_coords[poly[2][1]][1],
1,
0,
)
except IndexError:
continue
# Start it!
if __name__ == "__main__":
export_unreal(sys.argv[1], sys.argv[2])
All you must do in command-line is to provide the following arguments:
Code: Select all
python unreal_conv.py <folder where all Wavefront frames reside> <filename of result .3d file (NOT INCLUDING THE ANIV/DATA SUFFIX OR EXTENSION!)>
And done! There is your completely skewed and chewed-on mesh. Courtesy of some fungus...Anyways, if you have any good ideas for this, please post!