[Xamarin.iOS] WikitudeでモバイルAR(拡張現実)アプリを作ってみた
1 はじめに
Wikitude(ウィキチュード)とは、ロケーションベースのAR及び、画像認識型のARを実装するための商用ライブラリです。今回、このSDKのXamarin用コンポーネントを利用して、ロケーションベースのARを試してみました。
最初に、作成したアプリの実行画面をご覧ください。 アプリ越しに景色を見ると、周辺施設の位置にラベルが表示され、そこまでの距離がリアルタイムに表示されます。
画面に「Trial」と表示されているのは、「トライアル版(無料)」を使用しているためです。
2 プロジェクト作成とコンポーネントの追加
(1) プロジェクト作成
新しいプロジェクトは、メニューから、ファイル - 新規 - ソリューションと辿り、iOSのSingle View Appから作成しました。
名前は、Xamarin.iOS.WikitudeSampleとしました。
(2) コンポーネントの追加
「ソリューション」ビューでComponetsを右クリックしてコンポーネントを追加します。 検索窓に「Wiki」などと入力すると簡単に見つけることができるでしょう。
追加が完了すると、次のような画面になります。
後は、利用するコードで下記のようにusingを追加することで、Wikitudeが利用可能になります。
using Wikitude.Architect;
3 ライセンスキー
Wikitudeを利用するには、ライセンスキーが必要ですが、下記のページからトライアルキー(無料)の入手が可能です。
製品をトライアルする
トライアルキーでは、画面に「Traial」の文字が表示されますが、機能については、制限なく試すことができます。
4 AR構造
WikitudeでのAR実装は、次の2つで構成されています。
- ARchitect World
- ARchitect View
最初のARchitect Worldは、AR世界を表現するオブジェクトであり、JavaScriptのAPIとなっています。「SDKの本体」とも言えるこの部分は、iOS/Androidで共通です。(Xamarinでも同じ)
次のARchitect Viewの方は、先のARchitect Worldをデバイス上に表示するためのビューであり、プラットフォーム固有のライブラリになっています。Xamarinコンポーネントを利用する場合、ここは、C#で記述することになります。
なお、ARchitect Viewは、どのようなアプリでも、恐らく殆ど同じになると思います。
5 ARchitect View
最初に、ARchitect Viewの実装を紹介します。
ビューを初期化するコードは次のとおりです。 WTArchitectViewからビューを生成して、ライセンスキーをセットし、ARchitect WorldのURLを渡すだけです。
protected WTArchitectView arView; protected WTNavigation architectWorldNavigation; public override void ViewDidLoad() { base.ViewDidLoad(); NSError error; if(WTArchitectView.IsDeviceSupportedForRequiredFeatures(WTFeatures.WTFeature_2DTracking | WTFeatures.Geo,out error)) { arView = new WTArchitectView(); arView.Frame = UIScreen.MainScreen.Bounds; // ライセンスキーについては、SecrecKey.csに定義されていますが、Githubでは、公開されていません。別途定義してください。 //public class SecretKey{ // public static string WT_LICENSE_KEY = "XXXXXXXXXX"; //} arView.SetLicenseKey(SecretKey.WT_LICENSE_KEY); var url = NSBundle.MainBundle.BundleUrl.AbsoluteString + "ARchitectWorld/index.html"; architectWorldNavigation = arView.LoadArchitectWorldFromURL(new NSUrl(url), WTFeatures.WTFeature_2DTracking | WTFeatures.Geo); View.AddSubview(arView); } }
そして、ARchitect Viewの開始と停止をコーディングします。
public override void ViewDidAppear(bool animated) { base.ViewDidAppear(animated); if (arView != null) { arView.Start(null,null); } } public override void ViewWillDisappear(bool animated) { base.ViewWillDisappear(animated); if (arView != null) arView.Stop(); }
最後に画面が回転した時に、ARchitect Viewにその事を伝えます。
// 全部の回転を許可する public override bool ShouldAutorotate() { return true; } public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations() { return UIInterfaceOrientationMask.All; } // 回転に応じて、WTArchitectViewを回転させる public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration) { //base.WillAnimateRotation(toInterfaceOrientation, duration); arView.SetShouldRotateToInterfaceOrientation(true, toInterfaceOrientation); }
以上で、必要なコーディングは終了ですが、ロケーションベースのARを作成する場合、iOS8以降、許可が必要なため、info.plistに次の記述が必要になります。
位置情報許可については、詳しくは、下記をご参照ください。
参考:[iOS] 位置情報の取得
<key>NSLocationWhenInUseUsageDescription</key> <string>Your message goes here</string>
6 ARchitect World
ARchitect Worldの方は、JavaScript/HTML/cssで記述しますが、それらは、Resourcesの下に配置します。
上記のように配置して、次のurlでARchitect Viewに伝えることになります。
var url = NSBundle.MainBundle.BundleUrl.AbsoluteString + "ARchitectWorld/index.html";
JavaScriptのコードについては、Wikitudeのサンプルに、複数の位置ラベルを表示するものがありましたので、そちらを改造することで作成しました。
参考:4_PointOfInterest_3_MultiplePois
メインとなるコードは、multiplepois.jsですが、この中で、ロケーション情報が変化した際に、スクリプトがキックされています。
AR.context.onLocationChanged = World.locationChanged;
また、jsondata.jsにある、位置情報からラベルを生成しています。
requestDataFromLocal: function requestDataFromLocalFn(centerPointLatitude, centerPointLongitude) { var poisToCreate = 10; var poiData = []; for (var i = 0, length = jsonData.length; i < length; i++) { var distance = World.getDistance(jsonData[i].latitude, centerPointLatitude, jsonData[i].longitude, centerPointLongitude); var distanceString = (distance > 999) ? ((distance / 1000).toFixed(2) + " km") : (Math.round(distance) + " m"); poiData.push({ "longitude": (jsonData[i].longitude), "latitude": (jsonData[i].latitude), "altitude": 50.0 + Math.floor( Math.random() * 11 ) *5, // 標高については、とりあえず50mを基準と、ランダムに重ならないよいうにしました "description": (distanceString), "name": (jsonData[i].name) }); } World.loadPoisFromJsonData(poiData); },
位置情報であるjsondata.jsは、次のようになっています。
var jsonData = [ { "latitude": 43.068823, "longitude": 141.349351, "name": "札幌駅" }, { "latitude": 43.060966, "longitude": 141.356049, "name": "テレビ塔" }, { "latitude": 43.065498, "longitude": 141.354618, "name": "東横イン"}, { "latitude": 43.062782, "longitude": 141.353599, "name": "時計台"}, { "latitude": 43.065773, "longitude": 141.355179, "name": "札幌全日空ホテル" }, ・・・省略・・・ { "latitude": 43.067478, "longitude": 141.352707, "name": "ビックカメラ札幌店" }, { "latitude": 43.066971, "longitude": 141.354126, "name": "ラーメン札幌一粒庵" }, { "latitude": 43.067554, "longitude": 141.352722, "name": "エスタ" }, { "latitude": 43.068211, "longitude": 141.352646, "name": "JRタワーホテル日航札幌" }, { "latitude": 43.067490, "longitude": 141.353058, "name": "札幌ら~めん共和国" }, { "latitude": 43.063953, "longitude": 141.352264, "name": "ホテル時計台" }, ];
紹介が不十分になってしまっていますが、詳しくは、Githubを御参照ください。
[GitHub] Xamarin.iOSによるWikitudeサンプル
7 最後に
今回は、Wikitudeを利用して、ロケーションベースのARを試してみました。このライブラリーは、ビューの構築以外は、全部JavaScriptで記述されているので、この部分の機種依存部がなく、Androidへの移植も非常に簡単だと思います。
今度は、googleの位置情報検索との連携や、画像認識型のARも試してみたいと思います。
最後に、ご近所の「札幌駅」と「かに本舗」です。
8 参考資料
iPhone向け拡張現実アプリの開発に挑戦してみた(Wikitude活用)[PR]
Xamarinコンポーネントのセットアップ
SETUP GUIDE XAMARIN COMPONENT(英語)
Wototude SDK Xamarin
Wikitude iOS Architect SDK API リファレンス
Wikitude SDK JavaScript API リファレンス
Wikitude Native SDK Reference
Xamarin記事一覧(SAPPOROWORKSの覚書)
[Developers.IO] Xamarinシリーズ