Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions Core/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,14 +717,15 @@ void LightMapTerrainTextureClass::Apply(unsigned int stage)

D3DXMATRIX inv;
float det;
D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
D3DXMATRIX d3dCurView = Build_D3DXMATRIX(curView);
D3DXMatrixInverse(&inv, &det, &d3dCurView);
D3DXMATRIX scale;
D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1);
inv *=scale;
if (stage==0) {
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&inv));
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, inv);
} if (stage==1) {
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4x4*)&inv));
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, inv);
}


Expand Down Expand Up @@ -971,7 +972,8 @@ void CloudMapTerrainTextureClass::Apply(unsigned int stage)

D3DXMATRIX inv;
float det;
D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
D3DXMATRIX d3dCurView = Build_D3DXMATRIX(curView);
D3DXMatrixInverse(&inv, &det, &d3dCurView);
D3DXMATRIX scale;
D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1);
inv *=scale;
Expand Down Expand Up @@ -999,7 +1001,7 @@ void CloudMapTerrainTextureClass::Apply(unsigned int stage)
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&inv));
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, inv);

// Disable 3rd stage just in case.
DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
Expand All @@ -1018,7 +1020,7 @@ void CloudMapTerrainTextureClass::Apply(unsigned int stage)
DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT );
DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4x4*)&inv));
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, inv);
}
#endif
}
Expand Down
168 changes: 98 additions & 70 deletions Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1717,9 +1717,9 @@ void W3DTreeBuffer::drawTrees(CameraClass * camera, RefRenderObjListIterator *pD

if (m_dwTreeVertexShader) {
D3DXMATRIX matProj, matView, matWorld;
DX8Wrapper::_Get_DX8_Transform(D3DTS_WORLD, *(Matrix4x4*)&matWorld);
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, *(Matrix4x4*)&matView);
DX8Wrapper::_Get_DX8_Transform(D3DTS_PROJECTION, *(Matrix4x4*)&matProj);
DX8Wrapper::_Get_DX8_Transform(D3DTS_WORLD, matWorld);
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, matView);
DX8Wrapper::_Get_DX8_Transform(D3DTS_PROJECTION, matProj);
D3DXMATRIX mat;
D3DXMatrixMultiply( &mat, &matView, &matProj );
D3DXMatrixMultiply( &mat, &matWorld, &mat );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,16 +240,16 @@ void WaterRenderObjClass::setupJbaWaterShader(void)
D3DXMATRIX inv;
float det;

Matrix4x4 curView;
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
D3DXMATRIX d3dCurView;
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, d3dCurView);
D3DXMatrixInverse(&inv, &det, &d3dCurView);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this inverse meant to be a transpose or does it really want to do the inverse here on a D3DXMATRIX that is in DX coordinates?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure - the old code cast a column-major Matrix4x4 to D3DXMATRIX* (row-major) without conversion, then inverted.
For orthogonal view matrices, inverse equals transpose.
In the Thyme commit, they still use D3DXMatrixInverse after removing the casts, so maybe inverse is intended? I'm going to test both and see what's right.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just played a skirmish with this build, and it seems normal to me. I imagine it would be very obvious if matrix math was inverted. I suppose I could run two clients and set a breakpoint and see if any values differ? What would you recommend?

Copy link
Author

@bobtista bobtista Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok update: I spent today testing and debugging this. I think it's ready now.

On main:

  • Matrix4x4 and D3DMATRIX have the same memory layout (both row-major in memory).
  • The unsafe cast is a direct memory copy with no transpose, which worked because both types share the same memory layout.

Main branch: Matrix4x4 M → direct copy → D3DMATRIX (same bytes) → direct copy → Matrix4x4 M
Fix branch: Matrix4x4 M → transpose → D3DMATRIX M^T → transpose → Matrix4x4 M

In today's testing I noticed that the ship cannon fire animations were glitching in the shell map.
The issue was that, while projection is directly sent to directx8 (transposed) and then we get it from directx8 (transpoesd), render_state.world and render_state.view are cached as Matrix4x4, only transposed when we send them to directx8 - and we can get them from the cache as Matrix4x4 too. The bug was that I was transposing world and view, but they're already in the right format. Once I removed the extra transpose, the cannon fire animations were back to normal.

I added debug lines and verified that the math now comes out the same on main and the branch (in the previous commit, the math was sometimes off because of the extra transpose).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this branch uses D3DXMatrixInverse() in W3DWater.cpp (lines 245, 1605, and 3001). This seems to be consistent with both main and the Thyme change. I tested changing them to D3DXMatrixTranspose() during debugging and water rendering still looked correct, but I haven't committed those changes. Google says For orthogonal matrices (rotation only), inverse = transpose, so if the view matrix is orthogonal at those points, transpose would be correct and more efficient. It's correct as it is, and matches the original, so I left it this way.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I found that I needed to update a bunch of other callers with my approach from before, and it was making the diff bigger. So, instead of storing Matrix4x4 in RenderStateStruct and converting at every use site, we now store D3DXMATRIX directly - this is more like how it was in the Thyme version too. Tested again, it looks good.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes storing D3DMATRIX in RenderStateStruct makes sense.

I reimplemented the change with #2052 from scratch because I was not entirely happy with the implementation details of this change.

D3DXMATRIX scale;

D3DXMatrixScaling(&scale, NOISE_REPEAT_FACTOR, NOISE_REPEAT_FACTOR,1);
D3DXMATRIX destMatrix = inv * scale;
D3DXMatrixTranslation(&scale, m_riverVOrigin, m_riverVOrigin,0);
destMatrix = destMatrix*scale;
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, *(Matrix4x4*)&destMatrix);
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, destMatrix);

}
m_pDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
Expand Down Expand Up @@ -1596,13 +1596,13 @@ void WaterRenderObjClass::Render(RenderInfoClass & rinfo)
D3DXMATRIX inv;
D3DXMATRIX clipMatrix;
Real det;
Matrix4x4 curView;

//get current view matrix
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
D3DXMATRIX d3dCurView;
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, d3dCurView);

//get inverse of view matrix(= view to world matrix)
D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
D3DXMatrixInverse(&inv, &det, &d3dCurView);

//create clipping matrix by inserting our plane equation into the 1st column
D3DXMatrixIdentity(&clipMatrix);
Expand All @@ -1622,7 +1622,7 @@ void WaterRenderObjClass::Render(RenderInfoClass & rinfo)
DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);

// Set texture generation matrix for stage 1
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4*)&inv));
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, inv);

// Disable bilinear filtering
DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
Expand Down Expand Up @@ -1800,8 +1800,8 @@ void WaterRenderObjClass::drawSea(RenderInfoClass & rinfo)

rinfo.Camera.Get_Transform().Get_Translation(&camTran);

DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, *(Matrix4x4*)&matView);
DX8Wrapper::_Get_DX8_Transform(D3DTS_PROJECTION, *(Matrix4x4*)&matProj);
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, matView);
DX8Wrapper::_Get_DX8_Transform(D3DTS_PROJECTION, matProj);

//default setup from Kenny's demo
m_pDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
Expand Down Expand Up @@ -1941,8 +1941,8 @@ void WaterRenderObjClass::drawSea(RenderInfoClass & rinfo)
m_pDev->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

//Restore old transforms
DX8Wrapper::_Set_DX8_Transform(D3DTS_VIEW, *(Matrix4x4*)&matView);
DX8Wrapper::_Set_DX8_Transform(D3DTS_PROJECTION, *(Matrix4x4*)&matProj);
DX8Wrapper::_Set_DX8_Transform(D3DTS_VIEW, matView);
DX8Wrapper::_Set_DX8_Transform(D3DTS_PROJECTION, matProj);

m_pDev->SetPixelShader(0); //turn off pixel shader
m_pDev->SetVertexShader(DX8_FVF_XYZDUV1); //turn off custom vertex shader
Expand All @@ -1966,7 +1966,7 @@ void WaterRenderObjClass::drawSea(RenderInfoClass & rinfo)

D3DXMatrixMultiply(&matTemp, &patchMatrix, &matWW3D);

