К содержанию
fohbook/ TouchDesigner
уверенный

Скрипты и колбэки

Execute DAT, CHOP Execute, Parameter Execute, Panel Execute: как реагировать на события, а не опрашивать их.

Колбэк — функция, которую TouchDesigner вызывает сам, когда что-то произошло. Это правильная альтернатива опросу в каждом кадре.

Операторы-колбэки

DAT Реагирует на
Execute Старт и конец кадра, старт и выход из проекта, перформ-режим
CHOP Execute Изменение значения канала, пересечение порога
Parameter Execute Изменение параметра оператора
Panel Execute События панели: клик, наведение, изменение
DAT Execute Изменение содержимого таблицы
OP Execute Создание, удаление, переименование операторов
Key / MIDI In / OSC In DAT Внешние события

CHOP Execute — самый полезный

def onValueChange(channel, sampleIndex, val, prev):
    if channel.name == 'kick' and val > 0.5:
        op('scene').par.Next.pulse()
    return

def offToOn(channel, sampleIndex, val, prev):
    debug('нажали', channel.name)
    return

Включаются нужные обработчики параметрами самого узла: Value Change, Off to On, While On, On to Off. Обязательно ограничьте набор каналов параметром Channels — иначе колбэк будет дёргаться на всех.

CHOP Execute на аудиоканале — самоубийство

Звук идёт с частотой 48 000 сэмплов в секунду. Колбэк на изменение значения такого канала вызовет Python тысячи раз за кадр. Сначала сведите сигнал к одному значению на кадр — Сглаживание.

Execute DAT

def onStart():
    op('logger').Log('проект запущен')
    return

def onFrameStart(frame):
    return

def onExit():
    op('dmx').par.active = 0
    return

onStart и onExit — правильное место для инициализации и корректного завершения: погасить свет, закрыть порты, записать в лог.

onFrameStart использовать по возможности не надо — Python в TouchDesigner.

Parameter Execute

Реагирует на изменение конкретного параметра — в том числе собственного параметра компонента. Основной способ сделать так, чтобы кнопка на панели что-то делала:

def onPulse(par):
    if par.name == 'Reset':
        op('feedback1').par.reset.pulse()
    return

Порядок и защита

  1. Колбэк выполняется внутри кадра. Всё, что в нём долго, — это пропущенный кадр.
  2. Изменение структуры сети из колбэка бывает опасно: используйте run(..., delayFrames=1).
  3. Оборачивайте рискованное в try/except и пишите ошибку в лог. Колбэк, упавший с исключением, тихо перестаёт работать — а шоу продолжается.
Один колбэк — одно решение

Не собирайте всю логику шоу в один Execute DAT. Пусть колбэк только переводит событие в вызов метода компонента (Extensions). Тогда логику можно тестировать и переиспользовать, а колбэк остаётся тонким.

рядом по смыслу