Wie man einen Teil eines 3D-Modells dynamisch auf etwas animiert


8

Ich bin gespannt, wie diese Art von Animation normalerweise codeweise ausgeführt wird.

Einige Beispiele:

Antworten:


4

Dies nennt man inverse Kinematik. Google ist wahrscheinlich Ihr bester Freund in diesem Fall, da es komplex werden kann.


Ich verstehe, ich muss die Bewegungen berechnen, die notwendig sind, um eine gewünschte Position zu erreichen. In diesem Fall würde ich nur die Bewegungen für den gewünschten Knochen berechnen.
Gerstmann

In der Tat heißt es in der Videobeschreibung "... ein Animationssystem, das vollständig auf inverser Kinematik basiert ..."
MichaelHouse

0

Originalartikel: So codieren Sie ein IK-System

Manchmal reicht die in Unity integrierte IK nicht aus. Ich werde Ihnen zeigen, wie Sie Ihr eigenes IK-Skript für Unity erstellen. Sie können diese IK auf jeden Gelenkkörper anwenden - Finger, Hände oder Füße. Das IK, das ich überprüfen werde, wird derzeit von Unity, Unreal, Panda und mehreren anderen Spiel-Engines verwendet. Es heißt FABRIK.

FABRIK ist eine iterative Methode. Eine iterative Methode ist eine Methode, die die Lösung nicht sofort erhält. Eine iterative Methode kommt der richtigen Lösung mit mehr Iterationen der Methode immer näher - mit anderen Worten, Iterationen einer Schleife.

Jedes IK-Problem hat einen bestimmten Gelenkkörper (eine Reihe verbundener Gliedmaßen mit Längen und Winkeln). Der Endeffektor (die Position des Endpunkts des letzten Gliedes) hat eine Startposition mit einer Zielposition. Es könnte andere Ziele haben, wie z. B. Winkel.

Jede FABRIK-Iteration besteht aus zwei Hauptteilen.

void FABRIK() {
    while( abs(endEffectorPosition  goalPosition) > EPS ) {
        FinalToRoot(); // PartOne
        RootToFinal(); // PartTwo
    }
}

Der erste Teil iteriert vom letzten Glied zum Wurzelglied. Für das letzte Glied müssen Sie den Winkel / die Drehung des Glieds ändern, um auf die Zielposition zu zeigen (die Innenbordposition verankert halten und die Außenbordposition durch die Winkeländerung verschieben lassen). Als nächstes verschieben Sie das letzte Glied entlang des aktualisierten Winkels in Richtung der Zielposition, bis die Außenborderposition des Glieds der Zielposition entspricht (wobei der Winkel beibehalten wird, die Innenbordposition des Glieds jedoch geändert wird). Das ist so ziemlich alles für das letzte Glied, außer dass Sie jetzt die aktuelle Zielposition aktualisieren müssen. Die aktuelle Zielposition wird jetzt auf die aktualisierte Innenbordposition des letzten Gliedes gesetzt.

Für jedes aufeinanderfolgende Innenborder-Glied tun Sie dasselbe. Um klar zu sein, werde ich es skizzieren. Für das aktuelle Glied müssen Sie den Winkel / die Drehung des Glieds ändern, um auf die aktuelle Zielposition zu zeigen. Als Nächstes verschieben Sie das aktuelle Glied entlang des aktualisierten Winkels in Richtung der aktuellen Zielposition, bis die Außenborderposition des Glieds der aktuellen Zielposition entspricht. Schließlich aktualisieren Sie die aktuelle Zielposition so, dass sie der aktualisierten Innenbordposition des aktuellen Glieds entspricht.

Wiederholen Sie diese Vorgänge, bis Sie diese Vorgänge am Wurzelglied abgeschlossen haben. Danach ist der erste Teil abgeschlossen.

/* Part One */
void FinalToRoot() {
    currentGoal = goalPosition;
    currentLimb = finalLimb;
    while (currentLimb != NULL) {
        currentLimb.rotation = RotFromTo(Vector.UP,
            currentGoal  currentLimb.inboardPosition);
        currentGoal = currentLimb.inboardPosition;
        currentLimb = currentLimb->inboardLimb;
    }
}

Der zweite Teil iteriert in umgekehrter Richtung: vom Wurzelglied zum letzten Glied. Für das Wurzelglied müssen Sie seine Innenposition auf die Wurzelposition aktualisieren. Dies sollte das gesamte Glied übersetzen (ohne sich zu dehnen). Das ist so ziemlich alles für das Wurzelglied, außer dass Sie jetzt die aktuelle Innenbordposition aktualisieren müssen. Die aktuelle Innenborderposition wird jetzt auf die aktualisierte Außenborderposition des Wurzelglieds gesetzt. Für jedes aufeinanderfolgende Außenborder-Glied tun Sie dasselbe. Um klar zu sein, werde ich es skizzieren. Für das aktuelle Glied müssen Sie seine Innenbordposition auf die aktuelle Innenbordposition aktualisieren. Dies sollte das ganze Glied übersetzen. Das ist so ziemlich alles für das aktuelle Glied, außer dass Sie jetzt die aktuelle Innenbordposition aktualisieren müssen. Die aktuelle Innenborderposition wird jetzt auf die aktualisierte Außenborderposition des aktuellen Glieds gesetzt.

Wiederholen Sie diese Vorgänge, bis Sie diese Vorgänge am letzten Glied abgeschlossen haben. Danach ist der zweite Teil abgeschlossen.

/* Part Two */
void RootToFinal() {
    currentInboardPosition = rootLimb.inboardPosition;
    currentLimb = rootLimb;
    while (currentLimb != NULL) {
        currentLimb.inboardPosition = currentInboardPosition;
        currentInboardPosition = currentLimb.outboardPosition;
        currentLimb = currentLimb->inboardLimb;
    }
}

Nachdem der erste Teil und der zweite Teil abgeschlossen wurden, haben Sie die erste Iteration der FABRIK-Methode abgeschlossen. Fahren Sie mit Teil 1 und 2 fort, bis der Endeffektor so nah wie nötig an der Zielposition ist, die durch ein EPS (Epsilon-Wert) definiert ist.

Das ist es! Das ist die FABRIK-Methode. Teil Eins iteriert vom letzten Glied rückwärts. Teil zwei iteriert vom Wurzelglied vorwärts. Die FABRIK-Methode wiederholt Teil 1 und Teil 2, bis der Endeffektor nahe genug an der Zielposition ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.