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

Aktuelle Zeit: Do Mär 28, 2024 16:58

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Assimp & Collada - Falsche Rotation
BeitragVerfasst: So Mai 28, 2017 17:42 
Offline
Fels i.d. Brandung
Benutzeravatar

Registriert: Sa Mai 04, 2002 19:48
Beiträge: 3827
Wohnort: Tespe (nahe Hamburg)
Moin,

ich bin momentan dabei in einem Projekt ein Bone-Animation-System zu implementieren und stecke dort nun bereits seit einer Weile an verschiedenen Problemen fest. Um einmal irgendwo anzufangen, nehme ich mal ein Teilproblem raus und hoffe daher, dass jemand von Euch vielleicht eine Idee hat oder mir zumindest geistig auf die Sprünge helfen kann. Leider ist es halt recht tricky, da eben doch eine recht große Codebasis ist in der hypothetisch der Fehler lauern kann. Durch diverse Tests glaube ich allerdings, dass das Problem nicht zu suchen ist im:
- Shader (zu simple, funktioniert)
- Renderer (funktioniert in zu vielen anderen Fällen ;))
- dem Animationsystem (Interpolation sieht eigentlich gut aus...)

Ich vermute daher, dass die Daten aus dem Modell nicht richtig sind oder von mir falsch interpretiert werden. Das Modell ist von einem Kumpel der diese mittels Blender anfertigt und dann nach Collada exportiert. Im Blender gibt es beim aktuellen Modell eigentlich nichts, was mich denken lassen könnte, dass der Fehler von dort kommt. Zum Laden des Modells verwende ich Assimp, habe also keinen eigenen Loader im Einsatz. Das Koordinatensystem ist bei mir nicht wie in OpenGL, sondern entspricht dem System von Blender. D.h. y geht positiv in den Screen rein, positive Z geht nach oben hin.

Auf diesem Screenshoot könnt ihr die Ansicht in Blender mitsamt des Bones sehen. Die Animation ist eine Bewegung entlang der X-Achse:
http://phobeus.de/tmp/blender.jpeg

Lade ich nun das Modell und rendere die Szene, erhalte ich Folgendes:
http://phobeus.de/tmp/anim_model.ogv
Die Achsenorientierung könnt ihr am Anchor sehen (R=x,G=y,B=z). D.h. die Bewegung selbst scheint richtig zu funktionieren und klappt. Allerdings sind die Achsen des Modells verdreht und zwar um rund 180° auf X.

Lade ich nun das Modell und erzeuge eine Animation programmatisch wie folgt:
Code:
  1.         Map<String, JointTransform> map = new HashMap<>();
  2.         map.put("Bone", new JointTransform(new Vector3f(0, 0, 0), new Quaternionf().rotate(0, 0, 0)));
  3.        
  4.         Map<String, JointTransform> map2 = new HashMap<>();
  5.         map2.put("Bone", new JointTransform(new Vector3f(5, 0, 0), new Quaternionf().rotate(0, 0, 0)));
  6.        
  7.         KeyFrame f1 = new KeyFrame(0,map);
  8.         KeyFrame f2 = new KeyFrame(2,map2);
  9.        
  10.         Animation animation = new Animation(new KeyFrame[]{f1,f2});

Erhalte ich folgendes: http://phobeus.de/tmp/anim_prog.ogv

D.h. das Modell scheint um -90° um x falsch gedreht zu sein. Wie man sieht besteht die Animation lediglich aus einer Translation und einem Identity Quaternion. Ich finde diese Rotation bereits ein wenig merkwürdig, da meine Erwartung wäre, dass diese identisch mit dem von Blender ist und nicht dem ursprünglichen OpenGL-Koordinatensystem entspricht. Ich habe bisher keinen Hinweis dafür gefunden, dass der Collada-Exporter eine entsprechende Korrektur vornimmt oder gar das Format selbst eine entsprechende Orientierung vorschreibt. Wenn da jemand allerdings mehr drüber weiß und erklären kann, wieso es zu dieser -90° Drehung kommt, ich habe ein offenes Ohr. Leider ist die Dokumentation bei beiden doch eher spärlich.

