Отрисовка индикатора направления ImGui

DaniilPovetkin

Известный
Автор темы
13
1
Всем привет, вопрос скорее к знатокам математических функций. Пишу отрисовку текста в пространстве SAMP, и хочу сделать, что когда игрок не смотрит на этот текст, то ему указывалось направление иконкой, например если точка сзади, то внизу экрана и так по всей его плоскости. Но сейчас работает коряво, вроде слева отображается, справа тоже, а когда спиной стою никак :(


C++:
ImVec2 CalculateEdgePosition(ImVec2 originalPos, ImVec2 screenSize)
{
    const float margin = 10.0f; // Отступ от края
    const float imageSize = 32.0f;

    // Определяем, в каком направлении находится точка за пределами экрана
    bool left = originalPos.x < 0;
    bool right = originalPos.x > screenSize.x;
    bool top = originalPos.y < 0;
    bool bottom = originalPos.y > screenSize.y;

    // Вычисляем позицию на краю экрана
    float x = originalPos.x;
    float y = originalPos.y;

    if (left) x = margin;
    else if (right) x = screenSize.x - margin - imageSize;
    else x = std::clamp(x, margin, screenSize.x - margin - imageSize);

    if (top) y = margin;
    else if (bottom) y = screenSize.y - margin - imageSize;
    else y = std::clamp(y, margin, screenSize.y - margin - imageSize);

    return ImVec2(x, y);
}

void СTooltipManager::RenderTooltip()
{
    ImGui_ImplDX9_NewFrame();
    ImGui_ImplWin32_NewFrame();
    ImGui::NewFrame();

    auto drawlist = ImGui::GetBackgroundDrawList();

    CVector targetPosition{ 2760.6069f,-2420.8516f,21.7059f };

    CPlayerPed* pLocalPed = FindPlayerPed(-1);
    CVector cameraPosition = pLocalPed->GetPosition();
    CVector cameraForward = pLocalPed->GetForward();

    float fDistance = DistancePointToPoint(cameraPosition, targetPosition);
    CVector screenPosition = Utils::ConvertGameCoordsToScreen(targetPosition);

    ImVec2 screenSize = ImGui::GetIO().DisplaySize;
    ImVec2 pos = ImVec2(screenPosition.x, screenPosition.y);

    ImVec2 posForward = ImVec2(screenPosition.x, screenPosition.y);

    bool isVisibleOnScreen = (screenPosition.x >= 0.0f && screenPosition.x <= screenSize.x) &&
        (screenPosition.y >= 0.0f && screenPosition.y <= screenSize.y);

    if (isVisibleOnScreen) {
        // Оригинальный рендеринг, когда точка в поле зрения
        char distanse[50];
        sprintf(distanse, "%.0f м.", fDistance);

        ImGui::PushFont(fontToolTip);

        float textWidth = ImGui::CalcTextSize(utf8(std::string(distanse))).x;
        ImVec2 textPos = ImVec2(pos.x - textWidth * 0.5f, pos.y);
        drawlist->AddText(textPos, IM_COL32(255, 255, 255, 255), utf8(std::string(distanse)));

        ImVec2 imagePos = ImVec2(pos.x - 16.0f, pos.y + 15.0f);
        drawlist->AddImage((void*)iconToolTip, imagePos, ImVec2(imagePos.x + 32.0f, imagePos.y + 32.0f));

        std::string tet = "Добыча камня";
        float text2Width = ImGui::CalcTextSize(utf8(tet)).x;
        ImVec2 text2Pos = ImVec2(pos.x - text2Width * 0.5f, pos.y + 32.0f + 15.0f);
        drawlist->AddText(text2Pos, IM_COL32(255, 255, 255, 255), utf8(tet));

        ImGui::PopFont();
    }
    else {
        ImVec2 edgePos = CalculateEdgePosition(pos, screenSize);
        ImVec2 imageSize = ImVec2(32.0f, 32.0f);
        drawlist->AddImage((void*)iconToolTip, edgePos, ImVec2(edgePos.x + imageSize.x, edgePos.y + imageSize.y));
    }

    ImGui::EndFrame();
    ImGui::Render();
    ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
}
Что-то типо такого в итоге, только просто иконкой в направлении к координатам

Изображение
 
Последнее редактирование: