Praca z kinematyką odwrotnąFlash Player 10 i nowsze wersje, Adobe AIR 1.5 i nowsze wersje, wymagany Flash CS4 lub nowsza wersja Kinematyka odwrotna (IK) to wspaniała technika tworzenia realistycznych ruchów. IK umożliwia tworzenie skoordynowanych ruchów w łańcuchu połączonych części nazywanych szkieletem IK, dzięki czemu części poruszają się jak w rzeczywistości. Części szkieletu są jego kości i stawami. Na podstawie punktu końcowego szkieletu IK oblicza kąty dla stawów, które są wymagane do uzyskania konkretnego punktu końcowego. Samodzielne obliczanie tych kątów byłoby bardzo trudne. Zaletą tej funkcji jest to, że można tworzyć szkielety interaktywnie za pomocą programu Adobe® Flash® Professional. Następnie można animować szkielety za pomocą języka ActionScript. Silnik IK zawarty w programie Flash Professional wykonuje te obliczenia w celu opisania ruchu szkieletu. Ruch można ograniczyć do pewnych parametrów w kodzie ActionScript. Nowością wprowadzoną do mechanizmu kinematyki odwrotnej w wersji Flash Professional CS5 jest koncepcja sprężynowania kości, kojarzona zazwyczaj z aplikacjami do tworzenia zaawansowanych animacji. Dzięki nowemu mechanizmowi symulacji fizycznej dynamiki ruchu funkcja ta umożliwia tworzenie realistycznych animacji. Efekt ten jest widoczny zarówno w środowisku wykonawczym, jak i podczas tworzenia treści. Do tworzenia szkieletów kinematyki odwrotnej wymagana jest licencja programu Flash Professional. Podstawowe informacje o kinematyce odwrotnejKinematyka odwrotna (IK) umożliwia tworzenie realistycznych animacji poprzez łączenie części w taki sposób, aby poruszały się względem siebie w sposób realistyczny. Na przykład: za pomocą IK można przesunąć nogę do określonego miejsca poprzez wykonywanie ruchów zginania w stawach nogi, która ma osiągnąć wymagane położenie. IK korzysta ze struktury kości połączonych ze sobą w strukturę o nazwie szkielet IK. Pakiet fl.ik ułatwia tworzenie animacji przypominających ruch naturalny. Umożliwia płynne animowanie wielu szkieletów IK bez konieczności posiadania szczegółowej wiedzy na temat zasad fizyki w algorytmach IK. Najpierw należy utworzyć szkielet IK z pomocniczymi kośćmi i stawami w programie Flash Professional. Następnie należy uzyskać dostęp do klas kinematyki odwrotnej w celu animowania szkieletu w środowisku wykonawczym. Szczegółowe informacje dotyczące tworzenia szkieletów kinematyki odwrotnej zawiera sekcja poświęcona korzystaniu z kinematyki odwrotnej w dokumentacji Korzystanie z programu Flash Professional. Ważne pojęcia i terminyNa poniższej liście objaśniono ważne terminy istotne w kontekście tego zagadnienia:
Przegląd animacji szkieletów kinematyki odwrotnejPo utworzeniu szkieletu IK w programie Flash Professional należy użyć klas fl.ik w celu ograniczenia jego ruchu, śledzenia zdarzeń i animowania szkieletu w środowisku wykonawczym. Poniższa ilustracja prezentuje klip filmowy o nazwie Wheel. Oś jest instancją IKArmature o nazwie Axle. Klasa IKMover porusza szkieletem w synchronizacji z obrotami koła. Kość IKBone, ikBone2, w szkielecie jest dołączona do koła przy stawie ogonowym. ![]()
W trakcie wykonywania koło obraca się zgodnie z animacją ruchu __motion_Wheel omówioną w sekcji Opisywanie animacji. Obiekt IKMover inicjuje i kontroluje ruch osi. Poniższa ilustracja prezentuje dwa zrzuty szkieletu osi dołączonego do obracającego się koła w różnych klatkach obrotu. ![]() W czasie wykonywania następujący kod ActionScript:
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);
}
}
Klasy IK używane do poruszania osią:
Pełny i szczegółowy opis tych klas zawiera dokumentacja pakiet ik. Pobieranie informacji o szkielecie kinematyki odwrotnejNajpierw należy zadeklarować szkielet, kość i staw, które tworzą części, jakie będą się poruszały. W poniższym kodzie wykorzystano metodę getArmatureByName() klasy IKManager w celu przypisania wartości szkieletu Axle do zmiennej tree klasy IKArmature. Szkielet Axle został poprzednio utworzony w programie Flash Professional. var tree:IKArmature = IKManager.getArmatureByName("Axle");
I podobnie — w poniższym kodzie wykorzystano metodę getBoneByName() klasy IKArmature w celu przypisania do zmiennej IKBone wartości kości ikBone2. var bone:IKBone = tree.getBoneByName("ikBone2");
Staw ogonowy kości ikBone2 jest częścią szkieletu, która jest dołączona do obracającego się koła. Poniższa linia deklaruje zmienną endEffector i przypisuje ją do właściwości tailjoint kości ikBone2: var endEffector:IKJoint = home.tailjoint; Zmienna pos jest punktem, który przechowuje bieżącą pozycję stawu endEffector.
var pos:Point = endEffector.position; W tym przykładzie pos jest pozycją stawu na końcu osi, w miejscu, w którym łączy się z kołem. Oryginalna wartość tej zmiennej jest uzyskiwana z właściwości position stawu IKJoint. Tworzenie instancji klasy IK Mover i ograniczanie jej ruchuInstancja klasy IKMover porusza osią. W poniższej linii tworzona jest instancja obiektu IKMover ik, a do jego konstruktora przekazywany jest element przeznaczony do poruszenia oraz punkt początkowy ruchu:
var ik:IKMover = new IKMover(endEffector, pos); Właściwości klasy IKMover umożliwiają ograniczanie ruchu szkieletu. Ruch można ograniczyć na podstawie odległości, iteracji oraz czasu ruchu. Poniższe pary właściwości wymuszają te ograniczenia. Pary zawierają wartość Boolean, która wskazuje, czy ruch jest ograniczony, oraz liczbę całkowitą, która określa limit:
Domyślnie wszystkie wartości typu Boolean są ustawiane na false, a zatem ruch nie jest ograniczony, o ile wartość Boolean nie zostanie jawnie ustawiona na true. Aby wymusić limit, należy ustawić odpowiednią właściwość na true, a następnie określić wartość odpowiadającej jej właściwości typu Integer. Jeśli zostanie ustawiona wartość limitu, ale nie zostanie określona odpowiednia wartość Boolean, wówczas limit zostanie zignorowany. W takim przypadku silnik IK będzie kontynuował ruch obiektu do czasu osiągnięcia innego limitu lub pozycji docelowej klasy IKMover. W poniższym przykładzie maksymalna odległość ruchu szkieletu jest ustawiona na 0,1 piksela na iterację. Maksymalna liczba iteracji dla każdego ruchu jest ustawiona na dziesięć.
ik.limitByDistance = true; ik.distanceLimit = 0.1; ik.limitByIteration = true; ik.iterationLimit = 10; Poruszanie szkieletem IKKlasa IKMover porusza osią w detektorze zdarzeń koła. Przy każdym zdarzeniu enterFrame koła obliczana jest nowa pozycja docelowa dla szkieletu. Za pomocą metody moveTo() klasa IKMover porusza staw ogonowy do jego położenia docelowego lub na odległość zgodną z ograniczeniami określonymi przez właściwości limitByDistance, limitByIteration i 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);
}
}
Korzystanie ze sprężynowaniaMechanizm kinematyki odwrotnej dostępny w aplikacji Flash Professional CS5 pozwala na obsługę sprężynowania kości. Sprężynowanie kości może być ustawiane podczas tworzenia, a atrybuty sprężynowania mogą być dodawane i modyfikowane w środowisku wykonawczym. Sprężystość jest właściwością kości i jej stawów. Właściwość jest opisana dwoma atrybutami: IKJoint.springStrength, który określa stopień sprężynowania, oraz IKJoint.springDamping, który zwiększa tłumienie drgań sprężyny i wpływa na szybkość zaniku efektu sprężynowania. Stopień sprężynowania to wartość wyrażona w procentach od 0 (domyślnie, całkowita sztywność) do 100 (elastyczność, sterowanie silnikiem Physics). Kości posiadające właściwość Spring reagują na ruch w ich stawach. Jeśli nie wystąpiła żadna zmiana (rotacja, przesunięcie x lub y), wówczas ustawienia sprężynowania nie mają wpływu na zachowanie kości. Tłumienie sprężynowania to wartość wyrażona w procentach od 0 (brak oporu) do 100 (pełne tłumienie). Tłumienie wpływa na czas, jaki upływa między początkiem ruchu kości a jej powrotem do pozycji spoczynkowej. Aby sprawdzić, czy sprężynowanie zostało aktywowane dla obiektu IKArmature, należy odczytać jego właściwość IKArmature.springsEnabled. Inne właściwości i metody Spring nalezą do poszczególnych obiektów IKJoint. Staw może umożliwiać obroty i przesunięcia wzdłuż osi x i y. Kąt sprężynowania dla stawu obrotowego można ustawić za pomocą właściwości IKJoint.setSpringAngle, a pozycję sprężyny dla stawu umożliwiającego przesuwanie można ustawić za pomocą właściwości IKJoint.setSpringPt. Ten przykład ilustruje wybór kości wg nazwy i identyfikację jej właściwości tailJoint. Kod testuje nadrzędny szkielet w celu sprawdzenia, czy sprężynowanie zostało aktywowane, a następnie ustawia właściwości sprężynowania dla stawu. 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
}
}
Korzystanie ze zdarzeń kinematyki odwrotnejKlasa IKEvent umożliwia utworzenie obiektu zdarzenia, który zawiera informacje dotyczące zdarzeń IK. Informacje w klasie IKEvent opisują ruch, który zakończył się z powodu przekroczenia limitu czasu, odległości lub iteracji. Poniższy kod prezentuje detektor zdarzenia i moduł obsługi zdarzenia dla śledzenia zdarzeń przekroczenia limitu czasu. Ten moduł obsługi zdarzeń zgłasza właściwości dotyczące czasu, odległości, liczby iteracji i stawu biorącego udział w zdarzeniu w przypadku przekroczenia limitu czasu klasy 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);
}
|
|