holodepth

Three.js · glTF pipeline

Modelin iskeleti: Node hiyerarşisi (düğüm yapısı)

Bir glTF veya OBJ dosyasını sahneye yüklediğinizde elinize tek bir «kutu» değil, karmaşık bir düğüm (node) ağacı geçer. Her düğüm; bir parça geometri, bir ışık, bir kemik veya yalnızca boş bir referans noktasını temsil edebilir.

Three.js tarafında bu yapı Object3D hiyerarşisiyle birebir örtüşür; isimler ve ebeveyn–çocuk zinciri, kodda parça bulmanın, animasyon hedefi seçmenin ve hata ayıklamanın anahtarıdır. Önceki konuda scene graph kurallarını gördük; bu sayfada aynı ağacı düğüm düzeyinde okuma ve yönetme pratiğine iniyoruz.

Önce okuyun: Scene graph (model içi hiyerarşi), Sahne (Scene) — Object3D, Object3D & sahne hiyerarşisi.

Node nedir? (düğümün anatomisi)

Üç boyutta her şey bir Object3D türevidir. Dosyadaki «node» kavramı, Three.js tarafında yine bu sınıf hiyerarşisine oturur; GLTFLoader yalnızca veriyi okuyup ebeveyn–çocuk ilişkisini ve yerel dönüşümleri korur. Aşağıda tipik bir glTF yüklemesinde sık görülen katmanları, mantıksal rol olarak ayırıyoruz — gerçek ağaç dosyaya göre daha derin veya daha sığ olabilir.

Scene (kök kapsayıcı)

gltf.scene genelde tüm modelin ana kapsayıcısıdır; yükleyici asıl ağacı burada veya bir alt düğümde sunar. Sahneye eklerken çoğu örnek scene.add(gltf.scene) desenini kullanır — böylece dosyanın kök dönüşümü ve alt dalları tek blok halinde gelir.

Root ve ara gruplar

Dışa aktarma aracına göre modelin genel ölçek/döndürme bilgisini taşıyan ilk düğüm veya ara bir Group görebilirsiniz. Bu düğüm «görünmez» olsa bile scene graph içinde matris zincirine katılır; animasyon veya skinning kökünü burada aramak yaygındır.

Mesh düğümleri

Geometri ve materyali barındıran görünür parçalar. Çok materyalli mesh’lerde material dizi olabilir; traverse sırasında her iki durumu da ele almak gerekir (bir sonraki bölümde örnek).

Bone ve rig düğümleri

Rig’li modellerde iskelet ağacını oluşturan düğümler; SkinnedMesh ile birlikte okunmalıdır. İsimler genelde DCC’deki kemik adlarıyla gelir — seçim ve hata ayıklama için Skinning konusuna hazırlık sayfasıdır.

İsimlendirilmiş düğümlerle çalışmak

Karmaşık bir modelde belirli bir parçayı (örneğin arabadaki direksiyon) bulmak için ağacı taramanız gerekir. Object3D üzerindeki name alanı, DCC aracında (Blender, Maya vb.) verdiğiniz nesne adlarıyla içe aktarılır; boşluk, büyük/küçük harf ve Türkçe karakterler dâhil dışa aktarma ayarına göre aynen gelebilir.

getObjectByName("Direksiyon") alt ağaçta özyinelemeli çalışır: isim, doğrudan çocukta veya daha derindeki torunlarda olsa bulunur. Aynı isimden birden fazla düğüm varsa ilk eşleşen döner; üretimde benzersiz isimlendirme veya ek kontrol şarttır.

Dar kapsamda aramak için önce ilgili üst düğümü (car.getObjectByName("Body") gibi) alıp sonra altında arama yapmak, hem performans hem de yanlış eşleşme riskini azaltır.

İsim çakışması

Wheel hem ön hem arka için kullanıldıysa, önce hangi dalın dolaşıldığına bağlı olarak yanlış mesh seçilebilir. Çözüm: Wheel_FL / Wheel_FR gibi tutarlı bir şema veya üst gruptan başlayıp daraltarak arama.

İsme alternatifler

İsme güvenmek istemezseniz userData ile özel kimlik saklayabilir veya yük sonrası traverse ile koşula göre etiketleyebilirsiniz; yine de kaynakta anlamlı isim en okunabilir yoldur.

HoloDepth ipucu

Modeli hazırlarken Blender’da parçalara verdiğiniz isimler Three.js’te name olarak gelir; kod tarafında seçim, animasyon hedefi ve hata ayıklama konsolu çıktısı için tek kararlı anahtarınız budur.

Koleksiyon / export adı ile sahne içi nesne adı farklı olabilir; glTF dışa aktarırken «nesne adlarını koru» benzeri seçenekleri kontrol edin. İsimleri değiştirdikten sonra eski kodda sabit dizgiler kaldıysa seçim sessizce null dönebilir — kritik parçalarda bulunamadıysa uyarı log’u ekleyin.

// Hiyerarşi içinde isme göre arama
const steeringWheel = carModel.getObjectByName("Direksiyon");

if (steeringWheel) {
  steeringWheel.rotation.y += 0.1; // Yalnızca direksiyon
}

Hiyerarşik dönüşümün gücü

Node hiyerarşisinin kritik özelliği bağıl hareket kabiliyetidir. Her çocuk, kendi position / rotation / scale değerlerini ebeveynin yerel uzayına göre tutar; ebeveyn hareket ettiğinde bu yerel değişmez, ancak zincirlenen world matrix güncellenerek dünya uzayındaki son konum ve yön birlikte değişir.

