Utilisation de la cinématique inverse

Flash Player 10 et les versions ultérieures, Adobe AIR 1.5 et les versions ultérieures, Flash CS4 ou ultérieur requis

La cinématique inverse (IK, Inverse kinematics) est une technique de création fantastique de mouvement réaliste.

IK vous permet de créer des mouvements coordonnés au sein d’une chaîne de sections connectées appelée squelette IK, de sorte que les sections se déplacent avec réalisme. Les sections du squelette représentent ses os et articulations. A partir de l’extrémité finale du squelette, IK calcule les angles des articulations requises pour atteindre cette dernière.

Calculer manuellement ces angles s’avérerait particulièrement complexe. Cette fonctionnalité présente l’avantage de permettre de créer des squelettes en mode interactif dans Adobe® Flash® Professional. Il vous suffit ensuite de les animer par le biais d’ActionScript. Le moteur IK intégré à Flash Professional exécute les calculs requis pour décrire le mouvement du squelette. Vous pouvez restreindre le mouvement à certains paramètres dans votre code ActionScript.

La version Flash Professional CS5 de la cinématique inverse (IK) intègre à présent le concept de ressort de segment, généralement réservé aux applications d’animation haut de gamme. Associée au nouveau moteur physique dynamique, cette fonctionnalité permet de configurer des mouvements réalistes. Cet effet est par ailleurs visible lors des phases d’exécution et de création.

Pour créer des squelettes de cinématique inverse, vous devez disposer d’une licence pour Flash Professional.

Principes de base de la cinématique inverse

La cinématique inverse (IK) vous permet de créer une animation réaliste en liant des sections de sorte qu’elles se déplacent les unes par rapport aux autres avec naturel.

L’utilisation d’IK vous permet par exemple de déplacer une jambe pour qu’elle occupe une position déterminée en articulant les mouvements des articulations de la jambe nécessaires à l’obtention de la pose appropriée. IK utilise une structure osseuse chaînée portant le nom de squelette IK. Le package fl.ik vous aide à créer des animations qui ressemblent à un mouvement naturel. Il vous permet d’animer plusieurs squelettes IK en toute transparence sans avoir à maîtriser les concepts physiques sur lesquels s’appuient les algorithmes IK.

Vous créez le squelette IK et les os et articulations qui le composent dans Flash Professional. Vous pouvez ensuite utiliser les classes IK pour les animer lors de l’exécution.

Pour obtenir des instructions détaillées sur la création d’un squelette IK, voir Utilisation de la cinématique inverse dans Utilisation de Flash Professional .

Concepts importants et terminologie

La liste de référence suivante contient des termes importants relatifs à la fonctionnalité étudiée.

Squelette
Chaîne cinématique composée d’os et d’articulations, utilisée en animation informatique pour simuler un mouvement réaliste.

Os
Segment rigide d’un squelette, équivalent à un os chez un animal.

Cinématique inverse (IK)
Processus d’identification des paramètres d’un objet souple articulé appelé squelette ou chaîne cinématique.

Articulation
Emplacement où deux os s’unissent, conçu pour permettre le mouvement des os ; analogue à une articulation chez un animal.

Moteur physique
Package d’algorithmes physiques qui permet d’intégrer des actions réalistes à l’animation.

Ressort
Qualité d’un segment qui se déplace et réagit lorsque le segment parent est déplacé, puis diminue progressivement par incréments.

Aperçu de l’animation de squelettes IK

Une fois le squelette IK créé dans Flash Professional, utilisez les classes fl.ik pour restreindre ses mouvements, suivre les événements correspondants et l’animer lors de l’exécution.

La figure ci-dessous illustre le clip Wheel. L’essieu est une occurrence d’un squelette IK appelée Axle . La classe IKMover déplace le squelette en le synchronisant avec la rotation d’une roue. Dans le squelette, IKBone, nommé ikBone2 , est rattaché à la roue au niveau de l’articulation arrière.

A.
Roue

B.
Essieu

C.
ikBone2

Lors de l’exécution, la roue tourne en association avec l’interpolation de mouvement __motion_Wheel étudiée dans Description de l’animation . Un objet IKMover lance et contrôle le mouvement de l’essieu. La figure suivante propose deux instantanés du squelette de l’essieu connecté à la roue qui tourne sur différentes images de la rotation.

Squelette IK occupant deux positions distinctes
Lors de l’exécution, le code ActionScript suivant :
  • Extrait des informations relatives au squelette et à ses composants.

  • Instancie un objet IKMover.

  • Déplace l’essieu en conjonction avec la rotation de la roue.

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

Les classes IK utilisées pour déplacer l’essieu sont les suivantes :

  • IKArmature : décrit le squelette (structure arborescente composée d’os et d’articulations). A créer dans Flash Professional.

  • IKManager : classe qui contient tous les squelettes IK du document, à créer dans Flash Professional.

  • IKBone : segment d’un squelette IK.

  • IKJoint : connexion entre deux os IK.

  • IKMover : lance et contrôle le mouvement IK des squelettes.

Pour obtenir une description détaillée de ces classes, voir ik package (Package ik) .

Obtention d’informations sur un squelette IK

Commencez par déclarer les variables associées au squelette, à l’os et à l’articulation qui composent les sections à déplacer.

Le code suivant utilise la méthode getsqueletteByName() de la classe IKManager pour affecter la valeur du squelette Axle à la variable IKArmature tree . Le squelette Axle a été précédemment généré dans Flash Professional.

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

De même, le code suivant utilise la méthode getBoneByName() de la classe IKArmature pour affecter à la variable IKBone la valeur de l’os ikBone2 .

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

