{"ok":true,"site":{"host":"urbanlama.github.io","url":"https://urbanlama.github.io/webmcp-character-animation/","type":"live","desc":"Animate a rigged 3D character with an AI agent","tools":[{"name":"describe_world","kind":"answer","impl":"imperative","description":"Sagt, wie die Welt liegt: welche Achse oben ist, wo vorne ist, auf welcher Hoehe der Boden liegt, wie gross die Figur ist. Enthaelt ausserdem eine Kurzanleitung, wie in dieser Seite gearbeitet wird. Braucht ein geladenes Modell.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{},"required":[]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"describe_rig","kind":"answer","impl":"imperative","description":"Die Gelenkliste. Nennt jedes vermessene Gelenk mit seinen Kanaelen, deren Grenzwerten in Grad und der Richtung, in die ein positiver Wert wirkt. DIE KANALNAMEN SIND JE GELENK VERSCHIEDEN und kommen aus der Vermessung: die Schulter hat andere als das Knie. Ohne diesen Aufruf sind set_pose und set_joint Raten. Nennt ausserdem die Rollen (foot_l, hand_r, ...) mit ihrem Knochen und der Konfidenz.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"detail":{"type":"boolean","description":"true liefert zusaetzlich Achsen, Vorzeichenquellen und Messbelege; die Antwort wird dann sehr gross. Ohne Angabe die Kompaktfassung."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"describe_body","kind":"answer","impl":"imperative","description":"Das gemessene Koerperprofil: Segmente mit Radius in Metern und Masse in Kilogramm, Fusssohlenpunkte, Ruheabstaende zwischen Koerperteilen. Fuer Reichweiten und Standflaechen. Zum blossen Setzen von Haltungen nicht noetig.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{},"required":[]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"probe_joint","kind":"act","impl":"imperative","description":"Probiert einen einzelnen Gelenkkanal aus: beugt ihn um den angegebenen Winkel und liefert Vorher und Nachher als Bild. Zum Nachsehen, in welche Richtung ein Kanal wirkt, wenn die Angabe aus describe_rig nicht reicht. Ohne channel wird der erste gemessene Kanal des Gelenks genommen; die Antwort sagt, welcher es war und welche es sonst noch gibt. Aendert die Timeline nicht.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"joint":{"type":"string","description":"Gelenkname aus describe_rig, z. B. hip_l"},"angleDeg":{"type":"number","minimum":-90,"maximum":90,"description":"Winkel in Grad, -90 bis 90"},"channel":{"type":"string","description":"optional: Kanalname dieses Gelenks aus describe_rig, z. B. flex. Die Namen sind je Gelenk verschieden - hip_l hat flex, arm_l hat lift. Fehlt die Angabe, wird der erste gemessene Kanal genommen"}},"required":["joint","angleDeg"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"set_intent","kind":"act","impl":"imperative","description":"Legt fest, woran die fertige Bewegung gemessen wird - was am Ende zutreffen muss. Wird sofort uebernommen, ohne Rueckfrage. Jedes Kriterium braucht seine Pflichtfelder: rotation {part, axis, minDeg oder maxDeg}, airtime {minSek oder maxSek}, travel {part, richtung, minHoehe oder maxHoehe}, contact_change {foot, von, bis}, clearance {partA, partB, minAnteil oder maxAnteil}, part_height {part, minAnteil oder maxAnteil}, part_speed {part, minHoeheProSek oder maxHoeheProSek}. WICHTIG: part ist ein KNOCHENNAME aus describe_rig, keine Rolle. Laengen in Anteilen der Koerperhoehe, Winkel in Grad, Zeiten in Sekunden.","inputSchema":{"type":"object","properties":{"checks":{"type":"array","minItems":1,"maxItems":20,"description":"Kriterien, je eines der 7 Arten: rotation, airtime, travel, contact_change, clearance, part_height, part_speed","items":{"type":"object","description":"Ein Kriterium. Welche Felder es braucht, haengt von kind ab — die Pflichtfelder stehen bei jedem Feld unten und in der Werkzeugbeschreibung.","properties":{"kind":{"type":"string","enum":["rotation","airtime","travel","contact_change","clearance","part_height","part_speed"]},"part":{"type":"string","description":"KNOCHENNAME aus describe_rig, keine Rolle. Pflicht bei rotation, travel, part_height, part_speed."},"axis":{"type":"string","enum":["x","y","z"],"description":"Drehachse. Pflicht bei rotation."},"minDeg":{"type":"number","description":"Untergrenze in Grad. rotation: minDeg oder maxDeg."},"maxDeg":{"type":"number","description":"Obergrenze in Grad. rotation: minDeg oder maxDeg."},"minSek":{"type":"number","description":"Untergrenze in Sekunden. airtime: minSek oder maxSek."},"maxSek":{"type":"number","description":"Obergrenze in Sekunden. airtime: minSek oder maxSek."},"richtung":{"type":"array","items":{"type":"number"},"minItems":3,"maxItems":3,"description":"Richtungsvektor [x, y, z], KEIN Wort wie \"hoch\". Pflicht bei travel."},"minHoehe":{"type":"number","description":"Untergrenze in Koerperhoehen. travel: minHoehe oder maxHoehe."},"maxHoehe":{"type":"number","description":"Obergrenze in Koerperhoehen. travel: minHoehe oder maxHoehe."},"foot":{"type":"string","description":"Fussrolle, z. B. foot_l. Pflicht bei contact_change."},"von":{"type":"integer","description":"Fruehester Frame, in dem der Fuss abheben darf. Pflicht bei contact_change."},"bis":{"type":"integer","description":"Spaetester Frame, in dem der Fuss abheben darf; von..bis ist ein Fenster. Pflicht bei contact_change."},"partA":{"type":"string","description":"erstes Segment. Pflicht bei clearance."},"partB":{"type":"string","description":"zweites Segment. Pflicht bei clearance."},"minAnteil":{"type":"number","description":"Untergrenze als Anteil der Koerperhoehe."},"maxAnteil":{"type":"number","description":"Obergrenze als Anteil der Koerperhoehe."},"minHoeheProSek":{"type":"number","description":"Untergrenze in Koerperhoehen je Sekunde."},"maxHoeheProSek":{"type":"number","description":"Obergrenze in Koerperhoehen je Sekunde."},"from":{"type":"integer","description":"Startframe des Messfensters, optional."},"to":{"type":"integer","description":"Endframe des Messfensters, optional."}},"required":["kind"]}}},"required":["checks"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"set_duration","kind":"act","impl":"imperative","description":"Legt fest, wie lang die Bewegung ist, in Frames. Muss vor jedem Setzen von Haltungen oder Phasen kommen; ohne Laenge weisen die anderen Werkzeuge ab. Die Framerate steht in der Antwort. Ändert NICHTS an bestehenden Haltungen — für einen sauberen Neuanfang vor der nächsten Bewegung gibt es clear_motion.","inputSchema":{"type":"object","properties":{"frameCount":{"type":"integer","minimum":12,"maximum":600,"description":"Anzahl Frames, 12 bis 600"}},"required":["frameCount"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"clear_motion","kind":"act","impl":"imperative","description":"Löscht die gesamte Bewegung und macht die Timeline leer: alle gesetzten Haltungen (set_pose, set_joint), alle Phasen, alle Fußanker (hold_foot) und die gesetzte Absicht (set_intent). Modell, Vermessung und Rollen bleiben — die Länge der Timeline (set_duration) bleibt auch. Für eine NEUE Bewegung: erst clear_motion, dann Haltungen setzen. Ohne ihn erbst du alle Schlüsselbilder der vorigen Bewegung, auch auf Frames, die du nie anfasst.","inputSchema":{"type":"object","properties":{},"required":[]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"set_joint","kind":"act","impl":"imperative","description":"EBENE 1, Feinschliff - traegt Gelenkwinkel in einem Frame NACH, ohne die uebrigen Kanaele anzufassen. Das ist der Unterschied zu set_pose: dort ist das Schluesselbild die ganze Haltung, hier bleibt alles Ungenannte stehen. MEHRERE KANAELE IN EINEM AUFRUF: nimm joints wie bei set_pose, also {frame, joints:{arm_l:{lift:-30,swing:68}, arm_r:{lift:-30,swing:68}}}. Ein einzelner Kanal geht weiterhin mit {frame, joint, channel, angleDeg}. Rufe NICHT viermal hintereinander fuer denselben Frame auf - dafuer gibt es joints. Eine ganze Haltung setzt man mit set_pose. Gelenk- und Kanalnamen kommen aus describe_rig; Werte ausserhalb der gemessenen Gelenkgrenze werden beim Loesen geklemmt und gemeldet. Auf einem Frame OHNE Haltung entsteht dabei ein neues Schluesselbild - es traegt nur diesen einen Kanal und keine Hoehe. Zwischen zwei gesetzten Hoehen (Sprung, Salto) gilt dort weiter die gesetzte Bahn; steht die Figur an dieser Stelle am Boden, setze die Hoehe mit set_pose ausdruecklich.","inputSchema":{"type":"object","properties":{"frame":{"type":"integer","minimum":0},"joints":{"type":"object","description":"MEHRERE Kanaele auf einmal: Gelenkname auf Kanalname auf Grad, z. B. {\"arm_l\": {\"lift\": -30, \"swing\": 68}}. Nicht genannte Kanaele des Frames bleiben unveraendert. Statt joint/channel/angleDeg zu verwenden.","additionalProperties":{"type":"object","additionalProperties":{"type":"number","minimum":-180,"maximum":180}}},"joint":{"type":"string","description":"Gelenkname aus describe_rig (Einzelkanal-Weg)"},"angleDeg":{"type":"number","minimum":-180,"maximum":180,"description":"Winkel in Grad"},"channel":{"type":"string","description":"Kanalname des Gelenks, z. B. bend, lift, flex, shrug — welche es an welchem Gelenk gibt, sagt describe_rig"}},"required":["frame"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"set_pose","kind":"act","impl":"imperative","description":"EBENE 1, DER HAUPTWEG - setzt eine ganze Koerperhaltung auf einen Frame: alle Gelenke in einem Aufruf, so wie ein Animator ein Schluesselbild setzt. So arbeitet man hier: mehrere Haltungen auf verschiedene Frames setzen; dazwischen wird beim Loesen ueberblendet, weich oder linear (ease). BODEN: die Figur steht immer auf dem Boden, solange du keine Hoehe setzt - der Loeser senkt die Wurzel je Frame so ab, dass der tiefste Punkt auf der Bodenebene liegt (Hocke, Stand, Schritt brauchen kein root). Eine Zahl in root.pos[1] hebt sie an (Sprung, Flug); unter den Boden geht es nie, zu tief Gesetztes wird angehoben und gemeldet. Die Antwort sagt dir mit Zahl, ob sie steht, schwebt oder angehoben wurde. Danach mit look ansehen und mit describe_pose nachmessen. Die angegebenen Gelenke ERSETZEN die Haltung dieses Frames, und das Schluesselbild ist die GANZE Haltung: jeder Kanal, den du hier nicht nennst, steht auf diesem Frame in der Ruhelage (0). Willst du einen Winkel behalten, nenne ihn wieder. set_joint dagegen ist ein Nachtrag und laesst die uebrigen Kanaele in Ruhe. Gelenk- und Kanalnamen kommen aus describe_rig und sind je Gelenk verschieden.","inputSchema":{"type":"object","properties":{"frame":{"type":"integer","minimum":0,"description":"Frame, auf dem die Haltung sitzt"},"joints":{"type":"object","description":"Gelenkname auf Kanal auf Grad, z. B. {\"arm_l\": {\"lift\": 70, \"swing\": 10}, \"elbow_l\": {\"bend\": 80}} — welche Gelenke und Kanäle es gibt, sagt describe_rig"},"root":{"type":"object","description":"WO die Figur steht und wohin sie schaut. Ohne root bleibt sie an ihrem Ort und steht auf dem Boden. {pos: [x, y, z]} in Metern im Weltsystem aus describe_world; y = null heisst \"auf dem Boden\" (der Loeser rechnet die Hoehe), eine Zahl in y ist eine feste Hoehe. {turnGrad: Zahl} dreht die ganze Figur um die Hochachse. Ein Schritt: pos [x, null, z] wandert entlang der Blickrichtung, die Hoehe bleibt am Boden. Ein Sprung: Absprungframe mit ease \"wurf\" (y = null: vom Boden weg, oder eine Zahl), Landeframe mit y = null. Flugdauer und Scheitelhoehe haengen zusammen: der Abstand der beiden Frames bestimmt, wie hoch die Parabel steigt. Flugposen dazwischen (Tuck, Drehung) OHNE pos setzen - sie folgen der Wurfbahn; drehGrad darf dabei stehen. Eine Hoehe im Flug teilt die Parabel in zwei Boegen mit Knick, den validate als Ballistikfehler meldet. Zwischen gesetzten Frames wird die Wurzel wie alles andere ueberblendet.","properties":{"pos":{"type":"array","items":{"type":["number","null"]},"minItems":3,"maxItems":3,"description":"Position des Beckens [x, y, z] in Metern; y = null stellt die Figur auf den Boden"},"turnGrad":{"type":"number","description":"Kurzform fuer drehGrad.y — Drehung um die Hochachse in Grad"},"drehGrad":{"type":"object","description":"Drehung der ganzen Figur in Grad, je Achse. x = Salto vorwaerts/rueckwaerts (Nicken), y = Drehung im Stand (Gieren), z = seitliches Kippen (Rollen). Ein Rueckwaertssalto ist x von 0 auf -360 ueber die Flugphase; eine halbe Drehung im Stand ist y von 0 auf 180. Wird zwischen Schluesselbildern ueberblendet, Achse fuer Achse — volle Umdrehungen bleiben dabei volle Umdrehungen.","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}}}},"ease":{"type":"string","enum":["smooth","linear","hold","wurf"],"description":"Übergang zum nächsten gesetzten Frame. \"wurf\" ist der freie Fall: der SCHWERPUNKT folgt exakt der Wurfparabel - also genau die Groesse, die die Ballistikpruefung misst. Auch wenn sich die Pose im Flug aendert (Salto, Hocke, Schwungbein), wandert der Schwerpunkt dann nicht gegenueber der Bahn: der Loeser rechnet die Wurzelhoehe je Frame dazu. Die y-Werte, die du an den Schluesselbildern setzt, bleiben WURZELHOEHEN und werden genau getroffen. Nimm ihn fuer die Flugphase - dann genuegen zwei Schluesselbilder fuer den ganzen Flug, und die Ballistikpruefung ist still. Sonst einer von 4: smooth, linear, hold, wurf; ohne Angabe smooth"}},"required":["frame","joints"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"measure","kind":"act","impl":"imperative","description":"DEIN MESSGERAET - du richtest es selbst aus. Statt fertiger Urteile bekommst du sieben Grundmessungen, die du beliebig kombinierst, um zu pruefen, ob eine Haltung stimmt. Beispiel Hocke: steht das Knie vor dem Zeh (abstand_vorne knee_l/toe_l), neigt sich der Rumpf nach vorne (neigung pelvis/neck), sitzt die Huefte hinter dem Knoechel (abstand_vorne pelvis/ankle_l)? Beispiel Schritt: wandert der Fuss (tempo), bleibt der andere stehen? Jede Bewegung braucht andere Fragen - stell sie. Koerperteile sind Rollennamen aus describe_rig, dazu \"com\" fuer den Schwerpunkt und \"sole_l\" / \"sole_r\" fuer den tiefsten Sohlenpunkt je Fuss - damit misst du, ob ein Fuss auf dem Boden steht (hoehe sole_l = 0). Der Fussknochen selbst sitzt Zentimeter ueber der Sohle. Alle Laengen in Metern, Winkel in Grad.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"frame":{"type":"integer","minimum":0,"description":"Frame, in dem gemessen wird. Fuer mehrere Frames nimm frames."},"frames":{"type":"array","items":{"type":"integer","minimum":0},"minItems":1,"maxItems":20,"description":"Mehrere Frames auf einmal, 1 bis 20. Dieselben Fragen werden auf jeden davon angewendet - so bekommst du einen Verlauf in EINEM Aufruf statt einem Aufruf je Frame. Ersetzt frame."},"fragen":{"type":"array","minItems":1,"maxItems":20,"description":"Was du wissen willst. Je Frage {art, a, ...}: hoehe {a} - Hoehe ueber dem Boden. abstand {a, b} - Luftlinie zwischen zwei Teilen. abstand_vorne {a, b} - wie weit a vor b liegt, entlang der Blickrichtung; negativ heisst dahinter. abstand_seite {a, b} - wie weit a neben b liegt. abstand_hoch {a, b} - wie weit a ueber b liegt. winkel {a, b, c} - Winkel bei b zwischen den Strecken zu a und c. neigung {a, b} - wie weit die Strecke a nach b von der Senkrechten abweicht; 0 heisst lotrecht, 90 heisst waagerecht. tempo {a, bisFrame} - Weg pro Sekunde zwischen diesem und jenem Frame. Optional name: dein eigener Name fuer die Messung.","items":{"type":"object","properties":{"art":{"type":"string","enum":["hoehe","abstand","abstand_vorne","abstand_seite","abstand_hoch","winkel","neigung","tempo"]},"a":{"type":"string","description":"Koerperteil, Rollenname oder \"com\""},"b":{"type":"string","description":"zweites Koerperteil, wo die Art es braucht"},"c":{"type":"string","description":"drittes Koerperteil, nur bei winkel"},"bisFrame":{"type":"integer","description":"Zielframe, nur bei tempo"},"name":{"type":"string","description":"eigener Name der Messung"}},"required":["art","a"]}}},"required":["fragen"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"list_poses","kind":"answer","impl":"imperative","description":"Zeigt alle gesetzten Haltungen mit ihrem Frame, der Zahl der Gelenke und ob eine Wurzelbewegung dabei ist. Der Ueberblick ueber die eigene Arbeit: ohne ihn weisst du nicht, was du schon gesetzt hast, und kannst nichts umsortieren.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"move_pose","kind":"act","impl":"imperative","description":"Verschiebt eine gesetzte Haltung auf einen anderen Frame — der Schritt, mit dem du den zeitlichen Ablauf zurechtrueckst, nachdem die Haltungen stehen. Kommt eine Bewegung zu frueh, ruecke sie nach hinten, statt sie neu zu bauen. Auf dem Zielframe darf noch keine Haltung liegen.","inputSchema":{"type":"object","properties":{"von":{"type":"integer","minimum":0,"description":"Frame, auf dem die Haltung jetzt liegt"},"nach":{"type":"integer","minimum":0,"description":"Frame, auf den sie soll"}},"required":["von","nach"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"delete_pose","kind":"transact","impl":"imperative","description":"Loescht eine gesetzte Haltung. Danach wird an dieser Stelle zwischen den benachbarten Haltungen durchgeblendet, als haette es sie nie gegeben. Fuer Haltungen, die sich als falsch erwiesen haben — undo nimmt nur den letzten Schritt zurueck.","inputSchema":{"type":"object","properties":{"frame":{"type":"integer","minimum":0,"description":"Frame, dessen Haltung weg soll"}},"required":["frame"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"describe_pose","kind":"answer","impl":"imperative","description":"Sagt in Zahlen, wie die Figur in einem Frame steht: Weltpositionen der Koerperteile in Metern, Schwerpunkt, Bodenkontakt, bodenabstand_m (tiefster Punkt ueber dem Boden, 0 = steht, negativ = im Boden), wurzelhoehe (ob Boden, dein root.pos oder eine Anhebung die Hoehe bestimmt hat, mit Betrag), sohlen_m je Fuss — dort steht neben der tiefsten Sohle GETRENNT die Hoehe von ferse und spitze sowie stand: flach, zehenstand, fersenstand oder frei. Nur so siehst du, WIE der Fuss aufliegt: eine Figur auf Zehenspitzen meldet als tiefsten Punkt ebenfalls 0, waehrend ihre Ferse handbreit in der Luft haengt. Dazu, ob der Frame eine gesetzte Haltung ist oder eine Ueberblendung. Dazu winkel_grad — die gefahrenen Gelenkwinkel je Gelenk und Kanal in Grad, auch auf ueberblendeten Frames — und gesetzteWinkel_grad, nur die, die auf diesem Frame gesetzt wurden. Damit liest du deine Haltung in deiner eigenen Sprache zurueck. Das Gegenstueck zu look: dort das Bild, hier die Zahlen.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"frame":{"type":"integer","minimum":0,"description":"Frame, dessen Haltung gefragt ist"}},"required":["frame"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"undo","kind":"act","impl":"imperative","description":"Nimmt die letzte Aenderung zurueck, egal von welchem Werkzeug. Eine einzelne Haltung loescht du mit delete_pose, verschiebst sie mit move_pose und ueberschreibst sie, indem du set_pose erneut auf denselben Frame aufrufst - dafuer brauchst du undo nicht.","inputSchema":{"type":"object","properties":{},"required":[]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"validate","kind":"act","impl":"imperative","description":"Prueft die gesamte Bewegung und meldet, was nicht stimmt: Bodendurchdringung, Selbstdurchdringung, verletzte Gelenkgrenzen, rutschende Fuesse, Gleichgewicht, Flugbahn - jeweils mit Frame und Betrag in Metern oder Grad. Dazu die mit set_intent gesetzten Kriterien. Liefert immer einen Bildstreifen mit. Braucht gesetzte Kriterien.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{},"required":[]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"trace","kind":"act","impl":"imperative","description":"Zeigt den ABLAUF der Bewegung als Folge von drei GROSSEN Einzelbildern in einer Antwort - gleichmaessig ueber die Timeline verteilt, in derselben Kamera, wie ein Daumenkino zu lesen. Damit siehst du, ob eine Bewegung flieszt, ohne jeden Frame einzeln anzufordern. Willst du einen Abschnitt genauer sehen, gib von und bis an - dann liegen die drei Bilder enger beieinander. Kamera wie bei look. RUFE DAS AUF, BEVOR DU EINE BEWEGUNG ABGIBST: ein einzelner Frame sagt nichts darueber, wie die Bewegung laeuft.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"von":{"type":"integer","minimum":0,"description":"Erster Frame des Abschnitts. Ohne Angabe der Anfang der Timeline."},"bis":{"type":"integer","minimum":0,"description":"Letzter Frame des Abschnitts. Ohne Angabe das Ende der Timeline."},"richtung_grad":{"type":"number","minimum":0,"maximum":359,"description":"Woher die Kamera blickt: 0 von vorn, 90 von links, 180 von hinten, 270 von rechts. Standard 30. In allen drei Bildern gleich."},"hoehe_grad":{"type":"number","minimum":-89,"maximum":90,"description":"Wie hoch die Kamera steht: 0 auf Augenhoehe, 90 von oben. Standard 10. Fuer Schritte und Fussstellung ist 90 gut."},"ziel":{"type":"string","description":"Worauf die Kamera zielt: \"figur\" (Standard) oder ein Gelenk aus describe_rig. Mit weite \"nah\" verfolgst du ein Gelenk durch die Zeit."},"weite":{"type":"string","enum":["ganz","halb","nah"],"description":"Wie viel im Bild ist: \"ganz\" die Figur (Standard), \"halb\" ein Koerperteil, \"nah\" ein Gelenk."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"look","kind":"act","impl":"imperative","description":"Fotografiert EINEN Frame und liefert EIN grosses Bild, annotiert mit Bodengitter, Hoehenleiste, Schwerpunkt, Kontaktpunkten und Stuetzflaeche. Du richtest die Kamera selbst: Blickrichtung, Blickhoehe, worauf sie zielt und wie nah sie herangeht. Ohne Angabe steht sie schraeg von vorn und zeigt die ganze Figur. DEN VERLAUF EINER BEWEGUNG SIEHST DU, INDEM DU MEHRMALS AUFRUFST - je Frame ein Bild, z. B. 0, 6, 12, 18. Bei gleicher weite ist der Massstab in jedem Bild derselbe und das Bodengitter steht fest im Raum, die Bilder sind also untereinander vergleichbar. Einen Fehler an einem Gelenk findest du mit ziel und weite: nah heran, dann siehst du ihn. Braucht keine Vorbereitung und keine Kriterien - loest selbst. NACH JEDER AENDERUNG AUFRUFEN: Zahlen allein zeigen nicht, ob eine Bewegung richtig aussieht.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"frame":{"type":"integer","minimum":0,"description":"Der Frame, den du sehen willst. Ein Aufruf ist ein Bild; fuer eine Abfolge rufe mehrmals mit derselben Kamera auf."},"richtung_grad":{"type":"number","minimum":0,"maximum":359,"description":"Woher die Kamera blickt, um die Figur herum: 0 von vorn, 90 von links, 180 von hinten, 270 von rechts. Standard 30 - schraeg von vorn, dort verdeckt keine Koerperseite die andere."},"hoehe_grad":{"type":"number","minimum":-89,"maximum":90,"description":"Wie hoch die Kamera steht: 0 auf Augenhoehe, 90 senkrecht von oben (Draufsicht, gut fuer Stand und Fussstellung), negativ von unten. Standard 10."},"ziel":{"type":"string","description":"Worauf die Kamera zielt: \"figur\" fuer die ganze Figur (Standard) oder ein GELENK aus describe_rig - dieselben Namen, mit denen du set_pose fuetterst, z. B. \"knee_l\", \"arm_r\", \"spine\". Zusammen mit weite \"nah\" faehrst du damit an das Gelenk heran, das du gerade verstellt hast."},"weite":{"type":"string","enum":["ganz","halb","nah"],"description":"Wie viel im Bild ist, gemessen an der Koerperhoehe: \"ganz\" die ganze Figur (Standard), \"halb\" etwa ein Koerperteil wie Oberkoerper oder Bein, \"nah\" ein Gelenk mit seinen Nachbarn - dort erkennst du Durchdringung und Ueberbeugung."}},"required":["frame"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"hold_foot","kind":"act","impl":"imperative","description":"Nagelt einen Fuss ueber einen Frame-Bereich fest: er bleibt da stehen, wo er zu Beginn des Bereichs steht (auf dem Boden, wenn du keine Hoehe gesetzt hast), auch wenn sich das Becken bewegt. Der Loeser rechnet die Beinkette dafuer selbst - du musst keine Gelenkwinkel dafuer suchen; ohne gesetzte Hoehe darf das Becken dabei sinken, so wie beim Gehen. GENAU DAS BRAUCHST DU FUER SCHRITTE: der Standfuss bleibt fest, waehrend die Figur ueber ihn hinweg wandert, der andere schwingt frei - und den haeltst DU ueber dem Boden (Knie beugen, Huefte heben); steckt er im Boden, wird die Figur angehoben und der Anker verfehlt, die Antwort sagt es. Ohne Anker rutschen die Fuesse mit dem Becken mit und validate meldet es. Mehrere Anker sind erlaubt; foot \"beide\" nagelt beide Fuesse fest. EINE SPANNE AENDERST DU MIT EINEM AUFRUF: ruf hold_foot mit demselben Fuss und der neuen Spanne, sie ersetzt jede alte, die sie beruehrt - kein remove noetig. Der Fuss bleibt dabei an dem Ort, an dem der alte Anker ihn hielt, auch wenn der Anfang wandert. Setze sie ERST, wenn die Haltungen stehen: sie wirken nach den Haltungen. Deine gesetzten Beinwinkel bleiben dabei stehen; reicht der Rest der Kette nicht bis zum Anker, gibt die Huefte nach und der Bericht nennt den Fuss mit dem Betrag in Metern, der fehlt.","inputSchema":{"type":"object","properties":{"foot":{"type":"string","description":"Fussrolle aus describe_rig: foot_l, foot_r oder beide"},"von":{"type":"integer","minimum":0,"description":"erster Frame, in dem der Fuss steht"},"bis":{"type":"integer","minimum":0,"description":"letzter Frame, in dem er steht"},"remove":{"type":"boolean","description":"true entfernt alle Anker dieses Fusses in diesem Bereich"}},"required":["foot","von","bis"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"},{"name":"export_clip","kind":"act","impl":"imperative","description":"Schreibt die fertige Bewegung als glTF heraus, mit Wurzelbewegung, in Metern und Y-oben. Letzter Schritt, wenn die Bewegung steht.","inputSchema":{"type":"object","properties":{},"required":[]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/webmcp-character-animation/"}],"category":"Developer Tools","apiSurface":"spec","toolCount":20}}