我正在尝试为World Matrix添加一个小值,以便复制已发射武器[手枪,突击步枪]的准确性
目前,我的World Matrix位于Parent Objects的位置,能够专门围绕Y轴旋转。
我在Unity3D中完成了这项工作,每当需要创建对象时运行[每次一次]:
var coneRotation = Quaternion.Euler(Random.Range(-spread, spread), Random.Range(-spread, spread), 0);
var go = Instantiate(obj, parent.transform.position, transform.rotation * coneRotation) as GameObject;
我正在尝试使用Direct3D11复制结果。
此lambda当前返回[-1.5,1.5]之间的随机值:
auto randF = [&](float lower_bound, float uppder_bound) -> float
{
return lower_bound + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (uppder_bound - lower_bound)));
};
我的第一个想法是简单地乘以随机x
&amp;&amp;在初始化时,y
进入对象的forward
向量,并以这种方式移动它:position = position + forward * speed * dt;
[speed
为1800
],但轮换不正确(更不用说子弹了)。
我还尝试制作一个Quaternion [在Unity3D中]:XMVECTOR quaternion = XMVectorSet(random_x, random_y, 0)
并使用XMMatrixRotationQuaternion
创建一个旋转矩阵。
然后我调用XMStoreFloat4x4(&world_matrix, XMLoadFloat4x4(&world_matrix) * rotation);
,并恢复矩阵的位置部分[访问world_matrix._41 /._ 42 /._ 43](world_matrix是“子弹”本身的矩阵,而不是父项。)< / p>
[我也尝试颠倒乘法的顺序]
我已经读过XMMatrixRotationQuaternion
没有作为欧拉四元数返回,而XMQuaternionToAxisAngle
也没有,但我并不完全确定如何使用它。
完成这样的事情的正确方法是什么?
非常感谢!
答案 0 :(得分:0)
您的代码XMVECTOR quaternion = XMVectorSet(random_x, random_y, 0);
未创建有效的四元数。首先,如果未将w
分量设置为1,则4向量四元数实际上并不代表3D旋转。其次,四元数的向量分量不是欧拉角。
你想使用XMQuaternionRotationRollPitchYaw
构造一个来自欧拉角输入的四元数旋转,或XMQuaternionRotationRollPitchYawFromVector
将三个欧拉角作为矢量。这些功能正在执行Unity Quaternion.Euler
方法正在做的事情。
当然,如果你想要一个旋转矩阵而不是四元数,那么你可以XMMatrixRotationRollPitchYaw
或XMMatrixRotationRollPitchYawFromVector
从欧拉角直接构造一个4x4旋转矩阵 - 无论如何它实际上都在内部使用四元数。根据您的代码段,您似乎已经将基本轮换作为要与展开四元数连接的四元数,因此您可能不希望在这种情况下使用此选项。
注意:您应该考虑使用C ++ 11标准<random>
而不是围绕可怕的C rand
函数的自制的lambda包装器。
类似的东西:
std::random_device rd;
std::mt19937 gen(rd());
// spread should be in radians here (not degrees which is what Unity uses)
std::uniform_real_distribution<float> dis(-spread, spread);
XMVECTOR coneRotation = XMQuaternionRotationRollPitchYaw( dis(gen), dis(gen), 0 );
XMVECTOR rot = XMQuaternionMultiply( parentRot, coneRotation );
XMMATRIX transform = XMMatrixAffineTransformation( g_XMOne, g_XMZero, rot, parentPos );
顺便说一下,如果您习惯使用Unity或XNA Game Studio C#数学库,您可能需要在SimpleMath中查看DirectXMath的DirectX Tool Kit包装。