moreveal
Известный
- 969
- 702
напрямую с мунлодеракак можно реализовать функцию convertScreenCoordsToWorld3D с луа на плюсы
чат гпт выдовал такой код
но он работает очень плохо и неправильноC++:#include <plugin.h> #include <game_sa/CCamera.h> #include <game_sa/CWorld.h> #include <game_sa/CColPoint.h> bool ConvertScreenCoordsToWorld3D(float screenX, float screenY, float& outX, float& outY, float& outZ) { auto viewMatrix = *(RwMatrix*)0xB6FA2C; CCamera* cam = TheCamera; float screenW = static_cast<float>(*reinterpret_cast<DWORD*>(0xC17044)); float screenH = static_cast<float>(*reinterpret_cast<DWORD*>(0xC17048)); float nx = (2.0f * screenX / screenW) - 1.0f; float ny = 1.0f - (2.0f * screenY / screenH); // перевёрнутый Y CVector forward(viewMatrix.at.x, viewMatrix.at.y, viewMatrix.at.z); CVector right(viewMatrix.right.x, viewMatrix.right.y, viewMatrix.right.z); CVector up(viewMatrix.up.x, viewMatrix.up.y, viewMatrix.up.z); float fov = cam->m_fFOV; float aspect = screenW / screenH; float fovRad = fov * 3.14159f / 180.0f; float tanFov = tanf(fovRad / 2.0f); CVector rayDir = forward + right * nx * aspect * tanFov + up * ny * tanFov; rayDir.Normalise(); CVector camPos = *cam->GetGameCamPosition(); CVector rayEnd = camPos + rayDir * 3000.0f; // дальность луча CColPoint col; CEntity* pHitEntity = nullptr; // трассировка с фильтрацией воды и прочего if (CWorld::ProcessLineOfSight( camPos, rayEnd, col, pHitEntity, true, true, true, true, false, true, false)) { outX = col.m_vecPoint.x; outY = col.m_vecPoint.y; outZ = col.m_vecPoint.z; return true; } return false; }
C++:
#include <d3d9.h>
#include <d3dx9.h>
void convertScreenCoordsToWorld3D(float screenX, float screenY, float depth, float* outX, float* outY, float* outZ)
{
static const uintptr_t pGameCamera = 0x0B6F028;
static const uintptr_t pRsGlobal = 0x0C17040;
D3DXMATRIX cameraMatrix;
std::memcpy(&cameraMatrix, reinterpret_cast<void*>(pGameCamera + 0xA04), sizeof(D3DXMATRIX));
cameraMatrix._44 = 1.0f;
D3DXMATRIX inverseMatrix;
if (!D3DXMatrixInverse(&inverseMatrix, nullptr, &cameraMatrix))
return;
int screenWidth = *reinterpret_cast<int*>(pRsGlobal + 4);
int screenHeight = *reinterpret_cast<int*>(pRsGlobal + 8);
if (screenWidth <= 0 || screenHeight <= 0 || depth == 0.0f)
return;
double invDepth = 1.0 / static_cast<double>(depth);
double normX = static_cast<double>(screenX) / (screenWidth * invDepth);
double normY = static_cast<double>(screenY) / (screenHeight * invDepth);
auto dx = static_cast<float>(normX);
auto dy = static_cast<float>(normY);
auto dz = depth;
*outX = inverseMatrix._11 * dx + inverseMatrix._21 * dy + inverseMatrix._31 * dz + inverseMatrix._41;
*outY = inverseMatrix._12 * dx + inverseMatrix._22 * dy + inverseMatrix._32 * dz + inverseMatrix._42;
*outZ = inverseMatrix._13 * dx + inverseMatrix._23 * dy + inverseMatrix._33 * dz + inverseMatrix._43;
}
Последнее редактирование: