前回の続きです。
オブジェクトの配置情報と頂点バッファを使ったバウンディングボックスを作成し
オブジェクトにフィットするよう衝突形状の配置を行いました。
これができるならば、その位置にモデルを描画することもできるはずです。
自分は BulletSharp の RigidBody クラスを継承した ExtRigidBody クラスを用意し
描画用のノードにアクセスする情報を持たせました。
これで CollisionObject を描画時に、必要な描画情報を手に入れられるようになったので
既存のノード描画機能にちょこっと手を加えて、CollisonObject の WorldTransform を使った
ノードの描画を行えるようにしました。
結果を次に示します。
CollisonObject の場所に…
オブジェクトが描画できるようになりました。
正しく配置できているようですね。
うずうず…
ちょっと遊ばせてください。
次に示す通りオブジェクトをセッティングしました。
再生!
ぶつかる!
ドミノ倒し
青色がスリープ中、ピンク色がアクティブなオブジェクトを表しています。
描画モードを切り替えると、衝突形状ではなくオブジェクトを描画します。
これにテクスチャを貼ったり、複雑なモデルに置き換えることも可能です。
いやー、楽しいですね。
はい、では続いて Constraint を設定できるようにしましょう。
どこに、何を追加して、何と何とを結びつけるのかですが…
新しく 3D カーソルというものを用意したいと思います。
そこでひとまず、ラインを描画できるようにしましょう。
ということでグリッドを描画する機能として利用しました。
正しく動作しているようです。
同じ要領で 3Dカーソルの描画も実装しました。
グリッドを作成する際、プリミティブごとの編集が大変煩雑だったため
(一つひとつ選択して修正するというもの…)
ついでに、ノードツリーを複数選択可能にして、一挙に選択したノードのプロパティを
編集できるようにしました。
動作を確認しました。
これは今後の作業効率がグンと上がりそうな修正ですね。
もっと早い時期に対応していても良かったと思いました。
WPF でのツリーの複数選択ですが、PropertyTools の機能を使って実現しました。
詳細はコチラ、デモのソースコードをジッと見つめれば誰でも対応できます。
(本当に PropertyTools は素晴らしいですね!これを独自で作るとなると結構大変なんです。)
では、3Dカーソルもできたことですし、続いて画面をクリックすることで衝突形状を選択する
という操作ができるようにしてみましょう。
なかなか予定通りには進まないというか…まずはコンテキストメニューの設置から実装しました。
次に示す通り、Shift + A キーを押すと Add メニューが現れ、各種コンストレイントの追加
ができるというものを用意しました。(まだ、どれも機能しません。)
右クリックは選択に使うので、使用するまでは Visibility を Collapsed にしておきます。
キーダウンイベントで Visibility を Visible にして .IsOpen = true; とすることで対応
コンテキストメニューを閉じる時に、また Collapsed にして再度右クリックで出ないようにします。
で、レイキャストを行う前に、点結合のコンストレイントの描画を行えるようにしました。
結果を次に示します。
デバッグ時にこれが確認できないといけないので、先に実装したというところです。
やっとレイキャストして2つの衝突形状を選択して、コンテキストメニューから
コンストレイントを指定すると、Constraint が 3D カーソルの位置に追加される
という機能の実装に取り掛かれます。
(本当に次、そこから実装するのか怪しいところですが…)
必要な情報を洗うと、1つまたは2つの CollisionObject(RigidBody) のクラスと
追加先の 3Dカーソルの位置、そして何を追加したいかという情報です。
コンテキストメニューと3Dカーソルより、「何をどこに追加したいか」はクリアしました。
「何と何とを結びつけるか」この情報を去年示した Bulletの衝突判定(レイキャスト)を使って実現
したいと思います。
視点から画素に向かってレイ(光線)を放つ…、デモと同じですね。
ひとまず、右クリックするとレイ(光線)を計算する部分を実装しました。
頭悪いのでちょっと悩みましたが、次のコードで正しく求められているようです。
衝突判定の勉強でやった通り AABB 判定の後、レイテストを行う処理を加えます。
…結果から言うと、上記のコードは正しく動作しませんでした。
らしい方向にレイが出るけど、完全な方向を向いていませんでした。
そこで、Demo にある GetRayTo を参考に実装して解決しました。(バカだな〜)
確認した結果です。
シフトキーを押すことで、複数選択が可能です。
選択したオブジェクトの色が緑色に近づきます。
正しく動作しているようです。
レイテストは簡略化して次のコードで解決しました。
これで必要な情報が揃ったので、Point2Point コンストレイントの追加機能を実装します。
…の前に、3Dカーソル位置を左クリックで設置できるようにしました。
現在の3Dカーソル位置を通る視線に垂直な平面とレイとの交点に移動するというものです。
レイが求められているので対応は簡単ですね。
参考に平面と直線との交点を求める関数を次に示します。
これは正しく機能しました。
(これダメだったらまずいでしょう。よく見かける問題ですし、過去何回か解いてますから。)
<実装>
やっと、3Dカーソルの位置に選択したオブジェクトを結びつける
点結合コンストレイントの設置が確認できました。(良かった)
コンストレイントだけを描画した結果がこちら↓
で、さっそく使い勝手が悪いと感じました。
色々試す前に次の機能が欲しいです。
ピック機能がほしい。
(選択したオブジェクトをマウスで直感的に移動できる機能のこと)
これがないと、セッティングしたはいいけど、どんな動きをするのか確認できない。
つまらない。
コンストレイントを設置したままリセットする機能
せっかくコンストレイントを苦労して設置したのに、停止するとこれらの情報が吹っ飛びます。
コンストレイントをそのままに、最初の状態に戻してそこから再生できるようにしたい。
3D カーソルをもっと配置しやすくしてほしい。
ひとまず直感的に置けるのは良かったのですが、座標指定なり、近くのグリッドへの配置なり
軸に沿っての移動など、目的の場所にさっと 3Dカーソルを移動できるようにしないと話にならない。
設定したコンストレイントの情報を保存できるようにしたい。
この機能が無いと編集する気も起きない。
(ファイルフォーマットを考えないとまずそう)
そのほか、コンストレイントのプロパティを実行時に編集したいとか…
で、今は点結合だけですが、コンストレイントの種類を増やすのはその後でいいと思います。
はい。
今回の目標、Constraint の設置を達成したので、ここで話を切りたいと思います。
次回は上記で示した使い勝手の悪いところを1つずつ修正していきます。
お楽しみに!
2012/10/10 初記。