[[開発者向け情報>devel]]

~

#contents
----
* SprBlender機能レビュー [#ab831b8f]
** 導入 [#e49a775f]
- [[SprBlender]]を参照
- 64bit blender -> springhead.pydも64bitに
-- Blender、インストーラ版だとうまく動かないかも zip版をダウンロード

- 試してみる:
-- Experimentsにあるblendファイルを開いてみる
-- Python Consoleで import spr_op
--- &ref(コードレビュー/2012年3月12日SprBlender/001_import.jpg,320x180);

** 使い方 [#s7076c08]
- Sceneパネルの中に重力・FPS・SubStepsの設定がある(Gravityは2カ所にあるけどおなじもの)
-- Substeps : spr_opのStep1回につき何回呼び出すか. 変更するとdtも変わる.精度の変更
-- テキストエディタのspr_main を開くと実際のFPS情報が見れる.
--- Time Step: SprBlender実行部のdt
--- Phisics Time Step: Springhead2のdt
--- &ref(コードレビュー/2012年3月12日SprBlender/002_texteditor.jpg,320x180);

** Objectパネル [#d5ec0fa5]
- 選択しているオブジェクトのプロパティ.この中の3つのパネルが関連.
*** SprObjectPanel [#a95c24c8]
-- 主にSolidの情報.
-- ShapeをNoneにするとSpringheadと連携しなくなる.(Solidを作らない)
--- (ただし動作中に消すことはできない.動作中に形状変更もできない.)
-- Material(摩擦とか反発とか)はここに表示されているけど実際にはMaterialパネル(テクスチャとか)の内容と関連づけられている.(※現在両方は表示 2012/3/27)
-- Inertiaの自動設定はBoxとSphereについて有効(自前コード).それ以外はどっちかに近似してる.

-- Box, Sphere → 選択オブジェクトのサイズからサイズ決定
--- BlenderオブジェクトのScaleも考慮される
-- Dimensions : Blenderが自動的に作るBounding Box.この情報を使ってる
-- Convex:メッシュ頂点の座標をSpringheadのCDConvexに反映.(たぶんScaleにも対応)
-- &ref(コードレビュー/2012年3月12日SprBlender/003_object.jpg,320x180);

-- Real Time Editing
--- → チェックマークが出たものについてはリアルタイムで編集可能.そうでないものについてはSetObjectsでの反映が必要
--- Real Time Editingでない場合はApply Parametersを押すと反映される(押すまで反映されない)

- SprJointPanel: 後述

- SprCreaturePanel: 後述



** 動かす [#x04e9803]
- 最初:SDKとSceneだけできていて中身はからっぽ
- SetScene → Blenderのシーンを解釈してPHSolidとかを生成.
-- (たぶんPHSceneを作り直すので二度押しするとシーンごと新しく作られる)
- Physics Step Enable→ 動き始める. (タイマーはその前から動いていて,Stepを呼ぶかどうかを決めるのがこれ)

- Restore SceneでSetSceneしたときの状態に戻る.
-- (SaveState的機能はほしい.RestoreSceneが何個かつくりたい)
-- &ref(コードレビュー/2012年3月12日SprBlender/004_operator.jpg,320x180);

- SetObject:選択したオブジェクトについてのみ,PHSolidとかを作成.
-- (例えば Shift-Dでオブジェクトをコピー(物理パラメータはコピーされる) → Set Objectsを押すと,PHSolidが生成される)
- Restore用データにも追加されるのでRestoreすると元に戻る.

- 既存オブジェクトのShape TypeをいじったあともSet Objectsを押す.


- ReRegister :
-- ファイルを読み直すと spr_opの再登録が必要になる(既にimportされているがオペレータとしては登録されていない状態になる)
-- ReRegisterを押したあとimport spr_opを押す
-- (ReRegisterは何度もおしてはだめ.タイマーが多重登録されて早くなる)


- *Tips : Gで移動.左クリックで決定.右ドラッグでもGと同様に移動

- Static(Dynamical Off)のオブジェクトは,キーフレームで動きを作れる.
-- (速度のセットまではしていない.)


- Enable Throw: Blender UI 上で動かした時の移動量から速度を計算してSolidに反映する.
-- (そうでない場合,Blender UIで動かした場合速度は0になる)


- Save SPR File : Blender直下にPHScene.sprができる.


- Record Keyframe : Springheadの動きをキーフレームに保存できる.
-- Unique Keyframe : キーフレーム記録開始地点
--- <Unique Keyframe : 他のモーションを再生しながら物理モーションを足して別の位置からのキーフレームに保存できる.>
-- Record Every N Step : 何ステップごとに記録するか
-- &ref(コードレビュー/2012年3月12日SprBlender/005_keyframe.jpg,320x180);


** Objectパネル(続き) [#xe2e2152]
- 凹形状(形状の集合体)
- Blenderの親子関係:ObjectパネルのRelations
- Solid的なパラメータは親が持つ
- 子オブジェクトの形状をConvexにして,Compound Childに
-- → Solidを新規作成せず親SolidにShapeを登録するようになる.


*** SprJointPanel [#rf8c6947]
- 親オブジェクトにくっつく子オブジェクトにJointが設定される.
- Joint Target Name : 接続先の親オブジェクトの名前(Blender Object的な).
-- *JointにはBlenderの親子関係は使っていない.

- Joint Collision :つながってるやつ同士の接触をするかどうか.

- JointのPlug位置の変え方:
-- 数字をかえることもできるが,(※現在は数字での変更不可 2012/3/27)
-- Plug Handle Modeを押すと矢印が表示される.
-- この矢印を移動・回転してApplyを押すと数値に反映される.
-- (Socketの位置は自動計算)
-- → 変更後はSet Scene.(Spring Damper等以外はリアルタイム反映できるようにしてない)
- &ref(コードレビュー/2012年3月12日SprBlender/006_joint.jpg,320x180);


** Creature [#ge9fc9ef]
- Enable Creatureをチェック → その後にSet Scene   : Creature関連のオブジェクトが作られる

- オレンジの : Solid
- 灰色の : オレンジのの子になっている.表示用モデル
- ライトをoffにしてviewport renderingをしないとオレンジだけ表示とかはできない

- IK : 
-- IK Enabledのチェックを入れる


*** SprCreaturePanel : [#n26f1e1c]
- Creature Bodyのチェックを入れる

- Creature ID : この番号のクリーチャに,現在のオブジェクトがパーツとして属する.

- Creature Core : クリーチャ全体の設定をするためのパネルが表示される.パーツのうちどれか一つについてこれをOnにしておく必要がある.

- Real time EditingモードはObjectパネルにあったのと同じもの(のCreature用)

- Apply Rules : 
-- cr_0_0_Basic の名前でテキストエディタを作ると読み込まれる.
-- cr_0_rulesにルール名を描いておくと追加で読み込まれる.(# はコメントアウト)

- Rule Parameters : bpy.data.objects[“Base”].spr_creature_rule_parameter_0 のようにして参照できる
-- (“Base” : Creature Coreになってるオブジェクトの名前)

- 可視化:
-- Visualizerにチェックをいれる
-- Display <-> Hide で可視化オブジェクトの表示を切り替えられる

- Visualizer Scale : 可視化オブジェクトのスケール
- Accv Factor , Attt Factor : 注意量→可視化オブジェクトの大きさ についての係数


- 表示されている可視化オブジェクトは,下の方にある「本体」の「参照オブジェクト」.
-- (本体の形を変えると自動的に変化する)
- どのオブジェクトを参照するかは,オブジェクト名( maxAtt_sample_(ID)  )で判断

- Creatureの動作状況はテキストエディタパネルにリアルタイムで表示される.

----
* SprBlenderコードレビュー [#m6cda8da]
**  __init__.py [#gd6f543d]
- モジュールロード時に自動的に呼ばれる
- オペレータ自体の定義

- Vector, QuaternionはBlenderの機能
- PhysicsController()はphysics.pyで定義

- SprOperatorはBlenderの流儀に則っている.

*** <<<オペレータ本体>>> [#g3267a66]
- modal(...) : イベントコールバックのようなもの.

- scene = bpy.context.scene : 現在アクティブなシーン
-- (レイヤとは違う.レイヤ群を含むシーン全体.普通に使っていると1つしかできないが,2つ以上作ることは可能)

- physics.info : テキストエディタに情報を表示する部分
- scene.game_settings : 実はbulletのパラメータ.変数として借用している

- 同期(physcis.sync()) : 位置・姿勢の同期

- scene.spr_step_enabled : Physics Stepのチェックボックス
-- (この変数名の定義はproperties.pyで行っている)

- キーフレーム
-- physics.record_keyframe_step_counter = 0 にすると,次ステップでphysicsが保存してくれる.
-- (0でない場合,1ずつ減らして0になると保存 → 数ステップに1回だけ保存)

- 可視化
-- physics.visualizerを呼ぶ


- execute() : operator登録時に呼ばれる
- context.window_manager : パネル群を管理している人
- タイマーの登録はここに対して行う

- cancel() : ?



*** <<<UI>>> [#s5005026]

<コールバック処理>

- UI Buttons:
-- Operatorを継承したクラスを作る.
--- (Buttonのコールバック関数を作る必要があるが,Blender上で関数オブジェクトに相当するものがOperator.)

- PlugHandle
-- 名前と結びついた矢印オブジェクトがあれば取得,なければ新規作成
-- bpy.data.objects.new で作る.第二引数がNoneだとEmpty.
-- Emptyの表示形態として矢印を選択しているがいろいろ選べる.
-- parentをもとのオブジェクトに指定している.→相対位置が固定される.
-- location, rotation_quaternion を指定することで位置を変えられる.

-- (今ハンドルは編集終了するといちいち消しているが,残して置いて編集不可にすることもできるだろう)
--- (※現在はハンドルを表示したまま編集不可にしている 2012/3/27)

*tips : context.object.~~ とかで現在選択しているオブジェクトのプロパティが取得できる

<UIの定義>

- bpy.types.Panel を継承したりとかして作る

- draw(): UIの変化があるたびに呼ばれる
- row.prop( ~~ ) でpropertiesのパラメータをいじるためのUIがつくられる
- “FIlE_TICK” : 緑チェックアイコン
- row.operator(~~) で上で書いたOperatorを呼び出すボタンが作られる



*** <<<登録>>> [#n6492dc5]
- register_properties : properties.pyにある



** properties.py [#ea6e3e7a]
- プロパティ.
- bpy.types.Scene.の下に新しい変数を作って,bpy.props.~~~クラスのインスタンスを作ることであたらしいプロパティが作られる.

- ↓context.sceneとかcontext.objectとかと結びついている
-- bpy.types.Object
-- bpy.types.Material
-- bpy.types.Scene


-(util.py, wrap_cr.py, wrap_ph.py は使っていない)


** physics.py [#v3a3084f]

*** PhysicsController() [#nd9a51cd]

- phSdk, phScene等を作って持っている
- visualizerも作って持っている

- initialize(), construct_scene() : Set Sceneでよばれる

- construct_scene() : 
-- 全Objectに対してsolidを作る
-- 全solid_controllerに対してjointを作る
-- CreatureControllerをCreatureの数(solid作成時に見つける)だけ作る


- add_object(): SetObjectsの機能.
-- 選択オブジェクト全てにたいしてconstruct_scene(のsolidとjoint)と同じ事をする



- create_solid() : 
-- もし登録済みであっても,一度消してもう一度作り直す
-- 消す: freeze処理 = 1光年先にとばしてコンタクトをoff
-- ShapeがNoneならなにもしない
-- Compound Objectの子ならやはりなにもしない(compound_objectsに入れて置いてあとでなんとかしてもらう)

- create_shape() : 
-- 形状をひたすらつくるー.


- create_joint() : 
-- Jointを作る(socketのポーズを計算したり)
-- jointはsolid_controllerに追加する
-- limitについては作るだけ作って置いて,set_joint_parametersで適用する


- step() : ふつうにstep

- sync() : 
-- solid controllerのsyncを呼んでいる





*** SolidController() :  剛体1つにつき1つ作られる [#fc9f2085]

- Apply Parametersを呼ぶと set_object_parametersが呼ばれる
-- リアルタイムモードだと毎ステップ呼ばれる

- sync() : 
-- blender childは ローカル座標しかもってないのでワールド座標を計算する
--- (mat_worldは取得できる)
-- blender側で動いていればblender→Springheadの反映をする.
-- そうでなければSpringhead→Blenderの反映をする

- Record Keyframeの機能はSpr→Blender反映の所に描いてある


- *Tips: C-i でなんでもキーフレームにできます.質量とか!



** creature.py [#qbfd3f40]
<<クリーチャ>>
*** CreatureController() : [#gf9b61f9]

- create_creature() : 
-- Creature構成
-- spr_creature_idの合致するすべてのsolid_controllerについて,
--- coreならcoreに設定
--- crIKSolidとcrIKJointを作成 → ボディに登録
--- コントローラを作成
--- 準備判定 → All Goかどうかをチェックする

- (creatureのstart()はここで呼ばれる.Enable Creatureのチェックボックスはこれではなく,PhsicsControllerのStepでcrSdk.Stepを呼ぶかどうかにかかわる


- update_rules() : 
-- bpy.data.texts[“~~~”]でテキストエディタが取得できる
-- テキストエディタの .as_string() で文字列

- update_parameters() : 
-- blenderのsceneの変更を,内部モデルシーンにも適用する
-- (リアルタイム適用モードじゃないとうまくいかないバグがある)→※修正済み2012/3/27


** visualizer.py [#x8a6f7f8]
<ビジュアライザ>
*** Visualizer(): [#da465ce6]
- 表示すべきデータはPhysicsControllerからとってくる

- update() : 
-- 各可視化機能のupdateを呼ぶ


- update_cr_current_model() :  注意と認識の可視化
--(最初のcontext_objは,あとでcontextを元に戻すために保存してある)

- copy.copy(cr.models[“current”])
-- → deep copyでないので問題が起きる可能性はある
-- (つちだ: model に clone というのがあるので試してみるといいかも)

<<visualize>>
- prepare_object : 可視化オブジェクトをあれば見つけるしなければ作る
-- →で,可視化オブジェクトの位置を更新する
-- (obj.location)

- 視覚・触覚注意 → 可視化オブジェクトの大きさをかえてるだけ
-- (obj.scale)

- info書き込み:
-- 変数はphysics_controllerに保存しているが,最終的にテキストエディタに反映するのはビジュアライザ

- L88 : lso.GetAttr(key) : NamedTuple (dictの一要素みたいなもん.key, value)
-- → lso.GetAttr(key).value とかやるといい


- prepare_object() :

-- parameters :
--- Mattvとか→ type
--- spr_attvとか→blenderの可視化オブジェクトの名前の接頭語(この後ろにcreature_idがつく)
--- *今は受け渡しに組み立てられた文字列を使っているが,その必要はなさそうだ.

-- 可視化オブジェクトがなければsampleを使う
--- bpy.ops.object.add_named →リンクを作れる

-- L422 : hide_select : 編集不可になる.

-- Group Visualize obj
--- Creatureごとにまとめて表示をOn / Offしたい
--- → Blenderのグループ機能を使う.
--- (グループに登録しておいて,まとめて消すときにはグループ内のすべてのオブジェクトを隠す)



- update_view_angle() : 視野の可視化
-- 視野角の設定値が変化したら,可視化オブジェクトも消して作り直す
-- 円錐形の頂点メッシュを自分で組み立てる
-- 頭にくっつけるのは頭をParentにすることで行ってしまう
-- これもグループに登録


** bl_util.py [#vec5c36c]
- マテリアルとかメッシュとか作る便利関数