Информация Полезные функции

Slppp

Участник
42
3
возвращает z координаты на определенных координатах

C++:
float FindGroundZForPosition(float fX, float fY)
{
    DWORD dwFunc = 0x569660;
    FLOAT fReturn = 0;
    _asm
    {
        push    fY
        push    fX
        call    dwFunc
        fstp    fReturn
        add        esp, 8
    }
    return fReturn;
}
 
  • Bug
Реакции: Dark_Knight

kin4stat

mq-team
Всефорумный модератор
2,731
4,692
возвращает z координаты на определенных координатах

C++:
float FindGroundZForPosition(float fX, float fY)
{
    DWORD dwFunc = 0x569660;
    FLOAT fReturn = 0;
    _asm
    {
        push    fY
        push    fX
        call    dwFunc
        fstp    fReturn
        add        esp, 8
    }
    return fReturn;
}
Спасибо мы тоже умеем смотреть в сорсы МТА и любим обмазываться ассемблером.
C++:
float fZ = ((float(__cdecl*)(float,float))0x569660)(fX, fY);
 
Последнее редактирование:

Savchik Blazer

Но я, мечту свою лелея...
Проверенный
672
292
функция воспроизводит аудио из URL через эмуляцию rpc

C++:
void playAudioStreamFromUrl(char url[])
{
    BitStream audio;
    audio.Write((UINT8)strlen(url));
    audio.Write(url, strlen(url));
    audio.Write((UINT8)0);
    SF->getRakNet()->emulateRecvRPC(41, &audio);
}

пример использования

пример:
playAudioStreamFromUrl(ссылка);
 

Savchik Blazer

Но я, мечту свою лелея...
Проверенный
672
292
меняет ссылку, на которую отправляется информация о краше
C++:
void SetCrashReportLink(const char* link)
{
    DWORD protect;
    VirtualProtect(reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0xD7374), strlen(link), PAGE_EXECUTE_READWRITE, &protect);
    std::strcpy(reinterpret_cast<char*>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0xD7374), link); //R2 - 0xD7384, R3 - 0xE9654, R4 - 0xE9674, 03DL - 0xB6E4
    VirtualProtect(reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0xD7374), strlen(link), protect, &protect);
}

функция возвращает ссылку на текущий аудиострим

C++:
reinterpret_cast<char*>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0x11A2F8); //R2 - 0x11A2F8, R3 - 0x12E378, R4- 0x12E4A0, 03DL - 0x16C4B8
 
Последнее редактирование:

F0RQU1N and

Известный
1,305
491
меняет ссылку, на которую отправляется информация о краше
C++:
void SetCrashReportLink(const char* link)
{
    DWORD protect;
    VirtualProtect(reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0xD7374), strlen(link), PAGE_EXECUTE_READWRITE, &protect);
    std::strcpy(reinterpret_cast<char*>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0xD7374), link); //R2 - 0xD7384, R3 - 0xE9654, R4 - 0xE9674, 03DL - 0xB6E4
    VirtualProtect(reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0xD7374), strlen(link), protect, &protect);
}

функция возвращает ссылку на текущий аудиострим

C++:
reinterpret_cast<char*>(reinterpret_cast<DWORD>(GetModuleHandleA("samp.dll")) + 0x11A2F8); //R2 - 0x11A2F8, R3 - 0x12E378, R4- 0x12E4A0, 03DL - 0x16C4B8
какой в этом смысл?
да и вообще вроде до вызова этой функции не доходит
1663045400987.png
 
  • Нравится
Реакции: Savchik Blazer

MeG@LaDo[N] ^_^

Известный
281
315
Генерация рандомной строки без массива с буквами и рандомного выбора из его, аргумент len это длина строки а str это строка(указывать не обязательно)
но если хотите сделать что то типа : RandomString -> ... то впишите в аргумент "RandomString -> "
piska:
std::string random_string(std::uint32_t len, std::string str = "") noexcept
{
    srand(GetTickCount()); //можете юзать time(0), но у меня подключен Windows.h так шо мне пох
    
    for (std::uint32_t iter = 0; iter < len; iter++) 
        str.push_back(rand() % 26 + 'a');

    return str;
}
 

