この記事では、Augmented Realityチップを使用して長い間アプリケーションを開発している人には新しいことは何も伝えませんが、おそらくこのトピックに興味があり、ARアプリケーションを作成することに近い人には役立つでしょう。
背景
少し叙情的な余談-ARとは何か、なぜモバイルデバイスで人気が出てきたのか。
むかしむかし、おそらく前世紀の80年代初頭に、航空機の前面ガラスに直接情報を投影するプロジェクターが軍事戦闘機(たとえば、垂直離陸戦闘機であるYak-41)に導入され始めました。 パイロットは革新に非常に満足していました。 この方法で最も重要なインジケーターを監視することは、アナログセンサー、さらにはデジタルセンサーを見るよりもはるかに便利でした。
このトピックには特に関連していませんが、すでに1992年にソビエトSu-27が照明付きノードで回転する航空機の3Dモデルを持っていたという事実(従業員の1人の父親が開発に参加しました)を知っています。 グラフィックエンジンは、4 MHzプロセッサ(8086)のアセンブラで作成されました。 アメリカ人が66 MHzから80486のきしみ音で同じことをしたことは重要であるため、私たちのコードは常に書き方を知っていました。
その後、同じILS(Windshield Indicators)が民間航空に導入され、1990年にボーイングのエンジニアの1人がまさに「拡張現実」という概念を導入しました。
ずっと後に、加速度計とジャイロスコープがスマートフォンに来たとき、明るい頭はカメラとOpenGL ESにそれらを接続するというアイデアを思い付きました-これは多くのゲーム、ナビゲーションアシスタントが生まれた方法でしたが、この方向の予算のほとんどはマーケティングとプロモーションアプリケーションに費やされました。 たとえば、雑誌の時計用の紙フレームを切り取り、手に置いて携帯電話のカメラを通して見ることで、ユーザーは雑誌を宣伝するあらゆるブランドの時計を「試着」できます。
純粋に技術的な部分であり、プログラマが最も人気のあるモバイルプラットフォームで遭遇する小さな問題です。
iOS
iPhoneとiPadのiOSバージョンは非常に似ていますが、いくつかの点で異なります。 残念ながら、これらのパラメーターには、iPad OSではカメラ画像出力ウィンドウ(UIImagePicker)が通常のUIViewであり、iPhone OSではUIViewControllerであるという事実が含まれています。 iPadの場合、すべてが明確である場合-他のビューと同様に管理および配置する場合、iPhoneではすべてが少し複雑です-ImagePickerウィンドウはモーダルである必要があり、カメラの上にビューを追加することは、cameraOverlayViewパラメーターを使用してのみ可能です。 つまり カメラの上に3Dを追加するには、次のことを行う必要があります。
imagePicker .cameraOverlayView = [[ARView new] autorelease];
おそらく、これはiOS 3以前から残された時代錯誤です。 これはどのような不便をもたらしますか? リスト全体へ:
- UIImagePickerControllerはステータスバーを非表示にします。 ARモードから、たとえばゲームメニューへの移行時にそれを戻す必要があります。 そうしないと、ほとんどの場合、すべてのビューが20ピクセルになります。
- フルスクリーンではなくカメラの画像を表示することはできません。 プレビューは、標準のUIImagePickerの下で作成され、下からコントロールされます。 そして、残りの2つのオプションがあります。下からコントロールを作成するか、画像変換にマトリックスを使用するための主なことは、画像の比率を正しく保持することです。
- 例えば、ボタンをクリックするだけで静的な背景にカメラ画像を変更する必要がある場合、これはいくつかのアクションにつながります-ビューコントローラーで静的な背景でビューをラップし、UIImagePickerControllerを削除し、ビューにcameraOverlayViewにあるオーバーレイを追加する必要があります新しいView Controllerを提示します。 また、メモリ内のビューを失い、時間内に保持/解放しないようにするか、常に保持プロパティに保持する必要があります。 これはすべてimagePickerView.hidden = YESの代わりです。 iPadの場合と同様に、plusは明らかにパフォーマンスが遅くなります。
- あまりにもスマートなUIButtonに遭遇することもあります。 AR /非ARモードの切り替えを実装するには、ViewControllerインスタンスでコードを実行する必要がありましたが、UIButtonにはこのための独自の計画があります。 UIButtonにtarget-ViewControllerのクリックハンドラーがある場合、ViewControllerからビューを削除してimagePicker.cameraOverlayViewに配置すると、このハンドラーは動作を停止します。 どうやら、UIButtonは、イメージがすべての上にある画像であり、メッセージを送信しないため、ターゲットのViewControllerが表示されなくなったことを認識しています。 内部ビューにView Controllerへのポインタを与え、すでにView Controllerを直接プルする中間コードを追加する必要がありました。
一般的に、すべての標準クラスがビューであり、ユーザーのみがView Controllerを制御している場合、松葉杖の束は常に優れています。
Android
Androidでは、状況は少し異なります。
カメラプレビュー、またはSurfaceViewは、任意のサイズのビューに配置でき、すべての上に何らかのモーダルアクティビティを作成する必要はありません。 しかし、特定のジェスチャーがなければできませんでした。 適切なプレビューサイズを見つける必要があることが判明しました(サイズのリストは大きい場合があり、メーカーによっては異なる場合がありますが、メーカーによっては異なります)。 最適な解像度と比率を求めて、可能なオプションからすべてのサイズを整理し、実行時にこのプレビューを配置するビューのサイズと比率と比較する必要があります。 プレビューのサイズは常にSurfaceViewのサイズに対応するとは限らないため、画像の縦横比を維持して適切なサイズを取得するには、ViewGroupを実行し、SurfaceViewをそこに配置し、onLayoutメソッドに何をどのように配置するかを計算する必要があります。
もう1つの興味深い点-iOSでカメラのプレビューの上に3Dモデルを描画したい場合、下にプレビュー(UIImagePicker)があり、3Dモデルを含む上からビューを描画します。 Androidは独自の方法でそれを行うことにしました。標準UI要素をプレビュー(SurfaceView)の上に簡単に描画できる場合、GLSurfaceViewの3Dモデルはプレビューの下(!)に配置する必要があります。 この場合、いくつかの体の動きを実行する必要があります。
- SurfaceViewの場合、getHolder()。setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)メソッドを呼び出しますが、ドキュメントではSURFACE_TYPE_PUSH_BUFFERSについて「この定数は非推奨です。 これは無視され、この値は必要に応じて自動的に設定されます。」が、この呼び出しがないとプレビューが機能せず、アプリケーションがクラッシュすることさえあります。
- GLSurfaceViewでは、透明であることを指定する必要があります-getHolder()。SetFormat(PixelFormat.TRANSLUCENT)。 この呼び出しがなければ、一部のデバイスではすべてが機能する(HTC Desire Sで動作する)か、動作しない可能性があります(Google GalaxyNexusでは動作しませんでした)。 おそらく、これは異なるデバイス上のGPUの違いによるものです。 したがって、この方法を無視しない方が良いです。
ARが機能するにはこれで十分ですが、非ARモードの静的な背景にはすぐに問題がありました。 デフォルトではGLSurfaceViewは透明ではないため、その下では標準UIを使用して何も表示できません(ImageVIewウィジェットも、GLSurfaceView自体の背景も機能しません)。 ただし、setZOrderOnTop(true)メソッドを使用して透明にすることができます-GLSurfaceViewは透明になりますが、同時にアクティビティのすべての要素の上に表示され始めます。違いはありません-それらは下、上、または別のビューにあります。 したがって、3Dモデルの下に何かを描画する必要があり、これがカメラからのプレビューではない場合、1つの方法しかありません。OpenGLESが役立ちます。 これを行うには、画像をテクスチャとしてメモリにロードし、2の累乗の倍数である辺を取得するように事前にサイズを変更する必要があります(一部のGPUでは、パフォーマンスの低下なしで動作します。一部では、まったく動作しないため、これを行う必要があります)。 このテクスチャは、寸法がビューポートの寸法と等しい平面に表示されます。 テクスチャの正しい割合しか計算できません。なぜなら、 さまざまな比率のさまざまな画面サイズがあります。
例えば
結果の例は、 AppStoreとGoogle Playでアプリケーションの例を見ることができます