コンテンツにスキップ

Animation Basics

Mapray JS でアニメーション表現を実現する方法について詳細に説明します。 簡易的な説明は こちらのページ をご覧ください。

アニメーションは、フレーム毎に時刻 \(t\) を決定し、時刻 \(t\) に応じて Entity の特定プロパティ(ピンの位置やサイズ、色など)を変更していくことで実現します。 Mapray JS のアニメーションでは、下記 UpdaterCurveBindingBlock を組み合わせることによって実現します。

image about animation flow

Updaterは、アニメーション時刻 \(t\) の更新を管理し Curve へ伝えます。 Curveは、受け取った時刻 \(t\) に対して、プロパティとして設定する値 \(v\) を決定します。 BindingBlockは、Updater, Curve をBind(関連付け)し、Entity のサイズや位置といったプロパティ値の更新を行います。 実装の手順を順に説明します。

時刻の管理

第一にフレーム毎に時刻 \(t\) を計算します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class CustomViewer extends maprayui.StandardUIViewer {
    constructor( container, apikey ) {
        super( container, apikey);
        this.totalTime = 0;
    }

    onUpdateFrame( delta_time ) { // override
        super.onUpdateFrame( delta_time );
        this.totalTime += delta_time;
        // update entity properties at this.totalTime
    }
}

onUpdateFrame() 関数は、 mapray.StandardUIViewer クラスに含まれる関数で、毎フレーム呼び出される関数です。 この関数をオーバーライドすることで毎フレーム処理を行うことができます(詳細はStandard Viewer の説明 を参照してください)。 onUpdateFrame() の引数( delta_time )は、前回の呼び出しから経過した時間(秒)です。 時刻 \(t\) を表す変数 totalTime は、コンストラクタで 0 に設定され、フレーム毎に現実の時間と同じように増えていきます。 この totalTime に応じてエンティティなどのプロパティを変更することでアニメーションを実現することができます。

Updater

onUpdateFrame() は非常に高頻度で呼び出されるため、処理時間を最低限にする必要があります。 60[fps] を維持するには 1フレームの全ての処理(Mapray JS内部の処理も含みます)が 16[ms] 以内に完了する必要があります。 この時間を超えると FPS が低下したりアニメーションがカクつく原因になります。 また FPS が低下しなくてもCPU使用率が高くシステムの動作が遅くなる原因になります。 mapray.animation.Updater クラス(以降 Updater)を用いることで、プロパティの更新を高速、効率的に行うことができます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class CustomViewer extends maprayui.StandardUIViewer {
    constructor( container, apikey ) {
        super( container, apikey);
        this.totalTime = 0;
        this.updater = new mapray.animation.Updater();
    }

    onUpdateFrame( delta_time ) { // override
        super.onUpdateFrame( delta_time );
        this.totalTime += delta_time;
        this.updater.update( mapray.animation.Time.fromNumber( this.totalTime ) );
    }
}

通常のアニメーション表現では毎フレーム実時間と同じように増えていきますが、早送りやスロー再生、逆再生するような場合など用途に応じて更新方法を変更します。

Curve

CurveUpdater から時刻 \(t\) を受け取り、その時刻におけるプロパティ値を計算します。 Curve は抽象クラスなので実際には具象クラスを利用します。 用途に応じて適切なクラスを選択して利用します。

クラス 概要 Type
ConstantCurve 常に一定の値を返す 任意
KFStepCurve あるキーフレームから次のキーフレームの直前まで一定の値を返す 任意
KFLinearCurve キーフレーム間の数値またはベクトルを線形補間した値を返す number, vector2, vector3, vector4
KFQuatLinearCurve キーフレーム間の四元数を線形補間した値を返す vector4
ComboVectorCurve 複数の Curve を組み合わせて新たなカーブを作成する vector2, vector3, vector4

また、独自の Curve クラスを作成することもできます。詳しくは Custom Curve をご覧ください。

出力 Type

Curve では、出力される値の型を明示的に管理されるため、初期化時に明示的に利用する型を指定する必要があります。 例えば KFLinearCurve で数値(Type は number)を扱う場合は下記のように初期化します。

1
2
3
4
5
6
const numberType = mapray.animation.Type.find( "number" );
const curve = new mapray.animation.KFLinearCurve( numberType );
curve.setKeyFrames([
    mapray.animation.Time.fromNumber( 0 ),  5.0,
    mapray.animation.Time.fromNumber( 5 ), 40.0,
]);

Type には下記の種類があります。

