ショートカットから.toeを起動する方法

インスタレーションなどでは、アプリが自動起動させて、システムを起動させる必要があります。その際に、Windowsのスタートアップやプロセス監視アプリから、.toeを実行できるショートカットが便利です。

また、インスタレーションなどでは、TouchDesignerから起動するのではなく、TouchPlayerという再生環境で実行するのが好ましいです。

.toeのショートカットを作成する

最初に、.toeのショートカットを作成します。起動させたい.toeファイルを右クリックし、「ショートカットの作成」を選択します。

すると、ショートカットが同じフォルダに作成されます。

この状態で、ダブルクリックしても、shortcut.toeが、TouchDesignerから開かられるので、ご注意を。

TouchPlayerのショートカットを作成する

次に、TouchPlayerのショートカットを作成します。TouchPlayerは、TouchDesginerの実行ファイルと同じフォルダにインストールされています。デフォルトのインストール先は、C:\Program Files\Derivative\TouchDesigner099\binです。

TouchPlayer099.exe(将来的にバージョンが変わった場合には、ファイル名が変わる可能性あり)というファイルがあるので、これのショートカットを上と同じく作ります。

作ったショートカットのプロパティを表示します。

プロパティの中の「ショートカット」タブを選択します。「リンク先」という項目のテキストフィールドに入っている文字列をすべてコピーします。TouchPlayerへの絶対リンクの文字列になります。

.toeのショートカットにTouchPlayerを設定する

最初に作成した.toeへのショートカットのプロパティを表示します。

リンク先の項目を選択し、カーソルを一番先頭に移動させます。

ここに、コピーしたTouchPlayerへの絶対パスをペーストします。次に、一文字だけ半角スペースを入れます。テキストフィールドには、こういった文字列が入ることになります。

"C:\Program Files\Derivative\TouchDesigner099\bin\TouchPlayer099.exe" C:\Users\banana\shortcut.toe

設定を保存して、ショートカットをダブルクリックすると、TouchPlayerから自動的に.toeが起動します。このショートカットをスタートアップに登録すると、Windowsが起動したときに、自動的に実行されます。

COMPごとにタイムラインをつくる方法

TouchDesignerでは、メイン(ルート)のタイムラインとCOMPごとのタイムラインを複数持つことができます。”timeline1″は、メインのタイムラインのフレーム数、null1は、base COMPが持つタイムラインのフレーム数を出力しています。それぞれ、違うフレーム数とタイムラインの最終点が違うことが確認できます。

今回のサンプルファイルはこちら
https://github.com/arkwknsk/touchdesigner/tree/master/tips/multi-timeline

Base COMPにlocal timelineを追加

新規プロジェクトに、Base COMPを追加。Base COMP上で右クリックし、”Add Component Time”をクリック。

すると、Baseの中に、”local”という名前のBase COMPが自動的につくられます。Base COMPの中に入って確認。ここで注目すべきは、画面下部に、今まで無かったタイムラインのUIが表示されています。この”local” Base COMPが、メインのタイムラインとは別時間軸で動くローカルタイムラインを制御してくれます。よって、この”local” Base COMPと同じCOMPにつくられたノードは、このローカルタイムラインを参照して動くようになります。

サンプルファイルの/project1/baseを開いてください。1のボタンを押すと、ローカルのタイムラインが1フレームにリセットされ停止します。2のボタンを押すと、再生されます。

先ほどと同じTimeBaseを追加する操作で、すでに、3“local”が追加されています。

ローカルタイムラインのフレーム数取得

このCOMP内の現在再生されているフレーム数を取得するには、4の様なtimeline CHOPを追加します。

プロパティのReference Operatorで、このCHOPが参照するオペレーターを指定できます。ここでは、このTimeline CHOPが置かれているCOMP(オペレーター)を指定します。

ローカルタイムラインを切り離す

ローカルタイムラインをメイン(ルート)タイムラインと切り離して、単独で再生できるようにします。3の中に入ると、

