頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


ARKitの画像トラッキングにおける画像平面の初期姿勢

ARKitの画像トラッキング(ARImageTrackingConfigurationを使うやつね)で対象の画像を見つけた場合に得られるARAnchorオブジェクト。それをanchorとするとanchor.transformでその位置・姿勢を得ることができる。

これをつかってごにょごにょ(※1)する時なんかにあれ?と思ったのはこのtransformがmatrix_identity_float4x4の状態にはこの平面はx-z平面にある、ということ。
x-y平面にあるものと思ってコード書いててなんかうまくいかねえ?となり気付いたんだが。
ちなみにMDLMeshのnewPlane(withDimensions:segments:geometryType:allocator:)で作成する平面はx-y平面に作成される。うー、なんかややこしいのう。


※1 ↓こういうのをやってたのです。
スポンサーサイト



VRゴーグルに穴をあけたARゴーグルで世界を見る実験

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

VRゴーグル

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

VRゴーグル(穴あけ状態)

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

カメラ画像を2つ並べたスクショ

↑このようにならべて見てみるとどんな感じだろうか?というものだ。

通常VRアプリは少し異なる画像を左右それぞれの目で見るわけだが、これが同じ映像だとどうなるのかピンとこなかった。
使ったのはiPhone XS Max。
画面いっぱいはもちろん、Safe Areaを左右半分にして画像を写しても大きすぎるのかVRゴーグルの仕様のせいかともかく焦点が合わないのでSafe Areaの9割を使っている(後述)。


【結果】
現時点で最新機種のiPhone XS Maxとは言え、カメラの映像はリアルより遅延があってそのせいか、酔った。おえーっ。
当然立体感はない。
通常の目で見る感覚より何もかも大きく見えるのですぐ近くのコップを掴むのもたどたどしい。歩くのも危ない。
捉える物体にピントが合うのに時間がかかる、、、これはコードがぬるいせいかもしれない。何かその辺りの設定できたんだっけ、、、


【感想】
そもそもは自作の’ARゴーグル’を使って現実世界に何か情報を表示する、という方向での技術的な蓄積、つまり‘iGlass’的なデバイスが登場した時の準備、なんて考えてたんだけどかなりやる気が失せた。

むしろ、iOS 13(現在beta 3らしい)のARKitで人物や自分の手を捉えるというデモ動画を見たので、それと合わせてVRアプリで操作するのに自分の手を使う、という方向を模索した方が面白いかも。

VR CROSS ROAD スクショ4
↑だいぶ前に作成したVRアプリ。みんなVRに興味あるのか今でもダウンロードされてる。
VR CROSS ROAD
このアプリでは音声を使って自機を動かすんだけど、カメラを使ってジェスチャーで操作なんてこともできるかもしれない。



【おまけ1】
DIYで使う木工用ドリルを使って、VRゴーグルに穴を開けたんだが6mmのドリルじゃ穴も小さいしそもそも位置もよくなかった、、、ということで、

VRゴーグル(さらに穴あけた状態)

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

部品が外れたVRゴーグル

↑パカっと部品が取れた、、、?
お、お前、取れるんか!
最初から穴なんて開けなくてもよかったやん!!!


【おまけ2】
コードについて。

storyboardでのviewの設定

↑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


iOSアプリ「旗当番表メーカー」をリリースしました(現在無料)

小学生の子供がいると旗持ち当番(旗振り当番とも言うようです)をしなければいけないところもあるでしょう。
そして場合によっては自分がその当番表を作成することになるかもしれません。
そんな時にお手伝いするアプリです。

メンバーを入れて、期間や曜日を設定し、文言を設定すれば、、、

作成した旗当番表

↑このようなPDFファイルを作成してくれます(このブログではPDFファイルのアップロードができないので編集時の画像を表示しています)。

現在無料です。今のうちにダウンロードを!
App Storeはこちら↓

旗当番表メーカーのアイコン
旗当番表メーカー


scrollViewをAutoLayoutとなるべく少ないコードで設定する例

