[OpenGL] Kamera um Objekt herum drehen



  • Irgendwie komm ich nicht drauf...

    Ich habe es mal so versucht, dass ich den Punkt nochmal für ein kleines bischen größeres Theta berechnet habe und den differenzvektor als up-vektor genommen habe, aber es kommt immer noch schwachsinn raus 😞

    void CubeWidget::AdjustCamera()
    {
    	glLoadIdentity();
    	//fix aspect ratio
    	glScalef(1.f, float(width()) / height(), 1.f);
    	gluPerspective(45, 1, 0.01, maxRadius);
    
    	float x = radius * sin(theta) * cos(phi);
    	float y = radius * sin(theta) * sin(phi);
    	float z = radius * cos(theta);
    
    	float dtheta = 0.05f;
    	float x2 = radius * sin(theta+dtheta) * cos(phi);
    	float y2 = radius * cos(theta+dtheta) * sin(phi);
    	float z2 = radius * sin(theta+dtheta);
    	float upX = x2 - x;
    	float upY = y2 - y;
    	float upZ = z2 - z;
    
    	gluLookAt(x,y,z,0,0,0,upX, upY, upZ);
    }
    


  • Fangen wir mal ganz wo anders an: Ist dir eigentlich klar, wofür der Up-Vektor genau steht?



  • Er zeigt von der mitte der "Kamera" aus nach oben?



  • Genau, und damit legt er die Drehung der Kamera um die Blickrichtung fest. Damit sollte eigentlich klar sein, in welche Richtung der Vektor genau zeigen muss.



  • Bildlich kann ichs mir vorstellen:
    http://upload.wikimedia.org/wikipedia/commons/8/82/Sphericalcoordinates.svg
    Auf diesem Bild müsste er vom roten punkt senkrecht zu r in Richtung des Winkelbogens von theta gehen.
    Ich komme nur gerade nicht darauf, wie ich diese Richtung ausrechnen kann.



  • Q schrieb:

    Auf diesem Bild müsste er vom roten punkt senkrecht zu r in Richtung des Winkelbogens von theta gehen.

    exakt

    Q schrieb:

    Ich komme nur gerade nicht darauf, wie ich diese Richtung ausrechnen kann.

    Kleiner Tipp: Überleg mal was passiert, wenn du Theta um 90° weiterdrehst 😉



  • Blöd das ich da nicht drauf gekommen bin, hab heute irgendwie nen Brett vorm Kopf 😃

    Habe jetzt folgendes gemacht:

    void CubeWidget::AdjustCamera()
    {
    	glLoadIdentity();
    	//fix aspect ratio
    	glScalef(1.f, float(width()) / height(), 1.f);
    	gluPerspective(45, 1, 0.01, maxRadius);
    
    	float x = radius * sin(theta) * cos(phi);
    	float y = radius * sin(theta) * sin(phi);
    	float z = radius * cos(theta);
    
    	float dtheta = pi / 2.f;
    	float upX = radius * sin(theta + dtheta) * cos(phi);
    	float upY = radius * cos(theta + dtheta) * sin(phi);
    	float upZ = radius * sin(theta + dtheta);
    
    	gluLookAt(x,y,z,0,0,0,upX, upY, upZ);
    	//gluLookAt(x,y,z,0,0,0,0,1,0);
    	//gluLookAt(x,y,z,0,0,0, cos(theta), sin(theta),1);
    }
    

    Aber leider funktionierts immer noch nicht.
    Hab ich das mit den 90 grad jetzt falsch eingebaut, oder ist das was anderes?



  • Schaut auf den ersten Blick so falsch nicht aus. Was genau funktioniert denn nicht? Kanns sein, dass du dein theta irgendwo künstlich begrenzt, was dann zu merkwürdigen Sprüngen führt?


  • Mod

    wenn man mit opengl arbeiten, vergisst man manchmal, dass die math lib mit rad arbeitet, also 0 bis 2*PI und nicht 0 bis 360, dann kann es kaputt aussehen weil sich alles 60mal zu schnell dreht.



  • rapso schrieb:

    wenn man mit opengl arbeiten, vergisst man manchmal, dass die math lib mit rad arbeitet, also 0 bis 2*PI und nicht 0 bis 360, dann kann es kaputt aussehen weil sich alles 60mal zu schnell dreht.

    Danke für den Tipp, aber das habe ich schon beachtet.

    Die entstehenden Drehungen sind einfach vollkommen falsch! Drehe ich nach links, dann dreht es sich erst in einem komischen Bogen etwas nach links und springt dann wieder zurück (beim zurückspringen wird alles um 180 grad oder so gedreht).
    In der anderen achse passiert etwas ähnliches.

    Ich habe im Moment keinerlei Beschränkungen an die Winkel drin.

    Ich überlege gerade, ob es nicht vielleicht doch mit glRotatef einfacher wäre.



  • Ich grab den thread jetzt nochmal aus, weil ichs immer noch nicht richtig hinbekommen hab.

    Ich habe mit gluLookAt einiges probiert, aber es hat nur probleme gemacht, deswegen habe ich es wieder auf glRotatef umgestellt, was einigermaßen funktioniert, aber noch ein paar Probleme bereitet.

    Folgendes Problem:
    Drehe ich nach starten des Programms um 180 grad nach rechts, klappt das super.

    Drehe ich nach starten des Programms aber erst um 180 "in den Bildschirm rein" und dann 180 grad nach rechts, dann dreht sich der würfel nach links statt nach rechts.

    Ich sehe dafür 2 Mögliche Ursachen:
    1.

    void CubeWidget::AdjustCamera() 
    { 
    	glLoadIdentity(); 
    	float scaleFac = 1.f/radius;
    	glScalef(scaleFac, scaleFac * float(width()) / height(), scaleFac); 
    	glRotatef(theta, 1, 0, 0);	
    	glRotatef(phi, 0, 1, 0);
    }
    

    Es wird erst um die eine Achse gedreht und dann um die andere Achse, wodurch die 2. Drehung durch die 1. beeinflusst wird.

    void CubeWidget::ChangePhi(float delta)
    {
    	phi += delta;
    	update();
    }
    
    void CubeWidget::ChangeTheta(float delta)
    {
    	theta += delta;
    	update();
    }
    

    Bei mausbewegungen/tastendrücken addiere ich einfach auf die Winkel drauf, ohne die aktuelle Kameraposition zu beachten. Wenn die Kamera "auf dem Kopf" steht müsste der Winkel sich aber anders ändern, als wenn sie normal ist (siehe Problem ganz oben).

    Ich bin mir nicht ganz sicher, ob beide Möglichkeiten relevant sind, oder ob es nur eins von beidem ist.

    Zur Lösung von 1. müsste ich irgendwie beide Drehungen zusammenfassen, so dass ich sie durch eine Drehung ersetzen kann.
    Zur Lösung von 2. müsste ich die Winkel basierend auf der aktuellen Kameralage anpassen.

    Bei beiden Problemen kann man sicher irgendwie mit den trigonometrischen Funktionen arbeiten, aber wie genau habe ich noch nicht rausgefunden. Alternativ könnten Drehmatrizen helfen, ich könnte mir z.B. vorstellen, dass ich die erste Drehung durchführe und die Drehmatrix für die zweite Drehung vor Anwendung mit der inversen der aktuellen Matrix multipliziere.
    Allerdings kompliziert die Verwendung solcher Matrizen alles etwas.

    Habt ihr ideen, wie ich das lösen kann?


Anmelden zum Antworten