将“Spread”值应用于XMFLOAT4X4

时间:2015-05-26 01:08:13

标签: rotation directx-11 matrix-multiplication quaternions

我正在尝试为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; [speed1800],但轮换不正确(更不用说子弹了)。

我还尝试制作一个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也没有,但我并不完全确定如何使用它。

完成这样的事情的正确方法是什么?

非常感谢!

1 个答案:

答案 0 :(得分:0)

您的代码XMVECTOR quaternion = XMVectorSet(random_x, random_y, 0);未创建有效的四元数。首先,如果未将w分量设置为1,则4向量四元数实际上并不代表3D旋转。其次,四元数的向量分量不是欧拉角。

你想使用XMQuaternionRotationRollPitchYaw构造一个来自欧拉角输入的四元数旋转,或XMQuaternionRotationRollPitchYawFromVector将三个欧拉角作为矢量。这些功能正在执行Unity Quaternion.Euler方法正在做的事情。

当然,如果你想要一个旋转矩阵而不是四元数,那么你可以XMMatrixRotationRollPitchYawXMMatrixRotationRollPitchYawFromVector从欧拉角直接构造一个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包装。