I understand that both Euler and Quaternion rotation types have their own distinctive quirks, however the problem that I'm having is that (for example) when performing the following rotations to an object:
rotateX = 90.0
rotateY = 90.0
... Oh, hang on a minute... now the X and Z axis are basically the same!
See, what I want is to rotate a cube say 90 degrees X, 90 degrees Y and still have all axis points back in their original position as opposed of rotating locally.
Any code examples would be ideal - Here is the code I'm currently using:
_model = scale(_scale) *
translate(_position) *
( rotate(_rotation.data[0], 1.0f, 0.0f, 0.0f) *
rotate(_rotation.data[1], 0.0f, 1.0f, 0.0f) *
rotate(_rotation.data[2], 0.0f, 0.0f, 1.0f) );
I have a Math.h that calculates the rotations like so:
template <typename T>
static inline Tmat4<T> rotate(T angle, T x, T y, T z)
{
Tmat4<T> result;
const T x2 = x * x;
const T y2 = y * y;
const T z2 = z * z;
float rads = float(angle) * 0.0174532925f;
const float c = cosf(rads);
const float s = sinf(rads);
const float omc = 1.0f - c;
result[0] = Tvec4<T>(T(x2 * omc + c), T(y * x * omc + z * s), T(x * z * omc - y * s), T(0));
result[1] = Tvec4<T>(T(x * y * omc - z * s), T(y2 * omc + c), T(y * z * omc + x * s), T(0));
result[2] = Tvec4<T>(T(x * z * omc + y * s), T(y * z * omc - x * s), T(z2 * omc + c), T(0));
result[3] = Tvec4<T>(T(0), T(0), T(0), T(1));
return result;
}
Related
I've been working on a project for some time and Needed something that could from a Vector3 representing rotation in the XYZ axis make Forward, Right and Up vectors. I was looking through a lot of stuff and after some time I figured out I had to implement Quaternions (I have my own Math Libary but this same thing happened with glm) and Here is the code for calculating the Forward Vector: (quaternion is the rotation Quaternion member in my class and Quaternion::Euler is a static function that returns a Quaternion from Euler Angles)
quaternion = Quaternion::Euler(rotation);
Vector3 ret = quaternion * Vector3(0.0f, 0.0f, 1.0f);
when the rotation is 0, 0, 0 the function returns 0, 0, 1 as it should, but if I try something like 0, 180, 0 it should return 0, 0, -1, but instead I get -8.74228e-08, 0, -1. After some investigation I figured out that the Quaternion::Euler function returns a Quaternion where the w part is messed up. In the case where the rotation is 0, 180, 0 the Quaternion the Quaternion::Euler function returns is 0, 1, 0, -4.37113883e-08 which is almost exactly half of the random number the Forward functions returns. Here is Quaternion::Euler:
float x = Radians(euler.x);
float y = Radians(euler.y);
float z = Radians(euler.z);
x = x / 2;
y = y / 2;
z = z / 2;
return Quaternion(cos(z) * cos(y) * sin(x) - sin(z) * sin(y) * cos(x), //X
cos(z) * sin(y) * cos(x) + sin(z) * cos(y) * sin(x), //Y
sin(z) * cos(y) * cos(x) - cos(z) * sin(y) * sin(x), //Z
cos(z) * cos(y) * cos(x) + sin(z) * sin(y) * sin(x));//W
and Honestly, I stole this function from an article of a guy that was making his own Math Engine, in his case this seemed to work. Here is the Quaternion Vector Multiplication function, that I "borrowed" from the Unity Implementation: (in this case it's inside the Quaternion struct so this is a pointer to the quaternion from the Quaternion Vector multiplication)
inline Vector3 operator*(const Vector3& other) {
float x = this->x * 2.0f;
float y = this->y * 2.0f;
float z = this->z * 2.0f;
float xx = this->x * x;
float yy = this->y * y;
float zz = this->z * z;
float xy = this->x * y;
float xz = this->x * z;
float yz = this->y * z;
float wx = this->w * x;
float wy = this->w * y;
float wz = this->w * z;
Vector3 ret;
ret.x = (1.0f - (yy + zz)) * other.x + (xy - wz) * other.y + (xz + wy) * other.z;
ret.y = (xy + wz) * other.x + (1.0f - (xx + zz)) * other.y + (yz - wx) * other.z;
ret.z = (xz - wy) * other.x + (yz + wx) * other.y + (1.0f - (xx + yy)) * other.z;
return ret;
}
Does anyone know what might be wrong ? I tried to do this with glm:
glm::quat quat(glm::vec3(glm::radians(rotation.x), glm::radians(rotation.y), glm::radians(rotation.z)));
glm::vec3 v = quat * glm::vec3(0.0f, 0.0f, 1.0f);
but it's the same thing, the vector is the same and the quaternion is the same too, I've been reading into things a lot about this and couldn't find a fix, always when I tried to search implementation for the Quaternio::Euler function it just came up with how to use a math library. It would be best if the solution wouldn't require me to use glm, because I have to use my own Math Library, but honestly I will try anything to at least understand what is wrong.
I want to rotate a point in OpenGL around an arbitrary axis. I want to utilize that to rotate a sphere.
This is what I got so far:
float degreeBetweenTwoVec(glm::vec3 &a, glm::vec3 b)
{
float prod = b.x * a.x + b.y * a.y + b.z * a.z;
float mag_axis = sqrt((b.x * b.x) + (b.y * b.y) + (b.z * b.z));
float mag_vec = sqrt((a.x * a.x) + (a.y * a.y) + (a.z * a.z));
float degree = prod / (mag_axis * mag_vec);
return acos(degree) * 180.0 / PI;;
}
void rotAroundZ(glm::vec3 &point, float degree)
{
glm::vec3 n_point;
n_point.x = (point.x * cos(degree * PI / 180.0)) - (point.y * sin(degree * PI / 180.0));
n_point.y = (point.x * sin(degree * PI / 180.0)) + (point.y * cos(degree * PI / 180.0));
n_point.z = point.z;
point.x = n_point.x;
point.y = n_point.y;
point.z = n_point.z;
}
void rotAroundY(glm::vec3& point, float degree)
{
glm::vec3 n_point;
n_point.x = (point.x * cos(degree * PI / 180.0)) + (point.z * sin(degree * PI / 180.0));
n_point.y = point.y;
n_point.z = ((point.x * -1.0f) * sin(degree * PI / 180.0)) + (point.z * cos(degree * PI / 180.0));;
point.x = n_point.x;
point.y = n_point.y;
point.z = n_point.z;
}
void rotAroundA(glm::vec3& point, glm::vec3 &axis, float zdegree)
{
float xdegree = degreeBetweenTwoVec(axis, glm::vec3{ 1.0f, 0.0f, 0.0f });
float ydegree = degreeBetweenTwoVec(axis, glm::vec3{ 0.0f, 1.0f, 0.0f });
rotAroundZ(point, xdegree);
rotAroundY(point, ydegree);
rotAroundZ(point, zdegree);
rotAroundY(point, -ydegree);
rotAroundZ(point, -xdegree);
}
void rotAObject(Object& obj, glm::vec3 &axis, float degree)
{
axis = glm::normalize(axis);
translate(axis, glm::vec3{ axis.x, axis.y, axis.z });
for (int i = 0; i < obj.vertices.size(); i++)
{
rotAroundA(obj.vertices[i], axis, degree);
}
rotAroundA(obj.mp, axis, degree);
translate(axis, glm::vec3{ axis.x * -1.0f, axis.y * -1.0f, axis.z * -1.0f });
}
This works just fine if the given axis happens to be on one of the global axis. However, if it isn't and the given axis is basiclly rotating around something else. There is some kind of axis it is rotating around but as soon as change the given axis, for example rotating it around the z axis it rotates around a completlly different axis than before. It looks like for every position the given axis can take there is some other axis the object is actually rotating around.
Any help is appreciated!
I recommend to use a rotation matrix. Use glm::rotate(), to set a rotation matrix by axis and angle.
Convert the point to glm::vec4 and transform it by the rotation matrix:
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
glm::mat4 rot_mat = glm::rotate(glm::mat4(1.0f), glm::radians(degree), axis);
glm::vec3 n_point = glm::vec3(glm::vec4(point, 1.0f) * rot_mat);
I am playing around with OpenGL and one thing I decided to do is create my own Matrix class, instead of using glm's matrices.
The Matrix class has methods for translating, rotating and scaling the object, which are written below:
Matrix4 Matrix4::translate(Matrix4& matrix, Vector3& translation)
{
Vector4 result(translation, 1.0f);
result.multiply(matrix);
matrix.mElements[3 * 4 + 0] = result.x;
matrix.mElements[3 * 4 + 1] = result.y;
matrix.mElements[3 * 4 + 2] = result.z;
return matrix;
}
Matrix4 Matrix4::rotate(Matrix4& matrix, float angle, Vector3& axis)
{
if (axis.x == 0 && axis.y == 0 && axis.z == 0)
return matrix;
float r = angle;
float s = sin(r);
float c = cos(r);
float omc = 1.0f - cos(r);
float x = axis.x;
float y = axis.y;
float z = axis.z;
matrix.mElements[0 + 0 * 4] = c + x * x * omc;
matrix.mElements[1 + 0 * 4] = x * y * omc - z * s;
matrix.mElements[2 + 0 * 4] = z * x * omc + y * s;
matrix.mElements[0 + 1 * 4] = x * y * omc + z * s;
matrix.mElements[1 + 1 * 4] = c + y * y * omc;
matrix.mElements[2 + 1 * 4] = z * y * omc - x * s;
matrix.mElements[0 + 2 * 4] = x * z * omc - y * s;
matrix.mElements[1 + 2 * 4] = y * z * omc + x * s;
matrix.mElements[2 + 2 * 4] = c + z * z * omc;
return matrix;
}
Matrix4 Matrix4::scale(Matrix4& matrix, Vector3& scaler)
{
matrix.mElements[0 + 0 * 4] *= scaler.x;
matrix.mElements[1 + 0 * 4] *= scaler.x;
matrix.mElements[2 + 0 * 4] *= scaler.x;
matrix.mElements[0 + 1 * 4] *= scaler.y;
matrix.mElements[1 + 1 * 4] *= scaler.y;
matrix.mElements[2 + 1 * 4] *= scaler.y;
matrix.mElements[0 + 2 * 4] *= scaler.z;
matrix.mElements[1 + 2 * 4] *= scaler.z;
matrix.mElements[2 + 2 * 4] *= scaler.z;
matrix.mElements[3 + 3 * 4] = 1;
return matrix;
}
When I call the translate, rotate and scale methods in while loop (in this particular order), it does what I want, which is translate the object, then rotate it around its local origin and scale it. However, when I want to switch order so I call rotation first and then translation, I want it to do this:
But my code dosen't do that. Instead, its doing this:
What can I do so that my object only rotates around the center of the screen and not around it's local origin aswell?
My only guess is that I am doing something wrong with adding the rotation calculation on transformed matrix, but I still can't tell what it is.
EDIT: One thing i need to point out is if i left out the rotation method and i only tackle with translation and scaling, they do what i expect them to do in translation first, rotation second and in rotation first, translation second order.
EDIT 2: Here is how i call these functions in while loop.
Matrix4 trans = Matrix4(1.0f);
trans = Matrix4::rotate(trans, (float)glfwGetTime(), Vector3(0.0f, 0.0f, 1.0f));
trans = Matrix4::translate(trans, Vector3(0.5f, -0.5f, 0.0f));
trans = Matrix4::scale(trans, Vector3(0.5f, 0.5f, 1.0f));
shader.setUniformMatrix4f("uTransform", trans);
You have to concatenate the matrices by a matrix multiplication.
A matrix multiplication C = A * B works like this:
Matrix4x4 A, B, C;
// C = A * B
for ( int k = 0; k < 4; ++ k )
for ( int j = 0; j < 4; ++ j )
C[k][j] = A[0][j] * B[k][0] + A[1][j] * B[k][1] + A[2][j] * B[k][2] + A[3][j] * B[k][3];
I recommend to create specify the matrix class somehow like this:
#include <array>
class Matrix4
{
public:
std::array<float, 16> mElements{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
const float * dataPtr( void ) const { return mElements.data(); }
Matrix4 & multiply( const Matrix4 &mat );
Matrix4 & translate( const Vector3 &translation );
Matrix4 & scale( const Vector3 &scaler );
Matrix4 & rotate( float angle, const Vector3 &axis );
};
Implement the matrix multiplication. Note, you have to store the result in a buffer.
If you would write the result back to the matrix member directly, then you would change elements, which will read again later in the nested loop and the result wouldn't be correct:
Matrix4& Matrix4::multiply( const Matrix4 &mat )
{
// multiply the existing matrix by the new and store the result in a buffer
const float *A = dataPtr();
const float *B = mat.dataPtr();
std::array<float, 16> C;
for ( int k = 0; k < 4; ++ k ) {
for ( int j = 0; j < 4; ++ j ) {
C[k*4+j] =
A[0*4+j] * B[k*4+0] +
A[1*4+j] * B[k*4+1] +
A[2*4+j] * B[k*4+2] +
A[3*4+j] * B[k*4+3];
}
}
// copy the buffer to the attribute
mElements = C;
return *this;
}
Adapt the methods for translation, rotation and scaling like this:
Matrix4 & Matrix4::translate( const Vector3 &translation )
{
float x = translation.x;
float y = translation.y;
float z = translation.z;
Matrix4 transMat;
transMat.mElements = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, z, 1.0f };
return multiply(transMat);
}
Matrix4 & Matrix4::rotate( float angle, const Vector3 &axis )
{
float x = axis.x;
float y = axis.y;
float z = axis.z;
float c = cos(angle);
float s = sin(angle);
Matrix4 rotationMat;
rotationMat.mElements = {
x*x*(1.0f-c)+c, x*y*(1.0f-c)-z*s, x*z*(1.0f-c)+y*s, 0.0f,
y*x*(1.0f-c)+z*s, y*y*(1.0f-c)+c, y*z*(1.0f-c)-x*s, 0.0f,
z*x*(1.0f-c)-y*s, z*y*(1.0f-c)+x*s, z*z*(1.0f-c)+c, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
return multiply(rotationMat);
}
Matrix4 & Matrix4::scale( const Vector3 &scaler )
{
float x = scaler.x;
float y = scaler.y;
float z = scaler.z;
Matrix4 scaleMat;
scaleMat.mElements = {
x, 0.0f, 0.0f, 0.0f,
0.0f, y, 0.0f, 0.0f,
0.0f, 0.0f, z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
return multiply(scaleMat);
}
If you use the matrix class like this,
float angle_radians = ....;
Vector3 scaleVec{ 0.2f, 0.2f, 0.2f };
Vector3 transVec{ 0.3f, 0.3f, 0.0f };
Vector3 rotateVec{ 0.0f, 0.0f, 1.0f };
Matrix4 model;
model.rotate( angle_rad, rotateVec );
model.translate( transVec );
model.scale( scaleVec );
then the result would look like this:
The function rotate() isn't performing an actual rotation. Only generating a partial rotation matrix, and overwriting it over the original matrix.
You need to construct a complete one and multiply it to the original matrix.
Matrix4 Matrix4::rotate(const Matrix4& matrix, float angle, const Vector3& axis)
{
if (axis.x == 0 && axis.y == 0 && axis.z == 0)
return matrix;
float r = angle;
float s = sin(r);
float c = cos(r);
float omc = 1.0f - cos(r);
float x = axis.x;
float y = axis.y;
float z = axis.z;
Matrix4 r;
r.mElements[0 + 0 * 4] = c + x * x * omc;
r.mElements[1 + 0 * 4] = x * y * omc - z * s;
r.mElements[2 + 0 * 4] = z * x * omc + y * s;
r.mElements[3 + 0 * 4] = 0;
r.mElements[0 + 1 * 4] = x * y * omc + z * s;
r.mElements[1 + 1 * 4] = c + y * y * omc;
r.mElements[2 + 1 * 4] = z * y * omc - x * s;
r.mElements[3 + 1 * 4] = 0;
r.mElements[0 + 2 * 4] = x * z * omc - y * s;
r.mElements[1 + 2 * 4] = y * z * omc + x * s;
r.mElements[2 + 2 * 4] = c + z * z * omc;
r.mElements[3 + 2 * 4] = 0;
r.mElements[0 + 3 * 4] = 0;
r.mElements[1 + 3 * 4] = 0;
r.mElements[2 + 3 * 4] = 0;
r.mElements[3 + 3 * 4] = 1;
return r * matrix;
}
I'm trying to implement a functionality that can convert an Euler angle into an Quaternion and back "YXZ"-convention using Eigen. Later this should be used to let the user give you Euler angles and rotate around as Quaternion and convert Back for the user. In fact i am realy bad at math but tried my best. I have no Idea if this matrices are correct or anything. The code Works, but my results are way to off, i suppose. Any idea where i take the wrong turn? This is what my Quat.cpp looks like:
#include "Quat.h"
#include <Eigen/Geometry>
#include <Eigen/Dense>
#include <cmath>
#include <iostream>
using namespace Eigen;
Vector3f Quat::MyRotation(const Vector3f YPR)
{
Matrix3f matYaw(3, 3), matRoll(3, 3), matPitch(3, 3), matRotation(3, 3);
const auto yaw = YPR[2]*M_PI / 180;
const auto pitch = YPR[0]*M_PI / 180;
const auto roll = YPR[1]*M_PI / 180;
matYaw << cos(yaw), sin(yaw), 0.0f,
-sin(yaw), cos(yaw), 0.0f, //z
0.0f, 0.0f, 1.0f;
matPitch << cos(pitch), 0.0f, -sin(pitch),
0.0f, 1.0f, 0.0f, // X
sin(pitch), 0.0f, cos(pitch);
matRoll << 1.0f, 0.0f, 0.0f,
0.0f, cos(roll), sin(roll), // Y
0.0f, -sin(roll), cos(roll);
matRotation = matYaw*matPitch*matRoll;
Quaternionf quatFromRot(matRotation);
quatFromRot.normalize(); //Do i need to do this?
return Quat::toYawPitchRoll(quatFromRot);
}
Vector3f Quat::toYawPitchRoll(const Eigen::Quaternionf& q)
{
Vector3f retVector;
const auto x = q.y();
const auto y = q.z();
const auto z = q.x();
const auto w = q.w();
retVector[2] = atan2(2.0 * (y * z + w * x), w * w - x * x - y * y + z * z);
retVector[1] = asin(-2.0 * (x * z - w * y));
retVector[0] = atan2(2.0 * (x * y + w * z), w * w + x * x - y * y - z * z);
#if 1
retVector[0] = (retVector[0] * (180 / M_PI));
retVector[1] = (retVector[1] * (180 / M_PI))*-1;
retVector[2] = retVector[2] * (180 / M_PI);
#endif
return retVector;
}
Input: x = 55.0, y = 80.0, z = 12.0
Quaternion: w:0.872274, x: -0.140211, y:0.447012, z:-0.140211
Return Value: x:-55.5925, y: -6.84901, z:-21.8771
The X-Value seems about right disregarding the prefix, but Y and z are off.
From Euler to Quaternion:
using namespace Eigen;
//Roll pitch and yaw in Radians
float roll = 1.5707, pitch = 0, yaw = 0.707;
Quaternionf q;
q = AngleAxisf(roll, Vector3f::UnitX())
* AngleAxisf(pitch, Vector3f::UnitY())
* AngleAxisf(yaw, Vector3f::UnitZ());
std::cout << "Quaternion" << std::endl << q.coeffs() << std::endl;
From Quaternion to Euler:
auto euler = q.toRotationMatrix().eulerAngles(0, 1, 2);
std::cout << "Euler from quaternion in roll, pitch, yaw"<< std::endl << euler << std::endl;
Taken from https://eigen.tuxfamily.org/dox/classEigen_1_1AngleAxis.html
Here's one approach (not tested):
Vector3d euler = quaternion.toRotationMatrix().eulerAngles(2, 1, 0);
yaw = euler[0]; pitch = euler[1]; roll = euler[2];
The Quaternation to Euler solution didnt work for me, so i researched and modified the code, now it works for my purpose:
Vector3f ToEulerAngles(const Eigen::Quaternionf& q) {
Vector3f angles; //yaw pitch roll
const auto x = q.x();
const auto y = q.y();
const auto z = q.z();
const auto w = q.w();
// roll (x-axis rotation)
double sinr_cosp = 2 * (w * x + y * z);
double cosr_cosp = 1 - 2 * (x * x + y * y);
angles[2] = std::atan2(sinr_cosp, cosr_cosp);
// pitch (y-axis rotation)
double sinp = 2 * (w * y - z * x);
if (std::abs(sinp) >= 1)
angles[1] = std::copysign(M_PI / 2, sinp); // use 90 degrees if out of range
else
angles[1] = std::asin(sinp);
// yaw (z-axis rotation)
double siny_cosp = 2 * (w * z + x * y);
double cosy_cosp = 1 - 2 * (y * y + z * z);
angles[0] = std::atan2(siny_cosp, cosy_cosp);
return angles;
}
I was inspired by this wiki entry and did some bench marking with the presented solution here.
Checkout the wiki:
https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
When I use
auto euler = q.toRotationMatrix().eulerAngles(0, 1, 2)
It can not work perfectly all the time, the euler angle always has a regular beat (the actual value and the calculated value have a deviation of ±π).
For example, read and show yaw angle by rqt
picture.
I have no idea about this, but I find ros tf::getYaw() also can achieve "Quaternion to Euler" (because I just need yaw angle).
Without Eigen (just in case), I did:
tf2::Matrix3x3 ( quat ) . getEulerYPR( &roll, &pitch, &yaw );
// and
tf2::Matrix3x3 ( quat ) . getRPY( &roll, &pitch, &yaw );
Though, these can give only two of the 24 configurations possible.
I am trying to display a 360 panorama using an IMU for head tracking.
Yaw works correctly but the roll and pitch are reverse. I also notice that the pitch contains some roll (and maybe vice-versa).
I am receiving (W, X, Y, Z) coordinate from the IMU that I am storing in an array as X, Y, Z, W.
The next step is converting the quaternion to a rotation matrix. I have looked at many examples, and can't seem to find anything wrong with the following code:
static GLfloat rotation[16];
// Quaternion (x, y, z, w)
static void quaternionToRotation(float* quaternion)
{
// Normalize quaternion
float magnitude = sqrt(quaternion[0] * quaternion[0] +
quaternion[1] * quaternion[1] +
quaternion[2] * quaternion[2] +
quaternion[3] * quaternion[3]);
for (int i = 0; i < 4; ++i)
{
quaternion[i] /= magnitude;
}
double xx = quaternion[0] * quaternion[0], xy = quaternion[0] * quaternion[1],
xz = quaternion[0] * quaternion[2], xw = quaternion[0] * quaternion[3];
double yy = quaternion[1] * quaternion[1], yz = quaternion[1] * quaternion[2],
yw = quaternion[1] * quaternion[3];
double zz = quaternion[2] * quaternion[2], zw = quaternion[2] * quaternion[3];
// Column major order
rotation[0] = 1.0f - 2.0f * (yy + zz);
rotation[1] = 2.0f * (xy - zw);
rotation[2] = 2.0f * (xz + yw);
rotation[3] = 0;
rotation[4] = 2.0f * (xy + zw);
rotation[5] = 1.0f - 2.0f * (xx + zz);
rotation[6] = 2.0f * (yz - xw);
rotation[7] = 0;
rotation[8] = 2.0f * (xz - yw);
rotation[9] = 2.0f * (yz + xw);
rotation[10] = 1.0f - 2.0f * (xx + yy);
rotation[11] = 0;
rotation[12] = 0;
rotation[13] = 0;
rotation[14] = 0;
rotation[15] = 1;
}
The rotation matrix is then used in the draw call as such:
static void draw()
{
// Get IMU quaternion
float* quaternion = tracker.getTrackingData();
if (quaternion != NULL)
{
quaternionToRotation(quaternion);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
// TODO: Multiply initialRotation quaternion with IMU quaternion
glMultMatrixf(initialRotation); // Initial rotation to point forward
glMultMatrixf(rotation); // Rotation based on IMU
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
gluSphere(quad, 0.1, 50, 50);
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
glFlush();
glutSwapBuffers();
}
I tried to set all but one fields in the quaternion to 0, and I notice that they all work individually, except roll and pitch is swapped around. I tried swapping X and Y but this does not seem to help.
Any help would be really appreciated. Please let me know as well if you have any steps that can let me debug my issue. Thanks!