Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Okt 31, 2024 23:50

Foren-Übersicht » Programmierung » Mathematik-Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Fr Jan 03, 2014 17:57 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Moinsen,
beim Schreiben des Artikels Dual Quaternion bin ich gerade ins Grübeln gekommen. Die skeletale Animation läuft bei mir derzeit mit dualQuats. Wenn ich dort einen Vertex transformieren möchte, sind das im Grunde drei Schritte:
1. Von der Position des Vertex wird die absolute Position des Joints in Ruhe-Pose (T-Pose) abgezogen, um eine Position relativ zum Joint zu bekommen.
2. Diese relative Position wird rotiert.
3. Anschließend wird die aktuelle absolute Position des Joints aufaddiert.

Das sind also 2 Translationen und eine Rotation. Der Translationsvektor im 3. Schritt ist aber ein völlig anderer als der im 1. Schritt. Bei dualQuats ist das kein Problem, weil man die verketten kann wie Matrizen und somit alle 3 Schritte in ein dualQuat packen kann.

Wie u.a. diese Diskussion vor einigen Monaten ergeben hat, setzen viele von euch aber keine dualQuats, sondern eine Kombination aus Quaternion und Translationsvektor ein. Wie schafft ihr es da, mit nur einem Translationsvektor auszukommen?

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Jan 04, 2014 20:53 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Ein berühmter DGL-Moderator schrieb einst:
Zitat:
DGL ist zwar für seine hervorragenden Antwortzeiten bekannt, aber 24h kann man schonmal warten
Die sind jetzt ja um. :wink:

Falls ich meine Frage zu unklar gestellt habe, hier nochmal die Transformationen, die ich bisher in ein dualQuat stecke, mit Bildern (aus dem noch unfertigen Tutorial):
http://wiki.delphigl.com/index.php/Benutzer:Glawesome/Tutorial_Charakteranimation#Transformation_der_Positionen

Ich frage mich/euch, wie man das mit einem Quaternion und nur einem Translationsvektor realisieren soll.
Im Artikel Boneanimation per Vertexshader wird der erste Schritt offenbar komplett weggelassen. Meiner Meinung nach müsste man dem Vertexshader zwei Translationsvektoren pro Joint übergeben - oder habe ich was übersehen?

Falls meine Frage immer noch unverständlich ist, bitte nachfragen! Die Erkenntnisse aus diesem Thread werden natürlich ins Wiki miteinfließen.
Sorry, dass ich so ungeduldig bin, aber nächste Woche werde ich möglicherweise keine Zeit finden, am Wiki zu arbeiten.

Vielen Dank schonmal für eure Antworten!

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Jan 05, 2014 14:12 
Offline
DGL Member

Registriert: Do Dez 29, 2011 19:40
Beiträge: 421
Wohnort: Deutschland, Bayern
Programmiersprache: C++, C, D, C# VB.Net
Die beiden Verschiebungen sollten doch zusammengefasst werden können.
Rein Geometrisch betrachtet kann man den durch die 3 Operationen erzeugte Transformation auch mit 2 Operationen erzeugen. Dafür müsste man einfach die erste Verschiebung mit der umgekehrten Rotation multiplizieren und dann mit dem anderen Verschiebungsvektor multiplizieren.
Auf jeden Fall scheinen mir die Dual Quaternions mathematisch wesentlich eleganter zu sein. Bei der Rotationsquaternion-/ Verschiebungsvariante kommt es unter anderem darauf an, ob erst verschoben wird und dann rotiert oder andersrum. Außerdem lassen sich mehrere Solcher Transformationen nur komplizierter zusammenfassen, wie du auch schon festgestellt hast.

Ich habe bis jetzt nur oberflächliches Wissen ober Charakteranimation, aber was ich mich da grundsätzlich dazu frage ist, wozu du Verschiebung überhaupt dienen soll. Zwischen den Bones sind doch Kugelgelenke, die nur gedreht werden können und nicht verschoben. Deshalb sehe ich schon mal gar keinen Sinn darin, irgendetwas verschieben zu wollen.


Zuletzt geändert von OpenglerF am Mo Jan 06, 2014 14:22, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Jan 05, 2014 14:34 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
glAwesome hat geschrieben:
Wie u.a. diese Diskussion vor einigen Monaten ergeben hat, setzen viele von euch aber keine dualQuats, sondern eine Kombination aus Quaternion und Translationsvektor ein. Wie schafft ihr es da, mit nur einem Translationsvektor auszukommen?


Ich mache die Bone-Animation zwar nicht mit Quaternionen, sondern nur mit altmodischen Matrizen und habe derzeit auch nur ein einziges winziges Testprogramm mit Bones laufen, weil das Thema "Animation" im Augenblick nicht meine volle Aufmerksamkeit hat. Aber das Prinzip sollte ja das Gleiche sein, egal ob es sich um Matrizen, Quaternionen oder Duale Quaternionen handelt.

Das, was ich Dir hier erzähle, habe ich von einer sehr informativen australischen Website, die es lange nicht mehr gibt (seufz), und etliches davon musste ich mir auch selber zusammenreimen; aber so, wie ich es hier beschreibe, funktioniert meine Testanwendung und es sieht auch richtig aus.



Ich betrachte das Animations-Problem etwas anders als Du, und mit einem kleinen, naja, "Trick" ist der OffsetVektor immer gleich. Ich zerlege das Problem dazu in zwei Teile:


(Anmerkung: Der "OffsetVector" ist der Positionsvektor des jeweiligen Gelenks in der BindPose, und der ist für ein Gelenk immer gleich)

Teil 1: Herstellen der lokalen Transformations-Matrizen (*LTM*) der Gelenke:
    *Das Gelenk wird zum Koordinatenursprung verschoben (OffsetVector = negative Gelenkposition; Space = Model-Space)
    *Die LOKALE Rotation ist repräsentiert durch eine vorhandene RotationsMatrix (ich kümmere mich jetzt nicht darum, wo man diese herbekommt, es genügt irgendeine)
    *Das Gelenk wird nach der Rotation wieder mit dem *positiven* Offset-Vector in seine BindPose-Position zurück verschoben.


Diese drei Transformationen kann man in eine einzige Matrix verpacken. Wenn man das Sonnensystem simulieren wollte und die einzelnen Planeten rotieren möchte, macht man im Prinzip das Gleiche; Ich nenne diese Funktion in meiner eigenen Math3D-Lib "MatrixRotateLocal" auf Deutsch: Rotieren am Stand :wink: :

Code:
  1. Function MatrixRotateLocal(Const AOffset: TVector3F;
  2.                    Const Angle: Single;
  3.                    Const Axis: TVector3F): TMatrix16F;
  4. Var
  5.    MatInvers,MatRevers,MatRotation: TMatrix16F;
  6. Begin
  7.    MatInvers:= MatrixShift(VectorInvers(AOffset));
  8.    MatRotation:= MatrixRotate(Angle,Axis);
  9.    MatRevers:= MatrixShift(AOffset);
  10.  
  11.    // Order: 1.Invers, 2.Rotate, 3.Revers
  12.    Result:= MatrixMultiply(MatRevers,
  13.                MatrixMultiply(MatRotation,MatInvers));
  14. End;


Teil 2: Herstellen der kombinierten Transformations-Matrizen (*CTM*) der Gelenke:
Vom Haupt-Gelenk her wird nun die jeweilige kombinierte Gelenks-Matrix folgendermaßen hergestellt:

CTM(aktuelles Gelenk) = CTM(voriges Gelenk) * LTM(aktuelles Gelenk)

Wobei im ersten Gelenk ist CTM = LTM.
Achtung auf die Reihenfolge bei der Matrixmultiplikation: LTM muss die erste sein.


Mit einer Baum-mäßigen Rekursionsfunktion schafft man Teil 2 mit höchstens 2 Zeilen Code.


Ich schätze jetzt mal (ich weiß es aber nicht), dass in den üblichen Animations-Formaten nur mehr die CTMs vorhanden sind, denn der OffsetVektor aus Teil 1 wird vollkommen "verschluckt", daher bekommt der Shader m.E. eben nur mehr ein Model(View)-Matrix-Array übergeben. Der Translationsvektor aus Deiner Frage ist möglicherweise eine Verschiebung des Modells im World-Space, es könnte sich also einfach um ein Missverständnis handeln.

Viele Grüße
Traude


PS: @OpenglerF: das Hin- und Herverschieben braucht man, damit die Rotation überhaupt möglich gemacht wird, denn Rotieren funktioniert nur am Koordinatenursprung


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Jan 05, 2014 16:00 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Traude hat geschrieben:
Das, was ich Dir hier erzähle, habe ich von einer sehr informativen australischen Website, die es lange nicht mehr gibt (seufz)
Hast du noch die URL? Wenn ja könnte archive.org helfen.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Jan 05, 2014 18:28 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich habe nach längerem Suchen die URL der Website gefunden und habe es auf archive.org versucht, aber dort wurde zwar die Website registriert aber der relevante Inhalt war offenbar nicht mehr gespeichert. Lt. meinen eigenen Aufzeichnungen habe ich das in 2006 heruntergeladen; ist schon ziemlich lange her, dass ich mich mit Bone Animation beschäftigt habe.

Ich habe aber nicht nur die URL gespeichert, sondern auch ein Exzerpt aus dem Inhalt der Website als RichText-File. Wenn jemand interessiert ist, kann ich das zur Verfügung stellen. Allerdings - heute gibt es glaub ich viel bessere Infos über Bone Animation im Web als im Jahr 2006.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Jan 05, 2014 21:19 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Danke für die doch plötzlich sehr vielen Antworten!

OpenglerF hat geschrieben:
Die beiden Verschiebungen sollten doch zusammengefasst werden können.
Jetzt wird's mir klar. Ist ja im Prinzip das gleiche wie bei Matrizen. Man kann Translationsmatrix * Rotationsmatrix * Translationsmatrix rechnen und aus dem Resultat den Rotations- und Translationsteil extrahieren.

OpenglerF hat geschrieben:
Ich habe bis jetzt nur oberflächliches Wissen ober Charakteranimation, aber was ich mich da grundsätzlich dazu frage ist, wozu du Verschiebung überhaupt dienen soll. Zwischen den Bones sind doch Kugelgelenke, die nur gedreht werden können und nicht verschoben.
Die Verschiebung, von der ich sprach, dient auch nicht dazu, eine Gelenk zu verschieben, sondern um um den richtigen Punkt zu drehen. Jedes Gelenk dreht ja um seine Position und die ändert sich während der Animation. Daher müssen die Vertices vor und nach der Rotation entsprechend verschoben werden, da man mit einem Quaternion/einer Rotationsmatrix immer nur um den Ursprung drehen kann.
Andererseits gibt es durchaus Anwendungen, wo Gelenke nicht nur gedreht, sondern richtig transliert werden müssen. Mit skelettaler Animation lassen sich ja nicht nur Menschen, sondern z.B. auch Maschinen (Kolben) animieren.

@Traude:
Was du beschreibst, scheint mir sehr ähnlich zu meinem Tutorial zu sein. Nur dass du erst die drei Transformationen berechnest und dann die absoluten Transformationen rekursiv bestimmst. Ich mache es genau andersherum - sollte aber beides funktionieren.

Die Erkenntnisse aus diesem Thread werde ich dann voraussichtlich nächstes Wochenende ins Wiki überführen (scheiß Uni).

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jan 06, 2014 12:37 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
glAwesome hat geschrieben:
@Traude:
Was du beschreibst, scheint mir sehr ähnlich zu meinem Tutorial zu sein. Nur dass du erst die drei Transformationen berechnest und dann die absoluten Transformationen rekursiv bestimmst. Ich mache es genau andersherum - sollte aber beides funktionieren.
Dann empfehle ich Dir, meinen Beitrag oben nochmals zu lesen, denn das, was ich oben beschrieben habe, kann man gar nicht umkehren. Einfach nur so drüberlesen ist in diesen Fall nicht erlaubt. Es gibt Code, der auf den ersten Blick ganz harmlos aussieht, aber der es in sich hat. Er hätte sich ein wenig mehr Aufmerksamkeit von Dir verdient.

glAwesome hat geschrieben:
Die Verschiebung, von der ich sprach, dient auch nicht dazu, eine Gelenk zu verschieben, sondern um um den richtigen Punkt zu drehen
Das kann nicht sein, denn die Gelenks-Matrix, die am Ende herauskommt, muss für *alle* Punkte gelten, die diese Gelenks-Matrix benutzen.

glAwesome hat geschrieben:
Daher müssen die Vertices vor und nach der Rotation entsprechend verschoben werden
Nein, es wird bloß das Gelenk hin und zurück verschoben. Darum geht's ja eigentlich.

glAwesome hat geschrieben:
Andererseits gibt es durchaus Anwendungen, wo Gelenke nicht nur gedreht, sondern richtig transliert werden müssen. Mit skelettaler Animation lassen sich ja nicht nur Menschen, sondern z.B. auch Maschinen (Kolben) animieren.
Ja, natürlich, aber dann nimmt man in meinem Teil 1 einfach eine Translationsmatrix oder auch eine kombinierte Translations/Rotationsmatrix. In Deinem Fall das entsprechende duale Quaternion.

Es geht mir jetzt nicht wirklich bloß darum, recht zu haben, denn ich sehe mir Deine Beiträge schon eine Weile an, eben weil Du Dich mit Animation beschäftigst, was mich selber ungeheuer interessiert, und was hier auf DGL verflixt selten ist. Du hast praktisch bewirkt, das ich jetzt wieder öfter einen Blick auf die DGL-Website mache. :wink:

Traude
Deren Erfahrung mit Skeletaler Animation zwar schon lange her ist, die sich damals aber sehr lange und intensiv damit beschäftigt hat.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jan 06, 2014 16:40 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Traude hat geschrieben:
das, was ich oben beschrieben habe, kann man gar nicht umkehren.
Ich habe mir nochmal die Zeit genommen und deinen Beitrag ganz genau durchgelesen. Und glaub mir: Man kann die Reihenfolge vertauschen. So funktioniert es ja bei mir.

Der Punkt ist der: Du baust in deine lokalen Matrizen bereits die beiden Translationen (um den negativen und positiven Offsetvektor) mit ein. Da du dies bereits in der lokalen Matrix tust, kannst du für beide Translationen den gleichen Vektor nehmen (zwar mit anderem Vorzeichen, sonst aber gleich). Danach erst verkettest du die Transformationen. Bei der Verkettung kommt es zu einer Verschiebung der Rotationscenter. Denn wenn du beispielsweise deinen Arm hebst (das Schultergelenk drehst) ändern sich ja die Positionen von Hand- und Ellenbogengelenk. Da du die Verkettung aber als letztes ausführst braucht dich das bei deinem Ansatz nicht zu interessieren.

Ich gehe den anderen Weg: Ich bestimme erst die absoluten (= nicht lokalen, "verketteten") Rotationen und Rotationscenter. D.h. ich multipliziere die Rotationen rekursiv vom Wurzelknoten bis zum Blatt durch. Die Translationen werden - nach der Anwendung der jeweiligen absoluten Rotation - addiert. Das heißt, nach dem ersten Schritt weiß ich für jeden Joint, welche Orientierung er hat und an welcher Stelle er sich befindet.
Erst jetzt baue ich die Matrizen/DualQuats. Da sich die Positionen der Gelenke inzwischen verschoben haben, kann ich nicht wie du um -Offset translieren, die Rotation anwenden und wieder um Offset translieren. Das würde nicht funktionieren. Ich benötige nämlich jetzt zwei völlig verschiedene Translationsvektoren. Ich muss nämlich erst die Position des Gelenks in der Standardpose abziehen, dann rotieren und anschließend die im ersten Schritt berechnete aktuelle Position des Gelenks addieren.

Da ich bei meinem Ansatz zwei verschiedene Translationsvektoren habe, habe ich mich gefragt, wie man mit nur einem auskommen soll - daher dieser Thread.

Ich hoffe, ich hab's vertsändlich formuliert bekommen. Sowas ist immer einfacher zu erklären, wenn man es sich an einem Live-Objekt veranschaulichen kann. :)
Die anderen Punkte, an denen du mir widersprochen hast, sollten nun hoffentlich klar sein.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jan 06, 2014 17:46 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich habe mir Deinen letzten Betrag auch genau durchgelesen. Ja, Du kannst das Ganze natürlich umkehren insofern, als Du zuerst den Gelenksbaum berechnest und erst anschließend die lokalen Matrizen. Aber ganz schaffst Du es doch nicht, weil Du jetzt den neuen Verschiebungsvektor erst berechnen musst. Wenn Du - wie Du gesagt hast - den zweiten Verschiebungsvektor Punkt-weise berechnest, ist das ein relativ hoher Berechnungsaufwand.

Gibt es einen Grund warum Du gerade diese Berechnungsweise gewählt hast? Vielleicht liegt es ja an den Dual Quaternions?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jan 06, 2014 20:01 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Traude hat geschrieben:
Du kannst das Ganze natürlich umkehren insofern, als Du zuerst den Gelenksbaum berechnest und erst anschließend die lokalen Matrizen.
Ich berechne keine lokalen Matrizen. Da der Gelenkbaum nach dem ersten Schritt die absoluten Positionen und Rotationen enthält, kann ich daraus direkt die absoluten/globalen/verketteten (such dir einen Begriff aus) Matrizen bzw. DualQuats berechnen.

Traude hat geschrieben:
Wenn Du - wie Du gesagt hast - den zweiten Verschiebungsvektor Punkt-weise berechnest, ist das ein relativ hoher Berechnungsaufwand.
Wo habe ich gesagt, dass ich ihn punktweise berechne?
1. Transformation: Translation um -(Position des Joints in T-Pose)
2. Transformation: Rotation
3. Transformation: Translation um die aktuelle Position des Joints

Das alles wird in eine Matrix/ein DualQuat gesteckt. Beide Translationsvektoren sind nicht vom jeweiligen Vertex abhängig, sondern nur vom Joint.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jan 06, 2014 22:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
glAwesome hat geschrieben:
Wo habe ich gesagt, dass ich ihn punktweise berechne?

Ich habe diese Passage von Deinem ersten Beitrag so interpretiert, insbesondere den Punkt 1:
glAwesome hat geschrieben:
1. Von der Position des Vertex wird die absolute Position des Joints in Ruhe-Pose (T-Pose) abgezogen, um eine Position relativ zum Joint zu bekommen.
2. Diese relative Position wird rotiert.
3. Anschließend wird die aktuelle absolute Position des Joints aufaddiert.


Daher war ich jetzt ein wenig hartnäckig.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Foren-Übersicht » Programmierung » Mathematik-Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.014s | 19 Queries | GZIP : On ]