Arbeta med omvänd kinematik (IK – inverse kinematics)

Flash Player 10 och senare, Adobe AIR 1.5 och senare, kräver Flash CS4 eller senare

Omvänd kinematik (IK) är en bra teknik när du skapar naturtrogen rörelse.

Med omvänd kinematik kan du skapa koordinerade rörelser i en kedja med sammankopplade delar som kallas för IK-armatur, så att delarna flyttas tillsammans på ett realistiskt sätt. Delarna i armaturen består av ben och leder. Utifrån slutpunkten i armaturen beräknas vinklarna för lederna som behövs för att nå fram till slutpunkten.

Att beräkna dessa vinklar manuellt kan vara mycket krävande. Fördelen med den här funktionen är att du kan skapa armaturer interaktivt med Adobe® Flash® Professional. Animera dem sedan med ActionScript. IK-motorn som ingår i Flash Professional utför beräkningar som beskriver armaturens rörelse. Du kan begränsa rörelserna till vissa parametrar i ActionScript-koden.

En nyhet i Flash Professional CS5-versionen av IK är begreppet benfjädring, som oftast associeras med förstklassiga animeringsprogram. Tillsammans med den nya, dynamiska fysikmotorn kan du använda den här funktionen för att konfigurera verklighetstrogna rörelser. Effekterna visas både under körning och redigering.

För att kunna skapa IK-armaturer måste du ha en licens för Flash Professional.

Grunderna i omvänd kinematik

Med omvänd kinematik (IK) kan du skapa realistisk animering genom att koppla ihop delarna så att de flyttas i förhållande till varandra på ett verklighetstroget sätt.

Med omvänd kinematik kan du till exempel flytta ett ben till en viss position genom att röra de leder i benet som behövs för att uppnå önskad ställning. Omvänd kinematik använder ett ramverk med ben sammankopplade i en struktur som kallas för en IK-armatur. Med paketet fl.ik kan du skapa animeringar som påminner om naturlig rörelse. Med det kan du animera flera IK-armaturer sömlöst utan att behöva kunna något om fysiken bakom IK-algoritmerna.

Skapa IK-armaturen med stödjande ben och leder med Flash Professional. Sedan kan du använda IK-klasser för att animera dem vid körning.

Mer information om hur du skapar en IK-armatur finns i avsnittet Använda omvänd kinematik i Använda Flash Professional.

Viktiga termer och begrepp

Följande referenslista innehåller viktiga termer om den här funktionen:

Armatur
En kinematisk kedja som består av ben och leder, som används vid datoranimering för att simulera realistisk rörelse.

Ben
Ett stelt segment i en armatur, som motsvarar ett ben i ett djurskelett.

Omvänd kinematik (IK)
Process för att fastställa parametrarna för sammankopplade flexibla objekt som kallas för kinematisk kedja eller armatur.

Led
Den plats där två ben sammankopplas för att möjliggöra benens rörelser, som motsvarar leden hos ett djur.

Fysikmotorn
Ett paket med fysikrelaterade algoritmer som används för verklighetstrogna rörelser i animeringar.

Fjädring
Kvaliteten på ett ben som rör sig och reagerar när det överordnade benet rör sig och som sedan försvinner sedan successivt.

Översikt över animering av IK-armaturer (Inverse Kinematic)

När du har skapat en IK-armatur i Flash Professional använder du fl.ik-klasserna för att begränsa dess rörelser, spåra dess händelser och animera den vid körning.

I bilden nedan visas ett filmklipp med namnet Wheel. Axeln är en instans av en IKArmature med namnet Axle. Klassen IKMover flyttar armaturen samtidigt som hjulet roterar. Ett IKBone, ikBone2, i armaturen kopplas till hjulet vid leden vid änden.

A.
Hjul

B.
Axel

C.
ikBone2

Vid körning snurrar hjulet tillsammans med rörelseinterpoleringen __motion_Wheel, som behandlas i Beskriva animeringen. Ett IKMover-objekt initieras och kontrollerar axelns rörelser. I bilden nedan visas två ögonblicksbilder av axelarmaturen som kopplas till spinnrocken vid olika bildrutor i rotationen.

Flytta IK-armaturen i två olika positioner
ActionScript gör följande under körning:
  • Hämtar information om armaturen och dess komponenter

  • Instansierar ett IKMover-objekt

  • Flyttar axeln i kombination med hjulets rotation

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); 
    } 
}

Följande IK-klasser används för att flytta axeln:

  • IKArmature: beskriver armaturen, en trädstruktur som består av ben och leder och som måste skapas med Flash Professional

  • IKManager: behållarklass för alla IK-armaturer i dokumentet, som måste skapas i Flash Professional

  • IKBone: ett segment i en IK-armatur

  • IKJoint: en koppling mellan två IK-ben

  • IKMover: initierar och kontrollerar armaturernas IK-rörelser

Fullständiga och detaljerade beskrivningar av de här klasserna finns i ik-paketet.

Hämta information om en IK-armatur (Inverse Kinematic)

Deklarera först variabler för armaturen, benet och leden som utgör de delar som du vill flytta.

Följande kod använder metoden getArmatureByName() för klassen IKManager för att tilldela värdet på axelarmaturen till IKArmature-variabeln tree. Axelarmaturen har redan skapats med Flash Professional.

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

