2015-04-17 27 views
2

我以为我这样做的时间最长,但是我相信我可能会以非常错误的方式做到这一点。旋转物体以匹配矢量

我有一个世界地形的3D引擎,物体可以放置在地面上,当它们被放置时,它们将面向它们所在的地形(旋转)。我这样做的方式是像这样:

D3DXVECTOR3 tNormal = GetNormalFromFile(...); //Get the terrain's normal 

placeItemData.placeMesh.meshRot.z = (acos(tNormal.x) - (D3DX_PI/2)); 
placeItemData.placeMesh.meshRot.x = -(acos(tNormal.z) - (D3DX_PI/2)); 

我店旋转的弧度矢量:X,Y,Z旋转,其中Y是的。所以我计算X轴和Z轴的旋转并相应旋转。玩家可以在放置它之前手动旋转Y轴周围的物体,并且所有这些都可以正常工作。

随着我不断改进物品放置代码,我意识到这不适用于近垂直飞机。例如,试图在墙上放置一张照片。此代码似乎可以将物品放置在接近水平(平坦)的地形上,但旋转对于垂直墙壁来说是可行的。

我错过了一个简单的计算吗?我需要以某种方式计算y轴值吗?我试图用atan2函数来计算旋转:

placeItemData.placeMesh.meshRot.z = (atan2(finalNormal.x,finalNormal.y)); 
placeItemData.placeMesh.meshRot.x = (atan2(finalNormal.z,finalNormal.y)); 

但是我遇到了类似的问题。

我是否需要为这些计算使用四元数?我能否再次轻松地将最终旋转值存储在3D矢量(x,y,z)中?

我感谢任何帮助!

更新1

下面是使用该代码的图像:当您将鼠标悬停在石

meshRot.z = - atan2(sqrt(finalNormal.y^2 + finalNormal.z^2), finalNormal.x); 
meshRot.x = - atan2(finalNormal.y, finalNormal.z); 

prob1 http://www.crystaldragon.com/TempImages/prob1.png

,正常的三角形的计算(对于图片中,石面的正常值是(0.637,-0.014,0.770))。当然,你在石头上看到的木块应该直接铺在石头的顶部(像悬挂成图片一样)。

更新2

从测试的“墙”定位在我的世界Z轴,我似乎有代码只是其中y = 0所有情况下工作。我能够将对象放置在所有垂直墙上,但不能放置在墙的水平(顶部)上。

这里是当前的代码:

placeItemData.placeMesh.meshRot.x = -(atan2(finalNormal.y, sqrt((finalNormal.x * finalNormal.x) + (finalNormal.z * finalNormal.z))) + (D3DX_PI/2)); 
placeItemData.placeMesh.meshRot.z = -(atan2(finalNormal.z, finalNormal.x) + (D3DX_PI/2)); 

只要在y正常是值0,对象将附加到每个垂直壁,但是没有水平(因为在y正常情况显然是非负数)。希望最后一步是计算出我需要输入的最终计算结果作为方程式中的y值,但是我仍然会提出失败的尝试。

+0

我知道旋转,但我不知道Direct3D。旋转的两个值就足够了,但是当您使用'meshrot'中的值旋转对象时,是使用自己的代码执行还是调用Direct3D函数? – Beta

+0

我只知道这将与'atan2(0,-x)'上'atan2'的不连续性有关。 – Wintermute

+0

这是我如何做我的旋转矩阵: 'D3DXMatrixRotationYawPitchRoll(&matRotate,0.0f,meshRot.x,meshRot.z); D3DXMatrixRotationYawPitchRoll(&matRotate2,meshRot.y,0.0f,0.0f); D3DXMatrixMultiply(&matRotate,&matRotate2,&matRotate);' – Carradine

回答

0

对于接近水平(平坦)的地形,地形上X-Z平面,因此对于正常的ÿ值是最有可能的1。0,它应该给你正确的旋转而不使用y法线。

然而,添加一个目的是在墙上时,该ÿ正常将被要求来计算旋转ý组件。你说球员在放置它之前可以围绕着轴手动旋转物体。

是你在哪里计算旋转的y分量使用正常值的y?如果没有,请确保您也在计算它。否则,你在2D中计算旋转,并以某种方式将其推断为3D。

+0

因此,对于展示位置,我目前没有在项目展示位置的任何计算中使用y组件。事实之后,将y旋转简单地添加为对象自己的“分离”旋转对象。我把旋转代码放到上面的注释块中。 – Carradine

0

我会推荐Quaternions。你可以让它在没有它们的情况下工作,但是你的代码必须对零进行大量的检查,并且如果你试图对任何事物进行动画处理,将会出现不连续性。有一个学习曲线与四元,但一旦你有:

  • 旋转方法

  • 从笛卡尔(或极性或其他)转换为四元数

  • 从四元数转换到笛卡尔(或其他)

它使用起来非常简单,它们是3D操作的正确选择。

我会诚实地说,你不需要理解数学要么让它工作;你只需要遵循四元数学的规则。

+0

谢谢。如果我无法获得更“传统”的方法,我可能会走这条路。 – Carradine

0

我不知道的Direct3D,而是通过快速浏览的文档去,看起来好像这是你想要的东西:

meshRot.z = - atan2(sqrt(finalNormal.y^2 + finalNormal.z^2), finalNormal.x); 
meshRot.x = - atan2(finalNormal.y, finalNormal.z); 

(我不知道这是否是正确的语法例如对于sqrt,但你看到我想要做什么。)

关于Y(“偏航”)的旋转可以留给用户 - 它对应于从北向东旋转雕像 - 面对,或倒挂在墙上的一幅画。

我假设旋转是关​​于对象固定的轴。如果情况并非如此,那么解决方案看起来会完全不同。试一试,如果它不起作用,我们可以尝试一些简单的测试用例来将其固定下来。

+0

我非常感谢帮助!我已经添加了对原始文章的更新,并给出了一些解释,显示了代码的当前结果。我也会继续做一些研究。 – Carradine