組對象Group、層級模型
本文是Three.js電子書的6.1節
本節課的目的是爲了大家建立層級模型的概念,所謂層級模型,比如一個機器人,人頭、胳膊都是人的一部分,眼睛是頭的一部分,手是個胳膊的一部分,手指是手的一部分…這樣的話就構成一個一個層級結構或者說樹結構。
Group案例
在詳細講解層級模型之前先通過Threejs的類Group實現一個網格模型簡單的案例。
下面代碼代碼創建了兩個網格模型mesh1、mesh2,通過THREE.Group
類創建一個組對象group,然後通過add
方法把網格模型mesh1、mesh2作爲設置爲組對象group的子對象,然後在通過執行scene.add(group)
把組對象group作爲場景對象的scene的子對象。也就是說場景對象是scene是group的父對象,group是mesh1、mesh2的父對象。這樣就構成了一個三層的層級結構,當然了你也可以通過Group
自己創建新模型節點作爲層級結構中的一層。
//創建兩個網格模型mesh1、mesh2
var geometry = new THREE.BoxGeometry(20, 20, 20);
var material = new THREE.MeshLambertMaterial({color: 0x0000ff});
var group = new THREE.Group();
var mesh1 = new THREE.Mesh(geometry, material);
var mesh2 = new THREE.Mesh(geometry, material);
mesh2.translateX(25);
//把mesh1型插入到組group中,mesh1作爲group的子對象
group.add(mesh1);
//把mesh2型插入到組group中,mesh2作爲group的子對象
group.add(mesh2);
//把group插入到場景中作爲場景子對象
scene.add(group);
網格模型mesh1、mesh2作爲設置爲父對象group的子對象,如果父對象group進行旋轉、縮放、平移變換,子對象同樣跟着變換,就像你的頭旋轉了,眼睛會跟着頭旋轉。
//沿着Y軸平移mesh1和mesh2的父對象,mesh1和mesh2跟着平移
group.translateY(100);
//父對象縮放,子對象跟着縮放
group.scale.set(4,4,4);
//父對象旋轉,子對象跟着旋轉
group.rotateY(Math.PI/6)
查看子對象.children
Threejs場景對象Scene、組對象Group都有一個子對象屬性.children
,通過該屬性可以訪問父對象的子對象,子對象屬性.children
的值是數組,所有子對象是數組的值,你可以在瀏覽器控制檯打印測試上面案例代碼。
執行console.log(group.children)
你可以在瀏覽器控制控制看到group的子對象是案例代碼中通過add
方法添加的兩個網格模型對象Mesh。
console.log('查看group的子對象',group.children);
場景對象結構
執行console.log(scene.children)
你在瀏覽器控制檯查看場景對象Scene的子對象,除了可以看到案例代碼通過add
方法添加的組對象group之外,還可以看到通過add
方法插入到場景中的環境光AmbientLight
、點光源PointLight
、輔助座標對象AxesHelper
等子對象。
console.log('查看Scene的子對象',scene.children);
場景對象對象scene構成的層級模型本身是一個樹結構,場景對象層級模型的第一層,也就是樹結構的根節點,一般來說網格模型Mesh、點模型Points、線模型Line是樹結構的最外層葉子結點。構建層級模型的中間層一般都是通過Threejs的Group
類來完成,Group
類實例化的對象可以稱爲組對象。
Threejs渲染的時候從根節點場景對象開始解析渲染,如果一個模型要想被渲染出來就要直接或間接插入到場景scene中,一個光源如果要在光照計算中起作用同樣需要通過add
方法插入到場景中。
.add()
方法
場景對象Scene
、組對象Group
、網格模型對象Mesh
、光源對象Light
的.add()
方法都是繼承自它們共同的基類Object3D。
父對象執行.add()
方法的本質就是把參數中的子對象添加到自身的子對象屬性.children
中。
.add()
方法可以單獨插入一個對象,也可以同時插入多個子對象。
group.add(mesh1);
group.add(mesh2);
group.add(mesh1,mesh2);
Scene根節點 渲染的問題
.remove()
方法
.add()
方法是給父對象添加一個子對象,.remove()
方法是刪除父對象中的一個子對象。
一個對象的全部子對象可以通過該對象的.children()
屬性訪問獲得,執行該對象的刪除方法.remove()
和添加方法.add()
一樣改變的都是父對象的.children()
屬性。
場景Scene
或組對象Group
的.remove()
方法使用規則可以查看它們的基類Object3D。
// 刪除父對象group的子對象網格模型mesh1
group.add(mesh1)
// 一次刪除場景中多個對象
scene.remove(light,group)