UE4+ARKitで作る遠隔タッチディスプレイ

先日頭の中にあったアイデアを形にしたくて、↓こんなものをつくりました。 {{< x user=“ayuma_x” id=“1210122895520718849” >}} iPadの上を指でなぞると、iPadの中のディスプレイに線が引かれているのですが、iPadを取り除くと実際のディスプレイにも同じ線が引かれています。 これは初見だと混乱するかもしれませんが、実はiPad側には何も表示は加えていません。iPadのディスプレイにはカメラの映像のみ表示しています。 何をしたかったのか? 少し前に仕事でiPad使ってARのコンテンツを作っていたのですが、その時に感じた「AR=[何か表示を重ねる]以外の使い方を考えてみたいな」と思ったのがきっかけです。 今回行った内容も多分誰かが似たようなことはやっているのだとは思いますが、「自分で考えてアイデアを形にすることに意味がある」ということでやってみました。 今回の実験においてiPadは入力機器として使います。 ARKitには画像検知や物体検知の機能があり、これをうまく使うことで遠隔タッチディスプレイを作ろうというアイデアです。 やるべきこと このアイデアを形にするためにやるべきことを以下にまとめました。 今回iPadのアプリケーションはUE4(4.24)のHandheld AR ブループリント テンプレートをベースに作ります。 iPadに映っているディスプレイの位置、角度を知る iPadに触れた指の位置をディスプレイの相対座標として知る iPadからPC側に座標を送る PC側で送られた座標にしたがって線を引く iPadに映っているディスプレイの位置、角度を知る まずはディスプレイの位置を知る必要があります。 位置を知る方法として「画像を利用したマーカー方式」と「物体検知」の2通りを考えましたが今回は物体検知を選びました。 UE4+ARKitでの物体検知の使い方は以前記事にしているので、興味ある方はみてください。 UE4でARKitの物体検出機能を使う - AYU MAX まずはディスプレイをスキャンして検知するためのデータづくりを行ったのですが、ディスプレイの形状に特徴点が少なく満足する結果が得られませんでした。 そこでディスプレイ横のごちゃごちゃした所の検知データを作成し、ディスプレイの位置、角度はそのポイントからの相対位置で判断するようにしました。 当然ですが、この方法ではディスプレイとの位置関係を変えてしまうと破綻します。 ↓スキャンしているところ スキャン後にディスプレイの位置、角度を知るのは上記した以前の記事の内容そのままです。 iPadに触れた指の位置をディスプレイの相対座標として知る 次にiPadに触れた指の位置を知るにはどうすれば良いか考えます。 今回使っているUE4のARテンプレートの中の実装には、タッチしたポイントにActorがあるかどうか調べるロジック(BP_ARPawnのWorldHitTest関数)があります。 これをちょっといじってディスプレイの位置を知ることを考えました。 まず現実世界のディスプレイと同じ大きさになるような板メッシュを用意してレベルに配置しておきます。このメッシュは見える必要はないので透明なマテリアルをつけときました。 次に毎Tick, ARKitが現実のディスプレイを検知した位置、角度にこのメッシュを移動させます。 次にWorldHitTest関数の中を見ると、LIneTraceForObjectsというノードが使用されているのが分かります。 LIneTraceForObjectsは指定した2点の間に3Dオブジェクトがあるかどうかの判定ができます。 このノードと直前に配置されているDeproject Screen to Worldを組み合わせると、タッチしたときのiPad上のスクリーン座標(x, y)から触れている場所に配置してある3Dオブジェクトが特定できます。 この仕組みを使うと、先ほど配置したメッシュを指で触れているかどうかということが分かります。 ただし、今回知りたいのはディプレイのどこを触れているかなので、もう少し詳細な情報が必要です。 そこでLIneTraceForObjectsで返される値をFind Collision UVに入れる部分を足してみました。 これで触れた3Dオブジェクトの表面のどの部分(UV座標)という情報までとれます。 ※ Find Collision UVを使うにはProject SettingsでSupport UV From Hit ResultsのチェックをONにする必要があります。(多分ONにすると処理負荷は上がっちゃいます) iPadからPC側に座標を送る iPadからPC(Windows)へはソケット通信(UDP)で座標を送ることにします。 UDP送信にはObjectDelivererを使います。 ObjectDelivererについては過去記事みてください。 まずは送信するための入れ物を作ります。といっても簡単で以下のようなブループリントを定義します。TouchPositionというオブジェクトの名前にしました。 ...

