如何正确使用XMVECTOR成员变量

发布于 2024-11-26 00:44:22 字数 871 浏览 1 评论 0原文

我有一个简单的 IRenderable 类,其中包含用于位置、缩放和旋转的成员:

XMFLOAT3 _position;
XMFLOAT3 _scaling;
XMVECTOR _rotation;

我尝试使用构造函数设置它们。这里的第一个方法给出了访问冲突 0x00000000 尝试设置 _rotation (_position 和 _scaling 都设置得很好):

IRenderable() : _position(XMFLOAT3(0, 0, 0)), _scaling(XMFLOAT3(1, 1, 1)), _rotation(XMQuaternionIdentity()) { }

将 _rotation 设为 XMVECTOR* 并在构造函数中使用 _rotation(new XMVECTOR()) 将其设置为空 XMVECTOR,但随后稍后在尝试设置身份四元数时抛出访问冲突:

*_rotation = XMQuaternionIdentity();

在构造函数中使用 XMQuaternionIdentity 的地址可以正常工作创建对象,

IRenderable() : _position(new XMFLOAT3(0, 0, 0)), _scaling(new XMFLOAT3(1, 1, 1)), _rotation(&XMQuaternionIdentity()) { }

但四元数本身在需要用于渲染时包含垃圾数据。 _position 和 _scaling 在所有这些情况下都工作正常。

在这种情况下使用 XMVECTOR 的正确方法是什么?

I have a simple IRenderable class that has members for position, scaling, and rotation:

XMFLOAT3 _position;
XMFLOAT3 _scaling;
XMVECTOR _rotation;

I am attempting to set them with the constructor. The first method here gives an access violation 0x00000000 trying to set _rotation (_position and _scaling are both set fine):

IRenderable() : _position(XMFLOAT3(0, 0, 0)), _scaling(XMFLOAT3(1, 1, 1)), _rotation(XMQuaternionIdentity()) { }

Making _rotation an XMVECTOR* instead and using _rotation(new XMVECTOR()) in the constructor sets it to an empty XMVECTOR, but then throws an access violation later when trying to set the identity Quaternion:

*_rotation = XMQuaternionIdentity();

Using the address of the XMQuaternionIdentity in the constructor works fine when creating the object,

IRenderable() : _position(new XMFLOAT3(0, 0, 0)), _scaling(new XMFLOAT3(1, 1, 1)), _rotation(&XMQuaternionIdentity()) { }

but then the quaternion itself contains garbage data by the time it needs to be used to render with. Both _position and _scaling are working fine in all of these situations.

What is the correct way to use XMVECTOR in this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

筱果果 2024-12-03 00:44:22

一般来说,您应该避免在结构中使用 XMVECTOR。 XMFLOAT# 类是存储类,应用于一般存储。但是,如果您将结构声明为对齐的,则可以使用 XMVECTOR。

http://msdn.microsoft.com/en-us/library/83ythb65.aspx

__declspec(align(16)) struct A{ XMVECTOR a, b, c, d, e; };

但我相信,如果你这样做,那么每个包含 A 的结构也必须是 16 字节对齐(或 32、48 等)。一般来说,使用存储类更容易、更清晰,当您要进行一些计算 (XMLoadFloat4) 并存储回 XMFLOAT# (XMStoreFloat4) 时,或者当您接收时,只需转换为 XMVECTOR 或 XMMATRIX函数的值(请务必阅读http://msdn.microsoft.com/en-us/library /windows/desktop/ee418728(v=vs.85).aspx ),或从函数返回值。

In general you should avoid using XMVECTOR in a struct. The XMFLOAT# classes are the storage classes, and should be used for general storage. You can however use the XMVECTOR if you declare the structure as aligned.

http://msdn.microsoft.com/en-us/library/83ythb65.aspx

__declspec(align(16)) struct A{ XMVECTOR a, b, c, d, e; };

but I believe that if you do this then every structure that has an A in it, must also be 16 byte aligned (or 32, 48 etc). In general, it is much easier and clearer to use the storage classes, and just convert to the XMVECTOR or XMMATRIX when you are going to do some calculation (XMLoadFloat4) and storing back into an XMFLOAT# (XMStoreFloat4), or when you take in values for functions (be sure to read http://msdn.microsoft.com/en-us/library/windows/desktop/ee418728(v=vs.85).aspx ), or returning values from functions.

多孤肩上扛 2024-12-03 00:44:22

为了解决 Eitenne 提到的错误,我简单地制作了一个 AxisAngle 结构:

struct AxisAngle {
    XMFLOAT3 Axis;
    float Angle;

    AxisAngle() : Axis(XMFLOAT3(0, 0, 0)), Angle(0) { }

    AxisAngle(XMFLOAT3 axis, float angle) {
        Axis = axis;
        Angle = angle;
    }
};

使用它代替 XMVECTOR 进行旋转,然后在渲染时仅使用以下内容来获取旋转矩阵:

XMMATRIX rotation = XMMatrixRotationNormal(XMLoadFloat3(&_rotation->Axis), _rotation->Angle);

显然这只是一种解决方法,真正的解决方案需要在编译器中进行修复,以允许 XMVECTOR 堆上有 16 位边界。

To work around the bug Eitenne mentioned, I simply made an AxisAngle struct:

struct AxisAngle {
    XMFLOAT3 Axis;
    float Angle;

    AxisAngle() : Axis(XMFLOAT3(0, 0, 0)), Angle(0) { }

    AxisAngle(XMFLOAT3 axis, float angle) {
        Axis = axis;
        Angle = angle;
    }
};

Using this in place of the XMVECTOR for rotation and then at render time just using the following to get the rotation matrix:

XMMATRIX rotation = XMMatrixRotationNormal(XMLoadFloat3(&_rotation->Axis), _rotation->Angle);

Obviously this is only a workaround and the real solution needs to be fixed in the compiler to allow the 16 bit boundaries on the heap for XMVECTOR.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文