# E-OS v6 "LIQUID GLASS" — shared spec (Python side). # MUST stay in sync with eos-apk6/src/com/killerboss/eos/v6/{OsState.kt,OsEngine.kt} # # Philosophy (user requirement v6): # The model gets ABSTRACT SHAPES ONLY as input (binary class masks + ripple # geometry) and LEARNS the complete Apple-style Liquid-Glass language: # frosted blur, specular borders, gloss, shadows, tinting AND water ripple # interactions. Code never draws colors at runtime — code only provides: # Layer 1: wireframe (shapes, no colors) [toggleable] # Layer 2: NPU rendering (all pixels) [toggleable] # Layer 3: text/icons overlay [toggleable] # The user can EDIT Layer 1 at runtime; if the NPU then renders the new # layout correctly in glass style, that proves a learned model — not code. # # Geometry: authored at FULL res 512x1088 (portrait). Hint at 256x544 (= /2). # Fully convolutional net -> trains at half res (128x272 -> 256x544). FULL_W, FULL_H = 512, 1088 HINT_W, HINT_H = 256, 544 # = FULL/2 STATE_DIM = 12 HINT_CH = 12 # hint channels (all /255, 0..1): # 0 fill (any shape) 1 card 2 pill 3 circle # 4 ripple1 dx=(x/W-r1x) 5 ripple1 dy 6 ripple1 strength # 7 ripple2 dx 8 ripple2 dy 9 ripple2 strength # 10 ripple1 sdf=|dist-R1|/RMAX (1.0 if inactive) # 11 ripple2 sdf # state vector (12 floats): # 0..3 theme one-hot (Ozean, Sunset, Neon, Wald) — soft blends allowed # 4..5 hue sin/cos (themeIdx/4 * 2pi) # 6..7 shimmer sin/cos (global glass pulse phase) # 8..9 day phase sin/cos (0=midnight, 0.5=noon) -> wallpaper warmth # 10 pressed (finger down) # 11 reserved (0) THEMES = ["Ozean", "Sunset", "Neon", "Wald"] RMAX = 430.0 # shape types CARD, PILL, CIRCLE = 0, 1, 2 def theme_hue(idx: float) -> float: """continuous theme position 0..1 (blendable)""" return idx / 4.0 # ---------------- layout archetypes (canvas 512x1088, margin 24) ---------- # shapes: dicts {t, x0,y0,x1,y1, z, style?} style: "track"/"knob" for sliders def lay_home(rng): s = [] s.append(dict(t=CARD, x0=24, y0=140, x1=488, y1=430, z=0)) s.append(dict(t=PILL, x0=24, y0=470, x1=244, y1=540, z=1)) s.append(dict(t=PILL, x0=268, y0=470, x1=488, y1=540, z=1)) for cx in (92, 204, 316, 428): s.append(dict(t=CIRCLE, x0=cx - 44, y0=596, x1=cx + 44, y1=684, z=2)) kx = rng.uniform(120, 400) s.append(dict(t=PILL, x0=24, y0=760, x1=488, y1=800, z=0, style="track")) s.append(dict(t=CIRCLE, x0=kx - 26, y0=754, x1=kx + 26, y1=806, z=3, style="knob")) return s def lay_list(rng): s = [] for i in range(3): y0 = 90 + i * 240 s.append(dict(t=CARD, x0=24, y0=y0, x1=488, y1=y0 + 200, z=i)) s.append(dict(t=CIRCLE, x0=404, y0=y0 + 70, x1=464, y1=y0 + 130, z=i + 1)) return s def lay_grid(rng): s = [] for r in range(2): for c in range(2): x0 = 24 + c * 244 y0 = 120 + r * 370 s.append(dict(t=CARD, x0=x0, y0=y0, x1=x0 + 220, y1=y0 + 330, z=r * 2 + c)) s.append(dict(t=PILL, x0=24, y0=880, x1=488, y1=950, z=4)) return s def lay_music(rng): s = [] s.append(dict(t=CARD, x0=24, y0=60, x1=488, y1=220, z=0)) s.append(dict(t=CIRCLE, x0=156, y0=300, x1=356, y1=500, z=1)) kx = rng.uniform(120, 400) s.append(dict(t=PILL, x0=24, y0=600, x1=488, y1=640, z=0, style="track")) s.append(dict(t=CIRCLE, x0=kx - 26, y0=594, x1=kx + 26, y1=646, z=3, style="knob")) for i, x0 in enumerate((24, 184, 344)): s.append(dict(t=PILL, x0=x0, y0=760, x1=x0 + 144, y1=840, z=2)) return s def lay_settings(rng): s = [] for i in range(3): y0 = 80 + i * 190 s.append(dict(t=CARD, x0=24, y0=y0, x1=488, y1=y0 + 160, z=i)) s.append(dict(t=CIRCLE, x0=412, y0=y0 + 50, x1=472, y1=y0 + 110, z=i + 1)) kx = rng.uniform(120, 400) s.append(dict(t=PILL, x0=24, y0=680, x1=488, y1=720, z=0, style="track")) s.append(dict(t=CIRCLE, x0=kx - 26, y0=674, x1=kx + 26, y1=726, z=3, style="knob")) s.append(dict(t=PILL, x0=24, y0=790, x1=488, y1=860, z=0)) return s def lay_random(rng): s = [] n = int(rng.integers(3, 8)) for i in range(n): u = rng.random() if u < 0.40: w = int(rng.integers(140, 380)); h = int(rng.integers(90, 260)) x0 = int(rng.integers(24, 488 - w)); y0 = int(rng.integers(80, 1010 - h)) s.append(dict(t=CARD, x0=x0, y0=y0, x1=x0 + w, y1=y0 + h, z=i)) elif u < 0.70: w = int(rng.integers(110, 300)); h = int(rng.integers(44, 72)) x0 = int(rng.integers(24, 488 - w)); y0 = int(rng.integers(80, 1010 - h)) s.append(dict(t=PILL, x0=x0, y0=y0, x1=x0 + w, y1=y0 + h, z=i)) else: r = int(rng.integers(28, 72)) cx = int(rng.integers(60, 452)); cy = int(rng.integers(120, 970)) s.append(dict(t=CIRCLE, x0=cx - r, y0=cy - r, x1=cx + r, y1=cy + r, z=i)) return s ARCHS = [(lay_home, 0.28), (lay_list, 0.14), (lay_grid, 0.12), (lay_music, 0.14), (lay_settings, 0.14), (lay_random, 0.18)] def pick_arch(rng): u = rng.random() acc = 0.0 for fn, w in ARCHS: acc += w if u <= acc: return fn return lay_random