# vr_decal_atlas.py - white stencil markings for the veiled robot (system Python + PIL). # Generic unit codes only: the references' maker name and logos are not copied. import json, os from PIL import Image, ImageDraw, ImageFont OUT = os.path.join(os.path.dirname(__file__), "..", "textures") S = 1024 im = Image.new("RGBA", (S, S), (255, 255, 255, 0)); d = ImageDraw.Draw(im) F = r"C:\Windows\Fonts\bahnschrift.ttf" def font(px): return ImageFont.truetype(F, px) W = (255, 255, 255, 255) R = {} # A boxed glyph (the small square badges on the chest) d.rectangle((10, 10, 190, 190), outline=W, width=12); d.text((100, 104), "7", font=font(130), fill=W, anchor="mm") R["badge"] = (0, 0, 200, 200) # B unit band d.text((512, 290), "UNIT 07", font=font(120), fill=W, anchor="mm"); R["unit"] = (220, 220, 804, 360) # C small code d.text((300, 430), "R7-341J", font=font(80), fill=W, anchor="mm"); R["code"] = (60, 385, 540, 475) # D round emblem: ring, cross hairs, two arcs cx, cy, r = 810, 570, 170 d.ellipse((cx - r, cy - r, cx + r, cy + r), outline=W, width=14) d.ellipse((cx - 90, cy - 90, cx + 90, cy + 90), outline=W, width=10) d.line((cx - r + 20, cy, cx + r - 20, cy), fill=W, width=10); d.line((cx, cy - r + 20, cx, cy + r - 20), fill=W, width=10) R["emblem"] = (cx - r - 10, cy - r - 10, cx + r + 10, cy + r + 10) # E chevrons for i in range(6): x = 30 + i * 90 d.polygon([(x, 520), (x + 45, 520), (x + 85, 580), (x + 45, 640), (x, 640), (x + 40, 580)], fill=W) R["chevron"] = (20, 510, 580, 650) # F tick ruler + small text for i in range(21): x = 40 + i * 26; h = 60 if i % 5 == 0 else 32 d.rectangle((x, 700, x + 7, 700 + h), fill=W) d.text((300, 800), "MAX 340 BAR", font=font(54), fill=W, anchor="mm"); R["ruler"] = (30, 690, 600, 840) # G vertical stack "07" in a frame d.rectangle((650, 790, 1000, 1000), outline=W, width=10); d.text((825, 895), "07", font=font(150), fill=W, anchor="mm") R["frame07"] = (640, 780, 1010, 1010) # H dark slot cut-outs (the references' plates are covered in them), a pair, a seam line D = (22, 24, 22, 255); L_ = (95, 98, 92, 255) def slot(x0, y0, x1, y1): d.rounded_rectangle((x0, y0, x1, y1), radius=(y1 - y0) // 3, fill=D) d.line((x0 + 6, y1 - 2, x1 - 6, y1 - 2), fill=L_, width=3) # lit lower lip slot(240, 25, 400, 75); R["slot"] = (232, 17, 408, 83) slot(430, 25, 560, 75); slot(590, 25, 720, 75); R["slotpair"] = (422, 17, 728, 83) d.rectangle((240, 100, 1000, 106), fill=D); R["seam"] = (236, 96, 1004, 110) # I shoulder sticker: light square, dark ring emblem (generic) d.rounded_rectangle((760, 120, 940, 300), radius=14, fill=(200, 202, 196, 255)) d.ellipse((790, 150, 910, 270), outline=D, width=12); d.ellipse((828, 188, 872, 232), fill=D) R["sticker"] = (756, 116, 944, 304) # J latch plate: dark frame, a lighter handle bar d.rounded_rectangle((20, 870, 180, 1010), radius=12, fill=D) d.rounded_rectangle((55, 905, 145, 935), radius=6, fill=(70, 72, 68, 255)); R["latch"] = (16, 866, 184, 1014) # K triangular cut-outs (forearm tops, 1.jpg), L bolt head, M short seam d.polygon([(230, 1010), (330, 1010), (330, 880)], fill=D); d.polygon([(350, 1010), (450, 1010), (350, 880)], fill=D) d.line((240, 1006, 322, 1006), fill=L_, width=3); d.line((358, 1006, 440, 1006), fill=L_, width=3) R["tris"] = (222, 872, 458, 1016) d.ellipse((480, 900, 540, 960), fill=(40, 42, 40, 255)); d.ellipse((492, 912, 528, 948), fill=(105, 108, 102, 255)) d.ellipse((500, 920, 520, 940), fill=(30, 32, 30, 255)); R["bolt"] = (476, 896, 544, 964) d.rectangle((560, 925, 900, 930), fill=D); R["seamshort"] = (556, 921, 904, 934) im.save(os.path.join(OUT, "T_VR_Decals.png")) json.dump({"size": S, "regions": R}, open(os.path.join(OUT, "T_VR_Decals.json"), "w"), indent=1) print("ok")