Matematiksel olarak bu, kökten yaprağa doğru çarpılan model–dünya matrislerinin (matrixWorld) her karede güncellenmesiyle aynı şeydir; Three.js bu zinciri sahne grafiğinde yukarıdan aşağıya işler — ayrıntılı çerçeve için Sahne köprüsü ve yerel / dünya uzayı bölümlerine bakın; burada odak düğüm zincirini kodda okumaktadır.

Kol ve iskelet örneği

Üst kol düğümünü döndürdüğünüzde ön kol, el ve parmak düğümleri aynı üst zincirde oldukları için birlikte hareket eder; her biri bir üst düğümün çocuğudur. Parmakları ayrıca bükümek için yalnızca ilgili alt düğümün yerel açısını değiştirmeniz yeterlidir — dünya pozisyonu tüm ata zinciriyle otomatik uyumlanır.

Yerel mi, dünya mı?

Animasyon veya fizik için «gerçek» dünya konumu lazımsa getWorldPosition / getWorldQuaternion kullanın; yalnızca child.position bakmak, ebeveyn dönüşümünü yansıtmaz.

Bu yapı, skinning ve morph ile birleştiğinde aynı düğüm ağacı üzerinden sürer; böylece karakter rig’i ile sahne içi hareket tutarlı kalır.

Traverse: tüm ağacı taramak

Bazen tüm parçalara aynı anda müdahale etmeniz gerekir (örneğin gölgeleri açmak, ortak bir tone mapping ayarını materyallere yazmak). Bunun için .traverse(callback) kullanılır; callback her düğüm için çağrılır, bu yüzden sahne büyüdükçe maliyeti göz önünde bulundurun.

node.isMesh ile filtrelemek yaygındır. material tek nesne veya dizi olabilir; aşağıdaki örnekte dizi durumu için Array.isArray kontrolü vardır — çoklu materyalde aynı işlemi her öğeye uygulamak için küçük bir yardımcı fonksiyon yazmak sık görülür.

Traverse, Sahne (Scene) — traversal bölümündeki fikirle aynıdır; fark, kökünüzün bu kez gltf.scene veya alt ağaç olmasıdır.

model.traverse((node) => {
  if (node.isMesh) {
    node.castShadow = true;
    node.receiveShadow = true;
    const m = node.material;
    if (m && !Array.isArray(m)) {
      m.envMapIntensity = 1.5;
    }
  }
});

İnteraktif: aynı prosedürel Car ağacı

Sahne grafiği sayfasındaki laboratuvarla aynı kök hiyerarşiyi (Car → gövde, tekerler, menteşe grubu, kapı mesh) paylaşıyoruz; burada odağı name, traverse, getObjectByName ve world / local okumasına kaydırıyoruz. Pivot «yanlış doğru» anahtarı yalnızca sahne grafiği lab’ında — bu sayfada düğüm davranışını gözlemlemek için hafif dönüş animasyonu ve toplu mesh vurgusu vardır.

Node lab · prosedürel ağaç · Three.js r170
Konum okuması
isim / kısmi arama

Düğüm ağacı (name)

Seçim · ata zinciri


                                
Seçim:

Amaç: Ağaçtan veya sahneden düğüm seçerek ata zincirini görmek; World / Local ile aynı düğümün iki konum okumasını karşılaştırmak; traverse ile tüm meshleri anlık vurgulamak; isim kutusunda kısmi, büyük/küçük harf duyarsız arama; tam isim eşleşmesinde (ör. Wheel_FL) yalnızca o düğüm, kısmi çoklu eşleşmede (ör. wheel) sahne yalnızca ilk eşleşmeyi vurgular, diğerleri açılır listeden seçilir — düzen kayması olmaması için liste kutunun altında katmandadır. Hiyerarşi sahne grafiği lab’ı ile aynıdır — sayfa rolleri farklıdır.

Boş düğümler (empty / null)

Hiyerarşide geometri taşımayan düğümler sık görülür; bunlar «hata» değil, tasarımcının bıraktığı mantıksal işaretleyiciler veya pivot taşıyıcılardır:

  • Pivot: dönme merkezini veya hizalamayı ayırmak için (detay için pivot stratejisi).
  • Locator / kanca: kodda efekt veya ek mesh bağlamak için bırakılmış yer tutucu.

Bu düğümleri silmeden önce animasyon veya dış araçların onlara referans verip vermediğini kontrol edin; bazen yalnızca visible = false yapmak daha güvenlidir.

Yaygın hata: yanlış kök seçimi

Dikkat

GLTFLoader sonucu bir «paket» objesidir; sahneye genelde scene.add(gltf.scene) ile kök düğümü eklersiniz. Ham yükü doğrudan sahneye eklemek (scene.add(gltf)) genellikle yanlış veya beklenmeyen davranıştır — asıl hiyerarşi gltf.scene altında başlar.

Konsolda traverse ile ağacı listelediğinizde beklediğiniz derinlik yoksa, önce gltf.scene altında mı dolaştığınızı doğrulayın.

HoloDepth «Node Hierarchy» checkpoint’i

Özet

Hiyerarşiyi anlamak, modelin üzerinde tam hakimiyet kurmaktır; isimler ve ebeveyn zinciri olmadan karmaşık sahneler yönetilemez.

Sıradaki konu: doku yuvalarının materyalle nasıl eşlendiğini Texture bağlama sayfasında işleyeceğiz.

HoloDepth özet stratejisi

  • İsimlendirme: Tasarımda parçalara anlamlı isimler verin (Wheel_FR, Headlight_L vb.).
  • Traverse: Materyal veya gölge ayarlarını tek tek değil, ağacı tarayarak topluca uygulayın.
  • Hiyerarşiyi bozma: Parçaları ebeveynlerinden koparıp doğrudan ana sahneye alırsanız bağıl animasyon ve pozisyonları kaybedebilirsiniz.