将 "Spread" 值应用于 XMFLOAT4X4
Applying a "Spread" value to an XMFLOAT4X4
我正在尝试向 World Matrix 添加一个小值,以复制射击武器 [手枪、突击步枪] 的准确性
目前,我的世界矩阵位于父对象的位置,能够专门围绕 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 return 是目前 [-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
&& y
乘以对象的 forward
向量,并以这种方式移动它:position = position + forward * speed * dt;
[speed
是 1800
],尽管旋转不正确(更不用说子弹发射了)。
我还尝试制作四元数 [如在 Unity3D 中]:XMVECTOR quaternion = XMVectorSet(random_x, random_y, 0)
并使用 XMMatrixRotationQuaternion
.
创建旋转矩阵
之后我调用XMStoreFloat4x4(&world_matrix, XMLoadFloat4x4(&world_matrix) * rotation);
,恢复矩阵的位置部分[访问world_matrix._41/._42/._43](world_matrix是[的矩阵=48=] 本身,而不是父级)。
[我也试过颠倒乘法的顺序]
我读到 XMMatrixRotationQuaternion
不 return 作为欧拉四元数,而 XMQuaternionToAxisAngle
是,尽管我不完全确定如何使用它。
完成这样的事情的正确方法是什么?
非常感谢!
您的代码 XMVECTOR quaternion = XMVectorSet(random_x, random_y, 0);
没有创建有效的四元数。首先,如果您没有将 w
组件设置为 1,那么 4 向量四元数实际上并不表示 3D 旋转。其次,四元数的向量分量不是欧拉角。
您想使用 XMQuaternionRotationRollPitchYaw
从欧拉角输入构造四元数旋转,或 XMQuaternionRotationRollPitchYawFromVector
将三个欧拉角作为向量。这些函数正在做 Unity 的 Quaternion.Euler
方法正在做的事情。
当然,如果你想要一个旋转矩阵而不是四元数,那么你可以XMMatrixRotationRollPitchYaw
或XMMatrixRotationRollPitchYawFromVector
直接从欧拉角构造一个4x4的旋转矩阵——实际上内部使用了四元数无论如何。根据您的代码片段,您似乎已经有了一个基本旋转作为四元数,您希望将其与扩展四元数连接起来,因此您可能不想在这种情况下使用此选项。
注意:你应该考虑使用 C++11 标准 <random>
而不是围绕糟糕的 C 编写的 lambda 包装器 rand
功能。
类似于:
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 wrapper for DirectXMath in DirectX Tool Kit。
我正在尝试向 World Matrix 添加一个小值,以复制射击武器 [手枪、突击步枪] 的准确性
目前,我的世界矩阵位于父对象的位置,能够专门围绕 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 return 是目前 [-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
&& y
乘以对象的 forward
向量,并以这种方式移动它:position = position + forward * speed * dt;
[speed
是 1800
],尽管旋转不正确(更不用说子弹发射了)。
我还尝试制作四元数 [如在 Unity3D 中]:XMVECTOR quaternion = XMVectorSet(random_x, random_y, 0)
并使用 XMMatrixRotationQuaternion
.
之后我调用XMStoreFloat4x4(&world_matrix, XMLoadFloat4x4(&world_matrix) * rotation);
,恢复矩阵的位置部分[访问world_matrix._41/._42/._43](world_matrix是[的矩阵=48=] 本身,而不是父级)。
[我也试过颠倒乘法的顺序]
我读到 XMMatrixRotationQuaternion
不 return 作为欧拉四元数,而 XMQuaternionToAxisAngle
是,尽管我不完全确定如何使用它。
完成这样的事情的正确方法是什么?
非常感谢!
您的代码 XMVECTOR quaternion = XMVectorSet(random_x, random_y, 0);
没有创建有效的四元数。首先,如果您没有将 w
组件设置为 1,那么 4 向量四元数实际上并不表示 3D 旋转。其次,四元数的向量分量不是欧拉角。
您想使用 XMQuaternionRotationRollPitchYaw
从欧拉角输入构造四元数旋转,或 XMQuaternionRotationRollPitchYawFromVector
将三个欧拉角作为向量。这些函数正在做 Unity 的 Quaternion.Euler
方法正在做的事情。
当然,如果你想要一个旋转矩阵而不是四元数,那么你可以XMMatrixRotationRollPitchYaw
或XMMatrixRotationRollPitchYawFromVector
直接从欧拉角构造一个4x4的旋转矩阵——实际上内部使用了四元数无论如何。根据您的代码片段,您似乎已经有了一个基本旋转作为四元数,您希望将其与扩展四元数连接起来,因此您可能不想在这种情况下使用此选项。
注意:你应该考虑使用 C++11 标准 <random>
而不是围绕糟糕的 C 编写的 lambda 包装器 rand
功能。
类似于:
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 wrapper for DirectXMath in DirectX Tool Kit。