clanker-hackathon / app /appearance.py
deucebucket's picture
clanker hackathon gradio entry (verification copy)
ecca2a3 verified
Raw
History Blame Contribute Delete
1.59 kB
"""Pure continuous mapping: mood[7] (V A D U G W I, 0-255) -> render params.
Hue flows smoothly with valence (red->orange->yellow->green); arousal sets
vividness and eye-openness; face is parametric (mouth curve, eye size, brow tilt)."""
from __future__ import annotations
def _lerp(x, x0, x1, y0, y1):
if x1 == x0:
return y0
t = max(0.0, min(1.0, (x - x0) / (x1 - x0)))
return y0 + (y1 - y0) * t
def _norm(x): # 0..255 -> 0..1
return max(0, min(255, x)) / 255.0
def _face(v: int, a: int) -> str:
"""Region string for voice/emoticon lookup (backward compatibility)."""
POS, NEG = 150, 106
if v >= POS:
return "excited" if a >= 170 else "content"
if v <= NEG:
return "angry" if a >= 128 else "sad"
return "neutral"
def mood_to_appearance(mood: list[int]) -> dict:
v, a, d, u, g, w, i = mood
return {
"hue": round((_lerp(v, 0, 128, 8.0, 48.0) if v <= 128 else _lerp(v, 128, 255, 48.0, 125.0)), 1),
"saturation": round(_lerp(a, 0, 255, 30.0, 95.0), 1),
"lightness": round(_lerp(a, 0, 255, 52.0, 70.0), 1),
"aura": round(_lerp(a, 0, 255, 0.12, 0.7), 2),
"scale": round(_lerp(d, 0, 255, 0.85, 1.18), 3),
"droop": round(_norm(g), 2),
"lean": round((i - 128) / 128.0, 2),
"face": {
"mouth": round((v - 128) / 128.0, 2), # +smile … -frown
"eye": round(_lerp(a, 0, 255, 0.5, 1.4), 2), # openness
"brow": round(((128 - v) / 128.0) * _norm(a), 2), # angry = low V + high A
},
"mood": mood,
}