Estoy intentando cargar una escena de un archivo en Three.js (formato personalizado, no uno que admite Three.js). Este formato particular describe un gráfico de escena donde cada nodo en el árbol tiene una transformación especificada como una matriz 4x4. El proceso para empujar en Three.js ve algo como esto:Uso de matrices para transformar el gráfico de escena 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!
}
}
O al menos eso es lo que me gustaría que fuera. Como señalé, la línea applyMatrix
no funciona de la manera que yo esperaría. La mayoría de la escena se ve bien, pero ciertos elementos que se han girado no están alineados correctamente (mientras que otros son, es extraño).
Mirando a través del cargador COLLADA (que hace aproximadamente lo mismo que estoy tratando de hacer) parece que ellos decompose the matrix en una trasladar/rotar/escalar y aplicar cada uno individualmente. Traté de que en lugar de la applyMatrix mostrado arriba
var props = threeMatrixFromSrcMatrix(child.matrix).decompose();
threeObj.useQuaternion = true;
threeObj.position = props[ 0 ];
threeObj.quaternion = props[ 1 ];
threeObj.scale = props[ 2 ];
Esto, una vez más, produce una escena en la que la mayoría de los elementos están en el lugar correcto, pero mallas que antes estaban mal alineado ahora se han transformado en el olvido en algún lugar y ya no se aparecer en absoluto. Entonces, al final, esto no es mejor que el applyMatrix
desde arriba.
Mirando a través de varias discusiones en línea sobre el tema, parece que la forma recomendada de utilizar matrices para sus transformaciones es aplicarlas directamente a la geometría, no a los nodos, así que intenté construyendo manualmente la matriz de transformación así:
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!
}
}
¡Esto realmente da los resultados correctos! (sin algunas peculiaridades con las normales, pero puedo descifrarlo). Eso es genial, pero el problema es que ahora hemos aplastado la jerarquía de escenas: cambiar la transformación en una matriz producirá resultados inesperados en los hijos porque la totalidad la pila de transformación ahora está "horneada" en las mallas. En este caso, esa es una pérdida de información inaceptable sobre la escena.
Entonces, ¿cómo puede uno decirle a Three.js que haga la misma lógica, pero en el punto apropiado en el gráfico de escena?
(Lo siento, me encantaría publicar algunos ejemplos de código en vivo, pero eso no es por desgracia una opción en este caso.)
La misma respuesta, a un minuto. :) ¡Gracias de todos modos! El bit de updateMatrix es muy interesante. – Toji