Jiroskop - 3D Modelleme
Telefonunuzu Bir Sihirli Değneğe Dönüştürün: Web Tabanlı 3D Jiroskop Kontrolcüsü
Selamlar! Ben Yunus. Bugün sizlerle üzerinde büyük keyifle çalıştığım, fiziksel dünya ile dijital ortamı gerçek zamanlı olarak birbirine bağlayan yeni projemi paylaşmak istiyorum: Web Tabanlı 3D Jiroskop Kontrolcüsü.
Biliyorsunuz, sistem mimarileri ve interaktif web deneyimleri üzerine kafa yormayı seviyorum. Bu projede amacım basitti: Herhangi bir uygulama indirmeden, sadece telefonumun kamerasından bir QR kod okutarak bilgisayar ekranımdaki 3D bir modeli (bir arabayı veya telefonu) kendi elimdeymiş gibi uzayda döndürebilmek.
Kulağa basit geliyor değil mi? Ancak işin içine farklı eksen uzayları, canlı soket bağlantıları, çoklu kullanıcı oturumları ve "deployment" süreçleri girince, fizik kurallarını backend'de bükmek sandığımdan biraz daha karmaşık bir hal aldı. Gelin bu sistemi nasıl inşa ettiğime ve hangi aşamalardan geçtiğime yakından bakalım.
🛠️ Teknoloji Yığını (Tech Stack)
Projeyi modern, ölçeklenebilir ve tip güvenli bir yapıda tutmak için aşağıdaki teknolojileri kullandım:
Frontend: Vite, TypeScript, Three.js, TailwindCSS
Backend: Node.js, Express.js, Socket.IO
Deployment: Vercel (Client), Render (API)
Tasarım Dili: Spatial Computing & Minimalist Industrial (Buzlu cam efektleri, monokrom tonlar)
🚀 Geliştirme Aşamaları ve Karşılaştığım Zorluklar
Bu proje tek bir gecede ortaya çıkmadı. Sistemi sağlam bir temele oturtmak için mimariyi adım adım ve çok detaylı bir şekilde inşa etmem gerekti.
Aşama 1: Prototip ve HTTP Çıkmazı
Başlangıçta her şeyi tek bir klasörde, basit HTML ve JavaScript dosyalarıyla kurmuştum. Sunucuyu ayağa kaldırıp telefondan bağlandığımda acı bir gerçekle yüzleştim: iOS ve modern mobil tarayıcılar, HTTP bağlantılarında jiroskop (DeviceOrientationEvent) verisine erişimi güvenlik gerekçesiyle tamamen engelliyordu. Sistemi test edebilmek için geliştirme ortamında (localhost) Vite'ın @vitejs/plugin-basic-ssl eklentisiyle otomatik HTTPS sertifikaları üreterek yerel ağda güvenli bir tünel açtım. Bu sayede ilk verileri bilgisayara akıtabilmeyi başardım.
Aşama 2: Mimariyi Parçalamak ve TypeScript'e Geçiş
Proje büyüdükçe eski require (CommonJS) yapısı ve global değişkenler baş ağrıtmaya başladı. Modeller bazen jiroskop verisi gelmese bile kendi kendine dönüyor, 3000 portu çakışıp sunucuyu çökertiyordu.
Derin bir nefes aldım ve projeyi baştan aşağı TypeScript ile refactor ettim. Sistemi src/client ve src/server olarak iki izole dünyaya böldüm. Socket.IO olaylarını Interface'ler ile tip güvenli (type-safe) hale getirdim. Artık sunucu çökmüyor, boşta kalan portu dinamik olarak bulup ayağa kalkıyordu.
Aşama 3: 3D Dünyanın Matematiği (Three.js Eksenleri)
En çok zaman harcadığım (ve kahve tükettiğim) kısım burasıydı. Telefonu öne eğiyordum, ekrandaki model sağa dönüyordu!
Bunun sebebi, telefonun ürettiği Euler açılarının (Alpha, Beta, Gamma) referans sistemiyle, Three.js'in kullandığı Y-Yukarı (Y-Up, Right-Handed) koordinat sisteminin tamamen farklı olmasıydı. Bu uyuşmazlığı çözmek için THREE.Euler üzerinde özel bir eksen eşlemesi (mapping) yaptım. Gerekli yerlerde radyan dönüşümleri ve ters yönlü hareketleri engellemek için negatif çarpanlar kullanarak modeli telefonun tam bir yansıması haline getirdim.
Ayrıca, yüklenen farklı .glb modellerinin (kimisi devasa, kimisi karınca kadar) ekranda standart görünmesi için sahneye giren modelin Bounding Box'ını (sınır kutusunu) hesaplayıp otomatik ölçekleme (auto-scaling) ve merkeze alma algoritması yazdım.
Aşama 4: Canlıya Alma (Deployment) Cehennemi
Projeyi Vercel ve Render'a yüklerken tam bir kaos yaşandı.
Vercel tarafı, backend'in TypeScript kodlarını da derlemeye çalışıp transforming... aşamasında sonsuz döngüye girerek dondu.
Render tarafı ise, bir Linux makinesi olduğu için benim Windows'ta oluşturduğum package-lock.json yüzünden Rollup derleme hatası (@rollup/rollup-linux-x64-gnu bulunamadı) verip çöktü.
Çözüm: Monolitik yapıyı deployment aşamasında bıçak gibi ayırdım. Vercel için arka planı tamamen görmezden gelmesini sağlayan bir vercel.json kuralı yazdım. Render'da ise vite build süreçlerini tamamen devre dışı bırakıp sunucuyu direkt node --import tsx ile canlıya aldım.
Aşama 5: Arayüz ve Çoklu Oturum Yönetimi (Rooms)
Sistemi internete açtığımda yeni bir sorun doğdu: Herkes aynı kanalı dinlerse, benim telefonum başka birinin ekranındaki arabayı döndürürdü.
Bunu çözmek için Oda (Room) Bazlı Oturum mimarisini kurdum. Masaüstü arayüzü açıldığında benzersiz bir UUID oluşturuyor ve bunu bir QR koda gömüyor. Telefon kamerasıyla bu QR kodu okuttuğunuzda, URL üzerinden o özel odaya katılıyorsunuz. Böylece veriler sadece sizin cihazlarınız arasında akıyor.
Son dokunuş olarak, arayüzü Spatial Computing trendlerine uygun; buzlu cam efektleri (Glassmorphism), temiz ince tipografiler ve verilerin aktığı devasa monospace fontlarla baştan tasarladım. Ayrıca mobil arayüze bir switch ekleyerek jiroskop dışında Touchpad ile kontrol opsiyonu da sundum.
Sonuç
Sadece bir cihazı diğerine bağlamaktan öte, donanım verilerini web soketleri üzerinden bir 3D grafik motoruyla senkronize etmek muazzam bir deneyimdi. Frontend'in estetiğini Backend'in katı mantığıyla birleştirdiğinizde, bir web tarayıcısının sınırlarının ne kadar genişleyebileceğini görmek gerçekten heyecan verici.
Bu projenin kodlarını detaylıca incelemek veya kendi modellerinizi yükleyip test etmek isterseniz, GitHub repoma göz atabilirsiniz. Yeni projelerde, sınırları daha da zorlamak üzere görüşürüz!
Yunus.
Görseller: