Исходник WorldToScreen

Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Вот где я его вижу, он сделан на получении матрицы и собственных расчетах. А не проще все это делать на стороне клиента?

1. Заводим структуру

C++:
struct VecToScreen
{
public:
    float toX;
    float toY;
    float toZ;
    float* outX;
    float* outY;
    float* outZ;
};
2. Обзаводимся функцией/
C++:
bool WorldToScreen(Vec3 vEntPos, Vec3& vOut)
{
    VecToScreen pVecToScreen;//<-Наша структура
//Пилим в неё данные
    pVecToScreen.toX = vEntPos.x;
    pVecToScreen.toY = vEntPos.y;
    pVecToScreen.toZ = vEntPos.z;
    pVecToScreen.outX = &vOut.x;
    pVecToScreen.outY = &vOut.y;
    pVecToScreen.outZ = &vOut.z;

//Дальше юзаем наш ProjectToScreen
    IRenderer::Singleton()->ProjectToScreen(&pVecToScreen);

    vOut.x *= (IRenderer::Singleton()->GetWidth() * 0.01f);
    vOut.y *= (IRenderer::Singleton()->GetHeight() * 0.01f);
    vOut.z *= 1.0f;
    return ((vOut.z < 1.0f) && (vOut.x > 0) && (vOut.x < (float)IRenderer::Singleton()->GetWidth()) && (vOut.y > 0) && (vOut.y < (float)IRenderer::Singleton()->GetHeight()));
}
Как бы и все, зачем юзать свое что-то, если можно это все сделать на стороне игры. Этот метод не менялся очень долго.

C++:
enum _IRender :DWORD64
{
    OffSets_ru = 42704,
    //r_Height 7-й
    getWidth_offset_ru = 0x9428,
    getHeight_offset_ru = 0x942C ,
    index_ProjectToScreen_ru = 872 / 8,

    OffSets_eur = 42704,
    getWidth_offset_eur = 0x9428,
    getHeight_offset_eur =  0x942C,
    index_ProjectToScreen_eur = 872 / 8
};

class IRenderer
{
public:

    static IRenderer* Singleton()
    {
        return *(IRenderer**)((DWORD64)(Check_version_game ? _SSystemGlobalEnvironment::_IRendererGlobalEnvironment_eur : _SSystemGlobalEnvironment::_IRendererGlobalEnvironment_ru));
    }

    Device* GetDevice()
    {
        return (Device*)*(DWORD64*)((DWORD64)this + (Check_version_game ? _IRender::OffSets_eur: _IRender::OffSets_ru));
    }

    int GetWidth()//Высота
    {
        //typedef int(__thiscall* oFunc)(PVOID);
        //return vFun_Call<oFunc>(this, (Check_version_game ? getWidth_offset_eur : getWidth_offset_ru))(this);
        return *(int*)((DWORD64)this + (Check_version_game ? getWidth_offset_eur : getWidth_offset_ru));//
    }

    int GetHeight()//Ширина
    {
        //typedef int(__thiscall* oFunc)(PVOID);
        //return vFun_Call<oFunc>(this, (Check_version_game ? getHeight_offset_eur : getHeight_offset_ru))(this);
        return *(int*)((DWORD64)this + (Check_version_game ? getHeight_offset_eur : getHeight_offset_ru));//
    }

