一覧に戻る

Unity3Dプラグインのインスタントトラッキング

2018.07.08Unity3Dプラグイン

Unity 3Dプラグインのインスタントトラッキング

以下のセクションでは、WikitudeネイティブSDKのインスタントトラッキング機能について詳しく説明します。最小限の実装にすることで、WikitudeネイティブSDKが提供するシンプルさを紹介します。

SMART - シームレスなARトラッキング

SMARTは、ARKit、ARCore、WikitudeのSLAMエンジンをあらゆるデバイスに対応する単一の拡張現実SDK(クロスプラットフォーム)に統合したシームレスなAPIです。SMARTはiOSデバイスの92.6%、市場で入手可能なAndroidデバイスの約35%をカバーし、多くのデバイスに最適なAR体験を提供します。

SMARTはデフォルトで有効になっていますが、インスタントトラッカーインスペクタの上部にあるSMART Enabledチェックボックスをオフにすると無効にすることができます。また、InstantTrackerのSMARTEnabledプロパティを使用してコード内で無効にすることもできます。これは、OnEnableメソッドで発生するネイティブのInstantTracker初期化処理の前に発生する必要があることに注意してください。


public InstantTracker tracker;

void Awake() {
    tracker.SMARTEnabled = false;
}

デバイスがプラットフォームアシスタントトラッキングをサポートしているかどうかを確認するには、WikitudeSDK.IsPlatformAssistedTrackingSupportedを使用します。これは、ネイティブコンポーネントが適切に初期化されていることを確認するために、WikitudeCameraのStartメソッドが実行された後に呼び出される必要があることに注意してください。IsPlatformAssistedTrackingSupportedメソッドは即時結果を返しませんが、結果が利用可能なときに呼び出されるコールバックメソッドのパラメータとして結果を受け取ります。


Tracker.IsPlatformAssistedTrackingSupported((SmartAvailability smartAvailability) => {
    if (smartAvailability == SmartAvailability.Supported) {
        /* Device offers platform tracking capabilities (ARKit or ARCore) */
    }
});

SMARTは、制御を犠牲にして改善されたトラッキング機能を提供します。 そのため、SMARTを有効にしてプラットフォームアシスタントトラッキング機能を使用すると一部のWikitude SDK機能を使用できません。

機能 SMART ON
(プラットフォームアシスタントトラッキングをサポート)
SMART OFF
トラッキングの改善 X
平面の方向 X
カメラの制御 X
インスタントターゲットの保存と読み込み X

 

紹介

インスタントトラッキングは、以前にWikitude SDKで導入されたものとは異なり、あらかじめ定義されたターゲットを認識し、トラッキング手順を開始することを目的とはせず、ただちに任意の環境でトラッキングを開始するアルゴリズムです。 これにより、具体的なユースケースを実装することができます。

アルゴリズムは2つの異なる状態で動作します。 最初のものは初期化状態です。 この状態では、ユーザーは、単にデバイスを指示し、それによってインジケータを整列させることによって、トラッキング手順の起点を定義する必要があります。 一旦、(ユーザーが積極的に確認する必要がある)ユーザーが満足できるものであると判明すると、トラッキング状態への移行が実行されます。 この状態では、環境は継続的にトラッキングされているため、シーン内に拡張を配置することができます。

インスタントトラッキングアルゴリズムは、初期化状態で別の入力値を提供することを要求します。具体的には、トラッキングデバイスの高さは、シーンの範囲内で正確に増加したスケールを調整するために必要となります。 この目的のために、この例では、メートル単位で高さを設定できる範囲入力要素を備えています。

初期化中は、インスタントトラッキングの地面の方向に影響を与える別のパラメータを設定することができる。この地面は、初期化インジケータによって示され、例えば、床の代わりに壁でインスタントトラッキングを開始するために地面を回転させることができます。

基本的なインスタントトラッキング

インスタントトラッキングの例は、ユーザが自分の環境に家具を置けるようにするアプリケーションの単純な実装を提供します。

シーン設定

