OpenGL: Gelenke



  • Hi!
    Jedes Gelenk kann ein Parentgelenk zugeordnet bekommen. Der Ellenbogen bekommt z. B. die Schulter als Parentgelenk zugeordnet. Wie kann ich nun korrekt die ganzen Gelenke transformieren?

    Zur Zeit mache ich es so(Pseudocode):

    ' Kamera
    glRotatef(-Kamera.Rotation[0], 1.0, 0.0, 0.0)
    glRotatef(-Kamera.Rotation[1], 0.0, 1.0, 0.0)
    glRotatef(-Kamera.Rotation[2], 0.0, 0.0, 1.0)
    glTranslatef(-Kamera.Position[0], -Kamera.Position[1], -Kamera.Position[2])
    
    ' Gelenke
    For Gelenk = EachIn GelenkListe
     glPushMatrix()
      ParentGelenk = Gelenk.Parent
      While ParentGelenk <> Null
       glTranslatef(ParentGelenk.Position[0], ParentGelenk.Position[1], ParentGelenk.Position[2])
       glRotatef(ParentGelenk.Rotation[0], 1.0, 0.0, 0.0)
       glRotatef(ParentGelenk.Rotation[1], 0.0, 1.0, 0.0)
       glRotatef(ParentGelenk.Rotation[2], 0.0, 0.0, 1.0)
       ParentGelenk = ParentGelenk.Parent
      Wend
    
      glTranslatef(Gelenk.Position[0], Self.Position[1], Self.Position[2])
      glRotatef(Gelenk.Rotation[0], 1.0, 0.0, 0.0)
      glRotatef(Gelenk.Rotation[1], 0.0, 1.0, 0.0)
      glRotatef(Gelenk.Rotation[2], 0.0, 0.0, 1.0)
      glScalef(Gelenk.Scale[0], Self.Scale[1], Self.Scale[2])
    
      Gelenk.Zeichnen()
     glPopMatrix()
    Next
    

    Das geht jedoch nur so lange gut, wenn ein ParentGelenk selber kein ParentGelenk besitzt.

    mfg olli



  • Alle Transformationsmatrizen der Parents multiplizieren.

    Bye, TGGC



  • Ich mache ja nix anderes 😉 Die Frage ist ja, in welcher Reihenfolge. A x B != B x A.
    Ich befürchte schon, das ich beim RootGelenk anfangen darf, so das mal wieder mein wunderschönes Konzept durcheinander gewürfelt wird.
    mfg olli



  • Na dann fürchte ich mal mit...

    Bye, TGGC



  • Hi Vertex

    Ich hab vor kurzen ein ähnliches Prog geschrieben, zwar in MDX, aber das tut mal nichts zur sache.
    Ich habe das jedenfalls mal so gelöst:
    Jeder Joint (=Gelenk) hatte bei mir 3 Eigenschaften, die mal für das Rotieren wichtig waren: Wie es selbst gedreht ist (SelfTurned), wie es gesamt gedreht ist (TotalTurned), plus der Abstand zum Parent (Distance).
    Wenn nun ein Gelenk gedreht wird:
    das gedrehte gelenk wird nicht verschoben, also wird nur selfTurned und TotalTurned verändert.
    SelfTurned = um wie viel es gedreht ist.
    TotalTurned = SelfTurned + Parent.TotalTurned
    Die Distanz bleibt im eigentlichen immer gleich.

    alle kindgelenke müssen aber auch verschoben werden, plus muss deren TotalTurned auch neu berechnet werden. Selfturned bleibt bei den Kindern gleich.
    um nun die Matrix zu berechnen:
    Eine Matrix transformierst du um die Distanz
    Eine weitere Matrix rotierst du um Parent.TotalTurned, also um die gesamtrotation des Parent-Gelenkes.
    Die Multiplikation funktioniert dann: TransformierteMatrix * RotierteMatrix
    die neue Position steht dann in der frisch berechneten Matrix (Elemente [3][0] bis [3][2])
    Die Rotation der Matrix muss allerdings erst gesetzt werden, und zwar einfach nur auf selfTurned.

    Ich hoffe, das jetzt nicht zu kompliziert erklärt zu haben 😉

    greetz
    chimaira





  • Chimaira: Danke für die Mühe! Bis auf die Sache mit der Distanz wird sich das auch änlich bei mir realisieren lassen.

    Vertexwahn: Super! Macht wirklich selten jemand ein Beispiel zu den ganzen Matrixkram 🙂 Naja haben sich mal wieder meine schlimmsten Befürchtungen realisiert. Ich muss rückwerts die Matrizen multiplizieren(wäre ja auch schlimm, wenn es einfach gehen würde ;)). Wäre doch mal eine Heruasforderung für ein Mathematiker ne Formel zu finden, die bei A x B x C = P aus P Q berechnen kann, wobei Q = C x B x A ist 🙂
    Ansonsten, ist das nur Zufall das wir bei fast selben Nickname die fast selbe Handschrift haben?

    mfg olli





  • LOL, ich dachte auch eben, du wärst Vertexwahn und wundere mich, warum du das wieder verlent hast.

    Bye, TGGC



  • So, wen es interessiert: http://vertex.art-fx.org/DreiDeNew.zip
    Example.exe (Komplette Sourcecode liegt bei)

    Steuerung über [1] und [2], [3] und [4], [5] und [6] sowie [ESC] zum Beenden.

    mfg olli


Anmelden zum Antworten