horacy

Известный
102
92
Read text from showdialog and other compressed strings on 03dl, reading textlen was corrupting the text
чтение текста из showdialog и других сжатых строк в 03dl, чтение textlen разрывает текст

C++:
         case RPC_ShowDialog:
        {
            traceLastFunc("RPC_ShowDialog");

                //UINT16 wDialogID, UINT8 bDialogStyle, UINT8 bTitleLength, char[] szTitle, UINT8 bButton1Len, char[] szButton1, UINT8 bButton2Len, char[] szButton2, CSTRING szInfo
        
                BitStream    bsData(rpcParams->input, rpcParams->numberOfBitsOfData / 8, false);
                WORD dialogId;
                uint8_t style, titleLen, button1Len, button2Len;
                char title[257], button1[257], button2[257], text[4096];
        
                bsData.Read(dialogId);
                bsData.Read(style);
                bsData.Read(titleLen);
                bsData.Read(title, titleLen);
                title[titleLen] = '\0';
                bsData.Read(button1Len);
                bsData.Read(button1, button1Len);
                button1[button1Len] = '\0';
                bsData.Read(button2Len);
                bsData.Read(button2, button2Len);
                button2[button2Len] = '\0';
                bsData.Write(0);
                bsData.Read(text);
                text[0] = '\0';
                stringCompressor->DecodeString(text, 4096, &bsData);
            
                addMessageToChatWindow("Decoded: %s ",text);
        }
 
  • Bug
Реакции: AdCKuY_DpO4uLa

_=Gigant=_

Известный
134
191
Simple samp query using imgui server address and socket api

ImGui::Begin("Server Info"); // Create a socket to communicate with the server int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Specify the server's address and port sockaddr_in addr = { 0 }; addr.sin_family = AF_INET; addr.sin_port = htons(7777); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); // Send a SAMP Query packet to the server char query[] = { 'S', 'A', 'M', 'P', ' ', '0', 'x', '54', '4F', '4D', '50', '\0' }; sendto(sock, query, sizeof(query), 0, (sockaddr*)&addr, sizeof(addr)); // Wait for a response from the server char buffer[2048] = { 0 }; int len = sizeof(sockaddr_in); recvfrom(sock, buffer, sizeof(buffer), 0, (sockaddr*)&addr, &len); // Parse the response and display the server info ImGui::Text("Server Name: %s", buffer + 11); ImGui::Text("Players Online: %d", *(int*)(buffer + 19)); ImGui::Text("Game Mode: %s", buffer + 23); ImGui::Text("Language: %s", buffer + 39); ImGui::Text("Weather: %d", *(int*)(buffer + 43)); ImGui::Text("Time: %d:%02d", *(int*)(buffer + 47), *(int*)(buffer + 51)); ImGui::Text("Ping: %d", *(int*)(buffer + 83)); ImGui::End();
 
Последнее редактирование:
  • Bug
Реакции: AdCKuY_DpO4uLa

AdCKuY_DpO4uLa

Известный
286
474
Simple samp query using imgui server address and socket api

ImGui::Begin("Server Info"); // Create a socket to communicate with the server int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Specify the server's address and port sockaddr_in addr = { 0 }; addr.sin_family = AF_INET; addr.sin_port = htons(7777); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); // Send a SAMP Query packet to the server char query[] = { 'S', 'A', 'M', 'P', ' ', '0', 'x', '54', '4F', '4D', '50', '\0' }; sendto(sock, query, sizeof(query), 0, (sockaddr*)&addr, sizeof(addr)); // Wait for a response from the server char buffer[2048] = { 0 }; int len = sizeof(sockaddr_in); recvfrom(sock, buffer, sizeof(buffer), 0, (sockaddr*)&addr, &len); // Parse the response and display the server info ImGui::Text("Server Name: %s", buffer + 11); ImGui::Text("Players Online: %d", *(int*)(buffer + 19)); ImGui::Text("Game Mode: %s", buffer + 23); ImGui::Text("Language: %s", buffer + 39); ImGui::Text("Weather: %d", *(int*)(buffer + 43)); ImGui::Text("Time: %d:%02d", *(int*)(buffer + 47), *(int*)(buffer + 51)); ImGui::Text("Ping: %d", *(int*)(buffer + 83)); ImGui::End();
 
  • Нравится
Реакции: _=Gigant=_

_=Gigant=_

Известный
134
191
inline float ByteToFloat(unsigned char value)
{
return static_cast<float>(value) / 255.0f;
}

ImVec4 D3DColorToImVec4(DWORD color)
{
float red = ByteToFloat((color >> 16) & 0xFF);
float green = ByteToFloat((color >> 8) & 0xFF);
float blue = ByteToFloat(color & 0xFF);
float alpha = ByteToFloat(color >> 24);
return ImVec4(red, green, blue, alpha);
}

Usage
DWORD d3dcolor = 0x00FF00FF; // Example color
ImVec4 imvec4 = D3DColorToImVec4(d3dcolor);

2# D3DCOLOR TO IMVEC4

unsigned char FloatToByte(float value)
{
return static_cast<unsigned char>(value * 255.0f);
}

DWORD ImVec4ToD3DColor(const ImVec4& color)
{
unsigned char red = FloatToByte(color.x);
unsigned char green = FloatToByte(color.y);
unsigned char blue = FloatToByte(color.z);
unsigned char alpha = FloatToByte(color.w);
return D3DCOLOR_ARGB(alpha, red, green, blue);
}

ImVec4 imvec4(1.0f, 0.0f, 1.0f, 0.5f); //usage
DWORD d3dcolor = ImVec4ToD3DColor(imvec4);
 
Последнее редактирование:

VRush

https://t.me/vrushscript
Проверенный
2,349
1,093
Отправка фейковой позиции...
C++:
void send_onfootdata(float x, float y, float z)
{
if (BS->getPlugin()->actor_driving(-1)) return;

BitStream bsOnfootSync;
stOnFootData ofSync;
memset(&ofSync, 0, sizeof(stOnFootData));

ofSync.byteArmor = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.byteArmor;
ofSync.byteCurrentWeapon = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.byteCurrentWeapon;
ofSync.byteHealth = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.byteHealth;
ofSync.byteSpecialAction = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.byteSpecialAction;
ofSync.fMoveSpeed[0] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fMoveSpeed[0];
ofSync.fMoveSpeed[1] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fMoveSpeed[1];
ofSync.fMoveSpeed[2] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fMoveSpeed[2];
ofSync.fPosition[0] = x;
ofSync.fPosition[1] = y;
ofSync.fPosition[2] = z;
ofSync.fQuaternion[0] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fQuaternion[0];
ofSync.fQuaternion[1] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fQuaternion[1];
ofSync.fQuaternion[2] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fQuaternion[2];
ofSync.fQuaternion[3] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fQuaternion[3];
ofSync.fSurfingOffsets[0] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fSurfingOffsets[0];
ofSync.fSurfingOffsets[1] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fSurfingOffsets[1];
ofSync.fSurfingOffsets[2] = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.fSurfingOffsets[2];
ofSync.sAnimFlags = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.sAnimFlags;
ofSync.sCurrentAnimationID = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.sCurrentAnimationID;
ofSync.sKeys = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.sKeys;
ofSync.sLeftRightKeys = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.sLeftRightKeys;
ofSync.sSurfingVehicleID = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.sSurfingVehicleID;
ofSync.stSampKeys = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.stSampKeys;
ofSync.sUpDownKeys = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData.sUpDownKeys;

bsOnfootSync.Write((BYTE)ID_PLAYER_SYNC);
bsOnfootSync.Write((PCHAR)&ofSync, sizeof(stOnFootData));
SF->getRakNet()->SendPacket(&bsOnfootSync);
}
C++:
void sendCoordination(float x, float y, float z) {
    BitStream bs;
    stOnFootData sync = SF->getSAMP()->getPlayers()->pLocalPlayer->onFootData;
    sync.fPosition[0] = x;
    sync.fPosition[1] = y;
    sync.fPosition[2] = z;
    bs.Write((BYTE)ID_PLAYER_SYNC);
    bs.Write((PCHAR)&sync, sizeof(stOnFootData));
    SF->getRakNet()->SendPacket(&bs);
}
 
  • Нравится