DX8Wrapper::_Set_DX8_Transform(D3DTS_WORLD, *(Matrix4x4*)&matTemp);
DX8Wrapper::_Set_DX8_Transform(D3DTS_WORLD, matTemp);

m_pDev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,m_numVertices,0,m_numIndices);
}
Expand Down Expand Up @@ -2996,16 +2996,16 @@ void WaterRenderObjClass::setupFlatWaterShader(void)
D3DXMATRIX inv;
float det;

Matrix4x4 curView;
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
D3DXMATRIX d3dCurView;
DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, d3dCurView);
D3DXMatrixInverse(&inv, &det, &d3dCurView);
D3DXMATRIX scale;

D3DXMatrixScaling(&scale, NOISE_REPEAT_FACTOR, NOISE_REPEAT_FACTOR,1);
D3DXMATRIX destMatrix = inv * scale;
D3DXMatrixTranslation(&scale, m_riverVOrigin, m_riverVOrigin,0);
destMatrix = destMatrix*scale;
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, *(Matrix4x4*)&destMatrix);
DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, destMatrix);

}
m_pDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
Expand Down
5 changes: 4 additions & 1 deletion Core/Libraries/Source/WWVegas/WWMath/matrix3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,10 @@ void Matrix3D::Get_Inverse(Matrix3D & inv) const
Matrix4x4 mat4Inv;

float det;
D3DXMatrixInverse((D3DXMATRIX *)&mat4Inv, &det, (D3DXMATRIX*)&mat4);
D3DXMATRIX d3dMat = Build_D3DXMATRIX(mat4);
D3DXMATRIX d3dMatInv;
D3DXMatrixInverse(&d3dMatInv, &det, &d3dMat);
Build_Matrix4(mat4Inv, d3dMatInv);

inv.Row[0][0]=mat4Inv[0][0];
inv.Row[0][1]=mat4Inv[0][1];
Expand Down
83 changes: 83 additions & 0 deletions Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,86 @@
return (!(a == b));
}

#ifdef BUILD_WITH_D3D8
#define WIN32_LEAN_AND_MEAN

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-profile+t+e

'WIN32_LEAN_AND_MEAN' : macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6+t+e

'WIN32_LEAN_AND_MEAN' : macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / vc6-profile+t+e

'WIN32_LEAN_AND_MEAN' : macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / vc6+t+e

'WIN32_LEAN_AND_MEAN' : macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / vc6-releaselog+t+e

'WIN32_LEAN_AND_MEAN' : macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / win32-debug+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-debug+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-vcpkg-debug+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-profile+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / win32-vcpkg-debug+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-vcpkg-profile+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / win32-profile+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / win32+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-vcpkg+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / win32-vcpkg-profile+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition

Check warning on line 199 in Core/Libraries/Source/WWVegas/WWMath/matrix4.cpp

View workflow job for this annotation

GitHub Actions / Build GeneralsMD / win32-vcpkg+t+e

'WIN32_LEAN_AND_MEAN': macro redefinition
#include <windows.h>
#include "d3d8types.h"
#include "d3dx8.h"

void Build_D3DMATRIX(D3DMATRIX& dxm, const Matrix4x4& m)
{
// Transpose: dxm.m[i][j] = m[j][i]
dxm.m[0][0] = m[0][0];
dxm.m[0][1] = m[1][0];
dxm.m[0][2] = m[2][0];
dxm.m[0][3] = m[3][0];

dxm.m[1][0] = m[0][1];
dxm.m[1][1] = m[1][1];
dxm.m[1][2] = m[2][1];
dxm.m[1][3] = m[3][1];

dxm.m[2][0] = m[0][2];
dxm.m[2][1] = m[1][2];
dxm.m[2][2] = m[2][2];
dxm.m[2][3] = m[3][2];

dxm.m[3][0] = m[0][3];
dxm.m[3][1] = m[1][3];
dxm.m[3][2] = m[2][3];
dxm.m[3][3] = m[3][3];
}

