render_model: use numeric conversion from float

This commit is contained in:
Zack Buhman 2025-04-26 02:50:06 -05:00
parent 99856aa1b9
commit 37e0b80b68
3 changed files with 48 additions and 7 deletions

View File

@ -45,6 +45,23 @@ class color_format:
("axxx4444", color_format.axxx4444), ("axxx4444", color_format.axxx4444),
])[s] ])[s]
class unconvert_color_format:
def argb1555(value):
a = (value >> 15) & 0b1
r = (value >> 10) & 0b11111
g = (value >> 5 ) & 0b11111
b = (value >> 0 ) & 0b11111
return (r * 8, g * 8, b * 8, a * 255)
def from_string(s):
return dict([
#("gbgr1555", unconvert_color_format.gbgr1555),
#("argb4444", unconvert_color_format.argb4444),
("argb1555", unconvert_color_format.argb1555),
#("rgb565", unconvert_color_format.rgb565),
#("axxx4444", unconvert_color_format.axxx4444),
])[s]
def convert_colors(convert, colors): def convert_colors(convert, colors):
for color in colors: for color in colors:
value = convert(*color) value = convert(*color)
@ -122,6 +139,12 @@ def write_mips(f, im: Image, is_twiddled: bool, convert):
for mip in generate_mips(im): for mip in generate_mips(im):
write_mip(f, mip, is_twiddled, convert) write_mip(f, mip, is_twiddled, convert)
def write_png_reference(size, filename, unconvert, colors):
im = Image.new("RGBA", size)
data = [unconvert(value) for value in colors]
im.putdata(data)
im.save(filename)
def main(): def main():
in_file = sys.argv[1] in_file = sys.argv[1]
format = sys.argv[2] format = sys.argv[2]
@ -130,6 +153,7 @@ def main():
assert sys.argv[4] in {"mipmapped", "non_mipmapped"} assert sys.argv[4] in {"mipmapped", "non_mipmapped"}
is_mipmapped = sys.argv[4] == "mipmapped" is_mipmapped = sys.argv[4] == "mipmapped"
out_file = sys.argv[5] out_file = sys.argv[5]
ref_file = sys.argv[6] if len(sys.argv) > 6 else None
convert = color_format.from_string(format) convert = color_format.from_string(format)
@ -145,6 +169,11 @@ def main():
write_mips(f, im, is_twiddled, convert) write_mips(f, im, is_twiddled, convert)
else: else:
write_mip(f, im, is_twiddled, convert) write_mip(f, im, is_twiddled, convert)
"""
if ref_file is not None:
unconvert = unconvert_color_format.from_string(format)
write_png_reference(im.size, ref_file, unconvert, colors)
"""
else: else:
assert False assert False
pixels = list(im.convert("P").getdata()) pixels = list(im.convert("P").getdata())

View File

@ -47,8 +47,8 @@ def parse(s):
sign = -1 if s.startswith('-') else 1 sign = -1 if s.startswith('-') else 1
s = s.removeprefix('-') s = s.removeprefix('-')
integer, fraction = s.split('.') integer, fraction = s.split('.')
assert all(c in string.digits for c in integer), integer assert all(c in string.digits for c in integer), (integer, s)
assert all(c in string.digits for c in fraction), fraction assert all(c in string.digits for c in fraction), (fraction, s)
assert len(integer) > 0 and len(fraction) > 0, s assert len(integer) > 0 and len(fraction) > 0, s
point = 10 ** len(fraction) point = 10 ** len(fraction)
value = int(integer) * point + int(fraction) value = int(integer) * point + int(fraction)
@ -58,6 +58,18 @@ def parse(s):
point point
) )
def from_float(f):
sign = -1 if f < 0 else 1
f = f * sign
point = 10 ** 6
value = int(f * point)
return FixedPoint(
sign,
value,
point
)
def equal(a, b): def equal(a, b):
epsilon = 0.00001 epsilon = 0.00001
return (a - b) < epsilon return (a - b) < epsilon

View File

@ -25,7 +25,7 @@ def render_face(face):
yield "}}," yield "}},"
def render_faces(prefix, name, faces): def render_faces(prefix, name, faces):
yield f"union {name} {prefix}_{name}[] = {{" yield f"const union {name} {prefix}_{name}[] = {{"
for face in faces: for face in faces:
yield from render_face(face) yield from render_face(face)
yield "};" yield "};"
@ -42,9 +42,9 @@ def unit_vector(vec):
z = vec.z.to_float() z = vec.z.to_float()
norm = math.sqrt(x ** 2 + y ** 2 + z ** 2) norm = math.sqrt(x ** 2 + y ** 2 + z ** 2)
return type(vec)( return type(vec)(
fixed_point.parse(f"{x / norm:f}"), fixed_point.from_float(x / norm),
fixed_point.parse(f"{y / norm:f}"), fixed_point.from_float(y / norm),
fixed_point.parse(f"{z / norm:f}") fixed_point.from_float(z / norm)
) )
def xyz(vec): def xyz(vec):
@ -113,7 +113,7 @@ def render_object(prefix, object_name, d, material):
yield f".quadrilateral_count = {quadrilateral_count}," yield f".quadrilateral_count = {quadrilateral_count},"
if material is None: if material is None:
yield f".material = -1,", yield f".material = -1,"
else: else:
yield f".material = {prefix}_{material.name}," yield f".material = {prefix}_{material.name},"