#include "belge_yonetici.hpp" #include #include #include "fiko/girdi/nav_kip.hpp" #include "fiko/render/vulkan_baglam.hpp" #include "fiko/sahne/sahne_islem.hpp" #include "fiko/ui/imgui_katman.hpp" #include "fiko/ui/pencere_cerceve.hpp" #include "imgui.h" namespace fiko { namespace { // Ana belgedeki tumunuSigdir'ın belge-yerel eşi (datum'lar fit dışı — aynı kural). void belgeSigdir(Belge& b) { Aabbf tum; for (auto& d : b.sahne.dugumler()) { if (!d.yerelSinir.gecerliMi()) continue; if (d.tip == DugumTip::Duzlem || d.tip == DugumTip::Eksen || d.tip == DugumTip::EksenSistemi || d.tip == DugumTip::Nokta) continue; const Vec3f m = d.dunyaMerkez(); const f32 r = d.dunyaYaricap(); tum.genislet(m - Vec3f{r, r, r}); tum.genislet(m + Vec3f{r, r, r}); } if (tum.gecerliMi()) b.kamera.sigdir(tum.merkez(), tum.kosegen() * 0.5f + 0.5f); } } // namespace BelgeKaydi& BelgeYonetici::yeniBelge(VulkanBaglam& vulkan, const std::string& shaderDizin) { auto k = std::make_unique(); k->kimlik = sonrakiKimlik_++; k->ad = "Belge " + std::to_string(k->kimlik); k->belge = std::make_unique(vulkan, shaderDizin); k->belge->sahne.originKur(); // her belgede kök referans (ana belgeyle aynı) k->hedef = std::make_unique(vulkan, k->istG, k->istY); kayitlar_.push_back(std::move(k)); return *kayitlar_.back(); } void belgeHedefleriniGuncelle(BelgeYonetici& yon, ImGuiKatman& arayuz, VulkanBaglam& vulkan, f32 dt, bool boyutlaniyor) { for (auto& kp : yon.hepsi()) { BelgeKaydi& k = *kp; if (!k.acik) continue; // Belge-scope kare bakımı (ana belgenin döngü başı eşi): kamera yumuşatma, // işaretli düğüm mesh inşası, biten arka plan işleri, parametrik zincir. Belge& b = *k.belge; b.kamera.guncelle(dt); b.sahne.bekleyenleriYenidenInsa(); b.partD.asyncBekleyenUygula(); // DM async apply sonuçları bu belgede de insin (MDI) b.cekirdek.gorevler().pompala(b.cekirdek.olaylar()); if (b.cekirdek.recompute().kirliVar()) b.cekirdek.recompute().hesapla(b.cekirdek, b.cekirdek.olaylar()); // Sürüklerken offscreen hedef resize'ını ertele (ana viewport ile aynı gerekçe). if (!boyutlaniyor) { k.hedef->boyutla(k.istG, k.istY); k.belge->secim.boyutAyarla(k.hedef->boyut().width, k.hedef->boyut().height); } if (k.kayitliGorunum != k.hedef->renkGorunum()) { if (k.doku) arayuz.dokuKaldir(k.doku); k.doku = arayuz.dokuEkle(vulkan.viewportOrnekleyici(), k.hedef->renkGorunum()); k.kayitliGorunum = k.hedef->renkGorunum(); } } } void belgePencereleriCiz(BelgeYonetici& yon) { ImGuiIO& io = ImGui::GetIO(); for (auto& kp : yon.hepsi()) { BelgeKaydi& k = *kp; if (!k.acik) continue; ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); const std::string baslik = k.ad + "###belge_" + std::to_string(k.kimlik); { // İç kapsam: pen yıkıcısı (End) PopStyleVar'dan ÖNCE koşsun // Belge viewport'u: pin yok (3B pencere), tam yükseklik cap (maxYukOran=1), dock'lanabilir. ui::Pencere pen{baslik.c_str(), &k.acik, {.boyut = {960, 600}, .maxYukOran = 1.0f, .pin = false, .bayrak = 0}}; if (pen) { const ImVec2 avail = ImGui::GetContentRegionAvail(); k.istG = (u32)std::max(avail.x, 16.0f); k.istY = (u32)std::max(avail.y, 16.0f); const ImVec2 p = ImGui::GetCursorScreenPos(); k.rectMinX = p.x; k.rectMinY = p.y; if (k.doku) ImGui::Image((ImTextureID)k.doku, avail); k.hover = ImGui::IsItemHovered(); // Pick imleci (Image-yerel) — ana belgedeki fare.sonX kalıbının eşi. k.imlecX = io.MousePos.x - k.rectMinX; k.imlecY = io.MousePos.y - k.rectMinY; // CATIA kamera jestleri (ana belgenin sade eşi): kombinasyon → kip. // Orta(4) → PAN, Orta+Sağ(6) → DÖNDÜR, Sol+Sağ(3) → ZOOM, teker → yakınlaş. OrbitKamera& kamera = k.belge->kamera; const int btn = (ImGui::IsMouseDown(ImGuiMouseButton_Left) ? 1 : 0) | (ImGui::IsMouseDown(ImGuiMouseButton_Right) ? 2 : 0) | (ImGui::IsMouseDown(ImGuiMouseButton_Middle) ? 4 : 0); const bool basildi = ImGui::IsMouseClicked(ImGuiMouseButton_Left) || ImGui::IsMouseClicked(ImGuiMouseButton_Right) || ImGui::IsMouseClicked(ImGuiMouseButton_Middle); if (k.hover) { if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { k.solBasX = k.imlecX; k.solBasY = k.imlecY; } if (basildi) k.kameraKullandi = false; if (io.MouseWheel != 0.0f) kamera.yakinlastir(io.MouseWheel * 1.7f); if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) belgeSigdir(*k.belge); } // Merkezi kip durum makinesi (ana pencereyle aynı NavKipTakip) + olay yayını. // btn: sol=1, sağ=2, orta=4 → besle(sol, orta, sağ, sağ-release). { const bool navBaglam = k.hover || k.kameraKip >= 0; const girdi::NavKip navKip = k.navKip.besle( navBaglam && (btn & 1), navBaglam && (btn & 4), navBaglam && (btn & 2), navBaglam && ImGui::IsMouseReleased(ImGuiMouseButton_Right)); const int yeniKip = girdi::navKipInt(navKip); if (yeniKip != k.kameraKip) k.belge->cekirdek.olaylar().yayinla( NavKipDegisti{(u32)navKip, (u32)girdi::navKipEnum(k.kameraKip)}, "Nav", OlaySiddet::Iz, OlayKaynak::Kullanici); k.kameraKip = yeniKip; } const f32 mdx = io.MouseDelta.x, mdy = io.MouseDelta.y; const bool hareket = (mdx != 0.0f || mdy != 0.0f); if (k.kameraKip == 0) { kamera.dondur(mdx, mdy); if (hareket) k.kameraKullandi = true; } else if (k.kameraKip == 1) { kamera.yakinlastir(-mdy * 0.03f); if (hareket) k.kameraKullandi = true; } else if (k.kameraKip == 2) { kamera.kaydir(mdx, mdy, io.KeyShift); if (hareket) k.kameraKullandi = true; } // CATIA navigasyon ghost'u (config global ayardan, runtime pencere-yerel) k.navGhost.aktif = navGhostGlobal().aktif; k.navGhost.boyut = navGhostGlobal().boyut; k.navGhost.opaklik = navGhostGlobal().opaklik; navGhostCizVeIsle(k.navGhost, kamera, ImGui::GetWindowDrawList(), k.kameraKip, k.kameraKip >= 0, io.DeltaTime, k.rectMinX, k.rectMinY, avail.x, avail.y, avail.x / std::max(avail.y, 1.0f), k.hover ? io.MouseWheel : 0.0f); // Mikro sol-tık = seçim (hover'daki öğe; Ctrl çoklu). Kamera sürüklemesi bastırır. if (k.hover && ImGui::IsMouseReleased(ImGuiMouseButton_Left) && !k.kameraKullandi) { const f32 kayma = std::abs(k.imlecX - k.solBasX) + std::abs(k.imlecY - k.solBasY); if (kayma < 6.0f) secimTiklaKaydet(k.belge->cekirdek, k.belge->sahne, k.belge->secimSis, io.KeyCtrl); } } // if (pen) } // iç kapsam sonu → pen yıkıcısı End() çağırır ImGui::PopStyleVar(); } } void belgeleriKaydet(BelgeYonetici& yon, VulkanBaglam& vulkan, BoruHatlari& hatlar, const IsikDurum& isikDurum, VkCommandBuffer kb, f32 zaman, int kare) { for (auto& kp : yon.hepsi()) { BelgeKaydi& k = *kp; if (!k.acik) continue; BelgeCizimGirdi g; g.zaman = zaman; g.kare = kare; g.imlecX = k.imlecX; g.imlecY = k.imlecY; g.vpHover = k.hover; g.navigasyonAktif = k.kameraKip >= 0; // nav sürerken pick duraklat g.kameraHareketli = k.belge->kamera.hareketliMi(); // B#2: yumuşatma oturana kadar da belgeCiz(*k.belge, *k.hedef, vulkan, hatlar, k.cizim, isikDurum, kb, g, k.sonEnBoy, k.sonG, k.sonY); } } } // namespace fiko