Софт Вопрос WorldToScreen D3D9

Начинающий
Статус
Оффлайн
Регистрация
9 Мар 2021
Сообщения
117
Реакции[?]
11
Поинты[?]
6K
Что не так?
Как преобразовать двухмерные координаты?
Screen Position хуевый!


1728584061853.png


C++:
bool WorldToScreen(vec3 pos, vec3& screen, float matrix[16], float windowWidth, float windowHeight)
{
    std::cout << "Matrix:" << std::endl;
    for (int i = 0; i < 16; ++i) {
        std::cout << "Matrix[" << i << "] = " << matrix[i] << std::endl;
    }

    std::cout << "Position: X: " << pos.x << " Y: " << pos.y << " Z: " << pos.z << std::endl;

    std::cout << "Window Width: " << windowWidth << " Window Height: " << windowHeight << std::endl;

    Vec4 clipCoords;
    clipCoords.x = pos.x * matrix[0] + pos.y * matrix[4] + pos.z * matrix[8] + matrix[12];
    clipCoords.y = pos.x * matrix[1] + pos.y * matrix[5] + pos.z * matrix[9] + matrix[13];
    clipCoords.z = pos.x * matrix[2] + pos.y * matrix[6] + pos.z * matrix[10] + matrix[14];
    clipCoords.w = pos.x * matrix[3] + pos.y * matrix[7] + pos.z * matrix[11] + matrix[15];

    std::cout << "X: " << clipCoords.x << " Y: " << clipCoords.y << " Z: " << clipCoords.z  << " W: " << clipCoords.w << std::endl;

    if (clipCoords.w < 0.1f)
    {
        std::cout << "Behind the camera." << std::endl;
        return false;
    }

    Vec3 NDC{ clipCoords.x / clipCoords.w, clipCoords.y / clipCoords.w, clipCoords.z / clipCoords.w };
    std::cout << "NDC: " << NDC << std::endl;

    screen.x = (NDC.x + 1.0f) * (windowWidth / 2.0f);
    screen.y = (1.0f - NDC.y) * (windowHeight / 2.0f);

    std::cout << "Screen Position: X: " << screen.x << " Y: " << screen.y << std::endl;

    if (screen.x < 0 || screen.x > windowWidth || screen.y < 0 || screen.y > windowHeight) {
        std::cout << "Behind the camera" << std::endl;
        return false;
    }

    return true;
}
 
Начинающий
Статус
Оффлайн
Регистрация
13 Май 2023
Сообщения
144
Реакции[?]
26
Поинты[?]
26K
Ну смотри. Каждая игра имеет свой мир.
C++:
inline bool ProjectToScreen2(int32* vp, const Vec3& ptx, Vec3& sx)
{
    // Обновление матриц только при необходимости
    g_MatrixManager.UpdateMatrices();
    Vec3 vOut;
    Matrix44 mIdent;
    mIdent.SetIdentity();
    // Использование матриц из глобального объекта
    Vec3 result = mathVec3Project(vOut, ptx, vp, g_MatrixManager.ProjectionMatrix, g_MatrixManager.ViewMatrix, mIdent);
    if (!result.IsEmpty())
    {
        sx.x = vOut.x * 100.0f / static_cast<float>(vp[2]);
        sx.y = vOut.y * 100.0f / static_cast<float>(vp[3]);
        sx.z = vOut.z;
        return true;
    }
    return false;
}
C++:
static Vec3 mathVec3Project(Vec3& pvWin, const Vec3& pvObj, const int pViewport[4], const Matrix44& pProjection, const Matrix44& pView, const Matrix44& pWorld)
{
    // Промежуточные переменные
    float x = pvObj.x, y = pvObj.y, z = pvObj.z;

    // Преобразование объекта в пространство мира
    float w = x * pWorld.m[0][3] + y * pWorld.m[1][3] + z * pWorld.m[2][3] + pWorld.m[3][3];
    float vX = x * pWorld.m[0][0] + y * pWorld.m[1][0] + z * pWorld.m[2][0] + pWorld.m[3][0];
    float vY = x * pWorld.m[0][1] + y * pWorld.m[1][1] + z * pWorld.m[2][1] + pWorld.m[3][1];
    float vZ = x * pWorld.m[0][2] + y * pWorld.m[1][2] + z * pWorld.m[2][2] + pWorld.m[3][2];
    float vW = x * pWorld.m[0][3] + y * pWorld.m[1][3] + z * pWorld.m[2][3] + pWorld.m[3][3];

    // Преобразование в пространство камеры
    float pX = vX * pView.m[0][0] + vY * pView.m[1][0] + vZ * pView.m[2][0] + vW * pView.m[3][0];
    float pY = vX * pView.m[0][1] + vY * pView.m[1][1] + vZ * pView.m[2][1] + vW * pView.m[3][1];
    float pZ = vX * pView.m[0][2] + vY * pView.m[1][2] + vZ * pView.m[2][2] + vW * pView.m[3][2];
    float pW = vX * pView.m[0][3] + vY * pView.m[1][3] + vZ * pView.m[2][3] + vW * pView.m[3][3];

    // Преобразование в пространство проекции
    float projX = pX * pProjection.m[0][0] + pY * pProjection.m[1][0] + pZ * pProjection.m[2][0] + pW * pProjection.m[3][0];
    float projY = pX * pProjection.m[0][1] + pY * pProjection.m[1][1] + pZ * pProjection.m[2][1] + pW * pProjection.m[3][1];
    float projZ = pX * pProjection.m[0][2] + pY * pProjection.m[1][2] + pZ * pProjection.m[2][2] + pW * pProjection.m[3][2];
    float projW = pX * pProjection.m[0][3] + pY * pProjection.m[1][3] + pZ * pProjection.m[2][3] + pW * pProjection.m[3][3];

    // Проверка на деление на ноль
    if (projW == 0.0f)
        return {};

    // Нормализация и преобразование в экранные координаты
    pvWin.x = ((projX / projW) + 1.0f) * (pViewport[2] * 0.5f) + pViewport[0];
    pvWin.y = ((1.0f - (projY / projW)) * (pViewport[3] * 0.5f)) + pViewport[1];
    pvWin.z = projZ / projW;

    return pvWin;
}
Это для ВФ
 
Начинающий
Статус
Оффлайн
Регистрация
9 Мар 2021
Сообщения
117
Реакции[?]
11
Поинты[?]
6K
Ну смотри. Каждая игра имеет свой мир.
C++:
inline bool ProjectToScreen2(int32* vp, const Vec3& ptx, Vec3& sx)
{
    // Обновление матриц только при необходимости
    g_MatrixManager.UpdateMatrices();
    Vec3 vOut;
    Matrix44 mIdent;
    mIdent.SetIdentity();
    // Использование матриц из глобального объекта
    Vec3 result = mathVec3Project(vOut, ptx, vp, g_MatrixManager.ProjectionMatrix, g_MatrixManager.ViewMatrix, mIdent);
    if (!result.IsEmpty())
    {
        sx.x = vOut.x * 100.0f / static_cast<float>(vp[2]);
        sx.y = vOut.y * 100.0f / static_cast<float>(vp[3]);
        sx.z = vOut.z;
        return true;
    }
    return false;
}
C++:
static Vec3 mathVec3Project(Vec3& pvWin, const Vec3& pvObj, const int pViewport[4], const Matrix44& pProjection, const Matrix44& pView, const Matrix44& pWorld)
{
    // Промежуточные переменные
    float x = pvObj.x, y = pvObj.y, z = pvObj.z;

    // Преобразование объекта в пространство мира
    float w = x * pWorld.m[0][3] + y * pWorld.m[1][3] + z * pWorld.m[2][3] + pWorld.m[3][3];
    float vX = x * pWorld.m[0][0] + y * pWorld.m[1][0] + z * pWorld.m[2][0] + pWorld.m[3][0];
    float vY = x * pWorld.m[0][1] + y * pWorld.m[1][1] + z * pWorld.m[2][1] + pWorld.m[3][1];
    float vZ = x * pWorld.m[0][2] + y * pWorld.m[1][2] + z * pWorld.m[2][2] + pWorld.m[3][2];
    float vW = x * pWorld.m[0][3] + y * pWorld.m[1][3] + z * pWorld.m[2][3] + pWorld.m[3][3];

    // Преобразование в пространство камеры
    float pX = vX * pView.m[0][0] + vY * pView.m[1][0] + vZ * pView.m[2][0] + vW * pView.m[3][0];
    float pY = vX * pView.m[0][1] + vY * pView.m[1][1] + vZ * pView.m[2][1] + vW * pView.m[3][1];
    float pZ = vX * pView.m[0][2] + vY * pView.m[1][2] + vZ * pView.m[2][2] + vW * pView.m[3][2];
    float pW = vX * pView.m[0][3] + vY * pView.m[1][3] + vZ * pView.m[2][3] + vW * pView.m[3][3];

    // Преобразование в пространство проекции
    float projX = pX * pProjection.m[0][0] + pY * pProjection.m[1][0] + pZ * pProjection.m[2][0] + pW * pProjection.m[3][0];
    float projY = pX * pProjection.m[0][1] + pY * pProjection.m[1][1] + pZ * pProjection.m[2][1] + pW * pProjection.m[3][1];
    float projZ = pX * pProjection.m[0][2] + pY * pProjection.m[1][2] + pZ * pProjection.m[2][2] + pW * pProjection.m[3][2];
    float projW = pX * pProjection.m[0][3] + pY * pProjection.m[1][3] + pZ * pProjection.m[2][3] + pW * pProjection.m[3][3];

    // Проверка на деление на ноль
    if (projW == 0.0f)
        return {};

    // Нормализация и преобразование в экранные координаты
    pvWin.x = ((projX / projW) + 1.0f) * (pViewport[2] * 0.5f) + pViewport[0];
    pvWin.y = ((1.0f - (projY / projW)) * (pViewport[3] * 0.5f)) + pViewport[1];
    pvWin.z = projZ / projW;

    return pvWin;
}
Это для ВФ
Да я понимаю, но мне на д3д9 надо, у меня есть позиция энтити, разрешение экрана и матрица(хз какая(вроде видовая), но слышал, что с помощью одной матрицы можно сразу перемножить на что-то не используя остальные матрицы)
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
9 Мар 2021
Сообщения
117
Реакции[?]
11
Поинты[?]
6K
Нашел ещё одну матрицу, но всё также хз как преобразовать в двухмерные координаты.

Скрины сделаны в одинаковый момент времени
1728689593792.png

1728689654547.png

1728689821838.png
 
Сверху Снизу