Fakt ist zumindest, dass wenn ich programmatisch die Werte setze ein anderes Ergebnis erhalte als wenn ich diese aus dem Modell nehme, da die Quaterions dort nochmals um 90° gedreht werden. Der Loader selbst ist dabei eigentlich recht straight forward und sihet nicht nach viel Potenzial für Fehler aus:
Code:
  1.         for (int f = 0; f < animationData.mNumChannels(); f++) {
  2.             PointerBuffer channels = animationData.mChannels();
  3.             Map<String, JointTransform> jointTransforms = new HashMap<>();
  4.  
  5.             for (int a = 0; a < animationData.mNumChannels(); a++) {
  6.                 AINodeAnim channel = AINodeAnim.create(channels.get(a));
  7.  
  8.                 AIVector3D positionData = channel.mPositionKeys().get(f).mValue();
  9.                 AIQuaternion rotationData = channel.mRotationKeys().get(f).mValue();
  10.  
  11.                 Vector3f position = new Vector3f(positionData.x(), positionData.y(), positionData.z());
  12.                 Quaternionf rotation = new Quaternionf(rotationData.x(), rotationData.y(), rotationData.z(),
  13.                 rotationData.w());
  14.  
  15.                 JointTransform jointTransform = new JointTransform(position, rotation);
  16.                 jointTransforms.put(channel.mNodeName().dataString(), jointTransform);
  17.             }
  18.  
  19.             KeyFrame keyFrame = new KeyFrame(f, jointTransforms);
  20.             keyFrames.add(keyFrame);
  21.         }


Da die Translation der Animation korrekt ist, würde ich erwarten, dass es ein Problem mit den Quaternions ist. Assimp scheint ja WXYZ zu verwenden, während die verwendete Java-Implementierung XYZW nutzt:

Code:
  1.     /**
  2.      * Create a new {@link Quaternionf} and initialize its components to the given values.
  3.      *
  4.      * @param x
  5.      *          the first component of the imaginary part
  6.      * @param y
  7.      *          the second component of the imaginary part
  8.      * @param z
  9.      *          the third component of the imaginary part
  10.      * @param w
  11.      *          the real part
  12.      */
  13.     public Quaternionf(float x, float y, float z, float w) {
  14.         this.x = x;
  15.         this.y = y;
  16.         this.z = z;
  17.         this.w = w;
  18.     }


Da ich leidglich die Bestandteile auslese und übernehme, sollte das ja eigentlich kein Problem sein oder misinterpretiere ich da etwas und die Quaternions verhalten sich da wieder biestiger als erwartet? ;)

Irgend jemand eine Idee, was hier schief laufen könnte und die Welt bei mir Kopf steht? Ist mein erstes Bones-System und ich stecke leider wirklich schon eine Weile dran fest und brauche dringend ein wenig Supervision. Leider sind die entsprechenden Teile immer nicht ganz so trivial zu debuggen, so dass ich inzwischen fast mit allem rechne. Trotzdem sollten die Werte aus dem Modell nicht abweichen von denen programmatisch erzeugten. Vielleicht hast Du ja auch einen Collada-Loader und könntest wenigstens einmal das Modell bei Dir durchjagen und verifizieren, ob dieses bei Dir genauso lädt, wie Du es erwarten würdest. Bereits dies würde eine große Hilfe darstellen!
http://phobeus.de/tmp/x+_move_rotate
http://phobeus.de/tmp/base-cube_Texture.png

Vielen Dank vorab für jedliche Art von Hilfe!

Beste Grüße,
Phobeus

_________________
"Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Mai 28, 2017 19:19 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Hmm, ich tappe da auch im Dunkeln. Aber ein Rotationsfehler von 180° könnte sehr gut daher kommen, dass die Quaternionen in nicht einheitlicher Reihenfolge gespeichert werden. Die Komponenten eines Quaternions werden ja so berechnet:
Code:
  1. x = axis.x * sin(angle/2);
  2. y = axis.y * sin(angle/2);
  3. z = axis.z * sin(angle/2);
  4. w = cos(angle/2);
