とあるモデルでのモーションの挙動がオカシイということで調べてみた所、
どうやら「付与」がうまく行ってない感じ。
付与に関してはうまく行っているようでダメな場合があり、
よく分からない状況だったりしました。
ところが先日色々いじくってたら、
なんかうまく行くようになりました。
当初は素直に、
対象ボーンをA、参照するボーンをBとして、
Aの変形量 += Bの変形量 × 付与率
とやったりしたのですが、どうもうまく行かない。
次に、
ある描画フレームとその次のフレームでの変形量の差分を求めて、
Aの変形量 += Bの変形量の差分 × 付与率
とやったらうまく行ったのですが、モデルによってはダメなことも。
そして今度は、
バインドポーズ時との差分でやってみたらイイ感じになりました。
バインドポーズ時の各ボーンの回転量はゼロなので、
当初のやり方でも回転に関しては間違ってないのですが、
バインドポーズ状態に初期化してないことが原因でした。
初期化してないので延々積算してしまっていました。
要するに初期化のし忘れ・・・でした(^_^;)
ということでまとめると、
1)各ボーンをバインドポーズ状態に初期化
2)Aの変形量 += Bの変形量の差分 × 付与率
を毎フレームやれば良い感じ。
実際には1)と2)の間で Bone Skinning とか IK とかをやります。
そして回転に関しては基準の回転量がゼロなので、
差分計算は省いても大丈夫なことになります。
「回転付与」に関してはおそらく解決だとは思いますが、
試すのに良さげなデータを持ってないため、
「移動付与」や「ローカル付与」は未検証です。
後で問題が起きるかも?(^_^;)
ということで改善後の動作テストを見るにはこららからどうぞ。
改善前はこららです。
確かにヒジの曲がりが直ってる感じです。
なお、テストでは以下のデータを使用させていただきました。
モデルはこちら、モデルモーションはこちら、カメラモーションはこちら。
それから今回はもう一つ問題がありました。
“瞳”の表示がなんかオカシイ・・・。
調べてみると、透過オブジェクトの描画順に起因する問題でした。
ところで three.js では、
透過オブジェクトは奥から手前へ、
不透過オブジェクトは手前から奥へ、
の順で描画するようになっています。
透過オブジェクトの描画順については、
そのようにしないと矛盾が起きるのは理解しやすいと思います。
不透過については奥から手前でも問題ないのですが、
手前から奥にすると効率がよくなります。
奥行きを表すZバッファの値を比較することで、
実際の描画量を減らせる効果を期待できるからです。
明示的に透過指定のあるマテリアルや、
テクスチャが透過成分を含むマテリアルの場合に、
透過フラグを指定するように今までやってました。
大抵のモデルではそれで問題は起きない感じなのですが、
一部のモデルではうまく行かない場合があるようです。
そこで、
全マテリアルの透過フラグを強制的にオンにする機能を追加して、
透過問題に対応できるようにしました。
でも、よく考えてみると、
材質モーフとかで透過度が変化することは十分ありそうなので、
描画効率が落ちるかもしれないけど
デフォルトでオンにしてしまった方がよさそうです。
透過になるかどうかは静的ではなく動的にならざるをえないので、
それに対応できるようにしないとうまくない感じですね。
ただ現状では頂点モーフしか対応してなかったり・・・(^_^;)
それ以外の種類のモーフはいずれどうにかしたいですね。