見出し画像

ARKit for spatial computing その1 - Anchor #visionOS

visionOS / Vision Proは現実を拡張するソフトウェア/ハードウェアであり、ARKitはそのキーとなる技術のひとつだと思うのだが、WWDC23の40以上もあるSpatial Computing関連セッションのうち、意外にもARKitに関するものは実は2つしかない。

そのうちのひとつである "Meet ARKit for spatial computing" の内容を、

Spatial Computing向けに特化している部分や、新しく追加された部分に絞って整理し、まとめていく。

逆に従来の(iOS向けの)ARKitの解説は割愛する。
(過去の公式サンプルやARKit-Sampler、拙著等を参照してください)

本記事ではまずアンカーについて。

その2、セッションとデータプロバイダ編はこちら:

(本記事の画像と引用表記部分は基本的にWWDC23の同セッションより引用)


AnchorとARAnchor

はいはいアンカーね、と既知のものとして流しそうになったが、元からARKitにあったものは ARAnchor クラスであり、

この "Anchor" はvisionOSで新たに追加されたプロトコル

ARAnchorはクラス、Anchorはプロトコル、ということで今回新たにARAnchorからプロトコルを切り出したのだろうか、と一瞬思ったが、まったく別モノのようだ。

ARAnchorはvisionOSでは使えず、Anchorにも準拠していない。

そしてAnchorはiOSでは使えず、visionOS専用。

TrackableAnchor

トラッキング可能なAnchorとして、TrackableAnchorプロトコルがある。

isTrackedプロパティを持ち、これがfalseのときはトラッキングされていないため、そのアンカーで固定した仮想コンテンツを非表示にする必要がある。

When a trackable anchor is not being tracked, you should hide any virtual content that you have anchored with it.

WorldAnchor

WorldAnchorの定義

visionOSにおいてワールドトラッキング時に、「アプリの原点」に対してアンカーを配置したいときに用いるアンカーがWorldAnchor。

TrackableAnchorに準拠しており、アプリの原点に対してアンカーを配置したい位置と向きをイニシャライザのtransform引数で受け取る。

World AnchorとRecenter

以下の画像はアンカーがない仮想コンテンツとアンカーがある仮想コンテンツの違いを可視化したもの。

どちらのキューブも、アプリの起動時にアプリの原点に対して相対的に配置されているが、

左側の青いキューブはWorldAnchorによって固定されておらず、右側の赤いキューブはWorldAnchorによって固定されている。

デバイスが移動しても、両方のキューブは配置された場所に留まる。

デジタルクラウンを長押しして"Recenter"(再中心化)を行うと、アプリの原点が現在地に移動する。

このとき、アンカーで固定されていない青い立方体は、アプリの原点との相対的な配置を維持するために移動し、アンカーで固定されている赤い立方体は、現実世界との相対的な配置を維持したまま留まる。

WorldAnchorの永続化

ワールドトラッキング中に追加したWorldAnchorは、アプリの起動や再起動を問わず自動的に永続化される。

自動永続化がアプリが実現したい体験にとって望ましくない場合は、アンカーを使い終わったら削除すればOK。(削除すれば永続化されることはない)

以下は永続化の詳細な解説。

As the device moves around, ARKit builds a map of your surroundings.
(デバイスが移動すると、ARKitは周囲のマップを構築します。)

When you add WorldAnchors, we insert them into the map and automatically persist them for you.
(WorldAnchorを追加すると、マップに挿入され、自動的に永続化されます。)

Only WorldAnchor identifiers and transforms are persisted.
(WorldAnchorの識別子とトランスフォームのみが永続化されます。)

No other data, such as your virtual content, is included.
(バーチャルコンテンツなど、他のデータは含まれません。)

It is up to you to maintain a mapping of WorldAnchor identifiers to any virtual content that you associate with them.
(WorldAnchorの識別子を、あなたが関連付ける仮想コンテンツにマッピングするのは、あなた次第です。)

Maps are location based, so when you take your device to a new location -- for instance, from home to the office -- the map of your home will be unloaded, and then a different map will be localized for the office.
(マップはロケーションベースなので、デバイスを新しい場所(例えば自宅からオフィス)に持っていくと、自宅のマップがアンロードされ、オフィスでは別のマップがローカライズされます。)

Any anchors that you add at this new location will go into that map.
(新しい場所で追加したアンカーは、すべてそのマップに入ります。)

When you leave the office at the end of the day and head home, the map that ARKit has been building at the office, along with any anchors that you placed there, will be unloaded.
(一日の終わりにオフィスを出て家に帰ると、ARKitがオフィスで作っていたマップと、そこに置いたアンカーはアンロードされます。)

