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