Apple Engine

Apple, iPhone, iOS, その周辺のことについて

技術書典3に出典しておりました

ブースにお越しいただい方、ご購入いたただいた方、ありがとうございます。

この Blog で書いている SceneKit についての PDF を出していまして、前半は Blog の内容、後半部分は iOS 11 で追加されたが書かれており、うっかり 340 ページ超えてしまいました。

iOS 11 の SceneKit の新機能はドキュメントでも「No overview available」が多く、 該当する機能のヘッダーファイルにコメントで説明が書かれているのですが、 SceneKit はコメント自体がないものがあって結構レアだったと思われます。

 

内訳

正確な数は伏せますが若干黒字です。
出典料、ユザワヤさんで買った机に敷く布、ダウンロードカード用の名刺印刷、 本紹介用の印刷物、その他雑費で大体1万ぐらい。
名刺の印刷は速く入稿するとかなり安くなりますし、 見本は iPad Pro にしていたので、PDF のみにすると大体このぐらいになります。

当初は印刷物にしようとしていたのですが、 1冊当たりの価格が薄い本の価格にしては異常に高くなるため諦めました。
ちなみに、現状のページで30部刷ると 13インチ MacBook Pro i5 メモリ8G 256GBストレージが買えるぐらい。

 

良いところ

知っていることでも、再度文字に起こしたり、まとめたりすることで理解が深まり、誤りに気付くこともありで、自分自身の勉強になりました。

 

思うところ

ざっくり見た感じですと Android / iOS 関連はあまりなく、 賑わっていそうなところは、Unity、Python や ML、Web 関連と数学関連でして、 書店で販売されるものにリンクしている感はありました。
需要として考えると真っ当な話ですが、やはりこういうものは儲けとかではなく出したいから出すべきかなと。

また、3度目(4度目?)の開催なのかわかりませんが、 運営の方が手馴れていてぐっじょぶでした。
開催が11時から、場所がUDX(家から近い)というのも良いです。

あえて言うと毎回天候に恵まれないところですかね。

 

反省点

Blog からもってきているので文章を常体から敬体に直すのが面倒なのと、
つくり終えた時に気づいたのですが、 3冊ぐらいに分けてもっと丁寧に解説した方がよかったと思いました。

あと、今回初めてでしたので1人で行ったのですが、ワンオペだと他のブースがあまり見られないのが難点です。

 

まとめ

こんなマイナージャンルの本を手にとってもらえる環境をつくっていただいた運営の方や来場者の方には深く感謝をしております。

ありがとうございました。

iPhone X の Safari で表示する Web ページの HTML / CSS 設定

どうやら、そのままだとサイトが表示領域の全体に面表示されないっぽい。

参照元
ayogo.com

 

対処方法

meta タグ Viewport に「viewport-fit=cover」を入れる。

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

 

このままだと問題があり、本体を横に傾けてランドスケープにすると コンテンツが両サイドまでいってしまい、四隅のアールやカメラ部分でコンテンツ内容が隠れてしまう。

アプリのように Safe Area があり、CSS で padding を設定すると余白をつけてくれる。

padding: 
constant(safe-area-inset-top) 
constant(safe-area-inset-right) 
constant(safe-area-inset-bottom)
constant(safe-area-inset-left);

 

ちなみに、constant(safe-area-inset-top) は margin など一部プロパティでも使用可能。

 

注意点

safe-area-inset を設定したタグに「width: 100%」 や 「height: 100%」を設定すると表示がうまくいかない可能性がある。

iOS 11 GM の ARKit で変更されたこと

フェイストラッキングで顔の形状を取り、顔や独自で作成した顔のジオメトリを AR の仮想空間設置し、表情を付加する機能が追加。
Message アプリでデモしていた AniMoji ようなものが、AR 空間で使用できる。

また、Beta 中に廃止となっていたものが完全に機能からなくなった。

 

廃止

ARWorldTrackingSessionConfiguration と ARSessionConfiguration が廃止

ARKit の初期にあったフル機能を使用する設定と、移動でジオメトリが固定できず追従してしまうが全端末で動く設定の ARWorldTrackingSessionConfiguration と ARSessionConfiguration が完全に廃止され 命令を受け付けなくなった。

要するに呼び出すと落ちる。

ちなみに公式のドキュメントからも該当ページがなくなっている。

 

ARWorldTrackingConfiguration と AROrientationTrackingConfiguration を使うべし。

 

変更前 / 変更後 機能説明 対応端末
ARWorldTrackingSessionConfiguration / ARWorldTrackingConfiguration フル機能を使用可能 A9 以上の端末
ARSessionConfiguration / AROrientationTrackingConfiguration 端末移動でジオメトリが追従してしまう 全端末

 

追加

