TouchDesigner Advent Calendar 2018 16日目の記事です。よろしくお願いします。
はじめに
リアルタイムで生成されるビジュアルのパラメータを変えて調整したり、気に入ったパラメータを保存したりすると思います。保存したものをプリセットとして使えたらいいなと思いつつ、Palette
> Derivative
> Techniques
> presets
が好いのかなと見てみるもあまりピンと来なかったので、自分で作ってみました。
サンプルファイル
githubにアップしましたので必要に応じて参照してください。
https://github.com/chimanaco/touchdesigner-advent-calendar-2018
ベースとして使用しているUI
UIのベースはPalette
> Derivative
> UI
> gal
に入っているものです。これまでPalette
> Derivative
> UI
> TUIK
内にあるものを使ってUIを作っていたのですが、中身を少し弄ろうとするとTscriptで実装されていてよく分かんないからPythonで実装されているgalにしとけとDiscordでアドバイスを頂きました。使ってみると確かにTUIKと比較して自分のやりたい用途としては使いやすかったです。
サンプルの構造
今回作ったプリセットの仕組みとしては0-9の各ボタンをクリックすると保存されているプリセットの値が反映され、UIで値を変更した後にSave
ボタンをクリックすると現在のUIの値が保存されるというものです。これらの値を使ってRamp Top
をアニメーションさせています。
VJツールのように何種類かビジュアルを用意するとして、UI_private
にそのビジュアル固有のプリセットを入れておいて、各ビジュアルごとにパラメータの名前や値の範囲などを個別に設定していくのを想定しています。UI_all
のほうは各ビジュアル共通の内容を保持しているもので、現状プリセットを選択するラジオボタンが入っていて、UI_private
の中身を一緒に表示しています。
プリセットのアップデート
table_all_values
に全てのプリセットのデータが入っていて、preset_save
の中のchopexec_save
からプリセットのアップデートをしています。
1列目が各プリセットの名前で、名前が一致した時にindexに該当する値を追加、または更新をします。
新しいプリセットが追加されたら新しい行(row)を追加するようになっています。
null_current = op('null_current_values')
chopto_current = op('chopto_current_values')
null_index = op('null_index')
table_all = op('../table_all_values')
def offToOn(channel, sampleIndex, val, prev):
# get index to update
presetIndex = int(null_index[0] + 1)
# get a list channels
chans = null_current.chans()
# reset index
index = 0
for c in chans:
done = False
for i in range(table_all.numRows):
table_name = table_all[i, 0]
# check if a row for this value exists
if(c.name == table_name):
table_name.val = chopto_current[index, 0]
updateValue(c, index, presetIndex)
done = True
break
# if a row for this value doesn't exist
if(done == False):
table_all.appendRow([c.name])
updateValue(c, index, presetIndex)
done = True
index += 1
return
def updateValue(chan, index, presetIndex):
# update value
param = table_all[index, presetIndex]
param.val = chan
プリセットにテーブルを使うのはおなじみMatthew Raganさんの記事を参考にしています。
TouchDesigner | FB HelpGroup | Presets | Matthew Ragan
UIのアップデート
プリセット番号をクリックした時に、chopexec_switch
で一度プリセットからの値を反映させた後、op('text_reset_switch').run(delayFrames = 60)
で60フレーム後にUIから値を変更できる状態に戻します。
constant_switch = op('constant_switch')
def onValueChange(channel, sampleIndex, val, prev):
constant_switch.par.value0 = 1
op('text_reset_switch').run(delayFrames = 60)
return
constant = op('constant_switch')
constant.par.value0 = 0
UI_private
内の各CHOP Execute
たちはそれぞれすぐ右側にあるUIのValueを直接アップデートしています。UIから変更した時にもプリセットから変更したときにもUI上の値が変更されてほしいのでこのようにしています。
改善したい点
- jsonとかにexportして
table DAT
に読み込めないですかね? - Pythonでcontainer内から外の
table DAT
を参照しているのと、CHOP Execute
から各UIのValueを直接アップデートしているのをどうにかしたい(単純にネットワークとコードをきれいにしたい)。
最後に
プリセットこんな風にやってるよーという方おられたら、ご教示頂ければ幸いです。
ありがとうございました。