Bei einer Rotation von 0° können x, y und z also beliebige Werte annehmen - wahrscheinlich hat einer den Wert 1 und die anderen beiden 0. w wird auf jeden Fall 1. Wenn du jetzt, sagen wir mal x mit w vertauschst, und w damit 0 wird, hast du eine Drehung um 180° um irgendeine Achse (denn cos(180°/2) = 0).

PS: Dein vorletzter Link funktioniert nicht. Vielleicht wegen Sonderzeichen?

_________________
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 Mai 28, 2017 19:42 
Offline
Fels i.d. Brandung
Benutzeravatar

Registriert: Sa Mai 04, 2002 19:48
Beiträge: 3827
Wohnort: Tespe (nahe Hamburg)
Hm, wenn die 180° von einem Komponentfehler bei den Quaternions her rühmen, habe ich aber wirklich ein Problem. Korrigiere ich die 90° die ich beim programmatische Ansatz habe, dann scheint translation und rotation absolut einwandfrei sein. Die Quaternions werden da genauso verwendet. Ich denke daher, dass es an dem Material liegt, dass ich vom Loader zurück bekomme. Ich habe mal die Quaternions gedumpt gedumpt die ich vom Assimp erhalte:
Code:
  1. 0.70710677
  2. 0.0
  3. 0.0
  4. 0.70710677


Code:
  1. 0.7071067
  2. 2.6222597E-8
  3. -5.8221513E-8
  4. 0.7071068


Die Werte überraschen mich ein wenig. Wenn ich sie nochmal dumpe nachdem sie durch die Quaternion-Klasse gelaufen sind, ergibt:
Code:
  1. (7,071E-1 0,000E+0 0,000E+0 7,071E-1)
  2. (7,071E-1 2,622E-8 -5,822E-8 7,071E-1)

Ist XYZW, da scheint also auf dem Weg auch nichts verloren zu gehen.

Was ich mich eher Frage, ob da vielleicht irgend etwas mit der Matrix falsch läuft, die vom Bone kommt. Wie man auf dem Blender-Bild sehen kann, steht der Bone ja aufrecht entlang der Z-Achse im Raum. Vom Assimp erhalte ich folgendes:
Code:
  1. Bone: Bone
  2. 1  0  0  0
  3. 0  0  1  0
  4. 0  -1  0  0
  5. 0  0  0  1


Ich habe den Link noch einmal editiert. Habe schlichtweg die Datei-Endung vergessen. Sorry :roll:

_________________
"Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Mai 28, 2017 20:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Erstmal muss ich mich selbst korrigieren: Bei einem Winkel von 0° wären natürlich w=1 und x=y=z=0, weil sin(0°)=0.

Phobeus hat geschrieben:
Die Werte überraschen mich ein wenig.
Alle von dir geposteten Quaternions beschreiben eine 90°-Roation um die x-Achse. Beachte die Exponenten-Schreibweise, d.h. 2.6222597E-8 ist eigentlich 0 mit Rundungsfehler. Weiterhin ist 0.707 = cos(90°/2) = sin(90°/2) – das Quaternion ist also das, was in anim_prog.ogv zu sehen ist. Auch deine Matrix beschreibt die gleiche Rotation.

Phobeus hat geschrieben:
Ich habe den Link noch einmal editiert.
Nope. Ist aber nicht so schlimm, da ich selbst keinen Collada-Loader habe. Aber vielleicht ja jemand anderes. :)

_________________
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 Mai 28, 2017 20:59 
Offline
Fels i.d. Brandung
Benutzeravatar

Registriert: Sa Mai 04, 2002 19:48
Beiträge: 3827
Wohnort: Tespe (nahe Hamburg)
glAwesome hat geschrieben:
Alle von dir geposteten Quaternions beschreiben eine 90°-Roation um die x-Achse. Beachte die Exponenten-Schreibweise, d.h. 2.6222597E-8 ist eigentlich 0 mit Rundungsfehler. Weiterhin ist 0.707 = cos(90°/2) = sin(90°/2) – das Quaternion ist also das, was in anim_prog.ogv zu sehen ist. Auch deine Matrix beschreibt die gleiche Rotation.

Okay, danke schon einmal für die Bestätigung. Dann ist die Beobachtung scheinbar doch richtig. Wenn ich programmatisch die Animation erstelle, kriege ich über den Bone eine 90° Drehung rein. Lade ich zusätzlich die Rotation von der Animation gibt es die nächsten 90° hinzu, so dass ein Fehler von 180° entsteht.

Phobeus hat geschrieben:
Ich habe den Link noch einmal editiert.
Nope. Ist aber nicht so schlimm, da ich selbst keinen Collada-Loader habe. Aber vielleicht ja jemand anderes. :)[/quote]
Damit verlagert sich der Fokus der Suche tatsächlich recht stark auf den Blender Exporter. Irgend jemand Erfahrungen mit diesem und kann vielleicht erklären, wie das da genau zu stande kommt? Scheinbar wollte man da irgendwie die Achsen von Blender wieder auf default bringen. Wenn jemand einen Sanity-Check mit dem von mir geposteten DAE machen könnte, wäre das wirklich super.

_________________
"Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jun 08, 2017 20:58 
Offline
Fels i.d. Brandung
Benutzeravatar

Registriert: Sa Mai 04, 2002 19:48
Beiträge: 3827
Wohnort: Tespe (nahe Hamburg)
Okay, ich sitze weiterhin am System und während es manchmal schon Ergebnisse gibt, die nicht so ganz schrecklich aussehen (alles auf der gleichen Achse und so), gibt es leider immer noch ein paar Probleme, die mich verzweifeln lassen. Ich bräuchte da also vielleicht nochmal die Hilfe von den Matrizen-Magiern... Danke vorab, ich bin tief in Eurer Schuld.

Und zwar haben wir hier ein Quader mit einem Bone aufwärts der Z-Achse im Ursprung, dass um 90° um die Z-Achse gedreht wird. Die folgenden Werte erhalte ich vom Assimp direkt beim Auslesen, also ohne das ich dort irgendwie auch nur mit meinem Kram in die Nähe komme. Im Blender wird für den ersten Keyframe die Rotation mit x,y,z=0,w=1.0 und beim zweiten mit x,z=0,y,w=0.707.

Beim Einlesen der Werte des AIQuaternions von Assimp ergibt sich folgendes. mRot ist die Rotation direkt als AIQuaternion. Qmat ist das Quaternion als Matrix ausgegeben. fRot ist mein interner Quaternion:

Code:
  1.  
  2. //Keyframe 1
  3. mRot #AIQuaternion [x=0.70710677,y=0.0,z=0.0,w=0.70710677]
  4. QMat:[
  5. m00=1,00000, m01= 0,00000, m02=0,00000, m03=0,00000
  6. m10=0,00000, m11= 0,00000, m12=1,00000, m13=0,00000
  7. m20=0,00000, m21=-1,00000, m22=0,00000, m23=0,00000
  8. m30=0,00000, m31= 0,00000, m32=0,00000, m33=1,00000]
  9. fRot:(0,70710677  0  0  0,70710677 )
  10. //Keyframe 2
  11. mRot #AIQuaternion [x=0.5,y=0.50000006,z=0.5,w=0.5]
  12. QMat:[
  13. m00=-0,00000, m01=1,00000, m02=-0,00000, m03=0,00000
  14. m10= 0,00000, m11=0,00000, m12= 1,00000, m13=0,00000
  15. m20= 1,00000, m21=0,00000, m22=-0,00000, m23=0,00000
  16. m30= 0,00000, m31=0,00000, m32= 0,00000, m33=1,00000]
  17. fRot:(0,5  0,50000006  0,5  0,5 )


Das ist natürlich recht wirr und entspricht damit überhaupt nicht dem Erwartungswerten. Schaue ich mir nun allerdings die Matrix des einzigen Bones an, so ergibt sich:
Code:
  1. BoneMatrix: Bone
  2. 1  0  0  0
  3. 0  0  -1  0
  4. 0  1  0  0
  5. 0  0  0  1


