ジェスチャー
Wikitude SDKは多数のジェスチャーをサポートしているため機能と相互作用できます。
このサンプルでは、ARシーンで3つのジェスチャを使用して、眼鏡、ひげ、帽子の画像をドラッグ、回転、拡大縮小して顔に配置する方法を示します。
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本の指で回転させたり、ピンチジェスチャで拡大縮小したりできます。
サンプルでは、変数oneFingerGestureAllowed
を使用して、どの種類のジェスチャが現在アクティブかを判断しやすくしています。 ドラッグは1本の指だけを使用する唯一のジェスチャであるため、2本の指でジェスチャを開始するとすぐに停止させなければなりません。 このイベントに応答するコールバック関数は、AR.context.on2FingerGestureStarted
と呼ばれます。 この関数が呼び出されるたびにoneFingerGestureAllowed
をfalse
に設定します。
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
は、oneFingerGestureAllowed
がtrue
の場合に想定される動作のみを行います。そのため、新しいドラッグが開始されるたびに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
}
});
次に、距離が変化したときに呼び出されるコールバック関数と、イベントをトリガーするミリメートル単位の変更しきい値を宣言します。
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";
},
...
描画可能な定義は最初のセクションとまったく同じです。
オプション 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';
}
});
これを有効にすると、ターゲットイメージが無くなってもトラッキングは続行されます。