【问题标题】:How do I perform rotations about an object's local (not global) axes using glRotatef?如何使用 glRotatef 围绕对象的局部(非全局)轴进行旋转?
【发布时间】:2015-07-19 06:57:46
【问题描述】:

我有一个网格/游戏对象可以使用 FreeGLUT 库通过 glRotatef 旋转:

glPushMatrix();
    glTranslatef(GlobalPos_x, GlobalPos_y, GlobalPos_z);

    glRotatef(Global_Yaw,0,1,0);
    glRotatef(Global_Pitch,1,0,0);
    glRotatef(Global_Roll,0,0,1);

    RenderMesh(mesh_Plane);
glPopMatrix();

开始时,对象与前 Z 轴对齐; Y 轴向上,X 轴向左。


“控制”:

W:每帧间距 +5 度

S:每帧俯仰 -5 度

A:每帧偏航 +5 度

D:每帧偏航 -5 度


目标:Global_Yaw、Global_Pitch 和 Global_Roll 值必须以某种方式从这些控件增加(范围分别为 -180 到 +180、-90 到 +90 和 -180 到 +180)。

问题是,如果飞机已经倾斜 90 度 它原来的位置,“偏航”反而会让它旋转 Y 轴(万向节锁定),这应该只发生在 First- 人物射击游戏。

所以只需执行 'if(GetAsyncKeyState(Key_A)) Global_Yaw += 5;'不是我要找的。​​p>


编辑:正方形 2

根据 tkausl 的提醒,我挖掘了我之前的一项尝试。我的想法是我将飞机当前的全局角度转换为一个矩阵,将该矩阵与玩家的关键输入生成的另一个矩阵相乘,然后以某种方式使用该矩阵来获得新的 Global_Yaw、Global_Pitch 和 Global_Roll 值:

// Convert ORIENTATION to MATRIX
Omatrix00 = cos(Global_Pitch)*cos(Global_Yaw);
Omatrix01 = sin(Global_Pitch);
Omatrix02 = cos(Global_Pitch)*sin(Global_Yaw);
Omatrix03 = 0;
Omatrix10 = -cos(Global_Roll)*sin(Global_Pitch)*cos(Global_Yaw)+sin(Global_Roll)*sin(Global_Yaw);
Omatrix11 = cos(Global_Roll)*cos(Global_Pitch);
Omatrix12 = -cos(Global_Roll)*sin(Global_Pitch)*sin(Global_Yaw)-sin(Global_Roll)*cos(Global_Yaw);
Omatrix13 = 0;
Omatrix20 = -sin(Global_Roll)*sin(Global_Pitch)*cos(Global_Yaw)-cos(Global_Roll)*sin(Global_Yaw);
Omatrix21 = sin(Global_Roll)*cos(Global_Pitch);
Omatrix22 = cos(Global_Roll)*cos(Global_Yaw)-sin(Global_Roll)*sin(Global_Pitch)*sin(Global_Yaw);
Omatrix23 = 0;
Omatrix30 = 0;
Omatrix31 = 0;
Omatrix32 = 0;
Omatrix33 = 1;


// Convert Commanded Turn Angles to MATRIX
matrix00 = cos(pitch_speed)*cos(yaw_speed);
matrix02 = cos(pitch_speed)*sin(yaw_speed);
matrix01 = sin(pitch_speed);
matrix03 = 0;
matrix10 = -cos(roll_speed)*sin(pitch_speed)*cos(yaw_speed)+sin(roll_speed)*sin(yaw_speed);
matrix11 = cos(roll_speed)*cos(pitch_speed);
matrix12 = -cos(roll_speed)*sin(pitch_speed)*sin(yaw_speed)-sin(roll_speed)*cos(yaw_speed);
matrix13 = 0;
matrix20 = -sin(roll_speed)*sin(pitch_speed)*cos(yaw_speed)-cos(roll_speed)*sin(yaw_speed);
matrix21 = sin(roll_speed)*cos(pitch_speed);
matrix22 = cos(roll_speed)*cos(yaw_speed)-sin(roll_speed)*sin(pitch_speed)*sin(yaw_speed);
matrix23 = 0;
matrix30 = 0;
matrix31 = 0;
matrix32 = 0;
matrix33 = 1;

// Next step: Somehow using this matrix to get new Global_Yaw, Global_Pitch and Global_Roll values...

我什至不确定我是否在我的代码中正确地乘以我的矩阵。

【问题讨论】:

    标签: c++ opengl freeglut


    【解决方案1】:

    您必须先绕 x 轴或 z 轴旋转,最后绕 y 轴旋转才能获得正确的结果。在大多数不需要滚动的游戏中,您会先围绕 x 旋转,然后围绕 z 旋转,一切都按预期旋转。

    【讨论】:

    • 这对我帮助不大...我的问题是,Global_Yaw、Global_Pitch 和 Global_Roll 值必须以某种方式从 WASD 控件中递增。 (分别从 -180 到 +180、-90 到 +90 和 -180 到 +180)。不过,我会编辑我的问题以更好地反映我的问题。
    • 哦,我想我明白了。在这种情况下,您必须使用四元数和矩阵来防止云台锁定
    猜你喜欢
    • 2014-11-29
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 2016-10-06
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    相关资源
    最近更新 更多