Folgende Fragen habe ich bzw. stellen sich mir:
1. Wenn die Quaternions aus der Animation nicht die Rotation angeben, sondern die Matrizen des Bones, so hätte ich erwartet, dass der Bone und die Matrix des Quaternion exakt gleich sind, da ja erwartet wird, dass es keine Rotation gibt. Diese Unterscheiden sich allerdings minimal. Erkennt jemand, wie diese Abweichung zu Stande kommt (das scheint nicht invers oder row/column vertauscht zu sein). Irgendwelche Ideen?
2. Die Rotation ist 90° um die Z-Achse. Erkennt jemand die in den Quaternions?
3. Ich habe mir mal folgende Seite angesehen und die Quaternions rausgesucht, die meinen irgendwie nahe kommen: http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/steps/index.htm (4 Reihe, ersten beiden). Das scheint -90° auf der X-Achse verdreht zu sein, allerdings wäre meine Erwartung, dass beim zweiten das z ist und nicht -z. Jemand dafür eine Erklärung?
4. Ich brauche dringend mal jemanden für eine Rücksprache, der bereits Animationen mit Assimp gemacht hat und ggf. ein paar Fragen bzgl. der Daten, die ich erhalte geben kann. Viele Quellen sind wirklich unzureichend um rauszufinden, was genau durch die Werte repräsentiert wird und ob dies absolut oder relativ ist und ob diese jeweils vom Ursprung sind. Nur keine Scheu, jeder der da Erfahrung hat, kann wirklich helfen!
5. Gleiches gilt auch für Modeller unter Euch oder welche die einen funktionierenden Loader haben. Ein simples Beispiel oder das Validieren eines meiner Modelle, könnte dabei helfen zu bestimmen, ob etwas beim Blender export schief läuft oder ich Werte falsche interpretiere.

Freue mich wirklich über jede Hilfe, da ich bereits seit einigen Wochen feststecken und mich irgendwie im Kreis drehe. Ihr erfreut gleich 2 Seelen, wenn wir das irgendwie weiter zum Laufen kriegen. In diesem Sinne vielen Dank vorab!

_________________
"Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Jun 09, 2017 18:48 
Offline
DGL Member

Registriert: Fr Mai 11, 2012 13:25
Beiträge: 229
Programmiersprache: c++, c, JavaScript
Kennst Du schon das Tutorial?
http://ogldev.atspace.co.uk/www/tutoria ... ial38.html
Das könnte helfen.

Phobeus hat geschrieben:
Ich brauche dringend mal jemanden für eine Rücksprache, der bereits Animationen mit Assimp gemacht hat und ggf. ein paar Fragen bzgl. der Daten, die ich erhalte geben kann.


Mein Kollege hat kürzlich erfolgreich per Assimp nen funktionierenden Animations-Loader gebaut.
Wenns wirklich nicht besser wird, melde Dich per PM, dann kann ich ihn evtl. vermittlen.

_________________
"Pixel, ich bin dein Vater."
-Darf Shader


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Jun 09, 2017 19:59 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Ich nutze ASSIMP für Collada mit Animationen für eines meiner Vulkan Demos (Skeletal Animation). Wenn ich mich recht erinnere hat das mit dem Export der Animationen aus Blender nach Collada aber damals auch nie richtig funktioniert. d.h. wenn ich das Model in Blender importiert hab und dann wieder als Collada gespeichert hab hat das in meiner Demo nicht mehr gepasst. Mit einem Collada-Exporter für 3DS MAX hats dann gepasst. Kann also sein dass der Exporter in Blender einfach fehlerhaft ist. Das mit 3DS MAX als Collada gespeicherte Model findest du unter https://github.com/SaschaWillems/Vulkan ... goblin.dae, den passenden (C++) Code unter https://github.com/SaschaWillems/Vulkan ... lanimation.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 14 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.045s | 17 Queries | GZIP : On ]