全て顔認識系のもの。

  • ARTrackable
  • ARFaceTrackingConfiguration
  • ARFaceAnchor
  • ARDirectionalLightEstimate
  • ARFrame > capturedDepthData
  • ARFrame > capturedDepthDataTimestamp

 

ARTrackable

フェイストラッキングが可能かどうか調べるプロトコル

 

ARFaceTrackingConfiguration

ARWorldTrackingConfiguration などと同様に、フェイストラッキングの設定をする。

 

ARFaceAnchor

顔を表す ARFaceAnchor オブジェクトが、今までと同様にアンカーリストを追加され、顔の位置と向き、顔のジオメトリーのトポロジーや表情が構成される。

表情に関しては Blend Shapes によるモーフィングで行う。

 

ARDirectionalLightEstimate

ARFaceTrackingConfiguration で isLightEstimationEnabled を true にしている場合、現実空間から光の情報を取得し仮想空間にライトの情報に適応する。
デフォルトでオン。

 

ARFrame > capturedDepthData

フレーム毎に深度カメラからキャプチャされた深度情報が AVDepthData で返される。

 

ARFrame > capturedDepthDataTimestamp

フレーム毎に深度カメラから生成される深度情報がキャプチャされた時間 (タイムスタンプ) が返される。

フレーム毎に生成されるカラー画像と深度画像のフレームレートが異なるため、カラー画像と深度画像のタイムスタンプが必ず一致するわけではない。

 

取得できる表情の Blend Shapes

英語だけどなんとなくわかるかと思われる。

リンク先の公式ドキュメントでは個別で画像とともに紹介されている。

 

左目

  • eyeBlinkLeft
  • eyeLookDownLeft
  • eyeLookInLeft
  • eyeLookOutLeft
  • eyeLookUpLeft
  • eyeSquintLeft
  • eyeWideLeft

 

右目

  • eyeBlinkRight
  • eyeLookDownRight
  • eyeLookInRight
  • eyeLookOutRight
  • eyeLookUpRight
  • eyeSquintRight
  • eyeWideRight

 

顎(Jaw)

  • jawForward
  • jawLeft
  • jawRight
  • jawOpen

 

口(Mouth)

  • mouthClose
  • mouthFunnel
  • mouthPucker
  • mouthLeft
  • mouthRight
  • mouthSmileLeft
  • mouthSmileRight
  • mouthFrownLeft
  • mouthFrownRight
  • mouthDimpleLeft
  • mouthDimpleRight
  • mouthStretchLeft
  • mouthStretchRight
  • mouthRollLower
  • mouthRollUpper
  • mouthShrugLower
  • mouthShrugUpper
  • mouthPressLeft
  • mouthPressRight
  • mouthLowerDownLeft
  • mouthLowerDownRight
  • mouthUpperUpLeft
  • mouthUpperUpRight

 

眉毛(Eyebrows)

  • browDownLeft
  • browDownRight
  • browInnerUp
  • browOuterUpLeft
  • browOuterUpRight

 

頬(Cheeks)

  • cheekPuff
  • cheekSquintLeft
  • cheekSquintRight

 

鼻(Nose)

  • noseSneerLeft
  • noseSneerRight

 

参照元

ARKit | Apple Developer Documentation

developer.apple.com

Face ID で変わることの予想


Face ID と噂されている顔認証で変わることを考えてみる。

 

ハード側から見てみると、まず画面が広く使え、噂通り、狭額縁になる為かなりの広さが期待される。
ホームボタンがなくなることで、それに起因する故障がなくなるし、手やホームボタンが汚れていた時に認証ができなくなることがなくなる。
これからの季節での利点は手袋をしていても顔認証できることだろう。

顔の部位で行う認識に関しては Lumia 1520 で便利さを感じたのでがんばってほしい。勿論、素早く認証ができるのであればの話だが。

 

ソフト側から見ると顔認証で今まで Touch ID で行なっていた認証が通る。
噂によると顔が画面を向いていると、スリープさせないように設定することができるらしい。

多分、iOS SDK の Vision Framework で使用できる Landmark の顔の形状の認識を使用しているので、顔がどのように向いているかわかると思われる。

スリープなど顔認証以外にも面白いことに使えそうな感じはする。

 

1つだけ気になっているのはマスクしていた時に認証は通るのだろうかというところ。

iOS 11 以降で Apple が目指す世界

今回、iOS SDK で目玉の機能だと思っているのは、CoreML、Vision、ARKit で、この3つの連携がスマートフォンの世界を変えると思っている。

以下、軽く説明。

 

Core ML

機械学習向けフレームワーク。 顔認識などで画像から特定のもの検知したり、Siri などで使われている言葉の分類分けなど、使いやすくしたもの。
具体的には、学習データを TensorFlow などで作成し、mlmodel などの専用ファイルに変換、Xcode のプロジェクト放り込むと mlmodel のファイルがクラスとして扱える。
必要なパラメータを渡すとそれに沿った結果が返ってくるクラスとなり、実装がかなり簡単。

