[[devel]]

* SprBlenderのインストールの方法 [#a7c5ac0b]

+ Blender最新版をインストールする
+ Springhead2をチェックアウトする(既にある場合は最新版にする)
+ svn+ssh://springhead.info/home/svn/spr2/SprBlender/trunk をSpringhead2と同じ場所にチェックアウトする。
 c:\Projects\Springhead2 にSpringhead2があるとしたら
 c:\Projects\Springhead にSpringhead2があるとしたら
 c:\Projects\SprBlenderにチェックアウト
+ SprBlenderフォルダにある install_blender271.bat を''管理者権限で''実行。
-- install_blender271.batを右クリックして管理者として実行を選ぶ。
+ SprBlenderフォルダにある install.bat を''管理者権限で''実行。
-- install.batを右クリックして管理者として実行を選ぶ。
-- 途中で「開発者モードでインストールしますか」と聞かれたら「y」を入力。


Kogumaを実行するには
+ svn+ssh://springhead.info/home/svn/lab/Experiments/trunk/SprBlenderExamples を、Experiments\SprBlenderExamples にチェックアウトする
+ Experiments\SprBlenderExamples\Koguma3GS\koguma3gs_sitting_nobasket.blend をBlenderに読み込んで実行する


* ルールスクリプトの在処 [#rf711917]

- koguma_leap3_delaysel.blend の場合
-- init
--- koguma_leap3_delaysel_rule_Koguma_init.py
-- step
--- koguma_leap3_delaysel_rule_Koguma_step_bpy.py

- Blender内のText Editorで編集してもよいし、外部のテキストエディタを使っても良い。
-- 外部のテキストエディタで編集した場合は、creatureのUpdateを行うと再読込される(その後initも呼ばれる)。


- 将来的には、他の.blendで使われていると共通するコードは別のファイルに移動するようにする。


* Creatureの処理の流れ [#j7c22318]

- 初期化時
-- creature_init
--- Updateボタンを押した時に呼ばれる。初期化用。

- 実行時
++ 物理シミュレーションステップ
++ creature_step
-- これとは別に creature_step_bpy が呼ばれる。
--- creature_stepは物理シミュレーションステップ1回につき必ず1回呼ばれる。
--- creature_step_bpyは物理シミュレーション数回に1回くらいの割合で呼ばれる。blenderのタイマで動くため周期は不確実(blenderの負荷によって変動もする)。

- stepとstep_bpyの違い
-- stepはSpringheadのタイマから呼ばれる。step_bpyはblenderのタイマから呼ばれる。
-- bpyを呼び出す場合はstep_bpyを使う(bpyをblenderのタイマ以外から呼び出すと不具合を起こすことがある)。



* 関数の見つけ方 [#e13c002a]

- 例
 creature_stepの中にある
 lookctl.step()
 の定義を探す場合
 
 lookctl が出てくる最初の行を init -> step の順に探す
 (initの中で変数定義されてるかもしれないし、stepの中かもしれないので)
 
 と、initの中に
 # Create Look Controller
 lookctl = LookController( head,  lefteye,  righteye)
 が見つかる。
 LookControllerクラスのオブジェクトということが分かる。
 
 そこでクラス定義 
 class LookController:
 を探す。
 
 クラス定義が見つかったら、step() の定義(def step(...):)を探す。

- これで見つからない場合
-- Springheadの関数かも
-- bpyの関数かも


* クリーチャパラメータについて [#efed389e]

- crHnd.get_cr_param("Reach Speed") のようにすると Reach Speedという名前のパラメータに現在セットされている値が得られる。
-- この関数が呼ばれた瞬間にGUIにセットされている値が帰ってくる。
-- なので、stepの中でこの関数が呼ばれている場合は、パラメータを変更すればすぐに動作に反映される。


* キャラクタを構成する全ての剛体・全ての関節についてループ処理したい場合 [#i0b6bb64]

- CreatureHandler が CRCreature を持っている。
- CRCreature が CRBody を持っている。
- CRBody が CRBone をたくさん持っている。
- CRBone が PHSolidやPHJoint を持っている。
- したがって、
 from spb.abbrev import *  
 
 # CreatureHandlerからCRCreatureを取り出す。
 # Kogumaはクリーチャを定義するグループ名
 crCreature = Cr['Koguma'].spr()
 
 # 最初の(0番目の)Bodyを取り出す
 crBody = crCreature.GetBody(0)
 
 # boneそれぞれについて処理する
 for bone in crBody.GetBones():
   # boneからSolidやJointを取り出す
   solid = bone.GetPHSolid()
   joint = bone.GetPHJoint()
   ikact = bone.GetIKActuator()  # ←IKアクチュエータ。Biasなどを管轄。無いこともあるので注意
   
   # ... あとはここでsolidやjointを使った処理をする ...


* ハンドラについて [#a6265418]

- ハンドラはSpringheadオブジェクトとblenderオブジェクトの仲介役。
-- .spr() でspringheadオブジェクトを、
-- .bpy() でblenderオブジェクトを取得できる。



* Python Consoleで補完できないことがあるのは何故か? [#jdc3db7e]

 >> Cr['Koguma'].spr().   # ←ここでCtrl+Spaceを押しても補完が働かない

こういう時は
 >> creature = Cr['Koguma'].spr()
 >> creature.   # ←ここでCtrl+Spaceを押すと補完が働く

- 何故か?
-- 「Cr['Koguma'].spr()」がどんなクラスのオブジェクトを返すかは実行してみるまで分からない(Pythonなどの動的言語の特徴)。
-- どんなクラスのオブジェクトが返ってくるか分からないと、どんなメソッドが使えるかわからない。
-- Cr['Koguma'].spr()を実行してcreatureに代入すると、creatureがCRCreatureクラスのオブジェクトであることが確定している。なので補完ができる。

- わざわざ代入するのがめんどいときは以下の様な方法も有効。
 >> Cr['Koguma'].spr().dir() [ENTER]
 または
 >> dir(Cr['Koguma'].spr()) [ENTER]
-- 前者は使えない場合があるので注意。後者は必ず使える。


* クリーチャのグループについて [#fb50277d]

- SprBlenderでクリーチャを作るには、クリーチャ1体を構成する複数のblenderオブジェクトを、一つの「グループ」に所属させる。
-- グループパネルは、オブジェクトパネルの中にある。
-- クリーチャに対応するグループは、SprCreature にチェックを入れる。




* スクリプトを外部ファイル化する方法 [#tf09979f]

- Text Editの Textメニューから Save as を選択。
- ファイル名を付けて保存する。
-- ファイル名は blendファイル名_ルール名.py とでもするのがよいだろう

- 次に、ファイルパスを相対パスにする(そのままだと絶対パスになってしまう)。
-- blenderのFileメニューを開き、
-- External Data  ->  Make All Paths Relative
-- あとは普通にSaveすればOK。


* Pythonのよく見るエラー [#i66b19f2]

- 基本的には分からないエラーメッセージはGoogle検索することをおすすめします。

- 'XXXXX' object has no attribute 'yyyy'
-- yyyyという名前のメンバ関数や変数がXXXXXオブジェクトにはない。yyyyのスペルミスなどを疑う。

- 'yyyy()' takes N arguments (M given)
-- 引数の数が違う。yyyy()関数はN個の引数を取るのにM個与えられた。