Öncelikle selamlar, W2S mantığını şu şekilde çok basitleştirilmiş mantığını anlatayım. Oyunlar 3D çizim yapar ve senin onların kordinatlarına bir Dikdörtgen yani Box çizebilmeni sağlar. Sana örnek bir W2S kodu atayım ve onun üzerinde anlatayım. Bu kodlar CS2 Temsili W2S kodudur. Sana yorum satırlarıyla anlatayım.
W2S Çağırma kısmı
Vector3 origin = pawn.GetOrigin();
Vector3 screenPos = origin.WTS(view_matrix);
W2S Kısmı
// View-Projection Matrix ile Çarpma
// 3D dünya koordinatları (x, y, z) view-projection matrisi ile çarpılıyor
// Bu, 3D noktayı kamera perspektifinden "clip space" denilen bir koordinat sistemine dönüştürüyor
float _x = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3];
float _y = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3];
float w = matrix[3][0] * x + matrix[3][1] * y + matrix[3][2] * z + matrix[3][3];
// w değeri derinlik bilgisi (perspektif için kritik)
if (w < 0.01f) // Bakış açının dışında veya çok yakınsa çizdirme
return false;
// Perspective Divide (Perspektif Bölme)
// Clip space'ten NDC (Normalized Device Coordinates) 'e geçiş
// Bu işlem perspektif etkisini uygular (uzaktaki nesneler küçülür)
// -1 ile +1 arasında normalize edilmiş koordinatlar
float inv_w = 1.f / w;
_x *= inv_w;
_y *= inv_w;
// Ekran Koordinatlarına Dönüşüm
// NDC koordinatları (-1 ~ +1) ekran piksellerine dönüştürülüyor
float x = screenWidth / 2;
// x: Ekranın ortasından başlayarak sağa/sola kaydırılıyor
float y = screenHeight / 2;
// y: Eksi işareti önemli - NDC'de +Y yukarı, ekran koordinatlarında aşağı yönlüdür
x += 0.5f * _x * screenWidth + 0.5f;
y -= 0.5f * _y * screenHeight + 0.5f;
// Sonuç : (0, 0) sol üst köşe, (screenWidth, screenHeight) sağ alt köşe
// Aslında işlem tamam X ve Y box çizdirmek için yeterli W ise mesafe hesaplamaları için derinlikte kullanılır
return { x , y, w };
Bu şekildede çizim yapabilirsin.
ImGuI Render Implementasyonu;
void DrawRect(int x, int y, int w, int h, RGB color, int thickness)
{
ImDrawList* drawList = ImGui::GetBackgroundDrawList();
ImVec2 p1(x, y);
ImVec2 p2(x + w, y);
ImVec2 p3(x + w, y + h);
ImVec2 p4(x, y + h);
drawList->AddLine(p1, p2, Colors(color), thickness); // Üst kenar
drawList->AddLine(p2, p3, Colors(color), thickness); // Sað kenar
drawList->AddLine(p3, p4, Colors(color), thickness); // Alt kenar
drawList->AddLine(p4, p1, Colors(color), thickness); // Sol kenar
}
float height = screenPos.y - screenHead.y;
float width = height / 2.4f;
`
DrawRect(
screenHead.x - width / 2,
screenHead.y,
width,
height,
Colors,
2.5
);
`