シーンは主に次の部分で構成されています。

  • WikitudeCamera:WikitudeCamera の標準的なプレハブは、それが 30FPSでSDで実行されていることを除いて、使用されています。アルゴリズムは計算が激しく、ユーザーが古いデバイスの速度低下を経験する可能性があるため、これはインスタントトラッキングに推奨される設定です。
  • UI:このサンプルで使用するUIのルート。インスタントトラッキングは2つの異なるフェーズで動作するため、UIも2つに分割され、インターフェイスを完全に切り替えることができます。 インスタントトラッカーが初期化モードにあるとき、UIは、前述のように高さを制御するスライダーと、トラッキングモードに切り替えるためのボタンのみを表示します。 切り替えが完了すると、UIには、シーンに追加できる家具モデルごとのボタンが表示されます。 各ボタンにはOnBeginDragイベントトリガがあり、新しい家具モデルをシーンに追加する必要があるときにコントローラに通知します。 イベントトリガには、作成するモデルを指定するintパラメータもあります。
  • Controller:複数のカスタムスクリプトコンポーネント用のコンテナ。
    • InstantTrackerController:インスタントトラッカー、UI、拡張機能、およびタッチ入力間のアクティビティを調整します。
    • ジェスチャーコントローラ:タッチ入力イベントに反応し、それに応じて拡張を移動またはスケーリングします。
    • グリッドレンダラー:25 cm間隔のグリッドをレンダリングします。このグリッドは、初期化とトラッキングの際に役立ちます。
  • Ground:シンプルな透明なプレーンで、カスタムシェーダで影を付けることができます。 また、プレーンにはコライダーがあり、物理的な相互作用に使用することができます。
  • インスタントトラッカー:実際にすべてのトラッキングを実行するコンポーネント。

インスタントトラッカーのシーン

                        インスタントトラッカーのシーン

インスタントトラッカーコントロール

コントローラスクリプトは、シーンの他のすべてのコンポーネントを調整します。 すべてのUI要素への参照を含み、それらのイベントに応答します。

Awake関数では、Application.targetFrameRateは60に設定されています。カメラとトラッキングが30 FPSでのみ実行されていても、Unityがより高いFPSで動作するようにすると、よりスムーズなユーザー対話が可能になります。

ドラッグが検出され、OnBeginDragコールバックが呼び出されると、受け取ったインデックスに基づいて新しいモデルを作成し、カメラに向かってタッチ位置に配置します。


// Select the correct prefab based on the modelIndex passed by the Event Trigger.
GameObject modelPrefab = Models[modelIndex];
// Instantiate that prefab into the scene and add it in our list of visible models.
Transform model = Instantiate(modelPrefab).transform;
_activeModels.Add(model.gameObject);
// Set model position by casting a ray from the touch position and finding where it intersects with the ground plane
var cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
Plane p = new Plane(Vector3.up, Vector3.zero);
float enter;
if (p.Raycast(cameraRay, out enter)) {
    model.position = cameraRay.GetPoint(enter);
}

// Set model orientation to face toward the camera
Quaternion modelRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(-Camera.main.transform.forward, Vector3.up), Vector3.up);
model.rotation = modelRotation;

デバイスをあまりにも速く動かすと、トラッカーがシーンを失う可能性があります。すべてのモデルとグリッドが隠されていることを確認します。 トラッキングが失われたときにカメラはもう移動しないので、隠蔽されていなければ、画面上に拡大表示されているように見えます。 ユーザーが新しいオブジェクトを追加しないように、家具のボタンを無効にする必要もあります。

SDKは現在編集モードでは動作しませんが、Unity Remoteを使用してエディタでデモをテストすることはできます。 また、SDKは、編集モードで期待されるほとんどのコールバックも送信します。これにより、デバイス上に常に構築することなくジェスチャの対話をプロトタイプ化できます。

デバイスでインスタントトラッカーのサンプルを実行中

インスタントシーンのピッキング

シーンピッキングの例では、タッチした位置を環境にマップした3Dの位置に変換する方法を示します。このAPIを使用する場合、ユーザーはオブジェクトを地面だけでなく、実際のオブジェクトの上に配置することもできます。

シーンのセットアップ

シーンの構造はインスタントトラッキングの例で説明したものと似ていますが、少し簡略化されています。具体的には、UIには家具関連のコントロールは含まれず、ジェスチャーコントローラもありません。

シーンピッキングコントローラ

コントローラスクリプトは、インスタントトラッキングの例よりはるかに簡単です。タッチ入力をリッスンし、その入力を3D座標に変換して、そこに拡張を配置します。また、InstantTrackerの状態を管理します。
入力タッチ位置を3D座標に変換するために、スクリプトはInstantTrackerのConvertScreenCoordinateメソッドを呼び出し、Unityが提供するタッチ位置を渡します。