time COMPというのがあります。これが、タイムラインを生成するCOMPになります。このプロパティの”Run Independently”をOnにします。

なお、このプロパティで、フレームレートやループ再生するかどうかなど、タイムラインの基本設定を行うことができます。

各OPにローカルタイムラインを反映

ローカルタイムラインを持つと、どんなことができるのかをサンプルにまとめてみました。

5のParticle SOPでは、シミュレーション時間をローカルタイムラインから参照することで、変化を付けることができます。 6LFO CHOPでは、生成するためのタイムラインを同期させることができます。フレームレートを落とすとLFOの生成速度が落ちます。 7Movie In Topでは、再生をタイムラインと同期するように設定するため、ローカルタイムラインが止まると再生が止まります。 8Animation COMPでは、ローカルタイムラインにそって、キーフレームが再生されます。そのため、メインタイムラインとは違う速度、方向で再生することができる様になります。

その他、スクリプトやReferenceで参照すれば、さまざまなOPの再生タイムラインを変更することができます。

とは言え、何に応用できるかは謎だったりするのですが、負荷を最適化するために、COMPごとのタイムラインを違うフレームレートで再生するとか、マルチプロセスで同期させるときなどに、メインタイムラインとは違うタイムラインで同期させることなどができそうです。

[TouchDesigner]イーズアニメーションをつくる

モーショングラフィックスの基本であるEaseアニメーションの仕方。
TouchDesignerでは、Keyframeを打つことでeaseを作ることができるが、ノードでつくる方法を。


サンプルファイルはこちら。
https://github.com/arkwknsk/touchdesigner/tree/master/tips/ease-interpolate

いくつかeaseをつくる方法がありますが、今回は、Interpolate CHOPを使い、

  • linear
  • ease in
  • ease out
  • ease in ease out

の4つのアニメーションをつくります。

初期値と最終値の設定

Interpolate CHOPは、入力されたCHOPの値を「補完」するノードです。ここでは、start1というConstant CHOPの0という値から、end1の1という値までを直線で補完する値を生成しています。

入力は複数持つことができ、一つの入力をAfter Effectsのキーフレームみたいな感じで設定できます。

最初に、二つのConstantを作り、一つはstart1と名前を付けて初期値を設定、最後の一つはend1と名前を付けてに最終的な値とキーフレームの時刻(時間)を設定します。

デフォルトで設定されていますますが、キーフレーム的に使うために、Constantのパラメータのchannelタブ→Single Sampleという項目が”On”になっていることを確認します。

次に、end1のパラメータで最終値を設定。

ここでは、最終値を1にします。

次に、Channelタブ→Startの値に、何フレームで最終値の1にするかというのを入れます。ここでは、Frameでも、Secondでも設定可能。ここでは、300フレーム後に1にするように設定。

Interpolate CHOP

Interpolate CHOPをつくり、すでにつくったConstant CHOPをつなげます。


そうすると、上の様なグラフがつくられます。1フレームから300フレームまで、きれいな直線の値が入ります。


ここで、Interpolate CHOPのパラメータのInterpolateタブ→Shapeのプルダウンメニューから希望するeaseなどを選ぶことができます。Cubicは、Ease in Ease outよりもすこしきつい加速する動きのアニメーションです。

実際のアニメーションに反映する方法

サンプルファイルの中に、4種類のアニメーションの実際のノードグラフを載せていますので、詳細はこちらを。

簡単に、ノードの流れを。

Interpolate CHOPでつくったアニメーションの動きをフレームごとに、TOPやSOPに渡す必要がありますので、lookup CHOPで、フレームごとに値を取り出します。

このとき、lookup CHOPが取り出したい位置(Index)をノードグラフ上部のSpeed CHOPで生成しています。Speed CHOPは、毎フレームごとに、Input値を増加量として、カウントアップしてくるCHOPです。i +=2 的な。

