読者です 読者をやめる 読者になる 読者になる

AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

SpringBoneでの運動方程式の近似処理

SpringBoneでの計算処理について
バネなので、F = K・X(t) が運動方程式

Verlet 法の計算原理
https://www1.doshisha.ac.jp/~bukka/lecture/jikkenn/simulation/verlet-3.html


curr=x(t+h)
prev=x(t)

hが十分小さいとして、Taylor展開して

x(t+h)=x(t)+ h*dx(t)/dt + ......

展開を三乗まで近似すると

x(t+h)=2・x(t)-x(t-h)+h^2*F(x(t))/m ←mは質量

curr = 2 * prev - preprev + h*h * Force / m

これは

next = 2 * curr - prev + h*h * Force / m

と同じ

これがプログラムの以下の代入と一致する

//verlet
currTipPos = (currTipPos - prevTipPos) + currTipPos + (force * sqrDt);

sqrDt = Time.deltaTime * Time.deltaTime = h * hってこと



たとえば空中から落下するとき、自分が動くと子供はバネでつながってるから、
バネに引っ張られるか、押される
(prevTipPos - currTipPos)の値の正負で力の向きが変わる


この運動方程式を上記のVerlet法で計算して、

Vector3 aimVector = trs.TransformDirection (boneAxis);
Quaternion aimRotation = Quaternion.FromToRotation (aimVector, currTipPos - trs.position);
trs.rotation = aimRotation * trs.rotation;

自分が計算された座標に方へ向くような回転をする
ボーンは移動はしてなくて、回転しかしてない。


スカートは斜めだから空中落下すると横に広がる

試しにプロ生ちゃんのお尻側のスカートが垂直になるように体を傾けて、上下に動かすと
垂直のお尻側スカートはほとんど動かない
水平成分に力が加わらないし、垂直方向はバネといっても、スプリングの距離を一定にする処理が入ってるので、
ボーンは動かないし、回転もしない


加わる力

//stiffness
Vector3 force = trs.rotation * (boneAxis * stiffnessForce) / sqrDt;

//drag
force += (prevTipPos - currTipPos) * dragForce / sqrDt;

force += springForce / sqrDt;


dragForceは減衰力
stiffnessForceはバネのやわらかさ

(prevTipPos - currTipPos)*dragForce
正方向に移動すると負になるので摩擦力みたいな抵抗になりますね。だから減衰力か


Vector3 force = trs.rotation * (boneAxis * stiffnessForce) / sqrDt;
この力が難しいなあ
やわらかいほどひらひらするんだろうけど 荒ぶるというか

tsubakit1.hateblo.jp


へー
QuaternionとVector3を掛け算したことなかった

Vector3.up * transform.rotation が、transform.upになるらしい
目から鱗
ローカル回転をワールド回転に変換する感じか

ってことは上記式は、boneAxisはロカールで、forceはワールド座標でのベクトルか

boneAxisってプロ生ちゃんは(0,1,0)で、UnityChanのSpringBoneでは(-1,0,0)になってる
これは子供の骨までの向きらしい


プロ生ちゃんはBlenderで作ってそうだから、座標系の違いを意味しているのかもしれない


SpringColliderとの衝突は、
f:id:yasu9780:20161124175441j:plain

広告を非表示にする