なるべくstoryboard上でscroll viewとそこでスクロールするviewオブジェクトを設定するがviewに表示する内容はコードで作成する(自分の場合は表をコードで描く)。
なのでデバイスや表示する内容次第でviewオブジェクトの高さは変わるが、このような場合にAutoLayoutなどの指定はどうしたらいいのか?

自分の中では納得できる最小実装がこんなの。

scroll view(UIScrollViewオブジェクト)はstoryboardで好きに設定したらOK。これはええねん。問題は中身や。
実際に縦にスクロールするview(UIViewオブジェクト)をここではcontentViewとしておく。これをどうするか?だ。

まずstoryboard上ではscroll viewにcontentViewを乗せる。

Xcodeでのファイル構成1

↑Xcodeで見ると構成はこんなになってる。
ありがたいこと乗せるだけでこのviewがスクロールするビューだと認識してくれる。特にこれだよ!ってview controllerなんかで指定してやる必要もない。感心するわ。

問題のcontentViewのconstraintsだけど、、、

contentViewに設定するconstraints

↑これだけ。Superviewはもちろんscroll viewのこと。
・scroll viewとの上下左右はゼロですよって指定(A)
・横幅同じ
・高さは適当な数字
としている。(A)が感覚的に納得できないがそうするものだとXcodeが教えてくれた。

IBOutlet NSLayoutConstraint *contentViewHeightConstraint;
↑view controllerでこのようなconstraintに関係するoutletを用意しといて先ほどの適当な数字を指定したのと接続する。つまり、

Xcodeでのファイル構成2

↑高さを指定したconstraintを選択し、

outlet設定画面

↑通常通りここからNew Referencing Outletをにゅーっとドラッグして接続すればOK。constraintについてもこんな風に参照をコードに持ってこれるって最近知りました!


コード内でviewに乗せる内容を記述したとして、、、その一番下のy座標がわかったら、
contentViewHeightConstraint.constant = label2.bottom;
↑このようにその値を入れてやればよい。
この記述はviewDidLoadでOK。
これでiPhone 5sでもXS Maxでも意図通りに表示されました。
(個人的にはあまり使いたくない)viewDidLayoutSubviewsを使う必要もなし☺️


タブごとにstoryboardファイルを分ける

storyboardファイルを軽くするためxibを切り離す時のAutolayoutについて

↑この記事の訂正版。
いざこの方法で製品用のプロジェクトを新規作成して作っていくぞー!とはりきっていたのだが、、、あれ?だめやん?!となった。
ナビゲーション周りやテーブルのセルをタップした時にどうするのか、、、みたいなのってxibじゃあダメだったのだ。いや、なんとも情けない。

そんなわけで結局、タブごとにstoryboardファイルを分けることにした。

storyboardの設定

↑新規のstoryboardファイルにnavigation controller、view controllerなどをセット(これは3番目のタブ)。
見えにくいけど一番左がnavigation controllerで、その右がtable view controller。このテーブルのセルをタップすると右のview controllerが表示される、というもの。

-(void)setupTab3
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@“Tab3” bundle:nil];
naviCon3 = [storyboard instantiateViewControllerWithIdentifier:@“tab3_navi1”];
naviCon3.title = @“tab title3”;//タブのタイトル
naviCon3.tabBarItem.image = [UIImage imageNamed:@“icon_edit.png”];//タブの画像
}
↑storyboardのnavigation controllerをこんな感じで引っ張ってきて、、、
{
[tabBarController setViewControllers:
[NSArray arrayWithObjects:naviCon1 , naviCon2 , naviCon3 ,nil]];

[self addChildViewController:tabBarController];
[self.view addSubview:tabBarController.view];
}
↑それぞれtab bar controllerに入れる。

結果のスクショ1

↑この方法なら前記事のようなトリッキーなことをぜずともstoryboard内のSafe Areaもそのまま使える(文字列にはconstraintは設定していない、右下の四角で確認した)し、

結果のスクショ2

↑テーブルも意図通り表示された。


タブの画像やタイトル設定をコードで書く必要があるもののまあこれならわかりやすいだろう、ということでこれで書いていこう。不具合あったら訂正します。




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.