Once again, though, we have been automatically persisting the map along with your anchors.
(しかし、今回もアンカーと一緒にマップを自動的に永続化しました。)

Upon returning home, ARKit will recognize that the location has changed, and we will begin the process of relocalizing by checking for an existing map for this location.
(帰宅すると、ARKitは場所が変わったことを認識し、この場所の既存のマップを確認して再ローカライズするプロセスを開始します。)

If we find one, we will localize with it, and all of the anchors that you previously added at home will become tracked once again.
(もし見つかったら、それを使ってローカライズし、以前自宅で追加したすべてのアンカーが再び追跡できるようになります。)

ImageAnchor

ImageAnchorもTrackableAnchorに準拠するアンカー。ARImageAnchorとほぼ同じで、画像トラッキング時に検出した画像に対して提供されるアンカー。

When an image is detected, ARKit provides you with an ImageAnchor.
(画像が検出されると、ARKit は ImageAnchor を提供します。)

ImageAnchors can be used to place content at known, statically placed images.
(ImageAnchor は、既知の静的な画像にコンテンツを配置するために使用できます。)

For instance, you can display some information about a movie next to a movie poster.
(例えば、映画のポスターの横に、映画に関する情報を表示することができます。)

ImageAnchors are TrackableAnchors that include an estimated scale factor, which indicates how the size of the detected image compares to the physical size that you specified and the ReferenceImage that the anchor corresponds to.
(ImageAnchorはTrackableAnchorで、推定スケールファクターを含んでおり、検出された画像のサイズが、指定した物理的サイズとアンカーが対応するReferenceImageと比較してどのようになるかを示しています。)

HandAnchor

HandAnchorの定義

ハンドトラッキングにより検出された手の情報は、HandAnchorという形で提供される。

HandAnchorはTrackableAnchorであり、skeletonプロパティ(Skeleton型)とchiralityプロパティ(HandAnchor.Chirality型)を持つ。

HandAnchorのtransformは、アプリの原点を基準とした手首のtransformを表す。

A HandAnchor's transform is the wrist's transform relative to the app origin.

HandAnchorsは、手から相対的にコンテンツを配置したり、カスタムジェスチャーを検出するために使用できる。

HandAnchor.Chirality

Chiralityは、左手なのか右手なのかの情報を持つ。

@frozen public enum Chirality : CustomStringConvertible, Sendable {

    case right

    case left

    public var description: String { get }

    public static func == (a: HandAnchor.Chirality, b: HandAnchor.Chirality) -> Bool

    public func hash(into hasher: inout Hasher)

    public var hashValue: Int { get }
}

Skeleton と Joint

Skeleton型は従来のiOSのARKitではARSkeleton3Dに相当する、ジョイントにより骨格を表現する構造体。

Joint構造体は、親ジョイント、名前、親ジョイントに対する相対的な localTransform、ルートジョイントに対する相対的な rootTransform、このジョイントがトラッキングされているかを示す Bool 値をプロパティに持つ。

手のスケルトンで利用可能なジョイントの一覧

ジョイントは名前で照会することができる。以下の画像は、手のスケルトンで利用可能な全ジョイントを列挙したもの:

  • 手首(.handWrist)は、手のルートジョイント

  • 各指の最初のジョイントは手首の親となる

    • たとえば、1は0の親になる

  • それ以降の指の関節は前の関節の親になる

    • たとえば、2は1の親になる

PlaneAnchor

平面検出により現実世界から検出された水平面や垂直面は、PlaneAnchorとして提供される。TrackableAnchorではなくAnchorに準拠し、水平 or 垂直を表す Alignment、平面の Geometry、床やテーブルなどの分類を表す Classification 等の情報をプロパティから取得できる。

ARPlaneAnchorとほぼ同じ。

MeshAnchor

シーンジオメトリは、実世界の形状を表すポリゴンメッシュを含むアンカーを提供する。

このアンカーがMeshAnchorで、こちらはTrackableAnchorではなくAnchorに準拠し、Geometry型のgeometryプロパティを持つ。

MeshAnchor.Geometry構造体は以下のような定義で、SCNGeometryと大体同じかと。

classificationsには以下の種類がある。

メッシュのSwiftでの取り扱いについては以下の記事も参考になると思う:

ここから先は

0字

文章やサンプルコードは多少荒削りかもしれませんが、ブログや書籍にはまだ書いていないことを日々大量に載せています。たったの400円で、すぐに購読解除してもその月は過去記事もさかのぼって読めるので、少しでも気になる内容がある方にはオトクかと思います。

技術的なメモやサンプルコード、思いついたアイデア、考えたこと、お金の話等々、頭をよぎった諸々を気軽に垂れ流しています。

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/