Search code examples
c++directx-11xna-math-library

How to properly use an XMVECTOR member variable


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?


Solution

  • 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.