Frei bewegliche Kamera (DirectX)



  • Hi,

    ich habe mich mal an einer frei beweglichen Kamera versucht. Die Bewegung funktioniert soweit auch, nur das Schwenken macht noch Probleme. Hier mein (zugegeben halb ergoogelter :D) Ansatz:

    D3DXVECTOR3 vDirection, vRotAxis, vtestAxis;
      D3DXMATRIX matRotAxis, matRotZ;
    
      D3DXVec3Normalize(&vDirection, &(vLookatPt - vEyePt));
      D3DXVec3Cross(&vRotAxis, &vDirection, &vUpVec);
      D3DXVec3Normalize(&vRotAxis, &vRotAxis);
    
      D3DXMatrixRotationAxis(&matRotAxis, &vRotAxis, yPos / -360);
      D3DXMatrixRotationY(&matRotZ, xPos / 360);
    
      D3DXVec3TransformCoord(&vDirection, &vDirection, &(matRotAxis * matRotZ));
      vLookatPt = vDirection + vEyePt;
    

    Das funktioniert soweit zwar, allerdings kann ich das so genannten Gimbal lock Problem reproduzieren. Wenn ich in eine rotierende Sphäre fliege, und dann die Rotation der Kamera der Rotation der Sphäre anpasse, verliere ich die Möglichkeit nach links bzw. nach rechts zu gucken. Wenn ich das versuche, dreht sich alles nur noch. Lustigerweise kann ich, indem ich weit weg fliege und dauernd mit der Kamera wackle, dieses Problem wieder beheben.

    Nunja, Wikipedia sagt jetzt dass man das wohl durch so genannte "Quaternions" beheben kann, allerdings habe ich noch nie etwas damit gemacht.

    Helfen diese Quaternions wirklich bei diesem Problem, und wenn ja, wäre jemand so freundlich mir diesen Code mit Quaternions umzuschreiben?

    (Oder liegt das Problem total woanders und ich sehs nur nicht? Bin noch neu in der Welt der Rotation :p)



  • Hat denn niemand hier eine Idee? Es werden doch schon viele eine simple freie Kamera implementiert haben..
    Um das Problem zu veranschaulichen habe ich mal ein YouTube Video dazu gemacht:
    http://www.youtube.com/watch?v=hLVobcNbmTI



  • Ich würd einfach Kugelkoordinaten nehmen um meinen Lookat Vektor auszurechnen. Gimbal Lock ist ein Problem von Eulerwinkeln, ob du dann Quaternionen oder Matrizen verwendest macht keinen Unterschied.



  • dot schrieb:

    Ich würd einfach Kugelkoordinaten nehmen um meinen Lookat Vektor auszurechnen.

    Du solltest bedenken, dass ich hier noch Anfänger bin. Verbesserter Code, eigener Code, Befehlsnamen oder aber MSDN-Links helfen da meistens 😉





  • dot schrieb:

    http://de.wikipedia.org/wiki/Kugelkoordinaten 😉

    Jaa mein Gott darauf bin ich auch schon gekommen^^. Ich habe aber keine Ahnung wie ich das umsetzen soll, dazu bräuchte ich irgendwie mal Denkanstöße :p





  • Scorcher24 schrieb:

    http://www.two-kings.de/tutorials/basics/basics01.html

    Da ist tatsächlich noch etwas zwischengeschoben, aber das hilft ehrlichgesagt nicht. Da steht zwar dass es gegen den Gimbal lock helfen soll, das ist aber nicht der Fall - ich kann das Problem immer noch reproduzieren..



  • Ok, Problem sollte (hoffentlich) gelöst sein. Im Gegensatz zu dem "Two-Kings-Verfahren" sollte man um den transformieten Up Vector rotieren. Falls es jemanden interessiert, das sieht dann so aus:

    D3DXVECTOR3 vDirection, vRotAxis;
    D3DXMATRIX matRotAxis, matRotUp;
    
    D3DXVec3Normalize(&vDirection, &(vLookatPt - vEyePt));
    D3DXVec3Cross(&vRotAxis, &vDirection, &vUpVec);
    D3DXVec3Normalize(&vRotAxis, &vRotAxis);
    
    D3DXMatrixRotationAxis(&matRotAxis, &vRotAxis, yPos / -360);
    D3DXMatrixRotationAxis(&matRotUp, &vUpVec, xPos / 360);
    
    D3DXVec3TransformCoord(&vDirection, &vDirection, &(matRotAxis * matRotUp));
    D3DXVec3TransformCoord(&vUpVec, &vUpVec, &(matRotAxis * matRotUp));
    vLookatPt = vDirection + vEyePt;
    

Anmelden zum Antworten