Реакции: Digger Man

AdCKuY_DpO4uLa

Известный
286
474
Данный класс позволяет скрыть модуль из списка загруженных модулей путем замены указателей на "скрываемый модуль" в структуре PEB_LDR_DATA процесса.
C++:
#include <Windows.h>
#include <winternl.h>

class ModuleHider
{
    private:
    //only x86 structs
    typedef struct _PEB_LDR_DATA {
        ULONG Length;
        BOOLEAN Initialized;
        HANDLE SsHandle;
        LIST_ENTRY InLoadOrderModuleList;
        LIST_ENTRY InMemoryOrderModuleList;
        LIST_ENTRY InInitializationOrderModuleList;
        PVOID      EntryInProgress;
    } PEB_LDR_DATA, * PPEB_LDR_DATA;
    typedef struct _LDR_DATA_ENTRY {
        //PVOID Reserved1[0];
        LIST_ENTRY InLoadOrderModuleList;
        LIST_ENTRY InInitializationOrderModuleList;
        LIST_ENTRY InMemoryOrderModuleList;
        //PVOID Reserved2[2];
        PVOID DllBase;
        PVOID Reserved3[2];
        UNICODE_STRING FullDllName;
        BYTE Reserved4[8];
        PVOID Reserved5[3];
        #pragma warning(push)
        #pragma warning(disable: 4201) // we'll always use the Microsoft compiler
        union {
            ULONG CheckSum;
            PVOID Reserved6;
        } DUMMYUNIONNAME;
        #pragma warning(pop)
        ULONG TimeDateStamp;
    } LDR_DATA_ENTRY, * PLDR_DATA_ENTRY;
    PPEB_LDR_DATA _m_pPEB_LDR;
    PLDR_DATA_ENTRY _m_pEntry;
    HINSTANCE _m_DllHandle;
    PLDR_DATA_ENTRY _m_pDoEntry, _m_pAfterEntry;
    LIST_ENTRY _m_origAddrs;
    bool _m_bIsHided;
    public:
    ModuleHider(const HINSTANCE hModule) : _m_DllHandle(hModule), _m_bIsHided(false)
    {
        _m_pPEB_LDR = (PPEB_LDR_DATA)NtCurrentTeb()->ProcessEnvironmentBlock->Ldr;
        _m_pEntry = (PLDR_DATA_ENTRY)_m_pPEB_LDR->InLoadOrderModuleList.Flink;
    };
    ~ModuleHider()
    {
        Show();
    };
    auto Hide(void) -> bool
    {
        if (_m_bIsHided == true)
            return false;

        while (_m_pEntry->DllBase)
        {
            if (_m_pEntry->DllBase == _m_DllHandle)
            {
                _m_pDoEntry = (PLDR_DATA_ENTRY)_m_pEntry->InLoadOrderModuleList.Blink;
                _m_pAfterEntry = (PLDR_DATA_ENTRY)_m_pEntry->InLoadOrderModuleList.Flink;

                _m_origAddrs.Flink = _m_pAfterEntry->InLoadOrderModuleList.Blink;
                _m_origAddrs.Blink = _m_pDoEntry->InLoadOrderModuleList.Flink;

                _m_pDoEntry->InLoadOrderModuleList.Flink = _m_pEntry->InLoadOrderModuleList.Flink;
                _m_pAfterEntry->InLoadOrderModuleList.Blink = _m_pEntry->InLoadOrderModuleList.Blink;

                _m_bIsHided = true;

                return true;
            }

            _m_pEntry = (PLDR_DATA_ENTRY)_m_pEntry->InLoadOrderModuleList.Flink;
        }
        return false;
    };
    auto Show(void) -> bool
    {
        if (_m_bIsHided == true)
        {
            _m_pDoEntry->InLoadOrderModuleList.Flink = _m_origAddrs.Flink;
            _m_pAfterEntry->InLoadOrderModuleList.Blink = _m_origAddrs.Blink;
            _m_bIsHided = false;
            return true;
        }
        return false;
    };
    auto IsModuleHided(void) -> bool
    {
        return _m_bIsHided;
    };
};
Пример использования:
C++:
HINSTANCE hModule{}; //предположим, что это валидный хендл нашего модуля

//создадим экзепляр класса, передавая в конструктор хендл модуля
std::unique_ptr<ModuleHider> pModuleHider = std::make_unique<ModuleHider>(hModule);

//метод для скрытия модуля
if (pModuleHider->Hide())
    std::cout << "hide ok\n";

//метод для возвращеня модуля в прежнее состояние
if(pModuleHider->Show())
    std::cout << "show ok\n";

//метод для проверки, скрыт ли модуль
bool bIsHided = pModuleHider->IsModuleHided();
 

Z3roKwq

Известный
294
157
Функцию позволяющая установить позицию камеры на 3д координаты

C++:
void SFrotateCameraAt3D(CVector coords) {
    CVector camera_orig = *GAME->GetCamera()->GetCam(GAME->GetCamera()->GetActiveCam())->GetSource();;
    int camera_mode = GAME->GetCamera()->GetCam(GAME->GetCamera()->GetActiveCam())->GetMode();
    CVector2D crosshair_offset;
    float aspect_ratio;
    CVector vector;

    vector = { (camera_orig.fX - coords.fX), (camera_orig.fY - coords.fY), (camera_orig.fZ - coords.fZ) };
    crosshair_offset = { *reinterpret_cast<float*>(0xB6EC10), *reinterpret_cast<float*>(0xB6EC14) };
    aspect_ratio = *reinterpret_cast<float*>(0xC3EFA4);

    float mult;
    float idk_fX, idk_fZ;
    float idk_afX, idk_afZ;

    mult = tan(GAME->GetCamera()->GetCam(GAME->GetCamera()->GetActiveCam())->GetFOV() * 0.5 * 0.01745);
    idk_fZ = (3.14 - atan2(1.0, mult * ((0.5 - crosshair_offset.fX) * (2 / aspect_ratio))));
    idk_fX = (3.14 - atan2(1.0, mult * 2 * (crosshair_offset.fY - 0.5)));

    if (!(camera_mode == 53 || camera_mode == 55)) {
        idk_fX = 3.14 / 2;
        idk_fZ = 3.14 / 2;
    }

    idk_afX = atan2(vector.fY, -vector.fX) - 3.14 / 2;
    idk_afZ = atan2(sqrt(vector.fX * vector.fX + vector.fY * vector.fY), vector.fZ);

    GAME->GetCamera()->GetCam(GAME->GetCamera()->GetActiveCam())->SetDirection((idk_afZ - idk_fZ), (idk_fX - idk_afX));
    //SF->getCLEO()->callOpcode("0A25: %f %f", (idk_afZ - idk_fZ), (idk_fX - idk_afX));
}

C++:
void rotateCameraAt3D(CVector coords) {
    CVector camera_orig = TheCamera.GetPosition();
    int camera_mode = TheCamera.m_aCams[0].m_nMode;
    CVector2D crosshair_offset;
    float aspect_ratio;
    CVector vector;
    
    vector = { (camera_orig.x - coords.x), (camera_orig.y - coords.y), (camera_orig.z - coords.z) };
    crosshair_offset = { *reinterpret_cast<float*>(0xB6EC10), *reinterpret_cast<float*>(0xB6EC14) };
    aspect_ratio = *reinterpret_cast<float*>(0xC3EFA4);
    
    float mult;
    float idk_fX, idk_fZ;
    float idk_afX, idk_afZ;
    
    mult = tan(TheCamera.FindCamFOV() * 0.5 * 0.01745);
    idk_fZ = (3.14 - atan2(1.0, mult * ((0.5 - crosshair_offset.x) * (2 / aspect_ratio))));
    idk_fX = (3.14 - atan2(1.0, mult * 2 * (crosshair_offset.y - 0.5)));

    if (!(camera_mode == 53 || camera_mode == 55)) {
        idk_fX = 3.14 / 2;
        idk_fZ = 3.14 / 2;
    }

    idk_afX = atan2(vector.y, -vector.x) - 3.14 / 2;
    idk_afZ = atan2(sqrt(vector.x * vector.x + vector.y * vector.y), vector.z);

    TheCamera.m_aCams[0].m_fHorizontalAngle = (idk_fX - idk_afX);
    TheCamera.m_aCams[0].m_fVerticalAngle = (idk_afZ - idk_fZ);
}
 

p1cador

cerf
Проверенный
220
359
Converts 2d screen coordinates (.z is depth) to world 3d coordinates. Actually, this is implementation of the SF opcode:
CLEO:
0B8F: convert_screen_coords 1@ 2@ depth 3@ to_world_3d 4@ 5@ 6@

C:
#if defined(_MSC_VER)
#define CC_STDCALL   __stdcall
#elif defined(__GNUC__) || defined(__clang__)
#define CC_STDCALL   __attribute__((stdcall))
#endif

typedef struct D3DMATRIX
{
    union {
        struct
        {
            float _11;
            float _12;
            float _13;
            float _14;
            float _21;
            float _22;
            float _23;
            float _24;
            float _31;
            float _32;
            float _33;
            float _34;
            float _41;
            float _42;
            float _43;
            float _44;
        };
        float m[4][4];
    };
} D3DMATRIX;

typedef struct CVector
{
    float x;
    float y;
    float z;
} CVector;

typedef char(CC_STDCALL* D3DXMatrixInverse_t)(void* a1, float* a2,
                                              const void* a3);
D3DXMatrixInverse_t D3DXMatrixInverse = (D3DXMatrixInverse_t)0x76795B;

void convert_screen_coords_to_world_3d(const CVector* screen_coors, CVector* world_coors)
{
    D3DMATRIX worldMatrix;
    /* Get the combined view-projection matrix and invert it */
    memcpy(&worldMatrix, (const void*)0xB6FA2C, sizeof(worldMatrix));
    worldMatrix.m[3][3] = 1.0f;
    D3DMATRIX inverseMatrix;
    // TODO: Check is it possible to reuse the same matrix
    D3DXMatrixInverse(&inverseMatrix, NULL, &worldMatrix);
    /* Apply the inverse view-projection matrix to the screen coordinates */
    float invZ = 1.0f / screen_coors->z;
    float screenX = screen_coors->x / (*(int*)0xC17044 * invZ);
    float screenY = screen_coors->y / (*(int*)0xC17048 * invZ);
    /* Transform the screen coordinates into world coordinates */
    world_coors->x = screenX * inverseMatrix._11 + screenY * inverseMatrix._21 +
                     screen_coors->z * inverseMatrix._31 + inverseMatrix._41;
    world_coors->y = screenX * inverseMatrix._12 + screenY * inverseMatrix._22 +
                     screen_coors->z * inverseMatrix._32 + inverseMatrix._42;
    world_coors->z = screenX * inverseMatrix._13 + screenY * inverseMatrix._23 +
                     screen_coors->z * inverseMatrix._33 + inverseMatrix._43;
}

Tested on 1.0 US
 
Последнее редактирование: