ジェスチャー

Wikitude SDKは多数のジェスチャーをサポートしているため機能と相互作用できます。

このサンプルでは、ARシーンで3つのジェスチャを使用して、眼鏡、ひげ、帽子の画像をドラッグ、回転、拡大縮小して顔に配置する方法を示します。

Target image

AR.ImageDrawableが生成されるたびに、応答するジェスチャを定義できます。

このサンプルでは、ドラッグ、回転、拡大縮小の3種類のジェスチャータイプを使用しています。それぞれジェスチャーに対する AR.ImageDrawableの応答を定義する3つのコールバック関数(onDragBegan, onDragChanged and onDragEnded)があります。

このサンプルでは、生成したAR.ImageDrawableが3つのジェスチャータイプすべてに応答します。

var overlay = new AR.ImageDrawable(imageResource, 1, {
    onDragBegan: function(x, y) {
        return true;
    },
    onDragChanged: function(x, y) {
        return true;
    },
    onDragEnded: function(x, y) {
        return true;
    },
    onRotationBegan: function(angleInDegrees) {
        return true;
    },
    onRotationChanged: function(angleInDegrees) {
       return true;
    },
    onRotationEnded: function(angleInDegrees) {
       return true;
    },
    onScaleBegan: function(scale) {
        return true;
    },
    onScaleChanged: function(scale) {
       return true;
    },
    onScaleEnded: function(scale) {
       return true;
    }
});

もし1つのAR.ImageDrawableだけを回転できるようにしたいならば、これが基本的な実装になります。

onRotationBegan: function(angleInDegrees) {
    return true;
},
onRotationChanged: function(angleInDegrees) {
   this.rotate.z = previousRotationValue + angleInDegrees;
   return true;
},
onRotationEnded: function(angleInDegrees) {
   previousRotationValue = this.rotate.z;
   return true;
}

onChangedコールバックは、ジェスチャが開始されたときの値と現在の値の差を示します。 このため、回転が正しく動作するように、ジェスチャ(previousRotationValue)の前にAR.ImageDrawableの最後の回転値を保存する必要があります。 ジェスチャが終了した後、その変数を現在の回転値に更新します。 AR.ImageDrawableの1つだけをドラッグ、拡大縮小、回転させないように、それぞれの値を保存する必要があります。

onRotationBegan: function(angleInDegrees) {
    return true;
},
onRotationChanged: function(angleInDegrees) {
   this.rotate.z = previousRotationValue[index] + angleInDegrees;
   return true;
},
onRotationEnded: function(angleInDegrees) {
   previousRotationValue[index] = this.rotate.z;
   return true;
}

現在、すべての単一のAR.ImageDrawableには、配列に格納されている最後のスケール、位置および回転値を保持しています。 AR.ImageDrawableのインスタンスを追加した後、1本の指でそれらをドラッグしたり、2本の指で回転させたり、ピンチジェスチャで拡大縮小したりできます。

Target image with overlays

サンプルでは、変数oneFingerGestureAllowedを使用して、どの種類のジェスチャが現在アクティブかを判断しやすくしています。 ドラッグは1本の指だけを使用する唯一のジェスチャであるため、2本の指でジェスチャを開始するとすぐに停止させなければなりません。 このイベントに応答するコールバック関数は、AR.context.on2FingerGestureStartedと呼ばれます。 この関数が呼び出されるたびにoneFingerGestureAllowedfalseに設定します。

onDragBegan: function(x, y) {
    oneFingerGestureAllowed = true;
    return true;
},
onDragChanged: function(x, y) {
    if (oneFingerGestureAllowed) {
        this.translate = {x:previousDragValueX[index] + x, y:previousDragValueY[index] - y};
    }
    return true;
},
onDragEnded: function(x, y) {
    previousDragValueX[index] = this.translate.x;
    previousDragValueY[index] = this.translate.y;
    return true;
}

onDragChangedは、oneFingerGestureAllowedtrueの場合に想定される動作のみを行います。そのため、新しいドラッグが開始されるたびにtrueに設定されます。

ターゲットまでの距離

このセクションでは、ターゲットとの距離を測定する方法と、測定値の変化にどのように応答するかを説明します。

ARシーンは、Advanced Image Trackingのコードに基づいており、ターゲットコレクションには1つのターゲットのみが含まれています。

AR.ImageTrackerを作成するときにターゲットの物理サイズを定義します。

