Другое С/С++ Вопрос - Ответ

tanksoftik

Новичок
10
3
как можно реализовать функцию 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;
}
но он работает очень плохо и неправильно
 

AdCKuY_DpO4uLa

Адский дрочер
Друг
345
757
как можно реализовать функцию 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++:
void CalcScreenCoors(CVector* vecWorld, CVector* vecScreen)
    {
        D3DXMATRIX m((float*)(0xB6FA2C));

        DWORD* dwLenX = (DWORD*)(0xC17044);
        DWORD* dwLenY = (DWORD*)(0xC17048);

        vecScreen->x = (vecWorld->z * m._31) + (vecWorld->y * m._21) + (vecWorld->x * m._11) + m._41;
        vecScreen->y = (vecWorld->z * m._32) + (vecWorld->y * m._22) + (vecWorld->x * m._12) + m._42;
        vecScreen->z = (vecWorld->z * m._33) + (vecWorld->y * m._23) + (vecWorld->x * m._13) + m._43;

        double    fRecip = (double)1.0 / vecScreen->z;
        vecScreen->x *= (float)(fRecip * (*dwLenX));
        vecScreen->y *= (float)(fRecip * (*dwLenY));
    }

    void CalcWorldCoors(CVector* vecScreen, CVector* vecWorld)
    {
        D3DXMATRIXA16 m((float*)(0xB6FA2C));

        D3DXMATRIXA16 minv;
        memset(&minv, 0, sizeof(D3DXMATRIXA16));
        m._44 = 1.0f;

        D3DXMatrixInverse(&minv, NULL, &m);

        DWORD* dwLenX = (DWORD*)(0xC17044);
        DWORD* dwLenY = (DWORD*)(0xC17048);

        float fRecip = 1.0f / vecScreen->z;
        vecScreen->x /= fRecip * (*dwLenX);
        vecScreen->y /= fRecip * (*dwLenY);

        vecWorld->x = vecScreen->z * minv._31 + vecScreen->y * minv._21 + vecScreen->x * minv._11 + minv._41;
        vecWorld->y = vecScreen->z * minv._32 + vecScreen->y * minv._22 + vecScreen->x * minv._12 + minv._42;
        vecWorld->z = vecScreen->z * minv._33 + vecScreen->y * minv._23 + vecScreen->x * minv._13 + minv._43;
    }
 

moreveal

Известный
Модератор
946
666
как можно реализовать функцию 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;
}
но он работает очень плохо и неправильно
напрямую с мунлодера спиздил взял, пусть тебе и скинули уже ответ, но зато оно идентично луашному convertScreenCoordsToWorld3D:
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;
}
 
Последнее редактирование:
  • Нравится
Реакции: whyega52 и ARMOR

0xff65

Новичок
27
2
Приветствую, пытаюсь собрать plugin-sdk. Возникает такая проблема -
Код:
1>CCoronas.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected: No such file or directory,
1>CCover.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected: No such file or directory,
1>CCoverPoint.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected: No such file or directory,
1>CCredits.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected:
Сборка выполняется на Visual Studio 19
 

san0

