three.jsでキーフレームアニメーションをする

three.jsには様々なアニメーションの方法がありますが、今回はthree.js上でキーフレームを作成・再生を行う方法について説明します。

今回は例として以下のデモのような回転しながら動くティーポットを作成します。


 ソースコード

キーフレームアニメーションとは?

プログラムの説明に入る前にキーフレームアニメーションについて簡単に説明します。キーフレームアニメーションとは、キーフレーム補間を用いたアニメーションのことです。ここでキーフレームとは時刻とそれに対応する値のペアのことです。数学っぽく書くと

    $$keyframe = (t,v)$$

という風になります。キーフレームが一つだけではアニメーションできないので、以下のように複数個用意します。

    $$(t_1,v_1),(t_2,v_2),(t_3,v_3),...,(t_n,v_n)$$

座標軸上にプロットすると以下のような感じになります。(適当に値を与えています)

見てもらえばわかる通り、このままでは、キーフレームの存在する時刻上にしか値が存在しません。
なので、キーフレームアニメーションに必要な補間をして任意の時刻に値が存在するようにします。これでアニメーションさせることができます。以下は補間の例です。

もちろん、補間の方法は一通りではなく自由に選ぶことができます。例えば、以下のようなものも考えられます。

以上がざっくりとしたキーフレームアニメーションの説明になります。次からthree.jsの説明になります。

KeyframeTrackオブジェクト

three.jsでキーフレームアニメーションをするにはKeyframeTrackオブジェクトを生成する必要があります。といっても直接KeyframeTrackクラスを呼び出す必要はなく、まず、以下のようにJSON形式で用意します。

var positionKeyframeTrackJSON = {
    name: ".position",
    type: "vector",
    times: [0, 1, 2],
    values: [0, 0, 0, 2, 1, 15, 0, 0, 0]
}

上からわかるように、JSONにはname, type, times, values計4つのプロパティが必要になります。

nameにはアニメーションさせたいプロパティ名を指定します。今回は位置を動かしたいので”.position”ですね。詳しくはthree.jsのドキュメントの.parseTrackNameの説明を参照してください。

typeにはプロパティの型を指定します。positionはVector3型なので、’vector’とします。このtypeには’vector’の他にも’number’,’color’,’quaternion’,’boolean’,’string’などの文字列を使用することができます。詳しくはKeyframeTrackのソースコードの_getTrackTypeForValueTypeNameメソッドを参照してください。

timesとvaluesには時刻とそれに対応する値をそれぞれ配列で渡します。例えば今回は
times: [0, 1, 2],
values: [0, 0, 0, 2, 1, 15, 0, 0, 0]
としていますが、これは0秒の時に位置が(0,0,0)、1秒の時は(2,1,15),2秒の時は(0,0,0)であることを表しています。

これで移動のキーフレームトラックを作成しました。次は回転に関するキーフレームトラックです。

var rotationKeyframeTrackJSON = {
    name: ".rotation[y]",
    type: "number",
    times: [0, 2],
    values: [0, 2 * Math.PI],
    interpolation: THREE.InterpolateSmooth
}

次はrotationのy軸回転に関してアニメーションさせたいのでnameは”.rotation[y]”としました。これは単なるスカラーですのでtypeは”number”とします。ここで、新しく’interpolation’というプロパティがあることに気づかれたと思います。これは先ほど説明した補間の式を表します。これは現在、’THREE.InterpolateLinear’,’THREE.InterpolateSmooth’,’THREE.InterpolateDiscrete’の三種類から選ぶことができ、何も入力しないと自動的に’THREE.InterpolateLinear’になります。

以上のようにいくつかキーフレームトラックを用意したら以下のようにまとめてパースします。

var clipJSON = {
    duration: 2,
    tracks: [
        positionKeyframeTrackJSON,
        rotationKeyframeTrackJSON
    ]
}

var clip = THREE.AnimationClip.parse(clipJSON)

これで、アニメーションクリップを作成することができました。(THREE.AnimationClip.parseメソッド内でKeyframeTrackオブジェクトが作成されています。)あとは以下のようにAnimationMixerに登録して…

var mixer = new THREE.AnimationMixer(cube)
var action = mixer.clipAction(clip)
action.play()

以下のようにアニメーションループを回します。

animate()
function animate() {

    requestAnimationFrame(animate)

    mixer.update(0.01)
    controls.update();
    renderer.render(scene, camera);

}

これで冒頭のアニメーションを作ることができます。

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL