Why does XMVector3Transform return multiplcation by the transpose?

26 Views Asked by At

I have a XMFLOAT4X4 matrix m. Mathematically, I should obtain the last column of this matrix by multiplying m with the vector (0, 0, 0, 1).

I only need the first three components of that column. For that reason, I've tried the following computation:

XMFLOAT3 x{};
XMStoreFloat3(&y, XMVector3Transform(XMLoadFloat3(&x), m));

I'm obviously assuming here that XMVector3Transform(XMLoadFloat3(&x), m) is computing "(m * (0, 0, 0, 1)).xyz". Maybe this assumption is wrong.

Anyways, what I'm getting are the first three components of the last row instead. That is, I'm actually getting what I expected, but with m replaced by the transpose of m. Why is that and how can I get the right result (by a matrix-vector multiplication)?

1

There are 1 best solutions below

3
Chuck Walbourn On BEST ANSWER

DirectXMath provides C++ implementations of all functions, so you can see them in the .inl files:

XMVECTOR XM_CALLCONV XMVector3Transform
(
    FXMVECTOR V,
    FXMMATRIX M
) noexcept
{
    XMVECTOR Z = XMVectorSplatZ(V);
    XMVECTOR Y = XMVectorSplatY(V);
    XMVECTOR X = XMVectorSplatX(V);

    XMVECTOR Result = XMVectorMultiplyAdd(Z, M.r[2], M.r[3]);
    Result = XMVectorMultiplyAdd(Y, M.r[1], Result);
    Result = XMVectorMultiplyAdd(X, M.r[0], Result);

    return Result;
}

This is a normal vector/matrix multiply assuming the implied 'w' in the vector3 is a 1.

The result is NOT guaranteed to be a 3-vector with an implied 1. That's why there are other functions like XMVector3TransformCoord which divides by W and XMVector3TransformNormal which ignores the offset in the transformation matrix.

Technically to transform a normal, you use the inverse of the transpose, and for pure rotation that results in the same matrix.