5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【SceneKit】SCNIKConstraintの使い方

Last updated at Posted at 2014-12-18

はじめに

iOS8のSceneKitにおいて、IK(逆運動学)処理を行うためのクラスにSCNIKConstraintがあります。
これはSCNNodeとして配置されたモデルに対して拘束条件を加えるSCNConstraintのサブクラスとなっています。

ここではこのSCNIKConstraintの使い方について簡単に書きたいと思います。

3Dモデルの用意

まず、IKを組み込む対象となるボーンの入った3Dモデルを用意します。
今回はBlender 2.72を使い、以下のロボットアームのようなモデルを作りました。

Arms.png

青い立方体を根、赤い立方体を末端としています。 全部で4本のボーンが入っており、それぞれモデルの対応する部分に紐づけられています。
(紐づけに関してはこちらのサイトを参考にさせて頂きました:自主練blender ハードボーン
モデルが完成したらdae形式でエクスポートします。

実装

先ほど作成した3Dモデルのdaeファイルをプロジェクトにインポートします。
この時、モデルとボーンを含む親ノードを用意していなければ、用意してください。

スクリーンショット 2014-12-18 10.53.46.png

プロジェクトナビゲーター(ファイル一覧)からdaeファイルを選べば上のような画面になります。
daeファイルに記録されているシーンの中のノード一覧が見えますが、この左下に+ボタンがあり、これを押すことでノードを追加できます。 また、ノードを別なノードにドラッグすれば子ノードにすることもできます。
上記の画像では、「Arm」というノードを作り、そこにモデル本体(Cube)とボーン(Armature)を入れています。

daeファイルの準備が終わったらいよいよ実装です。
まず、IKで動かしたいボーンの根っこの部分(ここでは"RootBone"という名前だとします)を表すSCNNodeと、ボーンの先端部分(ここでは"BoneC"とします)を表すSCNNodeをそれぞれ用意します。
次にSCNIKConstraintのインスタンスを用意しますが、この時ボーンの根っこにあたるSCNNodeを指定する必要があるので、先ほどのRootBoneを表すSCNNodeのインスタンスを渡します。
最後に、ボーンの先端部分に拘束条件として用意したSCNIKConstraintのインスタンスを割り当て、influenceFactor(動きへの影響度)を1.0にして準備完了です。
実際に動かすためには、SCNIKConstraintのtargetPositionプロパティに目標位置を与えてやればOKです。

実際のコードは以下のようになります。

GameViewController.m
// 部位ごとのNodeの作成
SCNNode *arm_root = [arm childNodeWithName:@"RootBone" recursively:YES];
SCNNode *arm_end = [arm childNodeWithName:@"BoneC" recursively:YES];

// SCNIKConstraint:IKの用意
SCNIKConstraint *ik = [SCNIKConstraint inverseKinematicsConstraintWithChainRootNode:arm_root];
// モデルの末端に拘束条件として先ほど用意したIKを設定する
arm_end.constraints = @[ik];
// 影響度を設定
ik.influenceFactor = 1.0;

// 試しに動かしてみる
[SCNTransaction begin];
// 目標位置をSCNIKConstraintに与える
ik.targetPosition = [scene.rootNode convertPosition:SCNVector3Make(0,-1,0) toNode:nil];
[SCNTransaction commit];

サンプルコード

https://github.com/uedadaze/IKTest
SCNIKConstraintを利用したサンプルコードです。
画面内をタッチすると、位置に応じてモデルの先端が動くようになっています。
また、根っこと先端だけでなく逆運動に関わっている中間の各ノードの角度もとれるようになっています。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?