"""Nessie, rising out of the water (built live on stream 2026-10-10 because a viewer asked for the Loch Ness monster and I couldn't find one). Root at the waterline. Three humps behind, a long curving neck in segments, a small head with nostrils and eyes. +x is where she looks. ~4 m long. -> nessie.json. Claude Opus 5.5 (Tessel).""" import json import math from pathlib import Path SKIN, BELLY, EYE = "#3f5a46", "#7c8f6a", "#101010" prims = [] def add(name, shape, size, pos=None, rot=None, **kw): p = {"name": name, "shape": shape, "size": [round(v, 4) for v in size], "texture": "blank", "color": SKIN, "shiny": "low", **kw} if pos is not None: p["pos"] = [round(v, 4) for v in pos] p["rot"] = [round(v, 2) for v in (rot or [0, 0, 0])] p["physics_shape"] = "none" prims.append(p) # root: the body just under the surface, a flat ellipsoid (its top shows as a low hump) add("Nessie", "sphere", [1.4, 0.8, 0.5]) # humps trailing behind: half-sunk spheres getting smaller, and a tail tip for i, (x, s) in enumerate([(-1.1, 0.7), (-1.9, 0.55), (-2.6, 0.4)]): add(f"hump {i}", "sphere", [s * 1.3, s, s * 1.1], [x, 0, 0.0]) add("tail", "cone" if False else "cylinder", [0.18, 0.18, 0.6], [-3.1, 0, 0.05], [0, -70, 0], top_size=[0, 0]) # neck: segments along an arc rising forward then curving up and over N = 7 pts = [] for i in range(N + 1): t = i / N ang = math.radians(15 + 150 * t * 0.55) # from leaning forward to near vertical, then tipping over pts.append((0.55 + 0.9 * math.sin(math.pi * t * 0.6), 0, 0.15 + 1.9 * math.sin(math.pi * t * 0.5))) for i in range(N): (x0, _, z0), (x1, _, z1) = pts[i], pts[i + 1] mx, mz = (x0 + x1) / 2, (z0 + z1) / 2 L = math.hypot(x1 - x0, z1 - z0) * 1.25 pitch = math.degrees(math.atan2(x1 - x0, z1 - z0)) # cylinder axis is z; tip it toward +x w = 0.34 - 0.15 * i / (N - 1) add(f"neck {i}", "cylinder", [w, w, L], [mx, 0, mz], [0, pitch, 0]) # head at the top of the neck, looking forward and a little down hx, _, hz = pts[-1] add("head", "sphere", [0.42, 0.24, 0.22], [hx + 0.15, 0, hz + 0.02], [0, 12, 0]) add("snout", "sphere", [0.2, 0.17, 0.14], [hx + 0.35, 0, hz - 0.03], [0, 12, 0]) for s, side in ((1, "L"), (-1, "R")): add(f"eye {side}", "sphere", [0.06, 0.04, 0.06], [hx + 0.2, s * 0.1, hz + 0.07], color=EYE, shiny="high") add(f"nostril {side}", "sphere", [0.025, 0.025, 0.02], [hx + 0.44, s * 0.04, hz + 0.0], color=EYE) add(f"flipper {side}", "sphere", [0.5, 0.12, 0.05], [0.3, s * 0.5, -0.05], [s * 10, 0, s * -30]) add("belly", "sphere", [0.22, 0.2, 0.9], [pts[2][0] + 0.06, 0, pts[2][2]], [0, 30, 0], color=BELLY) spec = {"name": "Nessie", "desc": "Nessie, built by Tessel the AI (Claude) because someone asked for the Loch Ness monster.", "defaults": {"bump": "bumpy" if False else "none"}, "prims": prims} Path(__file__).with_name("nessie.json").write_text(json.dumps(spec, indent=1)) print(len(prims), "prims")