gpt4 book ai didi

c++ - 对象围绕世界轴 OpenGL 的旋转

转载 作者:行者123 更新时间:2023-11-28 05:32:39 25 4
gpt4 key购买 nike

我正在尝试在 OpenGL 中制作一个可控制的球。我正在使用我自己的矩阵类来转换对象矩阵,但我似乎无法获得正确的旋转。我总是以球围绕局部轴旋转而告终。这就是它现在的样子 https://gfycat.com/LongKindBassethound .长线是局部轴。

所以当球向前移动时,下一个侧向移动将是错误的。矩阵类中有一个函数可以绕任意轴旋转:

Matrix& Matrix::rotationAxis(const Vector& Axis, float Angle) {
const float Si = sin(Angle);
const float Co = cos(Angle);
const float OMCo = 1 - Co;
Vector Ax = Axis;
Ax.normalize();

m00= (Ax.X * Ax.X) * OMCo + Co;
m01= (Ax.X * Ax.Y) * OMCo - (Ax.Z * Si);
m02= (Ax.X * Ax.Z) * OMCo + (Ax.Y * Si);
m03= 0;

m10= (Ax.Y * Ax.X) * OMCo + (Ax.Z * Si);
m11= (Ax.Y * Ax.Y) * OMCo + Co;
m12= (Ax.Y * Ax.Z) * OMCo - (Ax.X * Si);
m13= 0;

m20= (Ax.Z * Ax.X) * OMCo - (Ax.Y * Si);
m21= (Ax.Z * Ax.Y) * OMCo + (Ax.X * Si);
m22= (Ax.Z * Ax.Z) * OMCo + Co;
m23= 0;

m30= 0;
m31= 0;
m32= 0;
m33= 1;

return *this;
}

我想有了这个我可以获取世界方向 vector 并将它们转换到对象的局部空间,然后围绕结果旋转。不过我真的不知道该怎么做(球矩阵 * 世界 vector ?那行不通)。我真的很想避免使用四元数,但如果我做不到,我也会很感激这方面的建议。

编辑:更多信息

转换代码。如您所见,我尝试了不同的方法,但它们的作用都是一样的……所以它不起作用也就不足为奇了。

Matrix transM, rotX, rotZ;
rotationX = straight;
rotationZ = side;
if (velocity != Vector(0, 0, 0)) {
velocity.X = -0.0005 * DeltaTime;
velocity.X = clamp(velocity.X, 0, FLT_MAX);

velocity.Z = -0.0005 * DeltaTime;
velocity.Z = clamp(velocity.Z, 0, FLT_MAX);
}

velocity.X += speed * -side * DeltaTime;
velocity.Z += speed * straight * DeltaTime;
transM.translation(velocity.X, 0, velocity.Z);

if (velocity.Z != 0 || velocity.X != 0) {
//http://mathworld.wolfram.com/EulerAngles.html
//http://gamedev.stackexchange.com/questions/67199/how-to-rotate-an-object-around-world-aligned-axes

Vector localAxisX = m_Ball * Vector(1, 0, 0);
Vector localAxisZ = m_Ball * Vector(0, 0, 1);
rotX.rotationAxis(Vector(1, 0, 0), 0.5* M_PI * straight * DeltaTime);
rotZ.rotationAxis(Vector(0, 0, 1), 0.5* M_PI * side * DeltaTime);
//rotX.rotationX(0.5* M_PI * straight * DeltaTime * 3);
//rotZ.rotationZ(0.5* M_PI * side * DeltaTime * 3);
//Matrix fullRotation.rotationYawPitchRoll(Vector(0, 0.5* M_PI * straight * DeltaTime, 0.5* M_PI * side * DeltaTime));
m_Ball = transM * m_Ball * (rotX*rotZ);
}
else {
m_Ball = transM * m_Ball;
}

用我之前尝试使用 glRotatef 的尝试绘制代码(显然现在已经注释掉了)

void Ball::draw(float DeltaTime) {
glPushMatrix();
glMultMatrixf(m_Ball);
if(rotationX)
glRotatef(0.5* M_PI * rotationX * DeltaTime, 1.0, 0.0, 0.0);
if(rotationZ)
glRotatef(0.5* M_PI * rotationZ * DeltaTime, 0.0, 0.0, 1.0);
g_Model_ball.drawTriangles();
glPopMatrix();
drawAxis();
}

最佳答案

我强烈建议使用四元数来轻松处理复合旋转并避免万向节锁定。

https://en.wikipedia.org/wiki/Gimbal_lock

好的,关于您的评论和视频,您想要围绕球的中心旋转。看起来你在 m_Ball 中累积了你的旋转,但是做了一个奇怪的 transM 乘法。此外,您可能正在 transM 中积累翻译。

尽量不要混合平移和旋转,并避免在 m_Ball 中累积它们。你可以做这样的事情。

//transformation matrix
transM.translation(velocity.X, 0, velocity.Z);

//accumulate translations in m_BallT
m_BallT = transM * m_BallT;

//final Rotation
Matrix rotation = rotX * rotZ;

//accumulate rotations in m_BallR
m_BallR = rotation * m_BallR;

//now compute your final transformation matrix from accumulated rotations and translation
m_Ball = m_BallT * m_BallR;

注意 m_BallR 是如何累积旋转的。后乘法将确保在 m_BallR 中累积旋转后应用新的 rotation。最后转换为在m_BallT 中累积的最终位置。您的球将围绕其中心旋转并根据 m_BallT 移动。

您也可以简单地替换 m_BallR 上的转换组件,以避免额外的矩阵乘法。

关于c++ - 对象围绕世界轴 OpenGL 的旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39102181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com