PDA

View Full Version : [Frage] Camera Rotation mit Quaternion


Sensei
13-10-2007, 18:16
>> GELÖST!
Ich hatte vergessen view und side Vektor in rotate() zu normalisieren. Wirklich blöder kleiner Fehler, jetzt klappt alles! Wie so oft nur ein Stündchen nachdem man sich an Hilfe gewandt hat findet man den Fehler selber... ;-) danke trotzdem fürs Durchschaun!


Hallo!

Ich versuche meine Camera Drehungen (yaw, pitch, roll) mit Hilfe von Quaternions zu realisieren. Prinzipiell scheint es zu klappen, allerdings sind die pitch und roll Bewegungen "sprunghaft". yaw scheint so zu funktionieren wie es soll.
Hab da jetzt schon ewig Fehler gesucht, aber wenn sich hier irgendwer damit besser auskennt wär's toll wenn ihr mal kurz diese Code-Snippets scannen würdet und mir eventuelle Fehler sagen könntet. Für Verbesserungsvorschläge bin ich natürlich auch offen.

Im Moment update ich die Rotation einfach in meiner paint() Funktion:

_cam->rotate(0.0, 0.0, 0.1);Die rotate Funktion selbst sieht so aus:

void TCamera::rotate(float pitch, float roll, float yaw)
{
TVector* view = new TVector(_pos, _ref);
TVector* side = TVector::cross(view, _up);

view->normalize(); // EDITED
side->normalize(); // EDITED

TQuat* yawPitchRoll = TQuat::createFromYawPitchRoll(_up, view, side, pitch, roll, yaw);

yawPitchRoll->print();

TQuat* t1 = TQuat::product3(yawPitchRoll, new TQuat (0.0, view));
TQuat* t2 = TQuat::product3(t1,yawPitchRoll->getInverse());

_ref = TVector::add(_pos, t2->getVector());

TQuat* t3 = TQuat::product3(yawPitchRoll, new TQuat (0.0, _up));
TQuat* t4 = TQuat::product3(t3,yawPitchRoll->getInverse());

_up = t4->getVector();

side = TVector::cross(new TVector(_pos, _ref), _up);
side->normalize();

_up = TVector::cross(side, new TVector(_pos, _ref));
_up->normalize();
}In der Quaternion Klasse habe ich folgende beiden Funktionen:

TQuat* TQuat::createFromAxisAngle(TVector* axis, float angle)
{
TQuat* q = new TQuat(cos(((angle/2)*PI)/180), axis->getX()*sin(((angle/2)*PI)/180),
axis->getY()*sin(((angle/2)*PI)/180), axis->getZ()*sin(((angle/2)*PI)/180));
return q;
}


TQuat* TQuat::createFromYawPitchRoll(TVector* up, TVector* view, TVector* side, float pitch, float roll, float yaw)
{
TQuat* qyaw = TQuat::createFromAxisAngle(up, yaw);
qyaw->normalize();
TQuat* qtilt = TQuat::createFromAxisAngle(side, pitch);
qtilt->normalize();
TQuat* qroll = TQuat::createFromAxisAngle(view, roll);
qroll->normalize();

TQuat* t1 = TQuat::product3(TQuat::product3(qyaw, qtilt), qroll);
return t1;
}Ich denke das Quaternion produkt usw. müsste passen, weil es ja bei yaw hinzuhauen scheint. Aber diese anderen Drehungen machen mich noch sehr unglücklich... das ist selbst dann abgehackt und mit riesen Sprüngen, wenn ich nur 0.05 Grad übergebe!

Und noch eine kleine Frage: Ich würde rotate() prinzipiell ja gerne die Winkel übergeben, um die die Cam aus der Startposition verdreht weren soll. Das haut aber nicht hin. Dazu hatte ich testweise oben in rotate() die _pos, _ref und _up Vektoren wieder auf ihre Stertwerte gesetzt, und rotate() eben immer größere Werte übergeben (1.0, 2.0,...) und gedacht, so bekomme ich eine Drehung hin. das Ding dreht sich aber kein Stück! :shinner: Warum?

Danke, hoffe irgendjemand kennt sich da aus und kann helfen, Tobias