インバースキネマティックの操作

Flash Player 10 以降、Adobe AIR 1.5 以降、Flash CS4 以降(必須)

逆運動学(IK)は現実的な動きを作成する優れたテクニックです。

IK を使用すると、IK のアーマチュアと呼ばれる接続された部分の連鎖内で協調された運動を作成することによって、その部分全体を生きているように動かすことができます。アーマチュアの部分は、骨と関節です。アーマチュアの端点を前提として、IK では端点に到達するために必要な関節の角度を計算します。

そのような角度の計算をユーザーが手計算で行うことは困難です。この機能の優れた点は、Adobe® Flash® Professional を使用してインタラクティブにアーマチュアを作成できるということです。そして、ActionScript を使用してアーマチュアをアニメーション化します。Flash Professional に含まれる IK エンジンは、アーマチュアの動きを記述する計算を実行します。この動きを ActionScript コードの特定のパラメーターに制限できます。

Flash Professional CS5 バージョンの IK でボーンスプリングの概念が新しく導入されています。ボーンスプリングは、通常、ハイエンドのアニメーションアプリケーションで使用されます。この機能は、新しい動的な物理演算エンジンと共に使用され、自然な動作を設定できます。また、この機能は実行時およびオーサリング時の両方で表示できます。

逆運動学アーマチュアを作成するには、 Flash Professional のライセンスを所有している必要があります。

インバースキネマティックの基礎

逆運動学(IK)では、部分をリンクさせて実際のように相互に連携して動かすことによって、生き生きとしたアニメーションを作成できます。

例えば、IK を使用すると、目的のポーズを取るために必要な脚の関節の動きを関連付けることによって、特定の位置に脚を動かすことができます。IK は IK アーマチュアという構造内の全体が連鎖している骨格を使用します。 fl.ik パッケージを使用すると、自然な動きに似たアニメーションを作成することができます。このパッケージでは、IK アルゴリズムの背景の動きについての詳細を理解する必要なく、複数の IK アーマチュアをシームレスにアニメーション化することができます。

Flash Professional では、付随するボーンとジョイントを含む IK アーマチュアを作成します。次に、IK クラスにアクセスして実行時にそれらのアーマチュアをアニメーション化します。

IK アーマチュアの作成方法について詳しくは、『Flash Professional ユーザーガイド』の「インバースキネマティックの使用」の節を参照してください。

重要な概念と用語

次の参照リストに、この機能に関連した重要な用語を示します。

アーマチュア
現実的な動きをシミュレートするためにコンピューターアニメーションで使用されるボーン、ジョイントで構成される運動連鎖。

ボーン
アーマチュアの硬いセグメント。動物の骨格の骨に相当します。

インバースキネマティック(IK)
運動連鎖またはアーマチュアと呼ばれるジョイントのある柔軟なオブジェクトのパラメーターを特定するプロセス。

ジョイント
2 つのボーンが接する場所。ボーンの動きを可能にするように組み立てられており、動物の関節に相当します。

物理演算エンジン
物理演算に関するアルゴリズムのパッケージ。アニメーションで自然な動作を表現するのに使用します。

スプリング
親ボーンの動きに反応して動き、時間の経過とともに徐々に減衰するボーンの性質。

IK のアーマチュアのアニメーション化の概要

Flash Professional で IK のアーマチュアを作成したら、fl.ik クラスを使用して、動きを制限し、イベントを追跡し、実行時にアニメーション化します。

次の図に、Wheel という名前のムービークリップを示します。車軸は、Axle という名前の IKArmature のインスタンスです。 IKMover クラスは車輪の回転と同期してアーマチュアを動かします。アーマチュアの IKBone、ikBone2 が後ろ側の継ぎ目にある車輪に接続されます。

A.
車輪

B.
車軸

C.
ikBone2

実行時には、__motion_Wheel モーショントゥイーンに従って車輪が回転します。このモーショントゥイーンについては、アニメーションの作成で解説しています。IKMover オブジェクトは車軸の動きを開始し、制御します。次の図に、回転の異なるフレームで回転している車輪に連結されている車軸アーマチュアの 2 つのスナップショットを示します。

2 つの異なる位置にある IK アーマチュアを動かす
実行時は、次の ActionScript では以下を実行します。
  • アーマチュアとそのコンポーネントに関する情報の取得

  • IKMover オブジェクトのインスタンス化

  • 車輪の回転と連携して車軸を動かす

