それでは当初の目的通り、スカートを作ってみましょう。
スカートを作るためには、布シムに足との衝突判定を組み込む必要があります。
大量の格子点(重り)と足との接触を判定しなければならないので、なるべく計算の楽な方法を取る必要があります。
今回は、重りを点、足をカプセルとみなして判定を行うことにします。
カプセルとは円柱の両端に半球をくっつけたものです。
カプセルは線分と半径rで定義されます。線分からの距離がr以内の部分がカプセルになるわけですね。
キャラクタはボーンでアニメーションをつけます。
腰から膝までのボーンと、膝からかかとまでのボーンを使って足を動かすことにします。
ボーンを円柱の軸とみなせば簡単にカプセルの位置が計算できます。
アニメーション関係のソースはこちらの記事のものを流用しています。
衝突している重りに対しては足にめり込まないように足の外に押し出す力をかけます。
物理シム業界ではペナルティ法と呼ばれる方法です。
円柱の表面と重りとの間にバネを入れるだけで実現できます。
要はめり込んだ重りをバネの力で押し返すわけです。
ついでに重りのエネルギーを削るためにダンパを入れておくと動作が安定します。
ペナルティ法を使うことで、衝突判定が入る以外は今までの布シムの枠組みをそのまま流用できます。
カプセルと点の衝突判定についてWeb上に良い資料が見つからなかったので、補足しておきましょう。
衝突は円柱状の部分と両端の半球部分に分けて考えます。
衝突判定する点を点xとします。(以下、a,b,x,yは3次元ベクトル、sはスカラー)
点xから線分に下ろした垂線の足yを求めます。
線分の両端の座標をa,bとします。
点yはa,bを通る線上にあるのでy=a+s(b-a)として表されます。
垂線はその線と直交しているので、
(y-x)・(b-a)=0 (・は内積)を満たす必要があります。
未知数はsだけなので、この式は簡単に解けます。
sが分かれば点yが求まり、これで円柱との判定ができます。
点yが線分上に存在して、かつ点xと点yの距離r'がrより小さければ円柱と衝突しています。
r-r'が円柱表面から点xまでの距離になるので、この値をペナルティ法で使わせてもらいましょう。
円柱と衝突していなかった場合は、点と球との判定を行います。
こちらは点a,bと点xの距離がr以内であるかという判定をするだけなので簡単です。
蛇足ですが、カプセルと球(半径r'')との判定も同じ原理です。
上記のrをr+r''に置き換えるだけで済みます。
この辺のお手軽さが、衝突判定においてカプセルが使われる理由なのでしょう。
というわけで、今回のソースです。
足のシルエットが布越しに見える感じはなかなか良いんじゃないでしょうか?
とは言え、スカートと言うには少し布がビロビロしている感じです。
正直、パラメータの設定が難しいですね。
この布は重りの上下左右方向と対角方向の2種類のバネしか入れていないので、
もしかすると3種類目を入れると改善するのかもしれません。
スカートの形状が足に密着した長い円柱形状というのも宜しくないです。
現実世界では、そんなタイトロングなスカートでは足を大きく動かせません。
円錐形状にするか、膝の辺りまでスリットを入れるかすると、もう少しリアルになるかと。
プログラムを簡単にするために、一本のバネについて同じ計算が2度行われています。
実際にゲームで使う際には改良しておいたほうが無難でしょう。
いつものことながら、エラーチェックは最低限であり、
このサンプルの使用によるいかなる不幸も当方では責任を負いかねます。
# Microsoft DirectX SDK (March 2008) にでコンパイルし直した、バイナリ&ソースです。
# プロジェクトはVisualStudio2008用になります。
|