C4D.Python: CineversityのPythonエフェクタを再現

勉強のために、CineversityのNAB 2015 Rewind – Colin Sebestyen: Python Coding for Motion Designの40分ごろのPythonエフェクタを再現した。といってもプレゼンターもコピーして使ってくれと言ってくれていたので、基本そのままコピーしました。なお、Pythonエフェクタのモードは完全コントロールで、ユーザデータも4つ作成しています。

このPythonエフェクタは、各クローンがstepsizeで指定した距離分、XYZ+-の各方向に限定して1フレずつランダムに動くようになっています。width/height/depthの値は、クローンが動く範囲になります。
コード
import c4d
from c4d.modules import mograph as mo
from c4d.utils import *
import random
#Welcome to the world of Python
#タグのユーザデータを取得
width = op[c4d.ID_USERDATA,1]
height = op[c4d.ID_USERDATA,2]
depth = op[c4d.ID_USERDATA,3]
stepsize = op[c4d.ID_USERDATA,4]
#Walkerクラスの作成
class Walker():
#初期化。毎回変数selfを初期化する関数
def __init__(self,x,y,z):
self.x = x
self.y = y
self.z = z
#0~5の整数をランダムに出してその数字によってXYZの+-方向のどこに動かすか判定
def step(self):
choice = random.randint(0,5)
if choice == 0:
self.x +=stepsize
elif choice == 1:
self.x -=stepsize
elif choice == 2:
self.y +=stepsize
elif choice == 3:
self.y -=stepsize
elif choice == 4:
self.z +=stepsize
elif choice == 5:
self.z -=stepsize
#ただし、移動量がwidth/height/depthで決めた範囲を超えないように設定
self.x = ClampValue(self.x,0,width)
self.y = ClampValue(self.y,0,height)
self.z = ClampValue(self.z,0,depth)
#リストwalkerを作成
walker = []
#MoGraphのデータを取得
md = mo.GeGetMoData(op)
#クローンの複製数を取得
cnt = md.GetCount()
#リストwalkerにwidth/height/depthの値の1/2をクローンの複製分入力
for i in reversed(xrange(0,cnt)):
walker.append(Walker(width/2,height/2,depth/2))
def main():
if md==None: return False #MoGraphのデータがなければ終了
marr = md.GetArray(c4d.MODATA_MATRIX) #各クローンのマトリックスを変数marrに入れる
#各変数marrのマトリックスにリストwalkerの位置ベクトルを入れる
for i in reversed(xrange(0,cnt)):
marr[i].off = c4d.Vector(walker[i].x,walker[i].y,walker[i].z)
#各クローンにマトリックスを設定
md.SetArray(c4d.MODATA_MATRIX,marr,True)
#walkerリストに対して、Walkerクラスのsetp関数を実行
for i in reversed(xrange(0,cnt)):
walker[i].step()
return True
新たに自分でクラスWalkerを作って、独自の関数Stepを作成していますが、面白いのがランダムに動く仕組みが、サイコロを使って決めるような方法だという点です。整数のランダム数を生成するrandint()関するを使って0~5(XYZ*2(+とーの2方向))その出た数字でどの方向に移動するかを決めていることです。
実際動くようになりましたが、動かしてみるといろいろ問題点もありました。どうもクローン数を変更するとうまく動かないことがあります。一度カウントした値をどうも覚えてしまうようです。モードをパラメータコントロールに切り替えてから再度完全コントロールに戻すと更新されました。どこかで初期化するコードを入れる必要がありそうです。
このCineversityのプレゼンは非常に面白いのでお勧めです。ベクトルやフォースの解説もしてくれます。自然な動きをアルゴリズム化する方法を紹介しています。特に1時間1分ごろからスクラッチでPythonエフェクタを解説付きで作成してくれるので、勉強になると思います。
こちらのアルゴリズムについては、Nature of Codeという本で紹介されているそうです。日本語版もボーンデジタルさんから出ているそうです。