I have spent three weeks struggling with the quaternion camera!
Now I have two Implementations. One has some kind of gimbal lock issue or something like that. Another one is totally anti-human ( I feel like I am using a ZBrush camera to play a game).
the faulty one:
the zbrush and anti-human one:
key codes of that two cameras:
the faulty one:
void MouseInput(GLfloat xOffset, GLfloat yOffset, bool constrainPitch = 0) {
xOffset *= turnSpeed;
yOffset *= turnSpeed;
if (glm::abs(glm::fmod(pitch, 360.0f)) < 90.0f || glm::abs(glm::fmod(pitch, 360.0f)) > 270.0f)
yaw += xOffset;
else
yaw -= xOffset;
pitch += yOffset;
if (constrainPitch)
{
...
}
}
void Update() {
glm::quat qPitch = glm::angleAxis(glm::radians(-pitch), glm::vec3(1.0f, 0, 0));
glm::quat qYaw = glm::angleAxis(glm::radians(-yaw), glm::vec3(0, 1.0f, 0));
glm::quat qRoll = glm::angleAxis(glm::radians(roll), glm::vec3(0, 0, -1.0f));
orientation = glm::normalize(qYaw * qPitch * qRoll);
front = glm::normalize(orientation * glm::vec3(0, 0, -1.0f));
up = glm::normalize(orientation * glm::vec3(0, 1.0f, 0));
right = glm::normalize(orientation * glm::vec3(1.0f, 0, 0));
fps = ViewMatrix();
tps = ViewMatrixOrbital();
}
the zbrush and anti-human one:
void MouseInput(GLfloat xOffset, GLfloat yOffset) {
xOffset *= turnSpeed;
yOffset *= turnSpeed;
yaw = xOffset;
pitch = yOffset;
}
void Update() {
glm::quat qYaw = glm::angleAxis(glm::radians(-yaw), up);
glm::quat qPitch = glm::angleAxis(glm::radians(-pitch), right);
glm::quat qRoll = glm::angleAxis(glm::radians(roll), front);
orientation = glm::normalize(qRoll * qPitch * qYaw * orientation);
front = glm::normalize(orientation * glm::vec3(0, 0, -1.0f));
up = glm::normalize(orientation * glm::vec3(0, 1.0f, 0));
right = glm::normalize(orientation * glm::vec3(1.0f, 0, 0));
fps = ViewMatrix();
tps = ViewMatrixOrbital();
//Clear Everything
yaw = 0;
pitch = 0;
roll = 0;
}
The view matrix functions of both of them are the same:
glm::mat4 ViewMatrix() {
glm::mat4 translate = glm::translate(glm::mat4(1.0f), position);
glm::mat4 rotate = glm::mat4_cast(orientation);
return glm::inverse(translate * rotate);
}
glm::mat4 ViewMatrixOrbital() {
glm::mat4 translate = glm::translate(glm::mat4(1.0f), localPosition);
glm::mat4 aroundOnePoint = glm::translate(glm::mat4(1.0f), aroundPoint);
glm::mat4 rotate = glm::mat4_cast(orientation);
return glm::inverse(aroundOnePoint * rotate * translate);
}
The first one is messed up when I look directly from up to down or down to up.
The second one, I can never go back to the same position when I just drag/draw a circle with my mouse...
I really need some help to make a human-friendly, "robust", and elegantly quaternion camera(some things like the camera in the Ace Combat or EVERSPACE)...
The resources I have used:
https://stackoverflow.com/questions/49609654/quaternion-based-first-person-view-camera
http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/
https://www.3dgep.com/understanding-the-view-matrix/
and of course...
https://www.youtube.com/watch?v=d4EgbgTm0Bg&ab_channel=3Blue1Brown
Sorry for my English...
I want something like a jet or plane flying upside down or a spaceship that can rotate to any direction.
I hope the camera can be human-friendly/intuitively( only "roll" when I want to "roll", my "zbrush camera" rolling all the time...).
– potter john Sep 14 '22 at 08:28...And any tips about how to "remove" those kinds of rolls? google keyword? links resource? some pages of some books? someone's GitHub?
– potter john Sep 14 '22 at 08:59