D3DXMATRIX Build_D3DXMATRIX(const Matrix4x4& m)
{
// Transpose: result[i][j] = m[j][i]
return D3DXMATRIX(
m[0][0], m[1][0], m[2][0], m[3][0],
m[0][1], m[1][1], m[2][1], m[3][1],
m[0][2], m[1][2], m[2][2], m[3][2],
m[0][3], m[1][3], m[2][3], m[3][3]
);
}

void Build_Matrix4(Matrix4x4& m, const D3DMATRIX& dxm)
{
// Transpose: m[i][j] = dxm.m[j][i]
m[0][0] = dxm.m[0][0];
m[0][1] = dxm.m[1][0];
m[0][2] = dxm.m[2][0];
m[0][3] = dxm.m[3][0];

m[1][0] = dxm.m[0][1];
m[1][1] = dxm.m[1][1];
m[1][2] = dxm.m[2][1];
m[1][3] = dxm.m[3][1];

m[2][0] = dxm.m[0][2];
m[2][1] = dxm.m[1][2];
m[2][2] = dxm.m[2][2];
m[2][3] = dxm.m[3][2];

m[3][0] = dxm.m[0][3];
m[3][1] = dxm.m[1][3];
m[3][2] = dxm.m[2][3];
m[3][3] = dxm.m[3][3];
}

Matrix4x4 Build_Matrix4(const D3DMATRIX& dxm)
{
Matrix4x4 m;
Build_Matrix4(m, dxm);
return m;
}

void Build_Matrix4(Matrix4x4& m, const D3DXMATRIX& dxm)
{
Build_Matrix4(m, (const D3DMATRIX&)dxm);
}

Matrix4x4 Build_Matrix4(const D3DXMATRIX& dxm)
{
return Build_Matrix4((const D3DMATRIX&)dxm);
}
#endif

19 changes: 19 additions & 0 deletions Core/Libraries/Source/WWVegas/WWMath/matrix4.h
Original file line number Diff line number Diff line change
Expand Up @@ -836,3 +836,22 @@ WWINLINE void Matrix4x4::Transform_Vector(const Matrix4x4 & A,const Vector4 & in
out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z + A[2][3] * v->W);
out->W = (A[3][0] * v->X + A[3][1] * v->Y + A[3][2] * v->Z + A[3][3] * v->W);
}

#ifdef BUILD_WITH_D3D8
struct _D3DMATRIX;
typedef struct _D3DMATRIX D3DMATRIX;
struct D3DXMATRIX;

// When converting Matrix4x4 to D3DMATRIX or vice versa always use conversion functions below.
// Reason being, D3DMATRIX is row major matrix, and Matrix4x4 is column major matrix.
// Thus copying from one to another will always require a transpose (or invert).

void Build_D3DMATRIX(D3DMATRIX& dxm, const Matrix4x4& m);
D3DXMATRIX Build_D3DXMATRIX(const Matrix4x4& m);

void Build_Matrix4(Matrix4x4& m, const D3DMATRIX& dxm);
Matrix4x4 Build_Matrix4(const D3DMATRIX& dxm);
void Build_Matrix4(Matrix4x4& m, const D3DXMATRIX& dxm);
Matrix4x4 Build_Matrix4(const D3DXMATRIX& dxm);
#endif

Original file line number Diff line number Diff line change
Expand Up @@ -1907,7 +1907,10 @@ void W3DVolumetricShadow::updateMeshVolume(Int meshIndex, Int lightIndex, const
// system change, not the translations
//
Real det;
D3DXMatrixInverse((D3DXMATRIX*)&worldToObject, &det, (D3DXMATRIX*)&objectToWorld);
D3DXMATRIX d3dObjectToWorld = Build_D3DXMATRIX(objectToWorld);
D3DXMATRIX d3dWorldToObject;
D3DXMatrixInverse(&d3dWorldToObject, &det, &d3dObjectToWorld);
Build_Matrix4(worldToObject, (D3DMATRIX&)d3dWorldToObject);

// find out light position in object space
Matrix4x4::Transform_Vector(worldToObject,lightPosWorld,&lightPosObject);
Expand Down
Loading
Loading