    bool ProjectToScreen(VecToScreen* pVecToScreen)
    {
        typedef bool(__thiscall* oProjectToScreen)(PVOID, VecToScreen*);
        return vFun_Call<oProjectToScreen>(this, (Check_version_game ? index_ProjectToScreen_eur : index_ProjectToScreen_ru))(this, pVecToScreen);
    }
C++:
    BOOL WorldToScreen(Vec3 Pos, Vec3& Out)
    {
        D3DXVECTOR3 PosM = { Pos.x, Pos.y, Pos.z };
        D3DXMATRIX temp;
        D3DXMatrixTranspose(&temp, &this->GetCameraMatrix());
        D3DXVECTOR3 translationVector = D3DXVECTOR3(temp._41, temp._42, temp._43);
        D3DXVECTOR3 up = D3DXVECTOR3(temp._21, temp._22, temp._23);
        D3DXVECTOR3 right = D3DXVECTOR3(temp._11, temp._12, temp._13);
        FLOAT w = D3DXVec3Dot(&translationVector, &PosM) + temp._44;
        if (w < 1.29f)return Out.x = Out.y = 0;
        FLOAT y = D3DXVec3Dot(&up, &PosM) + temp._24;
        FLOAT x = D3DXVec3Dot(&right, &PosM) + temp._14;
        Out.x = (sCEnableSFunc.ScreenCX) * (1 + (x / w));
        Out.y = (sCEnableSFunc.ScreenCY) * (1 - (y / w));
        return TRUE;
    }
Зачем????
 
Последнее редактирование:
Coder [C++]
Начинающий
Статус
Оффлайн
Регистрация
22 Июн 2019
Сообщения
53
Реакции[?]
14
Поинты[?]
0
Разница в этой функции и в той что ты призываешь юзать в том что , в первой нет проверки углов (FOV) а во второй есть, проверка FOV делаеться для того что бы в не зависимости от угла обзора у вас была верная дистанция от кости до кости например , если ты сейчас протестируешь оба кода то второй тебе покажеться более верным в плане угла обзора твоей камеры
Код:
 BOOL WorldToScreen(Vec3 Pos, Vec3& Out)
    {
        D3DXVECTOR3 PosM = { Pos.x, Pos.y, Pos.z };
        D3DXMATRIX temp;
        D3DXMatrixTranspose(&temp, &this->GetCameraMatrix());
        D3DXVECTOR3 translationVector = D3DXVECTOR3(temp._41, temp._42, temp._43);
        D3DXVECTOR3 up = D3DXVECTOR3(temp._21, temp._22, temp._23);
        D3DXVECTOR3 right = D3DXVECTOR3(temp._11, temp._12, temp._13);
        FLOAT w = D3DXVec3Dot(&translationVector, &PosM) + temp._44;
        if (w < 1.29f)return Out.x = Out.y = 0;
        FLOAT y = D3DXVec3Dot(&up, &PosM) + temp._24;
        FLOAT x = D3DXVec3Dot(&right, &PosM) + temp._14;
        Out.x = (sCEnableSFunc.ScreenCX) * (1 + (x / w));
        Out.y = (sCEnableSFunc.ScreenCY) * (1 - (y / w));
        return TRUE;
    }
 
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Разница в этой функции и в той что ты призываешь юзать в том что , в первой нет проверки углов (FOV) а во второй есть, проверка FOV делаеться для того что бы в не зависимости от угла обзора у вас была верная дистанция от кости до кости например , если ты сейчас протестируешь оба кода то второй тебе покажеться более верным в плане угла обзора твоей камеры
Код:
 BOOL WorldToScreen(Vec3 Pos, Vec3& Out)
    {
        D3DXVECTOR3 PosM = { Pos.x, Pos.y, Pos.z };
        D3DXMATRIX temp;
        D3DXMatrixTranspose(&temp, &this->GetCameraMatrix());
        D3DXVECTOR3 translationVector = D3DXVECTOR3(temp._41, temp._42, temp._43);
        D3DXVECTOR3 up = D3DXVECTOR3(temp._21, temp._22, temp._23);
        D3DXVECTOR3 right = D3DXVECTOR3(temp._11, temp._12, temp._13);
        FLOAT w = D3DXVec3Dot(&translationVector, &PosM) + temp._44;
        if (w < 1.29f)return Out.x = Out.y = 0;
        FLOAT y = D3DXVec3Dot(&up, &PosM) + temp._24;
        FLOAT x = D3DXVec3Dot(&right, &PosM) + temp._14;
        Out.x = (sCEnableSFunc.ScreenCX) * (1 + (x / w));
        Out.y = (sCEnableSFunc.ScreenCY) * (1 - (y / w));
        return TRUE;
    }
Расстояние от кости до кости меряется в 3Д мире, а не на мониторе.
WorldToScreen переводит 3Д координаты в 2Д для рисовки на экране и не более, для чего проверка углов?
 
Coder [C++]
Начинающий
Статус
Оффлайн
Регистрация
22 Июн 2019
Сообщения
53
Реакции[?]
14
Поинты[?]
0
Расстояние от кости до кости меряется в 3Д мире, а не на мониторе.
WorldToScreen переводит 3Д координаты в 2Д для рисовки на экране и не более, для чего проверка углов?
Вот изучи ту же функцию только для игры COD Warzone

Код:
bool WorldToScreen(Vector3* Origin, const Vector3 vOrigin, Vector3* vOut)
{
    Vector3* ViewOrigins = Origin;
    Vector3 vLocal, vTrans;
    vLocal.x = vOrigin.x - ViewOrigins->x;
    vLocal.y = vOrigin.y - ViewOrigins->y;
    vLocal.z = vOrigin.z - ViewOrigins->z;
    vTrans.x = vLocal.Dot(Matrix[1]);
    vTrans.y = vLocal.Dot(Matrix[2]);
    vTrans.z = vLocal.Dot(rMatrix[0]);
    if (vTrans.z < 0.01f)
          return false;
    vOut->x = ((Width / 2) * (1 - (vTrans.x / FovX / vTrans.z)));
    vOut->y = ((Height / 2) * (1 - (vTrans.y / FovY / vTrans.z)));
    if (vOut->x > refdef->Width || vOut->y > refdef->Height || vOut->x < 0 || vOut->y < 0)
         return false;
    return true;
}
Видешь видишь тут на выходе координаты делят на значение угла (То есть FOV)
Это для того что бы например когда ты в прицелеле в 4х кратном , моделька увеличивается а вместе с ней меняются и точки костей этой модельки , что приводит к неверным координатам просто в WF не принято это всё в учёт брать)))
 
