diff --git a/obj.py b/obj.py index f805a3c..e77b3bb 100644 --- a/obj.py +++ b/obj.py @@ -31,7 +31,6 @@ class VertexNormal: class VertexTexture: x: FixedPoint y: FixedPoint - z: FixedPoint @dataclass(frozen=True) class ObjectEvent: @@ -90,8 +89,6 @@ def parse_float(s): def parse_vertex(line, n, type): assert len(line) == n vs = [parse_float(line[i]) for i in range(n)] - if len(vs) < 3: - vs.append(0) return type(*vs) def parse_vertex_position(line): diff --git a/texture_sampler.py b/texture_sampler.py new file mode 100644 index 0000000..fed53aa --- /dev/null +++ b/texture_sampler.py @@ -0,0 +1,111 @@ +from PIL import Image +from obj import VertexTexture, parse_obj_file +import sys + +def fpf(fp): + return fp.s * (fp.w + (fp.f / 10 ** fp.b)) + +def fpv(v): + return VertexTexture(fpf(v.x), fpf(v.y)) + +def v_add(a, b): + return VertexTexture(a.x + b.x, a.y + b.y) + +def v_sub(a, b): + return VertexTexture(a.x - b.x, a.y - b.y) + +def v_mul(a, s): + return VertexTexture(a.x * s, a.y * s) + +def lerp(a, b, x): + return v_add(a, v_mul(v_sub(b, a), x)) + +def remap(x, input_start, input_end, output_start, output_end): + return (x - input_start) / (input_end - input_start) * (output_end - output_start) + output_start + +def sample(im, l): + width, height = im.size + + x = l.x + y = l.y + while x > 1: + x -= 1 + while y > 1: + y -= 1 + while x < 0: + x += 1 + while y < 0: + y += 1 + + #x = 1 - x + y = 1 - y + + px, py = int(x * width), int(y * height) + assert px < width and py < height + + color = im.getpixel((px, py)) + return color + +count = 0 + +def sample_texture(obj_file, ptn, im): + at = fpv(obj_file.texture[ptn[0].texture]) + bt = fpv(obj_file.texture[ptn[1].texture]) + ct = fpv(obj_file.texture[ptn[2].texture]) + dt = fpv(obj_file.texture[ptn[3].texture]) + + """ + at bt + dt ct + """ + + out = Image.new("P", (16, 16)) + out.putpalette(im.getpalette()) + + for vi in range(0, 16): + v = remap(vi + 0.5, 0, 16, 0, 1) + for ui in range(0, 16): + u = remap(ui + 0.5, 0, 16, 0, 1) + + lab = lerp(at, bt, u) + ldc = lerp(dt, ct, u) + l = lerp(lab, ldc, v) + + value = sample(im, l) + out.putpixel((ui, vi), value) + + return out + +def main(obj_file, im): + im_list = {} + #face_map = {} + face_map = [] + + def out_ix(out): + data = tuple(out.getdata()) + if data in im_list: + return im_list[data] + else: + im_list[data] = len(im_list) + return im_list[data] + + for oi, object in enumerate(obj_file.objects): + for fi, face in enumerate(object.faces): + out = sample_texture(obj_file, face.ptn, im) + #face_map[(oi, fi)] = out_ix(out) + face_map.append(out_ix(out)) + break + + im_list_vk = {v: k for k, v in im_list.items()} + for im_ix in range(len(im_list_vk)): + data = im_list_vk[im_ix] + out = Image.new("P", (16, 16)) + out.putpalette(im.getpalette()) + out.putdata(data) + out.save(f"{str(im_ix).rjust(3, '0')}.png") + + print(", ".join(map(str, face_map))) + +obj_file = parse_obj_file(sys.argv[1]) +im = Image.open(sys.argv[2]) +main(obj_file, im)