正直、学習データを作成するのが、かなりしんどいので誰でも簡単にとは言わないが、学習データが手元にあれば機械学習がかなり手軽に試すことができる。

 

Vision フレームワーク

顔認識、文字認識、バーコード・QR コード、物体認識など既存で用意されているが、このフレームワークの真髄は Core ML との連携にある。

リアルタイムで撮っているカメラから Vision に渡し CoreML で画像解析という連携ができる。

 

ARKit

これに関しては色々記事が出ているのであまり語ることはないが一応説明。

現実空間に 2D / 3D でつくられた仮想のオブジェクトを合成し、あたかも現実にその物体があるかのように見せる技術。

現状、検知できる障害物は水平の平面のみ。

 

この3つから想像できる今後。

Core ML は機械学習から推測する予知や検知、
Vision は Core ML からのデータの受け渡しや分類をし、
ARKit はその入り口と最終的な情報の可視化を行うようになるだろう。

 

現状で自分が試しに行ったのは、
ARKit で画面タップの際に、撮る現実のカメラ画像から Vision に渡し、
Vision から Core ML の学習データから写真に何が写っているかを検知してテキスト情報に変換。
検知した情報を ARKit 上で文字のオブジェクトとして配置するようなもの。
簡単な実装でこれだけのものができてしまった。

 

多分、今後は Core ML の学習データ作成部分も Apple 謹製のもの出てきそう。
もし、ARM チッブでも使用できるのであれば Apple TV が学習データ作成用のデバイスとなるかもしれない。

ARKit に関しては Microsoft HoloLens のように見えている周囲の障害物の判定を行えるようになるだろう。
その際は、セカイカメラのようにいろいろなものにタグ付けしたり情報を表示することができるかものしれない。
また、何らかの情報をサジェストする機能も実装できるだろう。

 

今後、この技術を使用したアプリやデバイスがどのような進化をするか楽しみである。

iOS Human Interface Guidelines の Augmented Reality (ARKit) をざっくり訳す

以下、ざっくり訳。間違っていたらごめんなさい。
あと、軟弱なので訳せなかったところは飛ばしている。

一応、ベータなので内容は変更される可能性あり。

Augmented Reality - Technologies - iOS Human Interface Guidelines

 

注記
  • phone と原文で書かれているところは iPhone(iPad) にしている
  • () の部分は自分が追記したもの。ポエム。

 

Augmented Reality (AR)

ARKit を使用して仮想オブジェクトを現実の世界にシームレスに融合させる臨場感あふれる魅力的な体験を提供する。

AR アプリでは、カメラを使用して現実の世界を表示し、3次元の仮想オブジェクトが重ね合わされ、 実際に存在するという錯覚を作り出す。

ユーザーは、さまざまな角度からオブジェクトを鑑賞するためデバイスの方向を変えることができ、 ジェスチャーや動きを使ってオブジェクトを操作などインタラクションを起こすことができる。

 

エクスペリエンスの設計

ディスプレイ全体を使用する。

現実世界でアプリの仮想オブジェクト設置し、操作するためにできるだけ多くの画面を使用する。
没入体験を減らす操作系の UI や情報で画面が乱雑にならないようする。

 

現実的なオブジェクトを配置するときには頑張ってつくりこめ

すべての AR 体験でリアルなフォルムの仮想オブジェクトを必要とするわけではないが、使用する場合はその環境にあたかもあるような見栄えのオブジェクトを使うべき。
検出された現実世界のサーフェス上にオブジェクトを配置し、より良いテクスチャやジオメトリを作成し、適切なスケーリング、仮想オブジェクトに環境照明を反映させる。

 

ユーザーに不快感を与えないようにする

一定の距離や角度でデバイスを長時間保持させるとユーザーは疲労する可能性あり。 アプリを使用した際、デバイスをどのようにもって使用されるか考えて不快感を与えさせないように。

例えば、オブジェクトを遠くに配置することで、近くに移動する必要がなくなる。

 

アプリでユーザーが動くことを推奨する場合は、徐々に動きを促す。

最初にゲームなど経験に適応する時間を与えること。
その後、徐々に動きを促すべき。

  

ユーザーの安全に注意する

あまりにも長距離の移動をさせたり、近くに人や物が存在すると、危険な状態になる可能性がある。
なので、アプリを安全に運用する方法を検討する。

例えば、ゲームで大きな動きや突然の動きを避けるなど。

 

臨場感あふれる体験を高めるために、オーディオと触覚フィードバックを使用する

音響効果またはバイブレーション/触覚フィードバックは、仮想物体が現実世界表面、または他の仮想物体と接触したことを確認させることができる。

