Apply 3D transformations (#168)

This commit is contained in:
Anders Jenbo 2025-05-25 16:26:22 +02:00 committed by GitHub
parent c6e5e10921
commit f2a4ce9353
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -30,14 +30,35 @@ Direct3DRMViewportImpl::~Direct3DRMViewportImpl()
FreeDeviceResources(); FreeDeviceResources();
} }
void D3DRMMatrixMultiply(D3DRMMATRIX4D out, const D3DRMMATRIX4D a, const D3DRMMATRIX4D b)
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
out[i][j] = 0.0f;
for (int k = 0; k < 4; ++k) {
out[i][j] += a[i][k] * b[k][j];
}
}
}
}
HRESULT Direct3DRMViewportImpl::CollectSceneData(IDirect3DRMFrame* group) HRESULT Direct3DRMViewportImpl::CollectSceneData(IDirect3DRMFrame* group)
{ {
MINIWIN_NOT_IMPLEMENTED(); // Lights, textures, materials MINIWIN_NOT_IMPLEMENTED(); // Lights, camera, textures, materials
std::vector<PositionColorVertex> verts; std::vector<PositionColorVertex> verts;
std::function<void(IDirect3DRMFrame*)> recurseFrame; std::function<void(IDirect3DRMFrame*, D3DRMMATRIX4D)> recurseFrame;
recurseFrame = [&](IDirect3DRMFrame* frame, D3DRMMATRIX4D parentMatrix) {
// Retrieve the current frame's transform
Direct3DRMFrameImpl* frameImpl = static_cast<Direct3DRMFrameImpl*>(frame);
D3DRMMATRIX4D localMatrix;
memcpy(localMatrix, frameImpl->m_transform, sizeof(D3DRMMATRIX4D));
// Compute combined world matrix: world = parent * local
D3DRMMATRIX4D worldMatrix;
D3DRMMatrixMultiply(worldMatrix, parentMatrix, localMatrix);
recurseFrame = [&](IDirect3DRMFrame* frame) {
IDirect3DRMVisualArray* va = nullptr; IDirect3DRMVisualArray* va = nullptr;
if (SUCCEEDED(frame->GetVisuals(&va)) && va) { if (SUCCEEDED(frame->GetVisuals(&va)) && va) {
DWORD n = va->GetSize(); DWORD n = va->GetSize();
@ -55,19 +76,32 @@ HRESULT Direct3DRMViewportImpl::CollectSceneData(IDirect3DRMFrame* group)
for (DWORD gi = 0; gi < groupCount; ++gi) { for (DWORD gi = 0; gi < groupCount; ++gi) {
DWORD vtxCount, faceCount, vpf, dataSize; DWORD vtxCount, faceCount, vpf, dataSize;
mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, &dataSize, nullptr); mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, &dataSize, nullptr);
std::vector<D3DRMVERTEX> d3dVerts(vtxCount); std::vector<D3DRMVERTEX> d3dVerts(vtxCount);
std::vector<DWORD> faces(faceCount * vpf); std::vector<DWORD> faces(faceCount * vpf);
mesh->GetVertices(gi, 0, vtxCount, d3dVerts.data()); mesh->GetVertices(gi, 0, vtxCount, d3dVerts.data());
mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, nullptr, faces.data()); mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, nullptr, faces.data());
D3DCOLOR color = mesh->GetGroupColor(gi); D3DCOLOR color = mesh->GetGroupColor(gi);
for (DWORD fi = 0; fi < faceCount; ++fi) { for (DWORD fi = 0; fi < faceCount; ++fi) {
for (int idx = 0; idx < vpf; ++idx) { for (int idx = 0; idx < vpf; ++idx) {
auto& dv = d3dVerts[faces[fi * vpf + idx]]; auto& dv = d3dVerts[faces[fi * vpf + idx]];
// Apply world transform to the vertex
D3DVECTOR pos = dv.position;
D3DVECTOR worldPos;
worldPos.x = pos.x * worldMatrix[0][0] + pos.y * worldMatrix[1][0] +
pos.z * worldMatrix[2][0] + worldMatrix[3][0];
worldPos.y = pos.x * worldMatrix[0][1] + pos.y * worldMatrix[1][1] +
pos.z * worldMatrix[2][1] + worldMatrix[3][1];
worldPos.z = pos.x * worldMatrix[0][2] + pos.y * worldMatrix[1][2] +
pos.z * worldMatrix[2][2] + worldMatrix[3][2];
PositionColorVertex vtx; PositionColorVertex vtx;
vtx.x = dv.position.x; vtx.x = worldPos.x;
vtx.y = dv.position.y; vtx.y = worldPos.y;
vtx.z = dv.position.z; vtx.z = worldPos.z;
vtx.a = (color >> 24) & 0xFF; vtx.a = (color >> 24) & 0xFF;
vtx.r = (color >> 16) & 0xFF; vtx.r = (color >> 16) & 0xFF;
vtx.g = (color >> 8) & 0xFF; vtx.g = (color >> 8) & 0xFF;
@ -79,10 +113,10 @@ HRESULT Direct3DRMViewportImpl::CollectSceneData(IDirect3DRMFrame* group)
mesh->Release(); mesh->Release();
} }
// Recurse over sub-frames // Recurse into child frames
IDirect3DRMFrame* childFrame = nullptr; IDirect3DRMFrame* childFrame = nullptr;
if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMFrame, (void**) &childFrame)) && childFrame) { if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMFrame, (void**) &childFrame)) && childFrame) {
recurseFrame(childFrame); recurseFrame(childFrame, worldMatrix);
childFrame->Release(); childFrame->Release();
} }
@ -92,7 +126,9 @@ HRESULT Direct3DRMViewportImpl::CollectSceneData(IDirect3DRMFrame* group)
} }
}; };
recurseFrame(group); D3DRMMATRIX4D identity = {{1.f, 0.f, 0.f, 0.f}, {0.f, 1.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}};
recurseFrame(group, identity);
PushVertices(verts.data(), verts.size()); PushVertices(verts.data(), verts.size());