SOPで線を描きたい!
oFやProcessingのDrawLineのようにTouchDesignerでも線を書きたいと思ったのですが、シェーダーを使わずに実現する情報がありませんでした。内容的には薄いですが記録に残しておきます。
どのように実装する?
結論としては、Script SOPでscriptOp.appendPoly(n,closed=False),n>2です。
一旦結論は忘れてもらって、どうやったら線をいっぱいかけるのでしょう。
- まずCopy SOPやLeplicator+Merge SOPなどを思いつきます。Line SOPをReplicatorなどで複製して始点と終点を調整して...一番簡単ですが、スケールしなさそうですね。
- 次に思いつくのがinstancingです。デフォルトのLine SOPは(0,0,0),(1,0,0)を結ぶ線になっているので、ExecuteなどでPythonを書き、線を引きたい二点と原点を結ぶベクトルについての回転行列からオイラー角を求めた上で始点まで移動させてあげれば完璧...のはずなのですが計算が合わない...断念。この方法だとToyoshi MoriokaさんのPixel Stormなどと連携させれば高速に描画できるなぁと思っていたのですが。またチャレンジします。
- さて、本題はここからです。Script SOPポリゴンかけるなら線もかけるのでは?
まずポリゴンを一つ描画してみます。
def onSetupParameters(scriptOp):
return
def onPulse(par):
return
def onCook(scriptOp):
scriptOp.clear()
p0=scriptOp.appendPoint()
p0.x=-1
p0.y=0
p0.z=0
p1=scriptOp.appendPoint()
p1.x=1
p1.y=0
p1.z=0
p2=scriptOp.appendPoint()
p2.x=0
p2.y=1
p2.z=0
poly=scriptOp.appendPoly(3,closed=True,addPoints=False)
poly[0].point=scriptOp.points[0]
poly[1].point=scriptOp.points[1]
poly[2].point=scriptOp.points[2]
return
できました。
次に、(-1,0,0)と(1,0,0)を結ぶ線を描こうとします。
そこで、poly=scriptOp.appendPoly以降を以下のように変更します。
poly=scriptOp.appendPoly(2,closed=True,addPoints=False)
poly[0].point=scriptOp.points[0]
poly[1].point=scriptOp.points[1]
# poly[2].point=scriptOp.points[2]
return
ここでappendPolyメソッドの引数であるclosedに注目します。確かに線だとポリゴンといってもそもそも閉じてない...closed=Falsenにしてみます。
poly=scriptOp.appendPoly(2,closed=False,addPoints=False)
poly[0].point=scriptOp.points[0]
poly[1].point=scriptOp.points[1]
# poly[2].point=scriptOp.points[2]
return
ということは、ポイントに対してappendPoly(n, closed=False)さえしてあげれば、いくらでも点がかけることがわかります。以下のように数はいくつになっても大丈夫です。
import random
def onSetupParameters(scriptOp):
return
def onPulse(par):
return
def onCook(scriptOp):
scriptOp.clear()
n=10
poly=scriptOp.appendPoly(n,closed=False,addPoints=True)
for i in range(n):
p=poly[i].point
p.x=random.random()
p.y=random.random()
p.z=random.random()
return
さらに、一つのScript SOP内で複数の線(ポリゴン?)に分けて描くこともできます。
import random
def onSetupParameters(scriptOp):
return
def onPulse(par):
return
def onCook(scriptOp):
scriptOp.clear()
n=3
poly=scriptOp.appendPoly(n,closed=False,addPoints=True)
for i in range(n):
p=poly[i].point
p.x=random.random()
p.y=random.random()
p.z=random.random()
n=3
poly=scriptOp.appendPoly(n,closed=False,addPoints=True)
for i in range(n):
p=poly[i].point
p.x=random.random()
p.y=random.random()
p.z=random.random()
return
かけました! 以上です。
もっと良い方法がありましたらコメント頂けると幸いです。よろしくお願いします。