ここでは、Rectangle TOPの位置を移動をアニメーションさせるため、0~1の値をMath CHOPを使って、リマップしてます。ここでは、-0.25~0.25に変換してます。最初の初期値/終了値で設定することもできますが、このように途中で変換することでプロシージャルに、設定すると演出調整で便利です。

ここで変換した座標値をFit TOPノードのTranslateに入れ、実際のアニメーションに反映させます。モーショングラフィックス的にTOPを動かすのFitは便利です。蛇足なりますが、xにInterpolate CHOPの値を入れ、yにはサンプルとして見やすいように、pattern CHOPの直線的な値を入れ、4種類のボックスを上から均等配置しています。

ノードグラフ左側のGOボタンを押すと、60FPSが出るマシンだと5秒掛けてアニメーションする4つのボックスを確認できると思います。easeのかけ方で動きに変化がでることがわかると思います。アニメーション以外にもアルファなどの値もこの手法で変えられます。

[TouchDesigner]一定間隔で数が増える数値の出し方

一定間隔で数が増える数値を出したいときは、Pattern CHOPを使うと便利。

Pythonで書くとこんな処理

def onCook(scriptOp):
	scriptOp.clear()
	scriptOp.insertRow(['ty'], 0)

	n = 15
	step = 5

	j = 0
	i = 0
	for i in range(1,n+1):
		scriptOp.appendRow([j])
		if i % step == 0:
			j += 1

	return

Pattern CHOPをつくる

早速、Pattern CHOPをつくり、パラメーターの設定をする。


Typeから”Step”を選ぶ。今回、使用する項目は以下。

  • Length: sampleの長さ
  • Number of Steps: 何段階で目標値に増加させるか
  • Amplitude: 振幅数(この場合だと、中間地点の値)
  • Channel Names: 出力するチャンネルの名前

サンプル:階段状にBoxが増えていく

実際に、使えそうなシチュエーションとして、InstanceされるオブジェクトのYを段階的に増やして、階段状に上がっていくものサンプルとします。サンプルファイルは、こちら。
https://github.com/arkwknsk/touchdesigner/tree/master/tips/pattern-chop-step

完成はこういう感じのものです。横に5列、縦に3行のグリッド上にBoxが配置されますが、Z方向に1行(つまり、横に5個ずつ)ごとに、Yの値が変化し上がっていく構造です。

早速、ネットワークを見ていきましょう。

一番の左の”Para”というCHOPで、一列に何個、何行分表示するかをパラメータとして指定できるようにしています。その数値から、grid SOPでグリッドを作り、InstanceされるBOXの元の位置を生成。

Pattern CHOPのパラメータ項目の中で、簡単なPythonスクリプトを書き、生成する数列の長さ、ステップ数を入れています。また、grid SOPのパラメータも、スクリプトで指定しています。こうすることで、”Para”の値を変えると、動的に構造を変化させることができます。詳細は、サンプルファイルを。

生成されたGridをCHOPに変換し、次に、Select CHOPで、値をそのまま使うtxとtzだけを抽出します。tyの値は、Pattern CHOPで生成し、最終的にMerge CHOPでtx, ty, tzを合わせる形にします。

これをGeometry COMPにリンクし、インスタンスさせます。

サンプルファイル

https://github.com/arkwknsk/touchdesigner/tree/master/tips/pattern-chop-step

[TouchDesigner]動画を音声付きで再生する方法

TDで、動画を再生するときによく使われるMovie File In Topだけでは、音声は再生されない。音声を同時に再生するには、Audio Movie CHOPを使う。

動画ファイルを読み込む

最初に、以下のようなノードを作り、動画ファイルを読み込む。この時点では、音声は再生されません。

※Text DATは、クレジット表記なので作らなくても大丈夫です。

動画ファイルの音声を再生する

Audio Device Out CHOPをつくります。

次に、このAudio Device CHOPのパラメーターのMovie Audio -> Movie File In TOPに、すでにつくってあるMovie File In TOPをリンク。

