Rotation 应用一个";散布;值设置为XMFLOAT4X4

Rotation 应用一个";散布;值设置为XMFLOAT4X4,rotation,directx-11,matrix-multiplication,quaternions,Rotation,Directx 11,Matrix Multiplication,Quaternions,我试图给世界矩阵添加一个小值,以复制射击武器[手枪、突击步枪]的准确性 当前,“我的世界矩阵”位于父对象的位置,能够专门围绕Y轴旋转 我在Unity3D中完成了这项工作,在需要创建对象时运行[每创建一次]: var coneRotation = Quaternion.Euler(Random.Range(-spread, spread), Random.Range(-spread, spread), 0); var go = Instantiate(obj, pa

我试图给世界矩阵添加一个小值,以复制射击武器[手枪、突击步枪]的准确性

当前,“我的世界矩阵”位于父对象的位置,能够专门围绕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)));
    };
auto-randF=[&](浮点下限,浮点上限)->float
{
返回下限+静态施法(rand())/(静态施法(rand\u MAX/(上限-下限));
};
我的第一个想法是简单地在初始化时将一个随机的
x
&y乘以对象的
forward
向量,并以这种方式移动它:
position=position+forward*speed*dt[
速度
1800
],尽管旋转不正确(更不用说子弹会发射了)

我还尝试创建一个四元数[Unity3D]:
XMVECTOR四元数=XMVectorSet(random\ux,random\uy,0)
并使用
XMMatrixRotationQuaternion
创建一个旋转矩阵

然后我调用
XMStoreFloat4x4(&world\u矩阵,XMLoadFloat4x4(&world\u矩阵)*旋转),并恢复矩阵的位置部分[访问world\u matrix.\u 41/.\u 42/.\u 43](world\u matrix是“bullet”本身的矩阵,而不是父矩阵)

[我还尝试颠倒乘法的顺序]

我已经读到
XMMatrixRotationQuaternion
不会作为Euler四元数返回,而
xmquaternionAxisAngle
会返回,尽管我不完全确定如何使用它

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


非常感谢

你的代码
XMVECTOR四元数=XMVectorSet(random\ux,random\uy,0)未创建有效的四元数。首先,如果未将
w
组件设置为1,则4矢量四元数实际上并不表示三维旋转。第二,四元数的向量分量不是欧拉角


您要使用
xmquaternionrotationrollphitchyaw
从Euler角度输入构造四元数旋转,或使用
xmquaternionrotationrollphitchyawFromVector
将三个Euler角度作为向量。这些函数正在做Unity的
四元数.Euler
方法正在做的事情

当然,如果你想要一个旋转矩阵而不是四元数,那么你可以
XMMatrixRotationRollPitchYaw
XMMatrixRotationRollPitchYawFromVector
直接从Euler角度构造一个4x4旋转矩阵——实际上在内部使用四元数。根据您的代码片段,看起来您已经有了一个基础旋转作为四元数,您希望将其与扩展四元数连接起来,因此您可能不希望在这种情况下使用此选项

注意:您应该考虑使用C++11标准
,而不是在糟糕的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 );
std::随机设备rd;
标准:mt19937 gen(rd());
//此处的扩展应以弧度为单位(而不是Unity使用的度数)
标准:均匀实分布分布分布(扩散,扩散);
XMVECTOR coneRotation=xm四元数旋转滚转俯仰偏航(dis(gen),dis(gen),0);
XMVECTOR rot=XMQuaternionMultiply(parentRot,coneRotation);
XMMATRIX transform=XMMatrixAffineTransformation(g_XMOne,g_XMZero,rot,parentPos);

顺便说一句,如果您习惯于Unity或XNA Game Studio C#math库,您可能想在中查看DirectXMath的包装。

我实际上没有注意到
四元数的
w
[我认为是比例]的
1
。如果我想复制Unity3D中包含的
Quaternion.Euler
方法,需要什么?[我正试图尽可能直接地将我的Unity3D游戏移植到Direct3D11]
Quaternion.Euler
for Unity:“返回一个旋转,该旋转绕z轴旋转z度,绕x轴旋转x度,绕y轴旋转y度(按该顺序)。”<代码>XMQuaternionRotationRollPitchYaw
计算给定弧度的横滚(Z轴)、俯仰(X轴)和横摆(Y轴旋转)。