add material and object structs
This commit is contained in:
parent
61e2fb2c28
commit
00e7d75fda
@ -4,14 +4,14 @@ import sys
|
||||
|
||||
def generate_vec3(vs):
|
||||
for v in vs:
|
||||
yield f"{{{v.x}f, {v.y}f, {v.z}f}},"
|
||||
yield f"{{{v.x:.6f}f, {v.y:.6f}f, {v.z:.6f}f}},"
|
||||
|
||||
def generate_vec2(vs):
|
||||
for v in vs:
|
||||
yield f"{{{v.x}f, {v.y}f}},"
|
||||
yield f"{{{v.x:.6f}f, {v.y:.6f}f}},"
|
||||
|
||||
def generate_vec(name, type, func, vs):
|
||||
yield f"vertex_{type} {name}_{type}[] = {{"
|
||||
yield f"const vertex_{type} {name}_{type}[] = {{"
|
||||
yield from func(vs)
|
||||
yield "};"
|
||||
|
||||
@ -25,7 +25,7 @@ def generate_ptn(ptn):
|
||||
yield f"{{{p.position}, {p.texture}, {p.normal}}},"
|
||||
|
||||
def generate_faces(group_name, model_name, faces, type, n):
|
||||
yield f"union {type} {group_name}_{model_name}_triangles = {{"
|
||||
yield f"const union {type} {group_name}_{model_name}_{type}[] = {{"
|
||||
for face in filter_n(faces, n):
|
||||
yield "{ .v = {"
|
||||
yield from generate_ptn(face.ptn)
|
||||
@ -33,14 +33,32 @@ def generate_faces(group_name, model_name, faces, type, n):
|
||||
yield "};"
|
||||
|
||||
def generate_object(group_name, object):
|
||||
yield f"struct object {group_name}_{object.name} = {{"
|
||||
yield f"const struct object {group_name}_{object.name} = {{"
|
||||
yield f".triangle = &{group_name}_{object.name}_triangle[0],"
|
||||
yield f".quadrilateral = &{group_name}_{object.name}_quadrilateral[0],"
|
||||
triangle_count = sum(1 for _ in filter_n(object.faces, 3))
|
||||
quadrilateral_count = sum(1 for _ in filter_n(object.faces, 4))
|
||||
yield f".triangle_count = {triangle_count},"
|
||||
yield f".quadrilateral_count = {quadrilateral_count},"
|
||||
yield ".material = 0,"
|
||||
if object.material is None:
|
||||
yield ".material = 0,"
|
||||
else:
|
||||
yield f".material = {group_name}_{object.material.name},"
|
||||
yield "};"
|
||||
|
||||
def generate_object_array(group_name, obj_file):
|
||||
yield f"const struct object * {group_name}_object[] = {{"
|
||||
for object in obj_file.objects:
|
||||
yield f"&{group_name}_{object.name},"
|
||||
yield "};"
|
||||
|
||||
def generate_model(group_name):
|
||||
yield f"const struct model {group_name}_model = {{"
|
||||
yield f".position = {group_name}_position,"
|
||||
yield f".texture = {group_name}_texture,"
|
||||
yield f".normal = {group_name}_normal,"
|
||||
yield f".object = {group_name}_object,"
|
||||
yield f".object_count = {len(obj_file.objects)}"
|
||||
yield "};"
|
||||
|
||||
def generate_obj_file(group_name, obj_file):
|
||||
@ -54,6 +72,9 @@ def generate_obj_file(group_name, obj_file):
|
||||
yield from generate_faces(group_name, object.name, object.faces, "quadrilateral", 4)
|
||||
yield from generate_object(group_name, object)
|
||||
|
||||
yield from generate_object_array(group_name, obj_file)
|
||||
yield from generate_model(group_name)
|
||||
|
||||
if __name__ == "__main__":
|
||||
obj_file = parse_obj_file(sys.argv[1])
|
||||
render, out = renderer(indent_length=4)
|
||||
|
24
obj.py
24
obj.py
@ -33,14 +33,20 @@ class FacePTN:
|
||||
class Face:
|
||||
ptn: list[FacePTN]
|
||||
|
||||
@dataclass
|
||||
class Material:
|
||||
name: str
|
||||
|
||||
@dataclass
|
||||
class Object:
|
||||
name: str
|
||||
faces: list[Face]
|
||||
material: Material
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.faces = []
|
||||
self.material = None
|
||||
|
||||
@dataclass
|
||||
class ObjFile:
|
||||
@ -56,13 +62,15 @@ class ObjFile:
|
||||
self.objects = []
|
||||
|
||||
def parse_float(s):
|
||||
sign = -1 if s.startswith("-") else 1
|
||||
s = s.removeprefix("-")
|
||||
if '.' not in s:
|
||||
return int(s, 10)
|
||||
return sign * int(s, 10)
|
||||
i, f = s.split('.')
|
||||
f_digits = len(f)
|
||||
i = int(i, 10)
|
||||
f = int(f, 10)
|
||||
return i + (f / 10 ** f_digits)
|
||||
return sign * (i + (f / 10 ** f_digits))
|
||||
|
||||
def parse_vertex(line, n, type):
|
||||
assert len(line) == n
|
||||
@ -98,12 +106,17 @@ def parse_object_event(line):
|
||||
name, = line
|
||||
return ObjectEvent(name)
|
||||
|
||||
def parse_usemtl(line):
|
||||
assert len(line) == 1
|
||||
name, = line
|
||||
return Material(name)
|
||||
|
||||
def parse_line(line):
|
||||
t, *line = line.split(' ')
|
||||
if t == '#':
|
||||
return None
|
||||
if t == 'usemtl':
|
||||
return None
|
||||
return parse_usemtl(line)
|
||||
if t == 'mtllib':
|
||||
return None
|
||||
if t == 'o':
|
||||
@ -141,6 +154,11 @@ def parse_obj_lines(lines):
|
||||
object = Object(x.name)
|
||||
elif type(x) is Face:
|
||||
object.faces.append(x)
|
||||
elif type(x) is Material:
|
||||
if object.material != None:
|
||||
file.objects.append(object)
|
||||
object = Object(object.name + "_mtl_" + x.name)
|
||||
object.material = x
|
||||
else:
|
||||
assert False, x
|
||||
if object.faces:
|
||||
|
Loading…
x
Reference in New Issue
Block a user