three.js‎ > ‎

Bone アニメーション


ボーン(リグ)を使ったアニメーション。リグがどういうものかは、BVH Motion Playerを見てみてください。
別のアニメーション方式であるモーフターゲットに比べると、理論上はハイポリゴンでのファイルサイズは小さくなる。
実際は、ハイポリゴンを綺麗に、動かせるほど、リグの精度がよくない。(まだ2点だし)

ここではThree.jsでのBoneアニメーションの仕様 r46版をだいたい、解説したいです。
仕様は、リビジョンごとに、大きく変わるでしょう。

Colladaを読み込む

r46では、まだうまく読み込めませんが、Three.jsでのBoneアニメーションはCollada Loaderを使うのが本流になりそうです。
Collada Loaderのコードを読んでみることをお勧めします。

計算処理速度や、安定性(ラグの発生を防ぐ?) を考えると、Collada Loaderがやっている
Boneアニメーションデーターを読み込み時に単純なモーフアニメーションに変換するのは、ベストでしょう。
かわりに、相当メモリ消費しそうですが

どうもColladaの方がメインなため、Skinningの方は、いまだ2点 Weightのままのようです。

Bone付き、GeometryからSkiningMeshを作成する

リアルタイムでのSkinning アニメーションは速度的に難ありなのか、まだ開発段階のようです。

Boneの仕様は、以下サンプルのbuffalo.jsを見てみるとよくわかる。
角度や位置は相対的で、BVHフォーマットと非常によく似てます。
  • parent  親のBoneのindex.indexは表示される順番、ルートは-1
  • name Bone名
  • pos 親からの相対的な位置
  • scl スケール 普通 1,1,1
  • rot 親からの相対的な角度(rotqあればいらない)
  • rotq  四元数・クォータニオンでの表示

skinWeights・skinIndices

Vertexごとの、Weightと、対象ボーン
r46では、weightはたった2つのボーンに対してしか指定できないようです。
そして、2つ指定しますので、json上のskinWeightsは、vertexの数の2倍の長さになります。(後で変換されてVertexと同じ長さになる)

skinIndices には
vertex1のbone1,vertex1のbone2,vertex1のBone1,vertex2のbone2という風に続きます。

skinWeightsには
vertex1のbone1のweight,vertex1のbone2のweight,vertex1のBone1のweight,vertex2のbone2のweightという風に続きます。
weightは1と2で合計1にならないといけません。(内部で調整されますが1以下が望ましいでしょう)

boneが1つしか使わない場合はskinIndices には同じboneのindexをskinWeightsには、1,0か0.5,0.5を入れます。

skinIndices/skinWeightsを自動で取得するには
限りなく精度低いですが、devバージョンのThree.jsでは読み込めるColladaモデルから、
skins[0].skinController.skin.weights; に生のWeightsデーターがあります。
これを加工すると、ローポリゴンならそこそこなものになります。ハイポリは酷い結果ですが


Animationさせる

AnimationHandlerにanimationデーターを追加して、そこからAnimationを作成します。
JsonのAnimationDataからいろいろ変換しないといけないので、AnimationHandlerに追加する必要があります。

あとは、AnimationをPlayして、AnimationHandlerからUpdateするとアニメーションします。

ただ、ライトとか怪しいです。MeshBasicMaterialを使うほうが無難かもしれません。

Boneアニメーション周りは、いろいろ開発中みたいです。ただ、動かないことはないです。

サンプル

three.js webgl - animation - skinning - Boneアニメーションの方法がつまっています。これをよく読むとできるようになります。





Comments