Reputation: 456
I am going trough these 2 methods to calculate the lookat matrix
zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)
xaxis.x yaxis.x zaxis.x 0
xaxis.y yaxis.y zaxis.y 0
xaxis.z yaxis.z zaxis.z 0
-dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1
zaxis = normal(Eye - At)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)
xaxis.x yaxis.x zaxis.x 0
xaxis.y yaxis.y zaxis.y 0
xaxis.z yaxis.z zaxis.z 0
dot(xaxis, eye) dot(yaxis, eye) dot(zaxis, eye) 1
why is the translation for RH not multiplied by -1?
Upvotes: 0
Views: 317
Reputation: 41127
TL;DR: The Microsoft Doc page for D3DXMatrixLookAtRH
is wrong. I've filed a PR to fix it.
In the actual implementation of D3DXMath, it's clear that in both cases the Translation should be -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye)
for both LH & RH.
The only difference is the zaxis computation.
D3DXMATRIX* WINAPI D3DXMatrixLookAtRH
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
const D3DXVECTOR3 *pUp )
{
D3DXVECTOR3 XAxis, YAxis, ZAxis;
// Compute direction of gaze. (-Z)
D3DXVec3Subtract(&ZAxis, pEye, pAt);
D3DXVec3Normalize(&ZAxis, &ZAxis);
// Compute orthogonal axes from cross product of gaze and pUp vector.
D3DXVec3Cross(&XAxis, pUp, &ZAxis);
D3DXVec3Normalize(&XAxis, &XAxis);
D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);
// Set rotation and translate by pEye
pOut->_11 = XAxis.x;
pOut->_21 = XAxis.y;
pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);
pOut->_12 = YAxis.x;
pOut->_22 = YAxis.y;
pOut->_32 = YAxis.z;
pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);
pOut->_13 = ZAxis.x;
pOut->_23 = ZAxis.y;
pOut->_33 = ZAxis.z;
pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);
pOut->_14 = 0.0f;
pOut->_24 = 0.0f;
pOut->_34 = 0.0f;
pOut->_44 = 1.0f;
return pOut;
}
D3DXMATRIX* WINAPI D3DXMatrixLookAtLH
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
const D3DXVECTOR3 *pUp )
{
D3DXVECTOR3 XAxis, YAxis, ZAxis;
// Compute direction of gaze. (+Z)
D3DXVec3Subtract(&ZAxis, pAt, pEye);
D3DXVec3Normalize(&ZAxis, &ZAxis);
// Compute orthogonal axes from cross product of gaze and pUp vector.
D3DXVec3Cross(&XAxis, pUp, &ZAxis);
D3DXVec3Normalize(&XAxis, &XAxis);
D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);
// Set rotation and translate by pEye
pOut->_11 = XAxis.x;
pOut->_21 = XAxis.y;
pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);
pOut->_12 = YAxis.x;
pOut->_22 = YAxis.y;
pOut->_32 = YAxis.z;
pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);
pOut->_13 = ZAxis.x;
pOut->_23 = ZAxis.y;
pOut->_33 = ZAxis.z;
pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);
pOut->_14 = 0.0f;
pOut->_24 = 0.0f;
pOut->_34 = 0.0f;
pOut->_44 = 1.0f;
return pOut;
}
Both
D3DXMatrixLookAtRH
andD3DXMatrixLookAtLH
are part of "D3DXMath", the math library included in D3DX9 the D3DX10. These helper libraries are deprecated as is the DirectX SDK itself. The recommendation is to use DirectXMath instead.
If you must use D3DX9 for some reason, note you can avoid all the complicated issues covered on Microsoft Docs mixing the legacy DirectX SDK and modern versions of Visual Studio by just using the Microsoft.DXSDK.D3DX NuGet instead. New projects should move to any of the various replacements. See this blog post for more details.
Upvotes: 1