我試圖從一個文件加載到Three.js(自定義格式,不是Three.js支持的)一個場景。這種特殊格式描述了一個場景圖,其中樹中的每個節點都有一個指定爲4x4矩陣的變換。將其推入Three.js的過程如下所示:使用矩陣變換Three.js場景圖
// Yeah, this is javascript-like psuedocode
function processNodes(srcNode, parentThreeObj) {
for(child in srcNode.children) {
var threeObj = new THREE.Object3D();
// This line is the problem
threeObj.applyMatrix(threeMatrixFromSrcMatrix(child.matrix));
for(mesh in child.meshes) {
var threeMesh = threeMeshFromSrcMesh(mesh);
threeObj.add(threeMesh);
}
parentThreeObj.add(threeObj);
processNodes(child, threeObj); // And recurse!
}
}
或者至少這就是我所希望的。正如我指出的那樣,applyMatrix
行不符合我的預期。大部分場景看起來不錯,但某些已旋轉的元素沒有正確對齊(而其他元素則很奇怪)。
翻閱COLLADA加載程序(它的功能與我試圖做的大致相同),看起來它們是decompose the matrix的翻譯/旋轉/縮放並單獨應用。我想,在地方applyMatrix的上面顯示:
var props = threeMatrixFromSrcMatrix(child.matrix).decompose();
threeObj.useQuaternion = true;
threeObj.position = props[ 0 ];
threeObj.quaternion = props[ 1 ];
threeObj.scale = props[ 2 ];
這再次產生一個場面,大部分元素都在正確的地方,但網格,以前都是錯位現已地方,不再轉化成遺忘根本不出現。所以最後這不比上面的applyMatrix
好。
通過幾個關於該主題的在線討論,似乎推薦使用矩陣進行變換的方式是將它們直接應用於幾何體,而不是節點,因此我嘗試通過手動構建變換矩陣,如下所示:
function processNodes(srcNode, parentThreeObj, parentMatrix) {
for(child in srcNode.children) {
var threeObj = new THREE.Object3D();
var childMatrix = threeMatrixFromSrcMatrix(child.matrix);
var objMatrix = THREE.Matrix4();
objMatrix.multiply(parentMatrix, childMatrix);
for(mesh in child.meshes) {
var threeMesh = threeMeshFromSrcMesh(mesh);
threeMesh.geometry.applyMatrix(objMatrix);
threeObj.add(threeMesh);
}
parentThreeObj.add(threeObj);
processNodes(child, threeObj, objMatrix); // And recurse!
}
}
這實際上會產生正確的結果! (減去法線方面的一些怪癖,但我可以指出這一點)這很好,但問題是我們現在已經有效地展開了場景層次結構:更改父級變換會在子級上產生意想不到的結果,因爲滿變換堆棧現在被「烘烤」到網格中。在這種情況下,這是對現場信息的不可接受的損失。
那麼,如何告訴Three.js做相同的邏輯,但是在場景圖中的適當位置呢?
(對不起,我倒是十分想發佈一些活的代碼示例但是這不幸的是沒有這種情況的一個選項。)
相同的答案,間隔一分鐘。 :)但是,無論如何,謝謝! updateMatrix位非常有趣。 – Toji