iPhoneのバックカメラを使ったARアプリの検討ということである実験をしてみた。

↑だいぶ前に購入したVRゴーグルに、、、

↑えいやと穴をあけてiPhoneを設置。そのカメラで得た画像(動画)を

↑このようにならべて見てみるとどんな感じだろうか?というものだ。
通常VRアプリは少し異なる画像を左右それぞれの目で見るわけだが、これが同じ映像だとどうなるのかピンとこなかった。
使ったのはiPhone XS Max。
画面いっぱいはもちろん、Safe Areaを左右半分にして画像を写しても大きすぎるのかVRゴーグルの仕様のせいかともかく焦点が合わないのでSafe Areaの9割を使っている(後述)。
【結果】
現時点で最新機種のiPhone XS Maxとは言え、カメラの映像はリアルより遅延があってそのせいか、酔った。おえーっ。
当然立体感はない。
通常の目で見る感覚より何もかも大きく見えるのですぐ近くのコップを掴むのもたどたどしい。歩くのも危ない。
捉える物体にピントが合うのに時間がかかる、、、これはコードがぬるいせいかもしれない。何かその辺りの設定できたんだっけ、、、
【感想】
そもそもは自作の’ARゴーグル’を使って現実世界に何か情報を表示する、という方向での技術的な蓄積、つまり‘iGlass’的なデバイスが登場した時の準備、なんて考えてたんだけどかなりやる気が失せた。
むしろ、iOS 13(現在beta 3らしい)のARKitで人物や自分の手を捉えるというデモ動画を見たので、それと合わせてVRアプリで操作するのに自分の手を使う、という方向を模索した方が面白いかも。

↑だいぶ前に作成したVRアプリ。みんなVRに興味あるのか今でもダウンロードされてる。
VR CROSS ROADこのアプリでは音声を使って自機を動かすんだけど、カメラを使ってジェスチャーで操作なんてこともできるかもしれない。
【おまけ1】
DIYで使う木工用ドリルを使って、VRゴーグルに穴を開けたんだが6mmのドリルじゃ穴も小さいしそもそも位置もよくなかった、、、ということで、

↑試行錯誤しつつ穴を広げて行ってたところ、、、

↑パカっと部品が取れた、、、?
お、お前、取れるんか!
最初から穴なんて開けなくてもよかったやん!!!
【おまけ2】
コードについて。

↑storyboardでUIViewオブジェクトを作成。自分の場合はSafe Areaの横幅x0.9となるようにconstraintを設定。
中央の棒(UIViewオブジェクト)はただの中心の位置決め用(ゴーグルにセットする時に欲しい)。
使ったコードは一部だけど以下のような感じ。CAReplicatorLayerを使えば複数の画面を並べるだけなら簡単にできる。
class ViewController: UIViewController {
var cameraPosition : AVCaptureDevice.Position!
var captureSession : AVCaptureSession!
func setupBasic() {
cameraPosition = AVCaptureDevice.Position.back
captureSession = AVCaptureSession()
}
//↓画面タップでコールされる
func openCameraSession() {
do {
let videoCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video)
let captureDeviceInput = try AVCaptureDeviceInput(device: videoCaptureDevice!)
captureSession.addInput(captureDeviceInput)
captureSession.beginConfiguration()
captureSession.sessionPreset = AVCaptureSession.Preset.hd1280x720
captureSession.commitConfiguration()
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
previewLayer.connection?.videoOrientation =
AVCaptureVideoOrientation.landscapeRight
previewLayer.frame = CGRect(x:0, y:0,
width:mainView!.bounds.size.width/2,
height:mainView!.bounds.size.height)
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = CGRect(x:0, y:0,
width:mainView!.bounds.size.width/2,
height:mainView!.bounds.size.height)
replicatorLayer.instanceCount = 2
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(
mainView!.bounds.size.width / 2,0.0, 0.0);
replicatorLayer.addSublayer(previewLayer)
mainView!.layer.addSublayer(replicatorLayer)
captureSession.startRunning()
} catch {
print(error);
}
}
}
// in AppDelegate.swift
func applicationDidBecomeActive(_ application: UIApplication) {
application.isIdleTimerDisabled = true
}
↑あと、ゴーグルにセットして時間が経つとスリープしないようにする設定。
applicationWillResignActive(_:) でfalseに戻す。
※iOS12.3.1 , Swift 5.1