import fl.ik.* 
 
var tree:IKArmature = IKManager.getArmatureByName("Axle"); 
var bone:IKBone = tree.getBoneByName("ikBone2"); 
var endEffector:IKJoint = bone.tailJoint; 
var pos:Point = endEffector.position; 
 
var ik:IKMover = new IKMover(endEffector, pos); 
ik.limitByDistance = true; 
ik.distanceLimit = 0.1; 
ik.limitByIteration = true; 
ik.iterationLimit = 10; 
 
Wheel.addEventListener(Event.ENTER_FRAME, frameFunc); 
 
function frameFunc(event:Event) 
{ 
    if (Wheel != null) 
    { 
        var mat:Matrix = Wheel.transform.matrix; 
        var pt = new Point(90, 0); 
        pt = mat.transformPoint(pt); 
         
        ik.moveTo(pt); 
    } 
}

車軸を動かすために使用される IK クラスは次のとおりです。

  • IK のアーマチュア:アーマチュア、つまり、骨と関節で構成されるツリー構造を記述する。Flash Professional で作成されている必要があります。

  • IKManager:ドキュメント内のすべての IK アーマチュアのコンテナクラス。Flash Professional で作成されている必要があります。

  • IKBone:IK アーマチュアのセグメント。

  • IKJoint:2 つの IK の骨を接続する部分。

  • IKMover:アーマチュアの IK の動きを開始し、制御する。

これらのクラスについて詳しくは、ik パッケージを参照しください。

IK のアーマチュアの詳細

まず、動かしたい部分を構成するアーマチュア、骨、および関節の変数を宣言します。

次のコードでは、IKManager のクラスの getArmatureByName() メソッドを使用して、IKArmature 変数 tree に Axle アーマチュアの値を割り当てます。この Axle アーマチュアは、事前に Flash Professional を使用して作成したものです。

var tree:IKArmature = IKManager.getArmatureByName("Axle");

同様に、次のコードでは、IKArmature クラスの getBoneByName() メソッドを使用して、IKBone 変数を ikBone2 骨の値に割り当てます。

var bone:IKBone = tree.getBoneByName("ikBone2");

ikBone2 骨の後ろ側の継ぎ目は、回転している車輪に接続されているアーマチュアの部分です。

次の行では、変数 endEffector を宣言し、この変数を ikBone2 骨の tailjoint プロパティに割り当てます。

var endEffector:IKJoint = home.tailjoint;
変数 pos は、endEffector 関節の現在の位置を格納するポイントです。
var pos:Point = endEffector.position;

この例で、pos は車輪に接続している車軸の末端にある関節の位置です。この変数の元の値は、IKJoint の position プロパティから取得されます。

IK Mover のインスタンス化とその動きの制限

IKMover クラスのインスタンスは車軸を動かします。

次の行では、IKMover オブジェクト ik をインスタンス化し、動かすエレメントおよび動きの開始点をコンストラクターに渡します。
var ik:IKMover = new IKMover(endEffector, pos);

IKMover クラスのプロパティを使用すると、アーマチュアの動きを制限できます。距離、反復、動きの回数を基に動きを制限することができます。

プロパティの次のペアにより、これらの制限が実行されます。このペアは、動きが制限されているかどうかを示す Boolean 値と、その制限を指定する整数の組み合わせです。

Boolean プロパティ

整数プロパティ

設定される制限

limitByDistance:Boolean

distanceLimit:int

IK エンジンが反復ごとに動くピクセルの最大距離を設定します。

limitByIteration:Boolean

iterationLimit:int

IK エンジンの 1 回の移動での最大繰り返し回数を設定します。

limitByTime:Boolean

timeLimit:int

動きを実行するために IK エンジンに割り当てられる最大の時間をミリ秒単位で設定します。

デフォルトでは、すべての Boolean 値が false に設定されているため、明示的に Boolean 値を true に設定しない限り、動きは制限されません。制限を適用するには、適切なプロパティを true に設定した後、対応する整数プロパティに値を指定します。対応する Boolean プロパティを設定せずに、制限の値を設定しても、その制限は無視されます。この場合、IK エンジンは、IKMover の別の制限または目的の位置に到達するまで引き続きオブジェクトを動かします。