Начинающий
Статус
Оффлайн
Регистрация
8 Апр 2018
Сообщения
6
Реакции[?]
5
Поинты[?]
0
Ох как мне это все нравится)
Оба не правы) если уходить глубоко в оптимизацию чем больше лишних действий тем больше времени необходимо на его выполнение
Ошибка Димидрола, использовать виртуальные функции и не сцать за их последствия, уже давным давно есть понятие трейсинга стека в вф без использования каких либо winapi,
использование :
D3DXVECTOR3 - когда он увеличивает время работы кода (проще описать свой класс вектора и работать через него)
D3DXVec3... Функций, это лишнее обращение функций к сторонним функциям winapi что так же увеличивает время работы функции

Ошибка шока, думать что wf не использует информацию о углах, когда принцип всегда одинаковый view,proj,world матрицы используемые для информации

и чтобы не быть слишком многоумным прикреплю код
Данный код упрощён и работает уже с готовой матрицой viewproj или же view*proj
C++:
bool WorldToScreen(Vec3 vecWorld, Vec2& vecOut, Matrix44 Viev)
{
    float z = vecWorld.x * Viev._14 + vecWorld.y * Viev._24 + vecWorld.z * Viev._34 + Viev._44;

    if (z < 0.0f)
        return false;

    float x = vecWorld.x * Viev._11 + vecWorld.y * Viev._21 + vecWorld.z * Viev._31 + Viev._41;
    float y = vecWorld.x * Viev._12 + vecWorld.y * Viev._22 + vecWorld.z * Viev._32 + Viev._42;

    x /= z;
    y /= z;

    vecOut.x = (1.0f + x) * (Render->WindomPos.w / 2);
    vecOut.y = (1.0f - y) * (Render->WindomPos.h / 2);

    return ((vecOut.x >= 0.0f) && (vecOut.x <= Render->WindomPos.w) && (vecOut.y >= 0.0f) && (vecOut.y <= Render->WindomPos.h));
}
Из моего олдстарого исходника вф 17 года
C++:
Matrix44 Draw = Memory.Read<Matrix44>(Temp.Render + IRender_Matrix);
Vec2 Screen;

if (WorldToScreen(Actor.Pos, Screen, Draw))
{
MyRender->Text_No_Buffer(Screen.x, Screen.y, DT_CENTER, GREEN, str);
}
 
Coder [C++]
Начинающий
Статус
Оффлайн
Регистрация
22 Июн 2019
Сообщения
53
Реакции[?]
14
Поинты[?]
0
Ошибка шока, думать что wf не использует информацию о углах, когда принцип всегда одинаковый view,proj,world матрицы используемые для информации
Я говорил что кодеры не привыкли расчитывать угол обзора для своего W2S , я как раз это и пытаюсь обьяснить ему
 
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Я говорил что кодеры не привыкли расчитывать угол обзора для своего W2S , я как раз это и пытаюсь обьяснить ему
Для чего рассчитывать их? Если ты координаты располагаешь по ширина\высоты твоего разрешения.
 
Coder [C++]
Начинающий
Статус
Оффлайн
Регистрация
22 Июн 2019
Сообщения
53
Реакции[?]
14
Поинты[?]
0
Для чего рассчитывать их? Если ты координаты располагаешь по ширина\высоты твоего разрешения.
Zoom знаешь же что такое в играх шутерах ? Вот когда ты заходишь в зум от этого разрешение твоё не меняется а углы обзора становятся другими , и если это не брать в учёт w2s то и координаты будут такими как будто ты без зума а то есть угол обзора больше, вобщем забей , проехали
 
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Zoom знаешь же что такое в играх шутерах ? Вот когда ты заходишь в зум от этого разрешение твоё не меняется а углы обзора становятся другими , и если это не брать в учёт w2s то и координаты будут такими как будто ты без зума а то есть угол обзора больше, вобщем забей , проехали
Все что не попадает на экран, все отсеивается. При чем тут координаты? w2s чисто для отрисовки на экране.
 
Сверху Снизу