このところ、SceneKitを使って非常にシンプルながら仮想現実(VR)の世界をiPadの画面に描いています。前回はいろいろな形(ジオメトリ)のノードを床の上に配置し、照明の種類も変えて3D世界の見栄えの変化を確認しました。さらに画面に表示する映像を写すカメラを、任意の位置に設置して任意の方向に向ける方法も確かめました。
しかし、これまでに作ってきたシーンは、まがりなりにも仮想現実と呼ぶには、何か決定的に物足りない部分があったのも事実です。もちろん、現実世界ではあまり見かけないようなカプセルや円錐、ドーナッツ型といった数学的な形状の物体だけしかないという点もそうなのですが、それだけなら想像力でなんとか補える範囲かもしれません。それよりも絶望的だったのは、それらの物体に「動き」がまったくないということです。いわばすべてが静止した、時間という概念のない、死の世界だったのです。
そこで今回は、シーンの中に配置したノードに動きを付けていきましょう。非現実の世界なのでアニメーションと呼ぶのが自然でしょうか。いずれにしても、SceneKitのノードを動かす方法は何とおりも用意されています。それらを大別すると、まずノードを外部から操って強制的に動かす方法と、ノードに速度や加速度、あるいは重力場などの物理法則を適用して、いわば「自然に」動かす方法の2種類があります。今回は、前者のノードを外部から強制的に動かす方法を扱います。
一方、ノードの「動き」とひとくちに言っても、これも2種類に大別できるでしょう。ノードの形状がその場で変化するような動きと、ノード全体がシーンの中を動き回るような動きです。これについては、今回両方とも見ていきます。
Core Animationを使ってノードの形を変化させる
iOSのフレームワークで「アニメーション」と言えば、真っ先に思い出すのはCore Animationでしょう。これは、SceneKitに付随するものではありませんが、SceneKitのノードにも適用できます。Core Animationの場合、CABasicAnimationというクラスのオブジェクトを作成し、それをノードのaddAnimationメソッドを使って、ノードに張り付けるという形で機能させます。ちなみにaddAnimationメソッドは、SCNNodeクラスのメソッドではなく、SCNAnimatableプロトコルに定義されています。
前回配置したノードのうち、円錐を表すSCNConeのジオメトリから作成したノードに、このCABasicAnimationのオブジェクトを適用してみましょう。前回のプログラムの床のノードはそのままで、その上に円錐のノードだけを置きます。また、照明は特に指定せず、シーンビューのautoenablesDefaultLightingをtrueにセットして、それらしい照明の効果を利用します。
円錐は、初期状態でtopRadiusのパラメータを0.0にセットして、オーソドックスな先の尖った円錐から始めましょう。この値を、0.0と、bottomRadiusと同じ3.0との間で変化させて、円錐と円柱の間をいったり来たりさせます。その際、アニメーションのautoreversesプロパティをtrueにセットしています。それにより、fromValueとtoValueの間の値の変化が一方通行ではなく、toValueまで増えたら、逆にfromValueまで減少し、そこからまたtoValueまで増えるという動作を繰り返すようになります。時間はdurationで指定しますが、この場合片道1.5秒で、往復では3.0秒です。CABasicAnimationのkeyPathにgeometry.topRadiusを指定することで、ノードのジオメトリのtopRadiusをアニメートすることができます。
このプログラムを動かすと、床の中央にまず円錐が表示され、それが1.5秒かけて円柱になり、そこからさらに1.5秒かけて円錐に戻るという動作を延々と繰り返します。
上の例は、ノードを形作っているジオメトリのプロパティをCore Animationによって変化させるものでした。Core Animationでは、ジオメトリだけでなく、ノードの他のプロパティを変化させることもできます。その例として、ノードの座標変換のパラメータの1つ、rotationを直接操作してみましょう。今度はCABasicAnimationのkeyPathにrotationを指定してオブジェクトを作ります。回転量はSCNVector4の値として指定します。ここでは、ちょうど1回転するように、0.0から2πの間でy軸の回転角が変化するようにしています。回転していることがわかりやすいように、円錐に替えて四角錐(ピラミッド)のノードを配置しました。
このプログラムを動かすと、床の中央でピラミッドがy軸(垂直方向)を中心に回転し続けます。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