没入型のゲームでは、BGM はユーザーを仮想世界にのめり込ませるのに役立つ。

 

可能な限り、コンテキスト(前後関係, 流れ)でヒントを提供する

オブジェクトの周りに3次元回転インジケータを配置すると、オーバーレイで表示されたテキストベースの命令よりも直感的になる。

平面検出前やユーザーがコンテンツのヒントなどに応答していない場合など。

状況によっては、テキストオーバーレイヒントが必要。

f:id:x67x6fx74x6f:20170906113949p:plain

 

何らかの指示をするテキストを表示する場合は、わかりやすい用語を使用せよ

ユーザー全員がテクノロジーに詳しいわけではないので、
アプローチが容易になるように、ARKit、ワールドディテクション、トラッキングなどの開発者用語を使用しないようにする。

代わりに、ほとんどの人が理解できるフレンドリーな会話言葉を使用せよ。 (トラッキングとか大丈夫そうだけどドキュメントには書いてある)

×
平面を見つけることができません。 側面に移動するか、iPhone(iPad)の位置を変えてみてください。 平面を見つけることができません。トラッキングを調整します。
場所をタップして@配置するオブジェクトの名前」を配置します。 平面をタップしてオブジェクトを固定します。
多くの照明を点けて動してみてください。 機能が不十分です。
iPhone(iPad)をゆっくり動かしてみてください。 過度の動きが検出されました。

 

AR 体験への不必要な中断を避ける

現実環境を分析後、ユーザーが AR アプリを終了して AR アプリに再び入るたびに平面が検出される。

デバイスと仮想空間のカメラの位置が変更されている可能性があり、以前に配置されたオブジェクトは再配置される可能性が高くなる。

AR を非表示にしオブジェクト設定の変更をできるようにすることも解決策の一つ。
(状況によってはフルリセットも必要かも?)

 

拡張現実に入り込む

f:id:x67x6fx74x6f:20170906114205p:plain

初期設定が行われている状態を示し、ユーザーに伝える。
現実環境を分析する初期化プロセスは、アプリが AR に動作する度に発生し数秒かかる。

起こりうる混乱を減らし、プロセスをスピードアップするために、初期化中の状況を示し、周囲を探索させたり、積極的に平面を探すよう促す。

 

仮想オブジェクトの配置

f:id:x67x6fx74x6f:20170906114233p:plain

 

平面にインターフェースを配置して、オブジェクトを配置できるタイミングを理解させる

ビジュアルインジケータは、サーフェスターゲティングモードがアクティブであることを伝えるうえで最適な方法で 人が水平で平らな面をだと推測するのに役立つ。

平面がターゲットに設定されると、インジケータの外観が変更され、オブジェクトの配置が可能になることが見た目でわかるようになる。

アプリに合わせたビジュアルインジケータをデザインしても良い。

 

ユーザーがオブジェクトを配置するときに適切に応答させる

平面検出の間、(非常に短時間で)精度が向上する。

ユーザーが画面をタップしてオブジェクトを配置する場合は、現在使用可能な情報を使用して配置し、位置の設定、サーフェスの範囲を超えて配置されてしまった場合は戻す。

 

検出されたサーフェスのエッジにオブジェクトを正確置こうとしない

AR では、平面境界は環境分析毎に変化する可能性のあるため。

 

仮想オブジェクトとのユーザインタラクション

f:id:x67x6fx74x6f:20170906114317p:plain

 

画面上のコントロールは直接操作を優先させる

画面上のオブジェクトなど、別のコントロールする UI を使って操作するのではなく、直接オブジェクトを触り操作できれば、より没入感があり直感的。

ただし、ユーザーが動き回っているときなど、直接の操作が混乱を招いたり操作困難になることがあるので注意。

 

標準的で使い慣れたジェスチャーを使用して、仮想オブジェクトと直接操作する

たとえば、オブジェクトを移動するための1本指でのドラッグジェスチャ、回転するオブジェクトの2本指で操作するジェスチャをサポートするなどを検討する。

詳しい内容は ジェスチャ(英語) を参照。

 

インタラクションを簡素に保つ。

タッチジェスチャーの処理は 2 次元であるが、AR の現実世界は 3 次元。
仮想オブジェクトとのユーザーのやり取りを簡素化するために、以下のアプローチを検討する。

 

f:id:x67x6fx74x6f:20170906114416p:plain

  • オブジェクトが置かれている2次元表面への移動を制限する
  • オブジェクトの回転を単一の軸に制限する

 

操作可能な仮想オブジェクトの適切な位置でジェスチャーに応答させる

小さい、薄い、または遠くに置かれたオブジェクトの特定のポイントに人の指が正確に触れることは難しい。

アプリでインタラクションを起こすオブジェクトの近くでジェスチャを検出する場合は、ユーザーがオブジェクトに影響を与えることを想定することを勧める。

 

ユーザーが設置するオブジェクトの拡大縮小(スケーリング)が必要かどうかを検討する

通常、スケーリングはおもちゃやゲームのキャラクターなど、オブジェクトに固有のサイズがなく、ユーザーがそれを大きくしたり小さくしたりする場合に適している。

実際の世界に比べて大きさが決まっているサイズのオブジェクトの場合、家具のようなアイテムが正確なサイズに配置されている場合、スケーリングはさせない。

 

競合するジェスチャーに注意する

2本指のピンチジェスチャーは、2本指の回転ジェスチャーと非常によく似ている。

もし、2つのジェスチャーを実装する場合は、アプリをテストして、正しく操作するできることを確認しておく。

 

仮想オブジェクトの動きがスムーズであることを確認する

オブジェクトのサイズを変更したり、オブジェクトを回転させたり、新しい場所に移動したりするときに、オブジェクトが突然消えて現れたりなど、スムーズに表示されるよう注意する。

 

より魅力的なインタラクションの方法を探求する。

ジェスチャーが AR 内の仮想オブジェクトとインタラクションを起こす唯一の方法ではない。

モーション(ジャイロ、コンパス、加速度センサー)や近接(近接センサー)など、他の要素を使用してコンテンツを息吹を吹き込むことができる。

例えば、ユーザーが歩いているときに、ゲームキャラクターがユーザーを見るように頭を動かすなど。

 

エラーなど問題が起こった時の処理

使用できる環境の条件を満たしていない場合、ユーザー側からリセットできるようにする

オブジェクト配置の改善や条件の改善を待つように強制しない。
もう一度やり直してより良い結果が得られるかどうかを確認する方法を教える。

    f:id:x67x6fx74x6f:20170906114532p:plain

(多分、光が足りないとうことを伝えたいのだと思われる)

 

問題が発生した場合には可能な修正を提案する

ユーザーの環境と平面の検出の分析は、さまざまな理由で失敗することがある。

十分な光がない、平面が反射する、平面が充分なディテールを持っていない、カメラが大きく動くなど。

アプリ得る詳細情報が不十分か、動きが多すぎるか、平面の検出に時間がかかりすぎる場合は、問題を解決するための提案を提示する。

問題 考えられる提案
不十分な機能が検出されました 多くの照明を点けて移動してみてください
過度の動きが検出されました iPhone(iPad)を遅く動かしてみてください。
表面の検出に時間がかかりすぎる 移動して、より多くのライトをオンにして、iPhone(iPad)が模様など質感のある平面をカメラがとらえている事を確認してください。

 

可能なデバイスでのみ AR 機能を提供する

アプリの主な使用目的が AR の場合は、ARKit をサポートする端末での使用できるようにする。

製品写真を含む家具カタログのようなアプリで、AR を第2の機能として提供している場合、サポートされていないデバイスで AR 使用時は、エラーを表示しないようにする。
(AR の機能を塞ぐか、違う方法で似たような体験をさせるということだと思われる)

また、デバイスが ARKit をサポートしていない場合は、最初の画面にオプションである AR 機能を提示しないこと。

開発については、「 Information Property List Key Reference 」の UIRequiredDeviceCapabilities セクション の ARKit 用のキーと、ARConfigurationisSupported プロパティを参照。

 

もっと詳しく知る

開発者向けのガイダンスについては ARKit を参照。

iOS 11 / Xcode 9 の SceneKit プロパティ、メソッド等の追加・変更・廃止一覧

自分のメモ用。
Beta なので変更される可能性あり。

 

Type Color

  • 変更 / Modified
  • 追加 / Added
  • 廃止 / Deprecated

 