次の例では、アーマチュアの動きの最大距離は、反復ごとに 0.1 ピクセルに設定されています。すべての動きの反復の最大数は 10 に設定されます。
ik.limitByDistance = true; 
ik.distanceLimit = 0.1; 
ik.limitByIteration = true; 
ik.iterationLimit = 10; 

IK のアーマチュアの移動

IKMover は車輪のイベントリスナの内側に車軸を動かします。車輪の各 enterFrame イベントでは、アーマチュアの新しいターゲット位置が計算されます。その moveTo() メソッドを使用して、IKMover は後ろ側の継ぎ目を目的位置まで動かすか、limitByDistancelimitByIterationlimitByTime プロパティで設定した制約内で到達可能な位置まで動かします。
Wheel.addEventListener(Event.ENTER_FRAME, frameFunc); 
 
function frameFunc(event:Event) 
{ 
    if (Wheel != null) 
    { 
        var mat:Matrix = Wheel.transform.matrix; 
        var pt = new Point(90,0); 
        pt = mat.transformPoint(pt); 
         
        ik.moveTo(pt); 
    } 
} 

スプリングの使用

Flash Professional CS5 のインバースキネマティックでは、ボーンスプリングがサポートされています。どちらのスプリングともオーサリング時に設定可能で、ボーンスプリング属性は実行時に追加または変更できます。スプリングはボーンおよびそのジョイントのプロパティです。スプリングには 2 つの属性があります。1 つは IKJoint.springStrength 属性で、スプリングの強さを設定します。もう 1 つは IKJoint.springDamping 属性で、強さの値に抵抗を追加してスプリングの減衰率を変更します。

スプリングの強さは、デフォルトの 0(完璧な硬さ)から 100(非常にゆるく、物理演算で制御されます)までのパーセント値を設定します。スプリングが設定されたボーンは、ボーン自体のジョイントの動きに反応します。他の移動(回転、x 軸または y 軸方向)が有効化されていない場合は、スプリングを設定しても効果はありません。

スプリングの減衰は、デフォルトの 0(抵抗なし)から 100(減衰最大)までのパーセント値を設定します。減衰によって、ボーンの最初の動作から静止位置に戻るまでの時間が変化します。

IKArmature オブジェクトでスプリングが有効になっているかどうかを調べるには、IKArmature.springsEnabled プロパティを確認します。スプリングに関するその他のプロパティおよびメソッドは、個々の IKJoint オブジェクトに属します。ジョイントは、角度回転と x 軸および y 軸方向の移動に対して有効化できます。回転ジョイントのスプリング角度を設定するには IKJoint.setSpringAngle を使用し、移動ジョイントのスプリング位置は IKJoint.setSpringPt で設定できます。

この例では、名前でボーンを選択し、その tailJoint を識別します。コードでは、親アーマチュアをテストしてスプリングが有効になっているかどうかを確認してから、ジョイントのスプリングプロパティを設定します。

var arm:IKArmature = IKManager.getArmatureAt(0); 
var bone:IKBone = arm.getBoneByName("c"); 
var joint:IKJoint = bone.tailJoint; 
if (arm.springsEnabled) { 
    joint.springStrength = 50; //medium spring strength 
    joint.springDamping = 10; //light damping resistance 
    if (joint.hasSpringAngle) { 
        joint.setSpringAngle(30); //set angle for rotational spring 
    } 
}

IK イベントの使用

IKEvent クラスでは、IK イベントの関する情報を含むイベントオブジェクトを作成することができます。IKEvent 情報は、指定時間、距離または反復の制限を超えたために終了した動きを記述します。

次のコードは、時間制限イベントを追跡するためのイベントリスナーおよびハンドラーを示します。このイベントハンドラーは、IKMover の時間制限を超えたときに起動されるイベントの時間、距離、反復回数および関節の各プロパティについてレポートします。

var ikmover:IKMover = new IKMover(endjoint, pos); 
ikMover.limitByTime = true; 
ikMover.timeLimit = 1000; 
 
ikmover.addEventListener(IKEvent.TIME_LIMIT, timeLimitFunction); 
 
function timeLimitFunction(evt:IKEvent):void 
{ 
    trace("timeLimit hit"); 
    trace("time is " + evt.time); 
    trace("distance is " + evt.distance); 
    trace("iterationCount is " + evt.iterationCount); 
    trace("IKJoint is " + evt.joint.name); 
}