[MonoGame] Trackball Rotation mit Maus

  • C#
  • .NET (FX) 4.5–4.8

    [MonoGame] Trackball Rotation mit Maus

    Hi,
    ich versuche gerade eine Steuerung mit der Maus wie in Blender zu realisieren. Also Rotate, Pan und Zoom. Es scheitert aber schon am Rotieren. Im Netz gibt's auch tausend und ein Beispiel für einen Trackball (bin ich anscheinend zu doof für). Ich hab mir gedacht ich mach's über spherische Koordinaten, dann könnte man Zoom direkt über Radius machen und Rotation ist (zumindest gedanklich) leicht.

    Spoiler anzeigen

    C#-Quellcode

    1. public class Camera
    2. {
    3. public Matrix View { get; private set; }
    4. public Vector3 Target { get; set; }
    5. public Vector3 Up { get; set; } = Vector3.Up;
    6. float phi = 0;
    7. float theta = 0.01f;
    8. float radius = 5;
    9. bool thetaDirection = false;
    10. public Camera()
    11. {
    12. UpdateView();
    13. }
    14. private void AddPhi(float value)
    15. {
    16. phi += value;
    17. if (phi > MathHelper.TwoPi)
    18. phi -= MathHelper.TwoPi;
    19. else if (phi < 0)
    20. phi += MathHelper.TwoPi;
    21. }
    22. private void AddTheta(float value)
    23. {
    24. if (thetaDirection)
    25. value = -value; // Richtungswechsel
    26. theta += value;
    27. if (theta > MathHelper.Pi)
    28. {
    29. Debug.Print("Turn");
    30. AddPhi(MathHelper.Pi); // Um 180° drehen
    31. theta = MathHelper.TwoPi - theta;
    32. thetaDirection = !thetaDirection;
    33. }
    34. else if (theta < 0)
    35. {
    36. Debug.Print("Turn");
    37. AddPhi(MathHelper.Pi);
    38. theta = -theta;
    39. thetaDirection = !thetaDirection;
    40. }
    41. }
    42. public void Rotate(float phi, float theta)
    43. {
    44. AddPhi(phi);
    45. AddTheta(theta);
    46. UpdateView();
    47. }
    48. public void UpdateView()
    49. {
    50. float x = (float)(radius * Math.Sin(theta) * Math.Sin(phi));
    51. float y = (float)(radius * Math.Cos(theta));
    52. float z = (float)(radius * Math.Sin(theta) * Math.Cos(phi));
    53. View = Matrix.CreateLookAt(new Vector3(x, y, z), Target, Up);
    54. }
    55. }


    Jetzt hab ich zwei Probleme: Wenn sich Theta ändert, dann ändert sich auch die Drehrichtung von Phi. Und Theta verhält sich beim drehen seltsam. Wenn es sich Pi nähert, dann kippt's irgendwie weg.

    Über EulerAngle wäre es natürlich einfacher, aber wenn man RotationX*RotationY rechnet, dann ist die Rotation in die eine Richtung immer abhängig von der Anderen. Lange Rede kurzer Sinn: Wie kann ich eine Kamera zu den absoluten X und Y Achsen drehen?

    Grüße