Direct3D - 如何从视图矩阵计算滚动?

发布于 2024-08-24 08:01:13 字数 883 浏览 7 评论 0原文

这个问题困扰了我一晚上,我终于举手寻求帮助了。基本上,在进行相机更新后,立即从视图矩阵计算俯仰和偏航是相当简单的:

D3DXMatrixLookAtLH(&m_View, &sCam.pos, &vLookAt, &sCam.up);
pDev->SetTransform(D3DTS_VIEW, &m_View);

// Set the camera axes from the view matrix
sCam.right.x = m_View._11;
sCam.right.y = m_View._21;
sCam.right.z = m_View._31;
sCam.up.x    = m_View._12;
sCam.up.y    = m_View._22;
sCam.up.z    = m_View._32;
sCam.look.x  = m_View._13;
sCam.look.y  = m_View._23;
sCam.look.z  = m_View._33;

// Calculate yaw and pitch and roll
float lookLengthOnXZ = sqrtf( sCam.look.z^2 + sCam.look.x^2 );
fPitch = atan2f( sCam.look.y, lookLengthOnXZ );
fYaw   = atan2f( sCam.look.x, sCam.look.z );

所以我的问题是:必须有某种方法来获取以弧度为单位的横滚,类似于在代码的末尾。我尝试了几十种对我来说似乎有意义的算法,但没有一个给出完全理想的结果。我意识到许多开发人员不会跟踪这些值,但是我正在编写一些重新居中例程并根据这些值设置剪切,并且当您将混合旋转应用于视图矩阵时,手动跟踪会崩溃。那么,有人有从视图矩阵中获取以弧度(或度数,我不在乎)为单位的滚动的公式吗?

This one has been eating up my entire night, and I'm finally throwing up my hands for some assistance. Basically, it's fairly straightforward to calculate the Pitch and Yaw from the View Matrix right after you do a camera update:

D3DXMatrixLookAtLH(&m_View, &sCam.pos, &vLookAt, &sCam.up);
pDev->SetTransform(D3DTS_VIEW, &m_View);

// Set the camera axes from the view matrix
sCam.right.x = m_View._11;
sCam.right.y = m_View._21;
sCam.right.z = m_View._31;
sCam.up.x    = m_View._12;
sCam.up.y    = m_View._22;
sCam.up.z    = m_View._32;
sCam.look.x  = m_View._13;
sCam.look.y  = m_View._23;
sCam.look.z  = m_View._33;

// Calculate yaw and pitch and roll
float lookLengthOnXZ = sqrtf( sCam.look.z^2 + sCam.look.x^2 );
fPitch = atan2f( sCam.look.y, lookLengthOnXZ );
fYaw   = atan2f( sCam.look.x, sCam.look.z );

So my problem is: there must be some way to obtain the Roll in radians similar to how the Pitch and Yaw are being obtained at the end of the code there. I've tried several dozen algorithms that seemed to make sense to me, but none of them gave quite the desired result. I realize that many developers don't track these values, however I am writing some re-centering routines and setting clipping based on the values, and manual tracking breaks down as you apply mixed rotations to the View Matrix. So, does anyone have the formula for getting the Roll in radians (or degrees, I don't care) from the View Matrix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七堇年 2024-08-31 08:01:13

呜呼,明白了!感谢 stacker 提供了维基百科上欧拉角条目的链接,最后的伽玛公式确实是正确的解决方案!因此,要从“垂直平面”计算以弧度为单位的滚动,我使用以下 C++ 代码行:

fRoll  = atan2f( sCam.up.y, sCam.right.y ) - D3DX_PI/2;

正如欧拉指出的,您正在寻找 Y(向上)矩阵的 Z 值相对于 X 的反正切(右)矩阵的 Z 值 - 虽然在这种情况下我尝试了 Z 值,但它们没有产生所需的结果,所以我突发奇想尝试了 Y 值,得到了一个偏离 +PI/2 弧度的值(与期望值),很容易补偿。最后,我拥有了一个具有自校正平衡功能的、精确且稳定的 3D 相机平台。 =)

Woohoo, got it! Thank you stacker for the link to the Euler Angles entry on Wikipedia, the gamma formula at the end was indeed the correct solution! So, to calculate Roll in radians from a "vertical plane" I'm using the following line of C++ code:

fRoll  = atan2f( sCam.up.y, sCam.right.y ) - D3DX_PI/2;

As Euler pointed out, you're looking for the arc tangent of the Y (up) matrix's Z value against the X (right) matrix's Z value - though in this case I tried the Z values and they did not yield the desired result so I tried the Y values on a whim and I got a value which was off by +PI/2 radians (right angle to the desired value), which is easily compensated for. Finally I have a gryscopically accurate and stable 3D camera platform with self-correcting balance. =)

盗琴音 2024-08-31 08:01:13

维基百科关于欧拉角的文章似乎包含您正在寻找的公式结尾。

It seems the Wikipedia article about Euler angles contains the formula you're lookin for at the end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文