まず、Movie File In Topをドラッグし、Audio Device CHOPの”Movie File In TOP”のボックスまで持ってきたらドロップ。

そうすると、ボックスのところにドラッグしたTOPの名前が入り、 これでリンクされる。

リンク例

次に、サウンドデバイスにデータを送るAudio Device Out CHOPをつくり、Audio Movie CHOPとつなげる。すると、スピーカーかヘッドフォンから音声が再生される。

サンプルファイル

https://github.com/arkwknsk/touchdesigner/tree/master/tips/videoWithAudio

[notch]State Machine: 状態遷移の仕方

状態が変化し、表示されるGeometoryが切り替わる
Nodegraphの全体

State Machineとは?

State Machineノードを使うことで、状態遷移でノードを切り替えられ、シーンの状態を管理することができる。公式ドキュメントに従って、Geometryを切り替えるスタディ。

概要

State Machineを使うには、

  • State Machine node
  • State Machine State node
  • State Machine Events node

の3種類のノードが必要になる。Stateは、State Machine nodeの子供に、EventsはStateの子供になる必要ある。

ステート(State)とイベント(Event)

仕組みとしては、EventsのAttributesのActivateが1になった時に、イベントが発火し (きっかけ) 、次のステート(状態)に遷移することになる。移動したいステートには、EventsのOutputから、StateのIncoming Eventsにつなげる。Activateは、0~1の値を取る。

Activate Attribute
ここでは、Event0が発火すると、StateBに遷移する

ステートで切り替えたいGeometryのノードを配置し、Rootに繋げないで、表示したいステートのState nodeにつなげる。表示したいノードは複数持つことができる。ここでは、StateAでは、球体とステート名を表示するText nodeをし、StateBではBoxとステート名、StateCではTorusとステート名を切り替えている。

イベントの発火の仕方

イベントを発火するには、Event nodeのActivate Attributesに、1を送る必要がある。今回は、Accumulator Modifierで、0~3のfloatをカウントアップさせ、

0: Event0
1: Event1
2: Event2

の各イベントを発火させている。

Accumulator ModifierでカウントアップされたValueを一度、Expression Modifierで剰余算(割り算の余りを出す)することで整数化し、Condition ModifierでIF文的に条件分岐をしている。

Event1につながっているCondition ModifierのProperty

例えば、Event1を発火するには、Condition Modifierに入ってきた値が1のときに、条件式が等しくなるので、1をOutputから出力する。1以外のときは、常に0を出力している。

シーンファイルはこちら
https://github.com/arkwknsk/notch/tree/master/20190425_state-machine

log4jsのConfigurationの書き方がv2で変更になった

Node.js環境でログ出力をするlog4jsのConfigurationがv1からv2以降で大きく変わった。

v2.0x以降の記述方法

{
    appenders: {
        default: {
            type: 'file',
            "filename": "log/server.log",
            "maxLogSize":104857600,
            "layout": {
                "type": "pattern",
                "pattern": "%d [%p] %m"}
        }

    },
    categories: { default: { appenders: ['default'], level: 'debug' } }
}

古い記述方法だと、must have property “appenders” of type objectというエラーが発生する。
詳細は、Migrating from log4js versions older than 2.x

Debug.LogFormat

Debug出力する際に、定例分の中に変数を埋め込むString.formatは便利なのですが、Debug.Logと組み合わせると、コードが長くなってしまいますが、直接、フォーマットできる方法があります。

Debug.LogFormatを使うと、整形フォーマットを指定できます。

string foo = "abc";
Debug.LogFormat("foo: {0}", foo); // foo: abc

引数の指定の仕方は、String.formatと同じ。

C#で2次元配列

C#で2次元配列を宣言、初期化する

int[,] twoDim = new int[8,16];

要素8個の中に、要素16個を持つ2次元配列をつくる。

2次元配列のアクセス

int[2,4] = 128;