Kamera rotieren [C&P Edit!]

  • C#

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Eistee.

    Kamera rotieren [C&P Edit!]

    Hallom,

    bin gerade dabei meiner erste 3D Kamera zu bewegen, nur durch Try und Error bekomme ich es nicht hin.
    Links, Rechts, Vor, Zurück, Rauf und Runter ist ja Kinderkram, nur beim Rotieren haperts eben.
    Zuerst wollte ich das ganze selbst berechnen, was mit meinem Mathekenntnissen von vorne herein zum Scheitern verurteilt war.
    Also der 2. versuch über die Matrix Klasse und deren Methoden:

    C#-Quellcode

    1. Matrix rotationMatrix = Matrix.RotationX(0.001F);
    2. Vector3 transformedReference = Vector3.TransformCoordinate(lookAtPosition, rotationMatrix);
    3. lookAtPosition = transformedReference;
    4. basicEffect.View = Matrix.LookAtLH(cameraPosition, lookAtPosition, cameraUpVector);
    5. basicEffect.Techniques[0].Passes[0].Apply();


    Nur durch probieren komme ich einfach auf keinen grünen Zweig, daher wollt ich hier mal nachfragen.
    Wenn ich den Code wie oben anwende (wiederholter Aufruf durch KeyDown), eiert mein Würfel nur nach oben und unten ?(
    Bestimmt habe ich die Methoden bzw. Punkte in den Vetoren wieder völlig falsch verstanden, weswegen der Würfel nur rum eiert.

    Quellen:
    Vector3
    Vector3.TransformCoordinate
    Matrix.RotationX
    Matrix.LookAtLH

    Edit: Oh man, im jetzt bin ich im Off-Topic gelandet :wacko:

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „FlashTek“ ()

    Eine Rotationsmatrix rotiert immer um den Koordinatenursprung. Wenn du um den Würfelmittelpunkt rotieren willst, dann musst du diesen in den Ursprung verschieben. Nach dem Rotieren kannst du ihn dann wieder zurückschieben.
    Du kannst dir ja mal bei [OpenSource] MathUtils 2.4.2 - erweiterte Mathematikbibliothek ansehen, wie ich den Würfel im Testprojekt rotieren lasse (Vorsicht, die Matrizen in MathUtils funktionieren etwas anders, als die von Direct3D).
    Dann stell dir das mal so vor, dass du lookAt immer als Richtungsvektor von der Kamera Position aus siehst. Dann kannst du einen Vektor mit Matrix.TransformCoordinate(so kenns ich) um die Rotationsmatrix rotieren. Das einfachste ist dabei, wenn du einen Standard Blickrichtungsvektor hast(z.B. 0,1,0) und dann immer die Rotation speicherst und aufaddierst un dann immer um diese per Rotationsmatrix rotierst...
    @Artentus: Kommt auf den Anwendungszweck an.
    Performance technisch egal, da die so oder so miteinander multipliziert werden ;)
    Edit: oder manchmal mit View besser, da du sonst(jenachdem) auf CPU rechnen musst, was man auf GPU auslagern kann. Aber trotzdem immernoch jenachdem^^
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Ich find die Kamera deshalb einfacher, weil du dann die Welt immernoch unabhängig rotieren kannst, ohne dass man sich die Logik dahinter selbst machen muss :D
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    Artentus schrieb:

    Ich finds nur einfacher, die Welt zu rotieren, als die Kamera.

    jvbsl schrieb:

    Ich find die Kamera deshalb einfacher

    Ich bekomme gerade keins von beiden hin :S

    Das von jvbsl erwähnte "Matrix.TransformCoordinate" gibt es unter SharpDX nicht, oder könnte es Matrix.Transformation sein,
    bzw. es damit auch berechnen wenn man die anderen Werte nicht ändert/übernimmt?

    Musste deswegen erstmal ergoogeln was mit Quaternion gemeint ist
    (If a quaternion represents a rotation then w = cos(theta / 2), where theta is the rotation angle around the axis of the quaternion.).
    sharpdx.org/documentation/api/…or3-transformcoordinate-2
    Dachte wäre bei Matrix gewesen, hab mich da wohl vertan(bei meiner eigenen Klasse ists zumind. so :D)
    TransformCoordinate kenn ich den Unterschied zu Transform(aber nicht dein Transformation), dass eben w ignoriert wird, da man den nachher nicht braucht ;) Also man bekommt nen Vector3 statt Vector4 zurück
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Ich bin es jetzt x-mal durchgegangen, habe mir auch alle Werte auf den Bildschirm zeichnen lassen...
    Nur will es einfach nicht rotieren, mit den Werten auf dem Schirm komm ich leider auch nicht weiter, in der Hoffung
    dass ihr den Fehler findet hier mal der neue Code:

    C#-Quellcode

    1. -gelöscht-


    Ich muss nochmal (nochmal) von neu anfangen.
    Wenn lookAtOriginalPosition = new Vector3(0, 0, 0); ist.
    Und cameraRotation = Matrix.RotationX(0.2) * Matrix.RotationY(0.0); eine Rotation darstellt (X (0.2)
    Sowie cameraRotatedTarget = Vector3.TransformCoordinate(lookAtOriginalPosition, cameraRotation); was den Vector durch die Matrix teilt das W=1 ist?
    Ist der neue Richtungsvector lookAtPosition = cameraPosition + cameraRotatedTarget;.
    Das gleiche mit dem UpVector cameraUpVector = Vector3.TransformCoordinate(cameraOriginalUpVector, cameraRotation);
    und Updaten basicEffect.View = Matrix.LookAtLH(cameraPosition, lookAtPosition, cameraUpVector);

    Naja das Ergebnis ist mal wieder nicht zu gebrauchen.
    Der UpVector der LeftHanded-LookAt Matrix ist immer = -5 und die Rotation bleibt aus.
    Hättet ihr nochmal einen Tipp? Denn ich glaub auch nach einer halben ewigkeit wär ich nicht viel weiter :S
    So nach einigen weiteren rumprobieren, wurde ich Wahnsinnig und musste dann to go on vacation.

    Wieder zurück dacht ich mir, ich versuche es mal mit Copy&Paste.
    Gesagt getan:

    C#-Quellcode

    1. class Camera{
    2. public float speed { get; set; }
    3. Vector3 _position;
    4. Vector3 _target;
    5. Vector3 _upVector;
    6. BasicEffect _BasicEffectReference;
    7. public Camera(Vector3 position, Vector3 target, Vector3 upVector, float initialSpeed){
    8. _position = position;
    9. _target = target;
    10. _upVector = upVector;
    11. speed = initialSpeed;
    12. }
    13. public void Initialize(ref BasicEffect BasicEffectReference){
    14. _BasicEffectReference = BasicEffectReference;
    15. }
    16. public void Update(){
    17. _BasicEffectReference.View = Matrix.LookAtLH(_position, _target, _upVector);
    18. _BasicEffectReference.Techniques[0].Passes[0].Apply();
    19. }
    20. // Move Sideways --- FUNKTIONIERT NICHT RICHTIG ---
    21. public void move_DriftToLeft(){
    22. _position += Vector3.Cross(_upVector, _target) * speed;
    23. Update();
    24. }
    25. public void move_DriftToRight(){
    26. _position -= Vector3.Cross(_upVector, _target) * speed;
    27. Update();
    28. }
    29. // Move Forwards & Backwards --- FUNKTIONIERT NICHT RICHTIG ---
    30. public void move_Forward(){
    31. _position += _target;
    32. Update();
    33. }
    34. public void move_Backward(){
    35. _position -= _target;
    36. Update();
    37. }
    38. // Move Up & Down --- FUNKTIONIERT ---
    39. public void move_Up(){
    40. _position += new Vector3(0, 0.3F, 0);
    41. _target += new Vector3(0, 0.3F, 0);
    42. Update();
    43. }
    44. public void move_Down(){
    45. _position -= new Vector3(0, 0.3F, 0);
    46. _target -= new Vector3(0, 0.3F, 0);
    47. Update();
    48. }
    49. // Yaw Rotate - Gieren --- FUNKTIONIERT (in dieser Form nicht) ---
    50. public void rotate_Yaw(Single mouseDeltaX){
    51. _target = Vector3.TransformCoordinate(_target,
    52. Matrix.RotationAxis(_upVector, (-MathUtil.PiOverFour / 150) * mouseDeltaX));
    53. Update();
    54. }
    55. // Roll Rotate - Rollen --- FUNKTIONIERT ---
    56. public void rotate_RollLeft(){
    57. _upVector = Vector3.TransformCoordinate(_upVector,
    58. Matrix.RotationAxis(_target, MathUtil.PiOverFour / 45));
    59. Update();
    60. }
    61. public void rotate_RollRight(){
    62. _upVector = Vector3.TransformCoordinate(_upVector,
    63. Matrix.RotationAxis(_target, -MathUtil.PiOverFour / 45));
    64. Update();
    65. }
    66. // Pitch Rotation - Kippen --- FUNKTIONIERT ---
    67. public void rotate_PitchFront(Single mouseDeltaY){
    68. _target = Vector3.TransformCoordinate(_target,
    69. Matrix.RotationAxis(Vector3.Cross(_upVector, _target),
    70. (MathUtil.PiOverFour / 100) * mouseDeltaY));
    71. Update();
    72. }
    73. public void rotate_PitchBack(Single mouseDeltaY){
    74. _upVector = Vector3.TransformCoordinate(_upVector,
    75. Matrix.RotationAxis(Vector3.Cross(_upVector, _target),
    76. (MathUtil.PiOverFour / 100) * mouseDeltaY));
    77. Update();
    78. }
    79. }


    Erstellt mit hilfe von hier: (Quelle) www-rohan.sdsu.edu/~stewart/cs…ateFirstPersonCamera.html
    Nur noch nicht einmal das funktioniert richtig 8|

    Die Kamera macht allerhand ferrückte bewegungen, zieht seine Kreise und Achtern.
    Macht aber nicht immer was sie Soll:

    Rauf Runter funktioniert
    Yaw Rotate - Gieren funktioniert (auch wenn Links und Rechts noch vertauscht sind).
    Roll Rotate - Rollen funktioniert

    Move Sideways ist toal verückt, dreht alles seitlich bis es im anderen Wertebereich ist (von + zu - oder umgekehrt) und dreht dann alles um (gespiegelt).
    Move Forwards & Backwards macht die gleichen bewegungen wie Sideways nur auf einer anderen Achse.

    Dabei dachte ich diese wären die einfachsten.. denn für mich scheint es plausiebel wie auf der Seite beschrieben:
    "Positions-Vector += Ziel * (Geschwindigkeit)" Ist gleich, eine Bewegung in die Richtung in welche man schaut.
    Und warum das mit dem Kreuzprodukt nicht funktioniert wie beschrieben, ist mir auch ein Rätzel ?(

    Wär Nett wenn Jemand der mehr Verständniss und Ahnung von Vectoren hat sich die beiden funktionen mal anschauen könnte.
    Vielen dank und Gruß Eistee ❄ gekühlt ❄ :P

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Eistee“ ()

    ich werde mir den C&P Code nicht angucken, stattdessen sag ich dir, was aufjedenfall falsch ist :D
    du rotierst die LookAt Position, statt um den LookAt-Richtungsvektor und der darf ja nicht 0,0,0 sein. Dann funktioniert zumindest vlt. schon das rotieren :D
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Also LookAt-Richtungsvektor = LookAt Position - Position?
    Ich werd es mal probieren.

    Edit: Ah ok rotieren/gieren wahr wohl doch nicht ganz korrekt (drehte nur um ~ 50° dannach wieder zurück).
    Mit (_target - _position) Also dem LookAt-Richtungsvektor dreht er sich jetzt 360° im Kreis :thumbsup:

    Vielen dank dafür, wenn jetzt noch wer den Fehler in:

    C#-Quellcode

    1. public void move_DriftToLeft(){
    2. _position += Vector3.Cross(_upVector, _target) * speed;
    3. Update();
    4. }
    5. // und
    6. public void move_Forward(){
    7. _position += _target;
    8. Update();
    9. }

    Wenn die auch noch gefunden werden, ist die Kamera Klasse halbwegs zu gebrauchen :D

    Edit2: Wobei sich die Kanera beim rotieren/gieren immer nach unten ausrichtet, also schaut direkt zum Boden runter :cursing:

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Eistee“ ()

    hab das grad wieder gefunden :D
    _position += _target;

    Dasselbe Problem, wie bereits davor. _target ist kein Richtungsvektor sondern ein Ortsvektor. Du brauchst hier aber wieder einen Richtungsvektor. Dies gilt außerdem auch für DriftToLeft...

    Dein Edit2 versteh ich jedoch nicht @Eistee:
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:

    Dein Edit2 versteh ich jedoch nicht

    Es war so, das die Kamera sich zum Boden gerichtet hat. Also wenn es denn einen Boden gäbe.
    Die Kamera befindet sich im 3D raum, hat einen Up-Vector (new Vector3(0.0f, 1.0f, 0.0f)).
    Wenn die Kamera bezogen auf den Up-Vector Geradeaus schaut, ist diese beim drehen nach unten weggekippt.
    Also nach x° rotieren/gieren schaut die Kamera nicht mehr Geradeaus, sondern nach unten.

    Habe das ganze jetzt erstmal durch einen kleinen Trick umgangen, indem ich den Abstand zum beobachteten Objekt verringert habe, so kann ich kinderleicht um das Objekt rotieren ohne mir weiter den Kopf zu zerbrechen.
    Natürlich soll das nicht so bleiben aber im Moment hab ich nicht wirklich die Zeit das zu korrigieren.

    Muss bis (theoretisch) spätestens Montag wissen wie man Extremwertaufgaben löst und bei meinem Matheverständnis ist das alles andere als leicht :S