在 Three.js 中,
Skeleton
是一個用來管理骨骼系統的類,主要用於實現角色的骨骼動畫。透過Skeleton
,你可以控制多個骨骼(bones)的變換,從而驅動網格(mesh)模型的運動。
Skeleton( bones : Array, boneInverses : Array ) bones —— 包含有一組bone的陣列,預設值是一個空陣列。 boneInverses —— (可選) 包含Matrix4的陣列。 建立一個新的Skeleton.
Skeleton 有四個屬性七個方法
屬性
bones : Array 包含有一組bone的陣列。請注意,這是一份原始陣列的複製,不是引用,所以你可以在不對當前陣列造成影響的情況下,修改原始陣列。 對應建構函式中 bones 陣列的資料
boneInverses : Array 包含有一組Matrix4,表示每個獨立骨骼matrixWorld矩陣的逆矩陣。
const bone1 = new THREE.Bone(); const bone2 = new THREE.Bone(); bone1.add(bone2); const skeleton = new THREE.Skeleton([bone1, bone2]); console.log(skeleton.boneInverses); // 輸出 bone bone2 每個骨骼的逆矩陣 [ { "elements": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] }, { "elements": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] } ]
boneMatrices : Float32Array 當使用頂點紋理時,陣列緩衝區儲存著骨骼資料。這個陣列以線性方式儲存每個骨骼的 4x4 變換矩陣,每個矩陣佔用 16 個浮點數。該陣列的大小是 bones.length * 16。
// 在這個例子中,`boneMatrices` 會包含 `bone1` 和 `bone2` 的 4x4 變換矩陣,以 `Float32Array` 的形式儲存。 const bone1 = new THREE.Bone(); const bone2 = new THREE.Bone(); bone1.add(bone2); const skeleton = new THREE.Skeleton([bone1, bone2]); // 更新骨骼矩陣 skeleton.calculateInverses(); skeleton.pose(); console.log(skeleton.boneMatrices); // 輸出骨骼矩陣的 Float32Array { "0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0, "8": 0, "9": 0, "10": 0, "11": 0, "12": 0, "13": 0, "14": 0, "15": 0, "16": 0, "17": 0, "18": 0, "19": 0, "20": 0, "21": 0, "22": 0, "23": 0, "24": 0, "25": 0, "26": 0, "27": 0, "28": 0, "29": 0, "30": 0, "31": 0 }
boneTexture : DataTexture 當使用頂點紋理時,DataTexture儲存著骨骼資料。 在 Three.js 中,boneTexture 是 Skeleton 類的一個屬性,它是一個 DataTexture 物件,用於在需要大量骨骼動畫時將骨骼的變換矩陣儲存在紋理中。透過使用 boneTexture,可以利用 GPU 來處理骨骼動畫,從而提高渲染效能,特別是在有大量骨骼的情況下。如果場景中骨骼較少(通常少於 50 個),boneTexture 可能不會自動啟用,這種情況下沒有問題,因為 CPU 處理已經足夠快。
方法
clone () : Skeleton 返回一個當前Skeleton物件的克隆。
calculateInverses () : undefined 如果沒有在構造器中提供,生成boneInverses陣列。
const bone1 = new THREE.Bone(); const bone2 = new THREE.Bone(); bone1.add(bone2); const skeleton = new THREE.Skeleton([bone1, bone2]); // 計算骨骼的逆矩陣 skeleton.calculateInverses(); console.log(skeleton.boneInverses); // 輸出骨骼的逆矩陣 [ { "elements": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] }, { "elements": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] } ]
computeBoneTexture () : this 計算 DataTexture 的例項,以便更有效地將骨骼資料傳遞到著色器。紋理被分配給boneTexture。
const bone1 = new THREE.Bone(); const bone2 = new THREE.Bone(); bone1.add(bone2); const skeleton = new THREE.Skeleton([bone1, bone2]); // 計算骨骼的逆矩陣 skeleton.calculateInverses(); console.log(skeleton.boneInverses); // 輸出骨骼的逆矩陣 [ { "elements": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] }, { "elements": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] } ]
pose () : undefined 返回骨架的基礎姿勢。
update () : undefined 在改變骨骼後,更新boneMatrices 和 boneTexture的值。 如果骨架被用於SkinnedMesh,則它將會被WebGLRenderer自動呼叫。
getBoneByName ( name : String ) : Bone name —— 匹配Bone物件中.name屬性的字串。 在骨架中的骨骼陣列中遍覽,並返回第一個能夠和name匹配上的骨骼物件。
const bone1 = new THREE.Bone(); bone1.name = 'spine'; const bone2 = new THREE.Bone(); bone2.name = 'left_arm'; const skeleton = new THREE.Skeleton([bone1, bone2]); // 根據名稱查詢骨骼 const foundBone = skeleton.getBoneByName('spine'); console.log(foundBone); // 輸出為找到的骨骼物件(bone1) const missingBone = skeleton.getBoneByName('right_leg'); console.log(missingBone); // 輸出 null,因為沒有名為 'right_leg' 的骨骼 { "metadata": { "version": 4.6, "type": "Object", "generator": "Object3D.toJSON" }, "object": { "uuid": "193381dc-9ca6-4570-8927-e3ea2173fbc3", "type": "Bone", "name": "spine", "layers": 1, "matrix": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ], "up": [ 0, 1, 0 ] } }
dispose () : undefined 如果應用程式中的 Skeleton 例項已過時,則可以使用。該方法將釋放內部資源。