Följande kod använder på ett liknande sätt metoden getBoneByName() för klassen IKArmature för att tilldela värdet på benet ikBone2 till IKBone-variabeln.

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

Ändleden för benet ikBone2 är den del av armaturen som kopplas till spinnrocken.

Följande rad deklarerar variabeln endEffector och tilldelar den till egenskapen tailjoint för benet ikBone2:

var endEffector:IKJoint = home.tailjoint;
Variabeln pos är en punkt som lagrar den aktuella positionen för leden endEffector.
var pos:Point = endEffector.position;

I det här exemplet är pos positionen för leden i slutet på axeln där den ansluter till hjulet. Det ursprungliga värdet på den här variabeln hämtas från egenskapen position för IKJoint.

Instansiera en IK Mover och begränsa dess rörelse

En instans av klassen IKMover flyttar axeln.

Följande rad instansierar IKMover-objektet ik samt skickar elementet som ska flyttas och startpunkten för rörelsen till konstruktorn:
var ik:IKMover = new IKMover(endEffector, pos);

Med egenskaperna för klassen IKMover kan du begränsa armaturens rörelse. Du kan begränsa rörelsen utifrån rörelsens avstånd, iterationer och tid.

Följande egenskapspar framtvingar dessa gränser. Paren består av ett booleskt värde, som anger om rörelsen begränsas, och ett heltal, som anger gränsen:

Boolesk egenskap

Heltalsegenskap

Begränsning

limitByDistance:Boolean

distanceLimit:int

Anger det maximala avstånd i pixlar som IK-motorn ska flytta för varje iteration.

limitByIteration:Boolean

iterationLimit:int

Anger högsta antal iterationer som IK-motorn utför för varje rörelse.

limitByTime:Boolean

timeLimit:int

Anger maxtiden (i millisekunder) under vilken IK-motorn utför rörelsen.

Som standard anges alla booleska värden till false, vilket innebär att rörelsen inte är begränsad om du inte uttryckligen anger ett booleskt värde som true. Om du vill tvinga fram en begränsning anger du relevant egenskap som true och anger sedan ett värde för motsvarande heltalsegenskap. Om du anger begränsningen som ett värde utan att ange motsvarande boolesk egenskap ignoreras gränsen. I så fall fortsätter IK-motorn att flytta objektet tills en annan gräns eller målpositionen för IKMover uppnås.

I följande exempel anges maxavståndet för armaturens rörelse till 0,1 pixlar per iteration. Det maximala antalet iterationer för varje rörelse anges till tio.
ik.limitByDistance = true; 
ik.distanceLimit = 0.1; 
ik.limitByIteration = true; 
ik.iterationLimit = 10; 

Flytta en IK-armatur (Inverse Kinematic)

IKMover flyttar axeln i hjulets händelseavlyssnare. I varje enterFrame-händelse för hjulet beräknas en ny målposition för armaturen. Om du använder metoden moveTo() flyttar IKMover ändleden till målpositionen så långt bort det går inom de begränsningar som anges med egenskaperna limitByDistance, limitByIteration och limitByTime.
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); 
    } 
} 

Använda fjädring

Omvänd kinematik i Flash Professional CS5 har stöd för benfjädring. Benfjädring kan appliceras under redigering, och benfjädringsattribut kan läggas till eller ändras under körningstid. Fjädring är en egenskap för ett ben och dess leder. Den har två attribut: IKJoint.springStrength, som anger fjädringsmängden samt IKJoint.springDamping, som ökar styrkevärdets motstånd och ändrar fjädringens minskningstakt.

Fjädringsstyrka är ett procentvärde från standardvärde 0 (helt rigid) till 100 (mycket lös och kontrollerad av fysiken). Ben med fjädring reagerar på tillhörande leds rörelser. Om ingen annan översättning (rotation, x eller y) är aktiverad har fjädringsinställningarna ingen effekt.

Fjädringsdämpning är ett procentvärde från standardvärde 0 (inget motstånd) till 100 (kraftigt dämpad). Dämpning påverkar den tid som löper mellan ett bens initiala rörelse och dess återgång till viloläge.

Du kan se om det finns aktiverade fjädrar för ett IKArmature-objekt genom att kontrollera dess IKArmature.springsEnabled -egenskap. De övriga fjäderegenskaperna och metoderna hör till enskilda IKJoint-objekt. En led kan aktiveras för en vinkelrotation och översättning längs x- och y-axlarna. Du kan positionera en roterande leds fjädervinkel med IKJoint.setSpringAngle och en översättningsbar leds fjäderposition med IKJoint.setSpringPt.

I det här exemplet väljs ett ben efter namn och dess tailJoint identifieras. Koden testar den överordnade armaturen för att se om fjädrarna är aktiverade och anger därefter fjädringsegenskaperna för leden.

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 
    } 
}

Använda IK-händelser

Med klassen IKEvent kan du skapa ett händelseobjekt som innehåller information om IK-händelser. IKEvent-informationen beskriver rörelsen som har avbrutits på grund av att angiven gräns för tid, avstånd eller iteration överskrids.

Följande kod visar en händelseavlyssnare och hanterare för spårning av tidsgränshändelser. Den här händelsehanteraren rapporterar tid, avstånd och antal iterationer samt ledegenskaper för en händelse som utlöses när tidsgränsen för IKMover överskrids.

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); 
}