2019-12-28 · 1 分 · 86 文字 · ayumax

UE4でARKitの物体検出機能を使う

ARKitの物体検出(Object Detection) 物体検出機能はARKit2から利用可能になった機能で、あらかじめスキャンした物体のデータを登録しておくと作成したARアプリケーションから登録済みの物体を検出することができるようになります。 この機能についてはUnityを使った事例はいくつか記事になっているのですが、UE4を使った事例は見つかりませんでした。 今回どうしてもこの機能をUE4(4.22)で使いたくて、色々試し動かすことに成功したのでやり方をメモしておきます。 オブジェクトのスキャン まずは検出する物体のスキャンをします。 UE4を使ったスキャン UE4を使ってスキャンする場合は、まずARSessionConfigのSession Typeを「Object Scanning」にしてから、「Get AR Candidate Object」を使用して行うらしいです。 上で「らしい」という言葉を使ったのは理由があり、現状上記やり方ではスキャンは成功してないです。 「Get AR Candidate Object」をコールした際にアプリケーションが落ちてしまいスキャンはできませんでした。 成功した方がいらっしゃったら、教えてください。 Apple提供ツールを使ったスキャン 以下のサイトの上部にある「Download」ボタンを押すと、オブジェクトスキャンをするためのiOSアプリのプロジェクト一式がダウンロードできます。 Scanning and Detecting 3D Objects | Apple Developer Documentation ダウンロードしたプロジェクトをXCodeを使って、自分のiOS端末にいれて使用します。 使い方は結構直観的に分かり、最初に黄色いBoxで領域を確定した後、各面毎にスキャンを行います。 黄色いBoxの中に小さい黄色い点(多分物体の特徴点)がたくさんあったほうが後の検出率が高いような気がしています。 スキャンが終わると*.arobjectという拡張子のファイルが生成されるので、iCloudとかを利用して開発マシンまでファイルを持っていきます。 XCodeやUnityを利用したARアプリ開発の場合は上記方法で完結しており、*arobjectのファイルがそのまま利用できます。 UE4の場合はそのままは利用できず、ダウンロードしたスキャンアプリを一部書き換える必要があります。 ViewController.swiftのcreateAndShareReferenceObjectメソッド 変更前 try object.export(to: documentURL, previewImage: testRun.previewImage) 変更後 try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false).write(to: documentURL) 上記書き換え部分はファイルを生成する部分なのですが、利用する関数が違います。 変更前はARReferenceObjectクラスのexportを使っているのですが、これをNSKeyedArchiverを使ってバイナリ化した後そのままファイルに書き込むように変えました。 またオリジナルと区別するためファイルの拡張子を(*.arobject2)に今回はしています。 これはUE4のARKitプラグインでバイナリを復元する際(FAppleARKitConversion::ToARReferenceObjectSet)に使われているのがNSKeyedUnarchiverだからです。 最初書き換えなしで*.arobjectのファイルを読み込ませたところ、ARReferenceObjectの復元に失敗したため調査したところ上記書き換えで成功するようになりました。 arobjectファイルにはUnityで読み込むと静止画のサムネイルが表示されていたので、そういった付加情報が*.arobjectには入っており後者のファイルとはバイナリに保存される内容が違うのが原因かなと思っています。 スキャンデータのUE4への取り込み ARCandidateObjectアセットの作成 スキャンして生成された*.arobject2ファイルをUE4に取り込みたいのですが、今回は専用のアセット生成クラス(UFactoryを継承したクラス)をC++で書きました。 ファイルの中身は以下になります。 ここで気を付ける点としては、上記C++クラスはEditorの機能を利用するため、UnrealEdモジュールへの参照追加の必要があります。 また自分のプロジェクトのRuntimeモジュールにいれてしまうとアプリの書き出し時にエラーがでるので、Editorモジュールにいれてください。 このモジュールについては以下のヒストリアさんのサイトが分かりやすいです。 [UE4] モジュールについて|株式会社ヒストリア 上記ファイルをプロジェクトに追加してビルドすると*.arobject2ファイルをドラッグすることでファイルがインポートされてARCandidateObjectのデータアセットが作られます。 アセットを開くと「Candidate Object Data」の配列に大きな数字が入っているのが分かると思います。 ここに*.arobject2ファイルの中身がバイナリ形式で入っています。(配列を開くと数が多いのでとても重いです。開かないほうがいいと思います) ...

2019-08-15 · 1 分 · 103 文字 · ayumax