import sys import struct from itertools import chain from dataclasses import dataclass from obj import tangent with open(sys.argv[1], 'r') as f: lines = f.read().split('\n') position = [] texture = [] normal = [] faces = [] def parse_vertex(prefix, s): return s.removeprefix(prefix).strip().split() def float_vector(l, n): v = list(map(float, l)) assert len(v) == n return v vertex_types = [ ("v ", position, 3), ("vn ", normal, 3), ("vt ", texture, 2), ] ignore_prefixes = ["#", "mtllib ", "usemtl ", "o ", "s "] def parse_line(line): if not line.strip(): return for prefix in ignore_prefixes: if line.startswith(prefix): return for prefix, out, n in vertex_types: if line.startswith(prefix): out.append(float_vector(parse_vertex(prefix, line), n)) return if line.startswith("f "): vertices = [ tuple(int(i)-1 for i in vertex.split("/")) for vertex in parse_vertex("f ", line) ] assert len(vertices) == 3, vertices # is not triangle faces.append(vertices) return assert False, repr(line) # unhandled line prefix for line in lines: parse_line(line) vertex_buffer_keys = dict() vertex_buffer = [] index_buffer = [] for face in faces: for vertex in face: if vertex not in vertex_buffer_keys: vertex_buffer_keys[vertex] = len(vertex_buffer) vertex_buffer.append(tuple(chain( position[vertex[0]], texture[vertex[1]], normal[vertex[2]], ))) index_buffer.append(vertex_buffer_keys[vertex]) def render_vertex(f, vertex, tangent): # extra padding zero for normal R16G16B16A16 # position texture normal tangent stride = struct.pack("<" + "fff" + "ff" + "eeee" + "eeee", *vertex, 0, *tangent) print(vertex, tangent) #print(len(stride)) f.write(stride) minv = [0, 0, 0] maxv = [0, 0, 0] for v in vertex_buffer: for i in range(3): if v[i] > maxv[i]: maxv[i] = v[i] if v[i] < minv[i]: minv[i] = v[i] with open(sys.argv[2], 'wb') as f: header_size = 4 * 5 + 4 * 6 index_size = 2 * 1 index_buffer_size = index_size * len(index_buffer) vertex_size = (4 * 3) + (4 * 2) + (2 * 4) + (2 * 4) vertex_buffer_size = vertex_size * len(vertex_buffer) index_count = len(index_buffer) index_buffer_offset = header_size vertex_buffer_offset = header_size + index_buffer_size tangents = tangent.generate_tangents(vertex_buffer, index_buffer) header = struct.pack("