AR (augmented-reality、拡張現実) を Xamarin.Android と ARCore で試してみました

先日、「AR (augmented-reality、拡張現実) を Xamarin と iOS 11 で試してみました」で拡張現実の作成方法を紹介しました。今回は、Xamarin Android アプリで Google から見た AR を探ってみましょう。

新しい ARCore SDK は、モーション トラッキング、平面検出、および光源の推測など、AR (Augment Reality、拡張現実) 機能向けの API を提供します。これらは、Android アプリに AR エクスペリエンスを追加するために使用されるビルディング ブロックです。

はじめに        

ARCore は、現在 Google Pixel、Google Pixel 2、および Samsung Galaxy S8 などの限られたデバイスでのみ利用可能です。

ARCore を使用する場合、arcore-preview.apk をダウンロードし、インストールして、デバイスを準備する必要があります。

ARCore 開発に向けてデバイスを設定後、ARCore プレリリースの NuGet パッケージをインストールする必要があります。

ARCore API の基本

ARCore の以下の基本的な機能は、オブジェクトを配置するサーフェスの検出や、カメラとの相対的な空間内の位置の計算に役立ちます。

セッション オブジェクト:ARCore とのインタラクションにおける主要ポイントです。追加するアンカー、エンジンが検出したサーフェス、およびデバイスの現在のスナップショットを記録することによって、AR の状態を管理するのに役に立ちます。
平面:SDK が検出したサーフェスで、オブジェクトの固定した実際の位置 (方向を含む) を記述する Anchor を配置可能です。現在、上向きと下向きのサーフェス (床と天井のようなイメージ) を別々に検出できます。
セッション:Frame Object を返す .Update() を呼び出す場合における AR の状態の現在のスナップショットです。
フレーム:ディスプレイ上のタップ座標がいずれかの平面と交差するか判断するのに役に立つ便利な HitTest(..) メソッドです。各フレームには、カメラの向きや現実世界との関係に関する情報も含まれており、ユーザーに視覚的表現を表示するための投影行列を計算するのに役に立ちます。
・この SDK のもう 1 つの興味深い機能は、特定のフレームから LightEstimate を取得できる点です。この推定は、カメラ ビューの PixelIntensity を含みます。

シンプルなサンプルを動かしてみましょう

Xamarin に移植した HelloAR のサンプルは、GitHub でご覧いただけます!早速、このサンプルで行われている基本的な内容を説明します。

初めに、アクティビティ内の OnCreate でセッションを作成し、実行時にデバイスが ARCore をサポートしていることを確認する必要があります。

var config = Config.CreateDefaultConfig();
session = new Session(this);
 
// Make sure ARCore is supported on this device
if (!session.IsSupported(config)) {
    Toast.MakeText(this, "ARCore unsupported!", ToastLength.Long).Show();
    Finish();
}

ライブ カメラのフィード/AR (Augmented Reality) のビューをユーザーに表示するには、Android.Manifest.Permission.Camera の権限も要求しなければならないことに注意してください。“HelloAR” のサンプルでは、GLSurfaceView を使用してカメラと拡張をレンダリングします。GL サーフェスやルックがサンプル コードの通りに設定されていることを確認してください。

セッションが実行中であることから、GL サーフェスの OnDrawFrame の実装における AR のシステムの状態のスナップショットを取得できます。フレームが Tracking 状態であることが確認できたら、ヒット結果をチェックし、平面を交差することを予測して、アンカーを追加できます。

// See the PlaneAttachment class from the sample
// This helps associate Anchors with Planes they are attached to
List<PlaneAttachment> planeAttachments = new List<PlaneAttachment>();
void OnDrawFrame (IGL10 gl)
{
    var frame = session.Update();
 
    // You could keep track of taps by queueing up
    // MotionEvent's from a tap gesture recognizer
    var tap = motionEventsQueue.Dequeue();
 
    // Make sure we've got a tap and are in a tracking state for our frame
    if (tap != null && frame.GetTrackingState() == Frame.TrackingState.Tracking) {
        // Look at each hittest result
        foreach (var hit in frame.HitTest(tap)) {
            // We could get PointCloudsHitResult as well, check for Plane
            var planeHit = hit as PlaneHitResult;
            if (planeHit != null && planeHit.IsHitInPolygon) {
                // Create a new anchor
                var anchor = session.AddAnchor(hit.HitPose);
                // Keep track of our anchors and the planes they are attached to
                planeAttachments.Add(new PlaneAttachment(planeHit, anchor))
            }
        }
    }
}

さらに、描画メソッドのシーンで、さまざまなオブジェクトをレンダリングします。HelloAR のサンプルは、膨大な OpenGL のリフティングを行うためのさまざまなレンダリング機能を備えており、フレームから計算した投影に基づいてこれを実現します。

// Get projection matrix.
float[] projectionMatrix = new float[16];
session.GetProjectionMatrix(projectionMatrix, 0, 0.1f, 100.0f);
 
// Get camera matrix and draw.
float[] viewMatrix = new float[16];
frame.GetViewMatrix(viewMatrix, 0);
 
// Draw the detected planes
planeRenderer.DrawPlanes(session.AllPlanes, frame.Pose, projectionMatrix);
 
// Get lighting from avg intensity of the image
var lightIntensity = frame.LightEstimate.PixelIntensity;
 
// Draw all of our anchors attached to planes
float scaleFactor = 1.0f;
float[] anchorMatrix = new float[16];
 
foreach (var planeAttachment in planeAttachments) {
    // Only draw attachments currently tracking
    if (!planeAttachment.IsTracking)
        continue;
 
    // Get the current combined pose of an Anchor and Plane in world space
    planeAttachment.GetPose().ToMatrix(anchorMatrix, 0);
 
    // Update and draw the model
    objectRenderer.UpdateModelMatrix(anchorMatrix, scaleFactor);
    objectRenderer.Draw(viewMatrix, projectionMatrix, lightIntensity);
}

サンプルを分析してみると、実際の ARCore のコードは比較的簡単で、サンプルのほとんどは OpenGL のレンダリングに関するものです。

GitHub で、HelloAR のサンプル全体をご覧ください。Xamarin Android アプリで ARCore を使って、AR (Augmented Reality) エクスペリエンスを是非お試しください。

弊社では、Xamarin に関するさまざまな日本語のドキュメントを用意しています。ご興味のある方は、こちらの Xamarin 日本語ドキュメント ページをご覧ください。

Xamarin のパートナー一覧や、トレーニング情報はこちらのページにて随時更新中です。

記事参照:
2017 年 10 月 30 日 Jon Dick
© 2017 Xamarin Inc.
Augmented Reality in Xamarin.Android with ARCore

シェアする

  • このエントリーをはてなブックマークに追加

フォローする