Type JavaScript 既定値
boolean boolean false
number number 0
string string ""
vector2 mapray.Vector2 [0, 0]
vector3 mapray.Vector3 [0, 0, 0]
vector4 mapray.Vector4 [0, 0, 0, 0]
matrix mapray.Matrix [0, 0, 0, 0, ...]

Curve の実装

Curve の例を示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class CustomViewer extends maprayui.StandardUIViewer {
    constructor( container, apikey ) {
        super( container, apikey);
        this.totalTime = 0;
        this.updater = new mapray.animation.Updater();

        const numberType = mapray.animation.Type.find( "number" );
        const curve = new mapray.animation.KFLinearCurve( numberType );
        curve.setKeyFrames([
            mapray.animation.Time.fromNumber( 0 ),  5.0,
            mapray.animation.Time.fromNumber( 5 ), 40.0,
        ]);
    }

    onUpdateFrame( delta_time ) { // override
        super.onUpdateFrame( delta_time );
        this.totalTime += delta_time;
        this.updater.update( mapray.animation.Time.fromNumber( this.totalTime ) );
    }
}

この時点では Curve が独立に定義された状態で Updater などとは関連づけられていない状態です。

BindingBlock

BindingBlockUpdaterCurve による値の計算と、Entity プロパティなどの値の更新をBind(関連付け)します。

よく利用されるプロパティについては、Entityクラスごとに定義されているデフォルトの BindingBlock を利用することで、簡単に呼び出すことができます。

Entity については Entity.animation プロパティを利用することで、定義済みの BindingBlock を利用することができます。 その他 PointEntityEntry など、同様のプロパティが用意されているものがあります。

下記に PinEntityModelEntity の例を示します。

PinEntity のプロパティ

PinEntity では下記のプロパティがアニメーションに対応しています(APIドキュメント で確認することができます)。

プロパティ Type
fg_color vector3
bg_color vector3
size vector2, number
  • fg_color, bg_color
    • vector3 を出力する Curve を指定します(RGB 値として各 \(0.0〜1.0\) の数値で設定します)。
  • size
    • vector2number に対応しており vector2 を指定した場合は縦、横独立した値が指定され number を指定した場合は縦横同じ値が指定されます。

PinEntity を作成し sizeUpdaterCurve を指定する例を示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class CustomViewer extends maprayui.StandardUIViewer {
    constructor( container, apikey ) {
        super( container, apikey);
        this.totalTime = 0;
        this.updater = new mapray.animation.Updater();

        const numberType = mapray.animation.Type.find( "number" );
        const curve = new mapray.animation.KFLinearCurve( numberType );
        curve.setKeyFrames([
            mapray.animation.Time.fromNumber( 0 ),  5.0,
            mapray.animation.Time.fromNumber( 5 ), 40.0,
        ]);

        // Create Entity
        const pinEntity = new mapray.PinEntity( this.viewer.scene );
        const pinEntry = pinEntity.addPin( new mapray.GeoPoint( 139.699985, 35.690777, 40 ));
        this.viewer.scene.addEntity( pinEntity );

        // Bind size param with the updater and curve
        pinEntry.animation.bind( "size", this.updater, curve );
    }

    onUpdateFrame( delta_time ) { // override
        super.onUpdateFrame( delta_time );
        this.totalTime += delta_time;
        this.updater.update( mapray.animation.Time.fromNumber( this.totalTime ) );
    }
}

ModelEntity のプロパティ

ModelEntity では下記のプロパティがアニメーションに対応しています(APIドキュメント で確認することができます)。

プロパティ Type
position vector3
orientation matrix, vector3
scale vector3, number
  • position
    • vector3 の値に対応しており、要素が longitude, latitude, altitude の順に設定されていると解釈します。
  • orientation
    • matrix を出力する Curve インスタンスをBindした場合、行列は MLOCS での回転行列と解釈します。
    • vector3 の場合は、その要素が heading, tilt, roll 順であると解釈します。
  • scale
    • vector3 型の Curve インスタンスを接続した場合、XYZ 別の倍率、number 型のときは均等倍率と解釈します。

その他のEntity のプロパティ

リファレンスマニュアル を参照してください。

Entity のデフォルトの BindingBlock で用意されていないプロパティを扱いたい場合や、 Entity 以外の値を更新したい場合は独自の BindingBlock を作成することができます。 独自の BindingBlock を作成するには EasyBindingBlock を利用します。 このクラスを利用することで簡単に独自の BindingBlock を作成することができます。

利用方法については EasyBindingBlockページ をご覧ください。