« C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-1 | トップページ | C4D Python R12 テスト:アニメーションでPythonを使うなら、c4d.BaseTimeの事も少しは理解しないといけないよね… »

C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-2

パーティクルを発生させてみようかなぁ…
と、思ってC4D Python SDK Docを眺めているけど。

うぅぅん… パーティクルの割り当てのAllocParticleは見付けられるけど…
放出(Emit)とか、生成(Born)とか見当たらないね…
Allocate = Emit or Bornなのか?
全く試していないので、憶測だけ…
パーティクルのメモリーをアニメーションの最初のフレームで確保/割り当てして、発射のタイミングをon/offする…と予想しているんですがね…

さてと…

じゃあ、試しにThinkingParticles設定ダイアログを開いて、「All」を選択し…

Python_tp_41

スクリプトマネージャ(Python)に次のコードを入力。

Python
'''
パーティクルの割り当て
'''

import c4d

def main():
    if not tp: return

    tp.AllocParticle()


if __name__=='__main__':
    main()
    c4d.EventAdd()

単純なコードだ…

パーティクルの割り当ては…

TP_MasterSystem.AllocParticle() #パーティクルを1個だけ割り当てる
TP_MasterSystem.AllocParticles() #パーティクルを複数個割り当てる

パーティクルの割り当てが成功すると、パーティクルIDが返ってきます。
AllocParticles()の場合は、パーティクルIDのリストが返ってきます。

これで、パーティクルを1個割り当てることになるが…
放出させるにはどうするんだろうね。
まずは試しにスクリプトを実行する。
アニメーションは再生していないよ。

Python_tp_42

なるほど、パーティクルを割り当てしただけで、エディタビューにパーティクルが表示されている。
「All」グループのパーティクル数も実行するたび増加しているよ。
と言う事は…

Allocate = Emit or Born

で良い様だね…
前々回の記事で確認したね。
パーティクルが放出されると、グループのパーティクル数が増加する。
パーティクルが消滅するとパーティクル数が減少する。

気になるのがパーティクルを開放するFreeParticle等…
C4D Python SDK Docには…
注: 通常、使用しないでください。パーティクルが直ぐに死ぬよう、代わりに負の時間でSetLife()を使用するべきである。

FreeParticle等は、使う必要はないのかなぁ…
存在していると言う事は、使う場面があるという事だよね…
どんな場面で、どのタイミングで使うんだろうね…

グダグダしていないで、次へ行こう…

では、Pythonタグを使ってみよう。

Python_tp_43

ヌルオブジェクトにPythonタグを取り付けました。

次のコードを入力してみる。

Python
import c4d
from random import random


def main():
    if not tp:return

    pt_id = tp.AllocParticle()

    pos = c4d.Vector(random() - 0.5, random() - 0.5, 0.0)*100.0
    vel = c4d.Vector(0.0, 0.0, 300.0)

    tp.SetPosition(pt_id, pos)
    tp.SetVelocity(pt_id, vel)
TP_MasterSystem.SetPosition() #パーティクルの位置を設定
TP_MasterSystem.SetVelocity() #パーティクルの速度を設定

アニメーションを再生すると…

Python_tp_44

1フレーム毎に実行され1個放出されるので、丁度PStormでショット:1と同じ状態になります。
再生されたアニメーションを見ていると、有効期間が30fなんだろうか…

これで、パーティクルが放出されますが、このコードは完璧ではないのだ…
AllocParticle()がパーティクルの割り当てに失敗したとき、SetPosition()でエラーが起こります。
どんなときに失敗するのか?
このアニメーションのパーティクル数の増加は、30で止まっています。

試しにThinkingParticles設定の「パーティクルの最大数」を30以下に設定してみてください。

Python_tp_45

30で設定すると、パーティクル数の増加が29で止まり、コンソールにエラーが表示されます。

Traceback (most recent call last):
  File "<Python>", line 13, in main
IndexError: Index of particle out of range.

「パーティクルの最大数」をこんなに低く設定することは、ほとんどありませんが…
大量のパーティクルを使う場合、取得できたかチェックをする必要があるね。

さて、アニメーションを再生すると、最後のフレームでまた最初のフレームに戻るね…
パーティクルは、自動的にリセットされているようだ…

ますます、パーティクルを開放するFreeParticle()をどのような場面で使うのか?と疑問だ…

とりあえず…
Pythonタグのユーザデータに放出開始時間と終了時間、それとショット数を取り付けた。

Python_tp_46

パーティクルグループを「All」の下に1個増やしておいた。

次のコードを入力した。

Python
import c4d
from random import random

def RandomVec(x, y, z):
    vec = c4d.Vector(0.0)
    vec.x = (random()*2 - 1) * x
    vec.y = (random()*2 - 1) * y
    vec.z = (random()*2 - 1) * z
    return vec


def main():
    if not tp:return


    #Pythonタグのユーザデータより
    try:
        shot = op[c4d.ID_USERDATA,3]
        start = op[c4d.ID_USERDATA,1]
        end = op[c4d.ID_USERDATA,2]
    except:
        shot = 10
        start = c4d.BaseTime(1.0/3)
        end = c4d.BaseTime(2.0/3)

    #グループの取得
    gp = tp.GetRootGroup()
    if gp.GetDown(): gp = gp.GetDown()


    #パーティクルの放出
    #割り当てと初期値設定
    #XPressでのTPジェネレータとそれに繋いだノード部分

    if doc.GetTime().Get() > start.Get():
        if doc.GetTime().Get() < end.Get():

            pt_ids = tp.AllocParticles(shot)

            for pt_id in pt_ids:
                pos = RandomVec(50, 50, 0)
                vel = c4d.Vector(0.0, 0.0, 300.0)
                lif = c4d.BaseTime(10.0)

                #パーティクルに設定
                tp.SetLife(pt_id, lif)
                tp.SetPosition(pt_id, pos)
                tp.SetVelocity(pt_id, vel)
                tp.SetGroup(pt_id, gp)


    #グループ内の全てのパーティクルを処理
    #XPressoでのPPassノードとそれに繋いだ部分

    pt_id = gp.GetParticles()
    for id in pt_id:
        vel = tp.Velocity(id) + RandomVec(30.0, 30.0, 30.0)
        tp.SetVelocity(id, vel)
TP_MasterSystem.SetLife() #パーティクルの有効期間を設定
TP_MasterSystem.SetGroup() #パーティクルのグループを設定

再生すると…

Python_tp_47

ほぼ同じ感じになるように、XPressoで組んでみた…

Python_tp_48

PStormではなく、今回はPBornを使った。

Python_tp_49

まぁ、実際に作るときに、Pythonタグ1個で全部を処理するのが得策とは思えません…
例えば、TPヘルパーのPVolumePosition/PSurfacePosition等のオブジェクトのボリューム内やサーフェス上の位置を取得するのにPythonで全部処理する?
出来なくはないだろうけど… 時間を費やすことになるね…

今回は、最初に思っていたような感じではなかった…
放出するフレームで、Allocateして初期値を設定して使う…

てっきり自分は、アニメーションの最初のフレームでAllocateして放出するときにboolか何かを設定するものかなぁ…て思ってた。

|

« C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-1 | トップページ | C4D Python R12 テスト:アニメーションでPythonを使うなら、c4d.BaseTimeの事も少しは理解しないといけないよね… »

コメント

コメントを書く



(ウェブ上には掲載しません)




« C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-1 | トップページ | C4D Python R12 テスト:アニメーションでPythonを使うなら、c4d.BaseTimeの事も少しは理解しないといけないよね… »