変更内容

 

  • SCNScene
    • SCNScene.Attribute
      • init(rawValue: String)

 

  • SCNView
    • SCNView.Option
      • init(rawValue: String)
    • cameraControlConfiguration:SCNCameraControlConfiguration
    • defaultCameraController: SCNCameraController
    • rendersContinuously: Bool

 

  • SCNNode
    • SCNBoundingVolume
      • boundingBox: (min: SCNVector3, max: SCNVector3)
      • boundingSphere: (center: SCNVector3, radius: Float)
    • entity: GKEntity?
    • focusBehavior: SCNNodeFocusBehavior
    • simdEulerAngles: simd_float3
    • simdOrientation: simd_quatf
    • simdPivot: simd_float4x4
    • simdPosition: simd_float3
    • simdRotation: simd_float4
    • simdScale: simd_float3
    • simdTransform: simd_float4x4
    • simdWorldFront: simd_float3
    • simdWorldOrientation: simd_quatf
    • simdWorldPosition: simd_float3
    • simdWorldRight: simd_float3
    • simdWorldTransform: simd_float4x4
    • simdWorldUp: simd_float3
    • worldFront: SCNVector3
    • worldOrientation: SCNQuaternion
    • worldPosition: SCNVector3
    • worldRight: SCNVector3
    • worldUp: SCNVector3
    • localFront: SCNVector3
    • localRight: SCNVector3
    • localUp: SCNVector3
    • simdLocalFront: simd_float3
    • simdLocalRight: simd_float3
    • simdLocalUp: simd_float3
    • convertVector(SCNVector3, from: SCNNode?)
    • convertVector(SCNVector3, to: SCNNode?)
    • localRotate(by: SCNQuaternion)
    • localTranslate(by: SCNVector3)
    • look(at: SCNVector3)
    • look(at: SCNVector3, up: SCNVector3, localFront: SCNVector3)
    • rotate(by: SCNQuaternion, aroundTarget: SCNVector3)
    • setWorldTransform(SCNMatrix4)
    • simdConvertPosition(simd_float3, from: SCNNode?)
    • simdConvertPosition(simd_float3, to: SCNNode?)
    • simdConvertTransform(simd_float4x4, from: SCNNode?)
    • simdConvertTransform(simd_float4x4, to: SCNNode?)
    • simdConvertVector(simd_float3, from: SCNNode?)
    • simdConvertVector(simd_float3, to: SCNNode?)
    • simdLocalRotate(by: simd_quatf)
    • simdLocalTranslate(by: simd_float3)
    • simdLook(at: vector_float3)
    • simdLook(at: vector_float3, up: vector_float3, localFront: simd_float3)
    • simdRotate(by: simd_quatf, aroundTarget: simd_float3)

 

  • Basic 3D Data Types
    • SCNVector3
      • init()
      • init(float3)
      • init(double3)
      • init(Int, Int, Int)
      • init(Float, Float, Float)
      • init(Double, Double, Double)
      • init(CGFloat, CGFloat, CGFloat)
      • init(x: CGFloat, y: CGFloat, z: CGFloat)
      • init(x: Float, y: Float, z: Float)
    • SCNVector4
      • init()
      • init(float4)
      • init(double4)
      • init(Double, Double, Double, Double)
      • init(CGFloat, CGFloat, CGFloat, CGFloat)
      • init(Float, Float, Float, Float)
      • init(Int, Int, Int, Int)
      • init(x: CGFloat, y: CGFloat, z: CGFloat, w: CGFloat)
      • init(x: Float, y: Float, z: Float, w: Float)
    • SCNMatrix4
      • init()
      • init(double4x4)
      • init(double4x4)
      • init(float4x4)
      • init(float4x4)
      • init(m11: Float, m12: Float, m13: Float, m14: Float, m21: Float, m22: Float, m23: Float, m24: Float, m31: Float, m32: Float, m33: Float, m34: Float, m41: Float, m42: Float, m43: Float, m44: Float)
    • SCNFloat

 

  • SCNSceneRenderer
    • SCNHitTestOption
      • searchMode: SCNHitTestOption
      • SCNHitTestSearchMode
        • all
        • any
        • closest
    • SCNDebugOptions
      • init(rawValue: String)
      • renderAsWireframe: SCNDebugOptions
      • showCameras: SCNDebugOptions
      • showConstraints: SCNDebugOptions
      • showCreases: SCNDebugOptions
      • showSkeletons: SCNDebugOptions

 

  • SCNSceneRendererDelegate
    • renderer(SCNSceneRenderer, didApplyConstraintsAtTime: TimeInterval)

 

  • SCNRenderer
    • render(withViewport: CGRect, commandBuffer: MTLCommandBuffer, passDescriptor: MTLRenderPassDescriptor)
    • update(atTime: CFTimeInterval)

 

  • SCNHitTestResult
    • boneNode: SCNNode

 

  • SCNCamera
    • yFov: Double
    • xFov: Double
    • projectionDirection: SCNCameraProjectionDirection
    • SCNCameraProjectionDirection
      • horizontal
      • vertical
    • focalDistance: CGFloat
    • focalSize: CGFloat
    • focalBlurRadius: CGFloat
    • aperture: CGFloat
    • apertureBladeCount: Int
    • fStop: CGFloat
    • fieldOfView: CGFloat
    • focalBlurSampleCount: Int
    • focalLength: CGFloat
    • focusDistance: CGFloat
    • screenSpaceAmbientOcclusionBias: CGFloat
    • screenSpaceAmbientOcclusionDepthThreshold: CGFloat
    • screenSpaceAmbientOcclusionIntensity: CGFloat
    • screenSpaceAmbientOcclusionNormalThreshold: CGFloat
    • screenSpaceAmbientOcclusionRadius: CGFloat
    • sensorHeight: CGFloat
    • wantsDepthOfField: Bool

 

  • SCNCameraController
    • SCNInteractionMode
    • automaticTarget: Bool
    • delegate: SCNCameraControllerDelegate?
    • inertiaEnabled: Bool
    • inertiaFriction: Float
    • interactionMode: SCNInteractionMode
    • isInertiaRunning: Bool
    • maximumHorizontalAngle: Float
    • maximumVerticalAngle: Float
    • minimumHorizontalAngle: Float
    • minimumVerticalAngle: Float
    • pointOfView: SCNNode?
    • target: SCNVector3
    • worldUp: SCNVector3
    • beginInteraction(CGPoint, withViewport: CGSize)
    • clearRoll()
    • continueInteraction(CGPoint, withViewport: CGSize, sensitivity: CGFloat)
    • dolly(by: Float, onScreenPoint: CGPoint, viewport: CGSize)
    • dolly(toTarget: Float)
    • endInteraction(CGPoint, withViewport: CGSize, velocity: CGPoint)
    • frameNodes([SCNNode])
    • roll(by: Float, aroundScreenPoint: CGPoint, viewport: CGSize)
    • rollAroundTarget(Float)
    • rotateBy(x: Float, y: Float)
    • stopInertia()
    • translateInCameraSpaceBy(x: Float, y: Float, z: Float)

 

  • SCNCameraControlConfiguration

    • allowsTranslation: Bool
    • autoSwitchToFreeCamera: Bool
    • flyModeVelocity: CGFloat
    • panSensitivity: CGFloat
    • rotationSensitivity: CGFloat
    • truckSensitivity: CGFloat

 

  • SCNCameraControllerDelegate

    • cameraInertiaDidEnd(for: SCNCameraController)
    • cameraInertiaWillStart(for: SCNCameraController)

 

  • SCNLight
    • SCNLight.LightType
      • init(rawValue: String)
    • automaticallyAdjustsShadowProjection: Bool
    • forcesBackFaceCasters: Bool
    • maximumShadowDistance: CGFloat
    • sampleDistributedShadowMaps: Bool
    • shadowCascadeCount: Int
    • shadowCascadeSplittingFactor: CGFloat
    • sphericalHarmonicsCoefficients: Data

 

  • SCNMaterial
    • SCNMaterial.LightingModel
      • init(rawValue: String)
    • displacement
    • SCNTransparencyMode
      • `default`
      • dualLayer
      • singleLayer
    • SCNBlendMode
      • max
    • colorBufferWriteMask: SCNColorMask
    • SCNColorMask
    • fillMode: SCNFillMode
    • SCNFillMode

 

  • SCNMaterialProperty
    • textureComponents: SCNColorMask

 

  • SCNGeometry
    • SCNBoundingVolume
      • boundingBox: (min: SCNVector3, max: SCNVector3)
      • boundingSphere: (center: SCNVector3, radius: Float)
    • elements: [SCNGeometryElement]
    • sources: [SCNGeometrySource]
    • elementCount: Int
    • element(at: Int)
    • sources(for: SCNGeometrySource.Semantic)
    • tessellator: SCNGeometryTessellator?
    • SCNGeometryTessellator
    • wantsAdaptiveSubdivision: Bool

 

  • SCNGeometrySource
    • init(vertices: [SCNVector3])
    • init(normals: [SCNVector3])
    • init(textureCoordinates: [CGPoint])
    • SCNGeometrySource.Semantic
      • init(String)
      • init(rawValue: String)

 

  • SCNAnimatable
    • addAnimation(SCNAnimationProtocol, forKey: String?)
    • func animation(forKey: String)
    • func removeAnimation(forKey: String, fadeOutDuration: CGFloat)
    • func pauseAnimation(forKey: String)
    • func resumeAnimation(forKey: String)
    • func isAnimationPaused(forKey: String)
    • addAnimationPlayer(SCNAnimationPlayer, forKey: String?)
    • animationPlayer(forKey: String)
    • removeAnimation(forKey: String, blendOutDuration: CGFloat)
    • func setAnimationSpeed(CGFloat, forKey: String)

 

  • SCNAnimationEvent
    • SCNAnimationEventBlock

 

  • SCNAnimation
    • SCNAnimationDidStartBlock
    • SCNAnimationDidStopBlock
    • init(caAnimation: CAAnimation)
    • init(contentsOf: URL)
    • init(named: String)
    • animationDidStart: SCNAnimationDidStartBlock?
    • animationDidStop: SCNAnimationDidStopBlock?
    • animationEvents: [SCNAnimationEvent]?
    • autoreverses: Bool
    • blendInDuration: TimeInterval
    • blendOutDuration: TimeInterval
    • duration: TimeInterval
    • fillsBackward: Bool
    • fillsForward: Bool
    • isAdditive: Bool
    • isAppliedOnCompletion: Bool
    • isCumulative: Bool
    • isRemovedOnCompletion: Bool
    • keyPath: String?
    • repeatCount: CGFloat
    • startDelay: TimeInterval
    • timeOffset: TimeInterval
    • timingFunction: SCNTimingFunction
    • usesSceneTimeBase: Bool

 

  • SCNAnimationPlayer
    • init(animation: SCNAnimation)
    • animation: SCNAnimation
    • blendFactor: CGFloat
    • paused: Bool
    • speed: CGFloat
    • play()
    • stop()
    • stop(withBlendOutDuration: TimeInterval)

 

  • SCNTimingFunction
    • init(caMediaTimingFunction: CAMediaTimingFunction)
    • init(timingMode: SCNActionTimingMode)

 

  • SCNAnimationProtocol
    • NSObjectProtocol

 

  • SCNConstraint
    • isEnabled: Bool
    • isIncremental: Bool

 

  • SCNBillboardConstraint
    • SCNBillboardAxis
      • init(rawValue: UInt)

 

  • SCNLookAtConstraint
    • localFront: SCNVector3
    • var targetOffset: SCNVector3
    • var worldUp: SCNVector3

 

  • SCNDistanceConstraint
    • init(target: SCNNode?)
    • maximumDistance: CGFloat
    • minimumDistance: CGFloat
    • target: SCNNode?

 

  • SCNAvoidOccluderConstraint
    • init(target: SCNNode?)
    • bias: CGFloat
    • occluderCategoryBitMask: Int
    • target: SCNNode?
    • SCNAvoidOccluderConstraintDelegate
    • SCNAvoidOccluderConstraintDelegate

 

  • SCNAccelerationConstraint
    • damping: CGFloat
    • decelerationDistance: CGFloat
    • maximumLinearAcceleration: CGFloat
    • maximumLinearVelocity: CGFloat

 

  • SCNSliderConstraint
    • collisionCategoryBitMask: Int
    • offset: SCNVector3
    • radius: CGFloat

 

  • SCNReplicatorConstraint
    • init(target: SCNNode?)
    • orientationOffset: SCNQuaternion
    • positionOffset: SCNVector3
    • replicatesOrientation: Bool
    • replicatesPosition: Bool
    • replicatesScale: Bool
    • scaleOffset: SCNVector3
    • target: SCNNode?

 

  • SCNTransformConstraint
    • orientationConstraint(inWorldSpace: Bool, with: (SCNNode, SCNQuaternion) -> SCNQuaternion)
    • positionConstraint(inWorldSpace: Bool, with: (SCNNode, SCNVector3) -> SCNVector3)

 

  • SCNSkinner
    • skeleton

 

  • SCNMorpher
    • unifiesNormals: Bool
    • weights: [NSNumber]
    • setWeight(CGFloat, forTargetNamed: String)
    • weight(forTargetNamed: String)

 

  • SCNPhysicsBody
    • SCNPhysicsCollisionCategory
      • init(rawValue: UInt)

 

  • SCNPhysicsShape

    • SCNPhysicsShape.Option
      • init(rawValue: String)
      • SCNPhysicsShape.ShapeType
        • init(rawValue: String)  
  • SCNPhysicsContact

    • sweepTestFraction

 

  • SCNPhysicsWorld
    • SCNPhysicsWorld.TestOption
      • SCNPhysicsWorld.TestSearchMode
        • init(rawValue: String)
      • init(rawValue: String)

 

  • SCNPhysicsConeTwistJoint
    • init(body: SCNPhysicsBody, frame: SCNMatrix4)
    • init(bodyA: SCNPhysicsBody, frameA: SCNMatrix4, bodyB: SCNPhysicsBody, frameB: SCNMatrix4)
    • bodyA: SCNPhysicsBody
    • bodyB: SCNPhysicsBody?
    • frameA: SCNMatrix4
    • frameB: SCNMatrix4
    • maximumAngularLimit1: CGFloat
    • maximumAngularLimit2: CGFloat
    • maximumTwistAngle: CGFloat

 

  • SCNParticleSystem
    • SCNParticleSystem.ParticleProperty
      • init(rawValue: String)
    • orientationDirection: SCNVector3
    • particleIntensity: CGFloat
    • particleIntensityVariation: CGFloat

 

  • SCNShadable
    • SCNShaderModifierEntryPoint
      • init(rawValue: String)

 

  • SCNSceneSource
    • SCNSceneSource.LoadingOption
      • SCNSceneSource.AnimationImportPolicy
        • init(rawValue: String)
      • convertToYUp
      • convertUnitsToMeters
      • init(rawValue: String)
    • entryWithIdentifier(String, withClass: T.Type)

 

  • SCNNodeFocusBehavior
    • focusable
    • none
    • occluding

 

  • SCNTessellationSmoothingMode
    • none
    • phong
    • pnTriangles