ターゲットコレクションにすべてのターゲットの物理サイズの定義を含めることができるので、これは必ずしも必要ではありません(詳細は ターゲットの管理を参照)。

この目的のためにphysicalTargetImageHeightsオプションが使用され、各ターゲットのミリメートル単位の値が使用されます。

このサンプルでは、ターゲットのサイズが異なる場合、ターゲットが252mmの物理的な高さで標準のA4シートに印刷されていると想定します。もしターゲットサイズが様々ならばそれに応じて値を変更してください。そうしないと、測定値はそれほど正確になりません。

this.targetCollectionResource = new AR.TargetCollectionResource("assets/magazine.wtc");
this.tracker = new AR.ImageTracker(this.targetCollectionResource, {
    onTargetsLoaded: this.worldLoaded,
    physicalTargetImageHeights: {
        pageOne:    252
    }
});
ソースコードをGitHubで見る

次に、距離が変化したときに呼び出されるコールバック関数と、イベントをトリガーするミリメートル単位の変更しきい値を宣言します。

var pageOne = new AR.ImageTrackable(this.tracker, "*", {
    drawables: {
        cam: overlayOne
    },
    distanceToTarget: {
        changedThreshold: 1,
        onDistanceChanged: function(distance) {
            document.getElementById('distanceDisplay').innerHTML = "Distance from target: " + distance / 10 + " cm";
            overlayOne.rotate.z = distance;
        }
    },
    onImageRecognized: this.removeLoadingBar,
    onImageLost: function() {
        document.getElementById('distanceDisplay').innerHTML = "Distance from target: unknown";
    },
    ...
ソースコードをGitHubで見る

描画可能な定義は最初のセクションとまったく同じです。

オプション distanceToTargetは、トラッカーがどのように変更に応答するかを示します。 しきい値は1ミリメートルに設定されており、ユーザーがターゲットに向かって移動したり離れたりすると、コールバック関数によって値を画面の下部に表示し、回転させます。

また、ターゲットが表示されていないときに情報を表示したくないため、ImageLostトリガーも定義します。

拡張トラッキング

拡張トラッキングは、AR.ImageTrackableごとに個別に設定できるオプションモードです。このモードでは、元のターゲットイメージが表示されなくても、Wikitude SDKはユーザーの環境をスキャンしシーンをトラッキングしようとします。このため、トラッキングは元のターゲット画像の範囲外を超えて拡張されます。この機能のパフォーマンスは、デバイスのコンピューティングパワー、背景テクスチャ、およびオブジェクトなどのさまざまな要因に依存します。

ターゲットが拡張トラッキング用に有効になっている場合、元のターゲットイメージが表示されなくなったときに拡張トラッキングが中断されると、ImageLostトリガーは呼び出されません。

この機能が不要な場合、CPU負荷が高くなるのを回避するために、この機能を無効にすることをお勧めします。

このサンプルでは、 AR.ImageTrackableは、enableExtendedTrackingオプションがtrueに設定されている点を除いて、通常通り定義されています。

拡張トラッキングの品質に関する情報が必要な場合は、以下のサンプルのように、ExtendedTrackingQualityChangedでコールバック関数を定義する必要があります。

var pageOne = new AR.ImageTrackable(this.tracker, "*", {
    drawables: {
        cam: [pipes]
    },
    enableExtendedTracking: true,
    onExtendedTrackingQualityChanged: function (targetName, oldTrackingQuality, newTrackingQuality) {
        var backgroundColor;
        var trackingQualityText;
        if ( -1 == newTrackingQuality ) {
            backgroundColor = '#FF3420';
            trackingQualityText = 'Bad';
        } else if ( 0 == newTrackingQuality ) {
            backgroundColor = '#FFD900';
            trackingQualityText = 'Average';
        } else {
            backgroundColor = '#6BFF00';
            trackingQualityText = 'Good';
        }
        var cssDivInstructions = " style='display: table-cell;vertical-align: middle; text-align: middle; width: 50%; padding-right: 15px;'";
        var messageBox = document.getElementById('loadingMessage');
        messageBox.style.backgroundColor = backgroundColor;
        messageBox.innerHTML = "<div" + cssDivInstructions + ">Tracking Quality: " + trackingQualityText + "</div>";
        messageBox.style.display = 'block';
    }
});

これを有効にすると、ターゲットイメージが無くなってもトラッキングは続行されます。