opengl modelview matrix erstellen
-
Hey, ich versuche gerade in OpenGL eine Kamera per hand zu bauen. Das klappt leider nur so halb. Für mein verständnis: macht es einen Unterschied ob ich eine matrix Stückchenweise um x und y drehe oder in einem ruck (also die akkumulierten drehungen auf eine identity matrix anwenden)? Wenn ich das nämlich stückchenweise mach kann ich die kamera "verdrehen", heiß so bewegen das man sie nicht mehr in ihren ursprungszustand bekomme und das scheint mir nicht richtig ^^. Bisher sieht das so aus:
class Camera { public: Camera() { position = Vector4D<float>(0.0, 0.0, 0.0); along = Vector4D<float>(1.0, 0.0, 0.0); up = Vector4D<float>(0.0, 1.0, 0.0); forward = Vector4D<float>(0.0, 0.0, -1.0); } void Yaw(float angle) { along = along * cos(angle) + forward * sin(angle); along = normalize(along); forward = cross(along, up) * -1.0; } void Pitch(float angle) { forward = forward * cos(angle) + up * sin(angle); forward = normalize(forward); up = cross(forward, along) * -1.0; } void Roll(float angle) { up = up * cos(angle) - along * sin(angle); up = normalize(up); along = cross(forward, up); } void Translate(const Vector4D<float> &offset) { } void Move(float amount) { position += forward * amount; } void Strafe(float amount) { position += along * amount; } void Fly(float amount) { position += up * amount; } matrix<> GetMatrix() { float x = dot(along, position); float y = dot(up, position); float z = dot(forward, position); float mtx[16] = { along.x, up.x, forward.x, 0, along.y, up.y, forward.y, 0, along.z, up.z, forward.z, 0, x, y, z, 1 }; return matrix<>(mtx, 16); } private: Vector4D<float> position; Vector4D<float> along; Vector4D<float> up; Vector4D<float> forward; };
(leider nicht von mir).
benutzen tu ich das dann über
glLoadMatrixf(...);
Wie gesagt klappt das eigentlich auch. Zumindest solange man nur um x oder y dreht. Sobald man aber um beide achsen dreht scheint mir das nicht mehr ganz richtig zu sein... man kann das irgendwie schlecht erklären. Vielleicht weiss/sieht ja jemand wodran das liegen könnte
-
ok, hab den fehler beseitigt, wäre nur schön zu wissen wieso das eine geht und das andere nicht. Jetzt siehts so aus:
class Camera { public: Camera() { yaw_angle = 0; pitch_angle = 0; roll_angle = 0; position = Vector4D<float>(0.0, 0.0, 0.0); along = Vector4D<float>(1.0, 0.0, 0.0); up = Vector4D<float>(0.0, 1.0, 0.0); forward = Vector4D<float>(0.0, 0.0, -1.0); } void ResetRotations() { along = Vector4D<float>(1.0, 0.0, 0.0); up = Vector4D<float>(0.0, 1.0, 0.0); forward = Vector4D<float>(0.0, 0.0, -1.0); } void CalculateRotations() { ResetRotations(); // yaw along = along * cos(yaw_angle) + forward * sin(yaw_angle); along = normalize(along); forward = cross(along, up) * -1.0; // pitch forward = forward * cos(pitch_angle) + up * sin(pitch_angle); forward = normalize(forward); up = cross(forward, along) * -1.0; // roll up = up * cos(roll_angle) - along * sin(roll_angle); up = normalize(up); along = cross(forward, up); } void Yaw(float angle) { yaw_angle += angle; CalculateRotations(); /*along = along * cos(yaw_angle) + forward * sin(yaw_angle); along = normalize(along); forward = cross(along, up) * -1.0;*/ } void Pitch(float angle) { pitch_angle += angle; CalculateRotations(); /*forward = forward * cos(pitch_angle) + up * sin(pitch_angle); forward = normalize(forward); up = cross(forward, along) * -1.0;*/ } void Roll(float angle) { roll_angle += angle; CalculateRotations(); /*up = up * cos(roll_angle) - along * sin(roll_angle); up = normalize(up); along = cross(forward, up);*/ } void Translate(const Vector4D<float> &relative) { } void Move(float amount) { position += forward * amount; } void Strafe(float amount) { position += along * amount; } void Fly(float amount) { position += up * amount; } matrix<> GetMatrix() { float x = dot(along, position); float y = dot(up, position); float z = dot(forward, position); float mtx[16] = { along.x, up.x, forward.x, 0, along.y, up.y, forward.y, 0, along.z, up.z, forward.z, 0, x, y, z, 1 }; return matrix<>(mtx, 16); } private: float yaw_angle, pitch_angle, roll_angle; Vector4D<float> position; Vector4D<float> along; Vector4D<float> up; Vector4D<float> forward; };