void Update() {
    if (_isTracking && Input.GetMouseButtonUp(0)) {
        Tracker.ConvertScreenCoordinate(Input.mousePosition);
    }
}

変換には時間がかかるので、別のスレッドで実行され、結果が利用可能になったことを知らせるコールバックイベントがInstantTrackerで提供されます。サンプルスクリプトは、Awakeメソッドでこのイベントに登録します。

void Awake() {
    Tracker.OnScreenConversionComputed.AddListener(OnScreenConversionComputed);
}

最後に、変換が計算されると指定された場所に拡張表示が追加されます。これは、タッチイベントが発生したポイントクラウドに十分な情報がないと失敗する可能性があるため、最初に変換が成功したかどうかを確認する必要があります。座標はInstantTrackableのローカルスペースにあるため、_trackableの子として拡張を追加します。

public void OnScreenConversionComputed(bool success, Vector2 screenCoordinate, Vector3 pointCloudCoordinate) {
    if (success) {
        var newAugmentation = GameObject.Instantiate(Augmentation, _trackable.transform) as GameObject;
        // The pointCloudCoordinate values are in the local space of the trackable.
        newAugmentation.transform.localPosition = pointCloudCoordinate;
        _augmentations.Add(newAugmentation);
    }
}

持続的なインスタントターゲット

インスタントターゲットの保存および読み込みの機能により、AR体験は複数のユーザーがデバイスやオペレーティングシステムを横切って持続的にアクセスできるようになります。 さらにインスタントターゲットを拡大することができます。このセクションでは、サンプルアプリケーションに基づいてこの機能を紹介します。 この機能は、プラットフォームによるトラッキングが有効な場合は使用できません。「インスタントターゲットの保存」および「インスタントターゲットの読み込み」のサンプルは、Unityでこの機能を使用する方法を示しています。

シーンのセットアップ

シーンは、ControllerゲームオブジェクトにSaveInstantTargetスクリプト、またはLoadInstantTargetスクリプトが追加されている点を除いて、インスタントトラッキングの例で説明したものと似ています。

インスタントターゲットの保存

インスタントターゲットを保存するには、 インスタントトラッカーがトラッキングモードになっている間にInstantTracker.SaveCurrentInstantTrackerメソッドを呼び出す必要があります。このメソッドは、成功または失敗の場合に呼び出される2つのアクションパラメータを受け取ります。また、インスタントターゲットを保存するディレクトリも存在する必要があります。

private void SaveTarget() {
    var path = Application.persistentDataPath + "/InstantTarget.wto";
    Tracker.SaveCurrentInstantTarget(path, SaveSuccessHandler, SaveErrorHandler);
    InfoMessage.text = "Saving instant target to: " + path;
}

private void SaveSuccessHandler(string path) {
    /* Handle success */
}

private void SaveErrorHandler(Error error) {
    /* Handle errors */
}

ハンドラはラムダ関数で実装することもできます。

インスタントターゲットの読み込み

インスタントターゲットを読み込むには、以前に保存したインスタントターゲットへのパスを使用してInstantTracker.LoadInstantTargetメソッドを呼び出す必要があります。 SaveCurrentInstantTrackerと同様に、このメソッドは成功または失敗の場合に呼び出される2つの "アクション"パラメータも受け取ります。さらに、InstantTargetRestorationConfigurationによって拡張ポリシーを設定することもできます。 これにより、インスタントターゲットをさらに拡張するかどうかを制御します。

private void LoadTarget() {
    // A TargetCollectionResource is needed to manage file loading.
    var targetCollectionResource = new TargetCollectionResource();
    // UseCustomURL is used to specify that the file is not inside the "StreamingAssets" folder
    targetCollectionResource.UseCustomURL = true;
    // The "file://" is used to indicate that the file is located on disk, and not on a server.
    targetCollectionResource.TargetPath = "file://" + Application.persistentDataPath + "/InstantTarget.wto";
    var configuration = new InstantTargetRestorationConfiguration();
    // Indicate that we allow the target to be expanded after it was loaded.
    configuration.ExpansionPolicy = InstantTargetExpansionPolicy.Allow;
    Tracker.LoadInstantTarget(targetCollectionResource, configuration, LoadSuccessHandler, LoadErrorHandler);
}

インスタントターゲットが読み込まれた後、トラッカーは即座にターゲットを探し、トラッキングしようとします。