- 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());
}
Изображение
Последнее редактирование: