TouchDesigner

TouchDesigner 必要な時だけオペレータをcookする


cookとは

ネットワーク上のオペレータが何か処理を行なっている状態のことです。
@kodai100さんが「[#TouchDesigner] cookのWikiページを翻訳してみた」という記事でCookについて細かく紹介しています。

TouchDesigner公式wikiによるcookはこちら
サンプルファイルはこちら

作るもの

必要がないときにも全てのオペレータを走らせておくことは全体の処理が重くなってしまう原因になるので、必要な時だけ必要なオペレータが走るような(cookするような)処理の仕方の一例をメモしたいと思います。

cook.gif

このようにSwitchTopのindexに参照された値に対応するContainerCOMPがcookされ、他のContainerCOMPはcookがオフ(オペレータ上に×が表示される状態)になっています。

Switch機能の実装

スクリーンショット 2017-12-26 午後4.37.31.png

こちらの例では、ContainerCOMPを5つ(container0~container4)用意し、 中でMoviefileinTOPとOutTOPを繋いでいます。
OutTOPを繋いだことで、それぞれのContainerCOMPをSwitchTOPに繋ぐことができるようになります。

スクリーンショット 2017-12-26 午後4.41.59.png

ButtonCOMPのButton->ButtonTypeをMomentaryにします。
CountCHOPを繋ぎ、Count->LimitをLoop Min/Max、Limit Minimumを0、Limit Maximumを4に設定します。
CountCHOPの後にNullCHOPを繋ぎ、ContainerCOMPを繋いだSwitchTOPのindexに値をエクスポートします。
これで、ボタンを押すと順番にContainerCOMPが切り替わるようになりました。

必要な時だけcookする

CHOPExecuteDATにNullCHOPを参照させ、CHOP Execute->Value ChangeをOnにします。(デフォルトでOnになっています)
CHOPExecuteDATのonValueChangeに以下のコードを書きます。

def onValueChange(channel, sampleIndex, val, prev):
                op('container'+str(int(prev))).allowCooking = 0
                op('container'+str(int(val))).allowCooking = 1
                return

onValueChangeの第3引数valは現在の参照しているCHOPの値、第4引数prevは一つ前の値が入っています。cookしたいcontainerCOMPのallowCookingを1(オン)にするのと同時に、その直前にcookしていたcontainerCOMPのallowCookingを0(オフ)にします。こうすることで必要なオペレータだけをcookし、必要でないオペレータは処理を停止させておくことができました。

完成

スクリーンショット 2017-12-26 午後3.49.40.png

まとめ

ひとつのプロジェクトにたくさんの機能を持たせると全体の処理が重くなってしまいがちですが、処理させるところとさせないところのオンオフも組み込むことでFPSを守ることができました。