L’articulation arrière de l’os ikBone2 correspond à la section du squelette connectée à la roue qui tourne.

La ligne suivante déclare la variable endEffector et l’affecte à la propriété tailjoint de l’os ikBone2 :

var endEffector:IKJoint = home.tailjoint;
La variable pos est un point qui stocke la position actuelle de l’articulation endEffector .
var pos:Point = endEffector.position;

Dans cet exemple, pos correspond à la position de l’articulation raccordée à la roue à l’extrémité de l’essieu. La valeur d’origine de cette variable est extraite de la propriété position de IKJoint.

Instanciation de l’objet IKMover et restriction du mouvement

Une occurrence de la classe IKMover déplace l’essieu.

La ligne suivante instancie l’objet IKMover ik et transmet à son constructeur l’élément à déplacer et le point de départ du mouvement :
var ik:IKMover = new IKMover(endEffector, pos);

Les propriétés de la classe IKMover vous permettent de restreindre le mouvement d’un squelette. Vous pouvez restreindre le mouvement en fonction de la distance, des itérations et de la durée du mouvement.

Les paires de propriétés suivantes imposent ces restrictions. Les paires se composent d’une valeur booléenne qui indique si le mouvement est restreint et d’un entier stipulant la restriction :

Propriété Boolean

Propriété Integer

Restriction définie

limitByDistance:Boolean

distanceLimit:int

Définit la distance maximale en pixels parcourue par le moteur IK par itération.

limitByIteration:Boolean

iterationLimit:int

Définit le nombre maximal d’itérations effectuées par le moteur IK par mouvement.

limitByTime:Boolean

timeLimit:int

Définit la durée maximale, exprimée en millisecondes, affectée au moteur IK pour effectuer le mouvement.

Toutes les valeurs booléennes étant définies sur false par défaut, le mouvement n’est pas restreint, sauf si vous avez explicitement défini une valeur booléenne sur true . Pour imposer une restriction, définissez la propriété appropriée sur true , puis indiquez la valeur de la propriété Integer correspondante. Si vous définissez la restriction sur une valeur sans définir la propriété Boolean correspondante, elle n’est pas prise en considération. Dans ce cas, le moteur IK continue à déplacer l’objet jusqu’à ce qu’une autre restriction ou la position cible de l’objet IKMover soit atteinte.

Dans l’exemple suivant, la distance maximale parcourue par le mouvement du squelette est définie sur 0,1 pixel par itération. Le nombre maximal d’itérations par mouvement est défini sur dix.
ik.limitByDistance = true; 
ik.distanceLimit = 0.1; 
ik.limitByIteration = true; 
ik.iterationLimit = 10; 

Mouvement d’un squelette IK

L’objet IKMover déplace l’essieu au sein de l’écouteur d’événement associé à la roue. A chaque événement enterFrame de la roue, une nouvelle position cible du squelette est calculée. Par le biais de sa méthode moveTo() , l’objet IKMover place l’articulation arrière sur sa position cible ou parcourt une distance aussi longue que possible sans enfreindre les contraintes définies par ses propriétés limitByDistance , limitByIteration et 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); 
    } 
} 

Utilisation de ressorts

La cinématique inverse prend en charge le ressort de segment dans Flash Professional CS5. Vous pouvez définir les ressorts de segment lors de la phase de création et ajouter ou modifier les attributs correspondants lors de l’exécution. La propriété Spring se rapporte à un segment et aux liaisons correspondantes. Elle possède deux attributs, IKJoint.springStrength , qui définit l’intensité du ressort, et IKJoint.springDamping , qui ajoute une résistance à la valeur d’intensité et modifie la valeur de décroissance du ressort.

L’intensité du ressort est exprimée sous forme de pourcentage compris entre la valeur par défaut, 0 (rigidité absolue) et 100 (élasticité importante contrôlée par les lois de la physique). Les segments à ressort réagissent au mouvement de la liaison correspondante. Si aucune autre translation (rotation, x ou y) n’est activée, les paramètres du ressort n’ont aucun impact.

L’amortissement du ressort est exprimé sous forme de pourcentage, compris entre la valeur par défaut, 0 (aucune résistance) et 100 (amortissement important). L’amortissement modifie la durée de l’intervalle qui sépare le mouvement initial d’un segment et son retour à une position de repos.

Vérifiez si des ressorts sont associés à un objet IKArmature par le biais de la propriété IKArmature.springsEnabled . Les autres propriétés et méthodes relatives aux ressorts relèvent d’objets IKJoint individuels. Une liaison peut être soumise à une rotation angulaire et à une translation le long des axes x et y. Faites appel à IKJoint.setSpringAngle pour positionner l’angle de rotation d’un ressort de liaison et à IKJoint.setSpringPt pour définir la position par translation d’un ressort de liaison.

Cet exemple sélectionne un segment par nom et identifie la propriété tailJoint correspondante. Le code teste le squelette parent pour vérifier si des ressorts sont activés, puis définit les propriétés du ressort de la liaison.

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

Utilisation d’événements IK

La classe IKEvent vous permet de créer un objet événement qui contient des informations sur les événements IK. Une information IKEvent décrit le mouvement qui s’est arrêté car la durée, la distance ou le nombre maximal d’itérations stipulés ont été dépassés.

Le code suivant indique un écouteur et un gestionnaire d’événement destinés au suivi des événements de limite de temps. Ce gestionnaire d’événement signale les propriétés de durée, distance, nombre d’itérations et articulations d’un événement déclenché lorsque la durée maximale de l’objet IKMover est dépassée.

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