mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-06 11:52:58 +00:00
76 lines
2.8 KiB
Python
76 lines
2.8 KiB
Python
'''
|
|
This file is part of Telegram Desktop,
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
'''
|
|
|
|
# Converts a Wavefront .obj mesh into the compact .binobj format read at
|
|
# runtime by Ui::Premium::LoadStarModel (ui/effects/premium_star_model.cpp).
|
|
#
|
|
# Usage: obj2binobj.py <input.obj> <output.binobj>
|
|
#
|
|
# Format (big-endian, 32-bit ints and floats):
|
|
# int32 positionFloatCount; float32[positionFloatCount] # xyz triples
|
|
# int32 uvFloatCount; float32[uvFloatCount] # uv pairs
|
|
# int32 normalFloatCount; float32[normalFloatCount] # xyz triples
|
|
# int32 cornerCount; { int32 posIdx, uvIdx, normIdx } x cornerCount
|
|
# Indices are 0-based. UVs are stored raw; the loader flips V (1 - v).
|
|
|
|
import struct
|
|
import sys
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
sys.stderr.write('Usage: obj2binobj.py <input.obj> <output.binobj>\n')
|
|
return 1
|
|
|
|
positions = []
|
|
uvs = []
|
|
normals = []
|
|
corners = []
|
|
|
|
with open(sys.argv[1], 'r') as source:
|
|
for line in source:
|
|
parts = line.split()
|
|
if not parts or parts[0].startswith('#'):
|
|
continue
|
|
tag = parts[0]
|
|
if tag == 'v':
|
|
positions += [float(parts[1]), float(parts[2]), float(parts[3])]
|
|
elif tag == 'vt':
|
|
uvs += [float(parts[1]), float(parts[2])]
|
|
elif tag == 'vn':
|
|
normals += [float(parts[1]), float(parts[2]), float(parts[3])]
|
|
elif tag == 'f':
|
|
face = []
|
|
for vertex in parts[1:]:
|
|
fields = (vertex.split('/') + ['', ''])[:3]
|
|
face.append([
|
|
(int(fields[0]) - 1) if fields[0] else -1,
|
|
(int(fields[1]) - 1) if fields[1] else -1,
|
|
(int(fields[2]) - 1) if fields[2] else -1,
|
|
])
|
|
# Triangulate as a fan (a no-op for already-triangular faces).
|
|
for i in range(1, len(face) - 1):
|
|
corners += [face[0], face[i], face[i + 1]]
|
|
|
|
with open(sys.argv[2], 'wb') as out:
|
|
out.write(struct.pack('>i', len(positions)))
|
|
out.write(struct.pack('>%df' % len(positions), *positions))
|
|
out.write(struct.pack('>i', len(uvs)))
|
|
out.write(struct.pack('>%df' % len(uvs), *uvs))
|
|
out.write(struct.pack('>i', len(normals)))
|
|
out.write(struct.pack('>%df' % len(normals), *normals))
|
|
out.write(struct.pack('>i', len(corners)))
|
|
for corner in corners:
|
|
out.write(struct.pack('>3i', corner[0], corner[1], corner[2]))
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|