Известный
Друг
412
275
Приветствую, пытаюсь собрать plugin-sdk. Возникает такая проблема -
Код:
1>CCoronas.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected: No such file or directory,
1>CCover.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected: No such file or directory,
1>CCoverPoint.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected: No such file or directory,
1>CCredits.cpp
1>D:\plugin-sdk-master\safetyhook\safetyhook.hpp(38,10): fatal error C1083: Не удается открыть файл включение: expected:
Сборка выполняется на Visual Studio 19
std::expected это часть редакции стандарта C++23 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html).
В MSVC(CL) он доступен начиная с Visual Studio 2022 17.3 (_MSC_VER >= 1933) (https://github.com/microsoft/STL/commit/b7ba3ad82f330d606fc9b317940304223308ac8b).

Сам проект должен быть настроен с использованием /std:c++23preview или /std:c++latest (https://learn.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version). А для проверке на этапе сборки можно воспользоваться макросом __cpp_lib_expected
(https://en.cppreference.com/w/cpp/feature_test#cpp_lib_expected).

Если такая функциональность нужна в том окружении, где последние реализации недоступны, то можно воспользоваться похожими абстракциями из популярных библиотек типа StatusOr<T> из abseil или checked из Boost.Outcome. И кстати не стоит забывать за возможность поставить относительно портабельный и легковесный mingw (https://www.mingw-w64.org/, https://github.com/mstorsjo/llvm-mingw/releases), хотя думаю там также могут быть понадобиться модификации кода.

В Вашем случае полагаю проще будет или поставить любой бекпорт:

Либо просто взять старую версию plugin-sdk:
История изменений => https://github.com/DK22Pac/plugin-sdk/commits/master/safetyhook/safetyhook.cpp
Предыдущий коммит до добавления safetyhook => https://github.com/DK22Pac/plugin-sdk/tree/380105ec5242cdb3a0cbc18505b151308dd85b53

И конечно можно еще сделать git revert (https://git-scm.com/docs/git-revert) в master ветке, отменив кокретно добавление этой библиотеки, но это требует небольшого знания системы контроля версий, а также потребует некоторых изменений в коде, тем более что Вы не указали контекст использования (например, safetyhook - осознанный выбор в связи с поддержкой 64 битной трилогии которая unreal engine)
 

whyega52

Eblang головного мозга
Модератор
2,877
2,853
проблема есть я через RpGeometryForAllMaterials(atomic->geometry, material_callback, veh); крашу текстуру и все норм типо material->color нормально применяется, а если делать material->texture = texture; то в таком случае получается так что применяется на модель, а не на cvehicle и еще оно применяется только при спавне машины после спавна нельзя изменить текстуру. Как это можно исправить?
Нужно в каллбеке перед вызовом функции рендера изменять текстурой, а в каллбеке после вызова функции возвращать старую текстуру
 

TheLeftExit

Участник
29
15
Приветы, а можно как-то внутри C++ хука, зарегистрированного в registerChatCommand, асинхронно ждать внутри своего кода?
Допустим, у меня есть такое:
псевдокод:
SF->getCLEO()->callOpcode("0C8F: samp process_chat_input \"1\"");
// спать 300
SF->getCLEO()->callOpcode("0C8F: samp process_chat_input \"2\"");
// спать 300
SF->getCLEO()->callOpcode("0C8F: samp process_chat_input \"3\"");

На деле код спит полсекунды и затем все три строки в чат одновременно выдаёт (и две из них отлетают антифлудом). Cleo/sampfuncs дают какой-то способ поставить свой код в очередь выполняться через X мс?

Или если я могу сам подождать в соседнем треде, а потом отправить остальной код выполняться в нужный (как Control.Invoke), так ещё лучше.

upd: похоже, я могу спокойно гонять callOpcode из соседнего треда, в котором sleep ничего не блокирует. Вопрос снят :)
 
Последнее редактирование:

TheLeftExit

Участник
29
15
Вопрос выше снова актуален. Оказывается, вызов клео из соседних тредов небезопасен; я в одной функции добавил вообщение в чат (AddChatMessage) и запустил тред, который добавляет другое сообщение в чат, и в итоге второе сообщение превратилось в какую-то юникодную букву (вылечилось только комментированием AddChatMessage из кода соседнего треда).

Либо в принципе как-то потоко-безопасно выполнять код, когда игрок нажмёт нужные мне кнопки. Я могу чекать в цикле isKeyPressed/isKeyDown, но непонятно как в C++ это делать и не блокировать игру. В Lua делают wait(0), я полагаю moonloader это интерпретирует как "вернуться к скрипту в следующий фрейм", вот мне надо как-то сделать то же самое в C++.
 
Последнее редактирование: