ここでは、時間をコントロールするTimer CHOPを使ってみます。Timer CHOPは、指定した時間の経過を追跡するためのオペレーターです。タイマーの長さを設定し、開始、停止、リセットが可能で、タイマーの状態に応じてイベントをトリガーできます。例えば、カウントダウンや時間経過後の特定のアクションを実行する際に使用されます。視覚的なインターフェースを提供し、スクリプトや他のCHOPと連携して多様な時間制御が可能です。
Timer CHOPの基本
まずは、Timer CHOPのパラメータを色々変えてみましょう。このCHOPは非常に多機能なので、よく使う機能を中心に説明します。Timer CHOPを出してください。
- Initialize: タイマー初期化
- Start: タイマーの開始
- Length: タイマーの継続時間
- on Done: タイマー終了時のイベント
TimerタブのLengthの値を色々変えてから、InitilizeとStartを順番に押してみてください。タイマーの継続時間が変化したことがわかります。on Doneは以下の機能があり、タイマー終了時のイベントが選べます。
Do Nothing、Re-Initialize、Re-Start、Re-Start without Initializing
ボタンを追加
それでは、このTimer CHOPにボタンを追加してみましょう。Button COMPを2個、Null CHOPを2個出して、図のように繋げてください。その際、button1・2のTimerタブのButton TypeはMomentaryにします。また、button1・2のTimerタブのLabelはそれぞれInitialize、Startにしておきましょう。
button1・2の右下のボタンをViewer Activeにすることによって、ボタンの機能が有効になるので、ボタンを押して、タイマーが動くか確認してください。
時間経過によって動画を切り替える
それでは、動画の再生時間をタイマーによって制御してみます。以下のようにCount CHOP、Select CHOP、Movie File In TOPを2個、Switch TOPを繋いでください。
timer1は下図のように設定します。タイマーの継続時間を5秒、On DoneをRe-Startにしてタイマーを繰り返すようにします。
count1のパラメータは下図のようにように設定して下さい。これによって、count1の値は0と1を交互に繰り返します。
select1は以下のように設定し、count1のdoneの値だけ抽出します。
switch1のパラメータは以下になります。select1の値をswitch1のswitchタブ > Indexにエクスポートして下さい。
Initializeボタン→Startボタンを押すことにより、5秒ずつ動画が交互に再生されます。
任意の秒数で3個の動画を再生する(TimerのSegmentsを使う)
次にもっと複雑な時間管理を行なってみます。直前のサンプルは、動画を5秒ずつ再生しましたが、次のサンプルは任意の秒数だけ動画を再生します。下図のようにオペレータを接続して下さい。
ここでは、table1(Table DAT)に動画の再生時間(秒)を記載してtimer1 > Segmentsタブ > Segment DATに登録することによって、table1のリストの秒数に従ってTimerが作動します。まず、Table DATを出して、下図の通りtable1を作成して下さい。
次に、timer1のパラメータは下図のように設定します。まず、outputsタブ > SegmentをOnにします。
Segmentsタブ > Segments DATに作成したtable1をドラッグして登録します。
Timerタブ > On DoneはDo Nothingにします。
ボタンを押して再生してみて下さい。各動画がtable1に記載されている通りの秒数だけ再生されていることが分かります。
スクリプトを使って、より高度な制御を行う
それでは、スクリプトを使ってもう少し高度な制御を行ってみましょう。下図のようにオペレータを組んでください。その際、デバッグのためTextportを表示して下さい。
このサンプルで重要なのはtimer1_callbacksです。このスクリプトはコールバック関数といい、特定のイベントが発生したときに自動的に呼び出されます。TouchDesignerでは、ボタンが押された時やタイマーが終了した時などに使われます。今回は、Visual Studio Codeを使って書き換えます。
onInitialize
#グローバル変数
counter = 0
def onInitialize(timerOp):
#グローバル変数は関数内で定義する
global counter
counter = 0
#text1、2を初期化
op('text1').par.text = ''
op('text2').par.text = ''
#動画の再生ヘッドを先頭に戻す
op('movie1').par.cuepulse.pulse()
op('movie2').par.cuepulse.pulse()
op('movie3').par.cuepulse.pulse()
#初期化時に動画の再生はoff
op('movie1').par.play = 0
op('movie2').par.play = 0
op('movie3').par.play = 0
return 0
onStart
def onStart(timerOp):
#スタートボタンで全ての動画を再生開始
op('movie1').par.play = 1
op('movie2').par.play = 1
op('movie3').par.play = 1
return
onSegmentEnter
def onSegmentEnter(timerOp, segment, interrupt):
global counter
#新しいセグメントに入ったらcounterを1増やす
#table2のデータを表示
counter = counter + 1
op('text1').par.text = op('table2')[segment + 1, 'text']
op('text2').par.text = counter
debug("segmentEnter=%d" % segment)
debug("counter=%d" % counter)
#print("segmentEnter=%d" % segment)
return
onDone
def onDone(timerOp, segment, interrupt):
#終了時に動画の再生を停止
op('movie1').par.play = 0
op('movie2').par.play = 0
op('movie3').par.play = 0
return
Initializeボタンを押すと、動画が止まって再生ヘッドが動画の先頭になり、Startボタンで動画がtable1に記載された通りの時間で再生されて終了します。また、table1のテキスト指定された時間に順番に再生されます。
全てのコードが見たい場合は、サンプルをダウンロードして確認して下さい。