Three.js: Agregar y eliminar hijos de objetos girados

Estoy tratando de simular un cubo de rubik. Quería elegir una cara al azar y rotarla. Así que creé 27 mallas de cubo y las coloqué. Puedes ver el cubo de rubik que funciona (erráticamente) aquí http://codepen.io/theonepa1/full/fzAli

Cual es el problema.

Como puede ver en el enlace de arriba, los cubos más pequeños en los bordes se mueven de forma aleatoria (al menos no como yo esperaba)

Qué he hecho.

Al intentar rotar una cara, he agrupado 9 cubos pertenecientes a la cara que se agregaron como elementos secundarios a un nuevo objeto Object3D. Luego roté el object3d a lo largo de su eje usando object3d.rotate.x (o y o z).

Lo que he depurado

Me he asegurado de que los cubos que estoy seleccionando para la rotación de la segunda cara sean correctos. Después de completar la primera rotación de la cara, actualizo sus posiciones virtuales (no las coordenadas reales). Entonces, para la segunda rotación de la cara, he verificado que los cubos se eligen correctamente.

Lo que realmente sucede

Una observación que hice fue que los ejes de los cubos (más pequeños) se alteran después de rotar el object3d (padre que sostiene los 9 cubos de una cara). Y también las coordenadas de los cubos no se actualizan automáticamente después de la rotación de la cara. Digamos, por ejemplo, si uno de los cubos tiene (0,0,22) como coordenadas antes de la rotación de la cara, las coordenadas son las mismas incluso después de la rotación. Sin embargo, la orientación de los ejes del cubo cambia.

¿Cuál es la mejor manera de rotar un grupo de objetos alrededor de un eje? Está usando Object3D correcto? ¿Se supone que debemos eliminar a los niños de un padre antes de agregarlo a otro grupo para la rotación de la segunda cara?

¿Tengo que hacer algún tipo de actualización en los cubos individuales antes de agregarlos al segundo grupo para la rotación de la segunda cara?

He leído algunas publicaciones sobre applyMatrixWorld, pero realmente no pude entender cuál fue su efecto en la orientación de los ejes y las coordenadas del cubo.

¿Puede decirme dónde puedo leer sobre los conceptos como applyMatrixWorld, es algún tipo de concepto común en una progtwigción 3D normal?

Esa es una pregunta realmente larga. Realmente apreciaría su respuesta 🙂

El truco es hacer uso de THREE.SceneUtils.attach() y THREE.SceneUtils.detach() .

Debes comenzar con todos tus 27 cubos como un niño de la scene .

Deje que el pivote sea un Object3D() .

Let active sea ​​una matriz que contiene los 9 cubos que desea rotar. Ahora haz que los cubos sean un elemento secundario del pivote:

 pivot.rotation.set( 0, 0, 0 ); pivot.updateMatrixWorld(); for ( var i in active ) { THREE.SceneUtils.attach( active[ i ], scene, pivot ); } 

Luego, después de la rotación, vuelva a colocar los cubos como hijos de la scene .

 pivot.updateMatrixWorld(); for ( var i in active ) { cubes[ i ].updateMatrixWorld(); // if not done by the renderer THREE.SceneUtils.detach( active[ i ], pivot, scene ); } 

Lee la fuente de SceneUtils.js para que entiendas lo que está sucediendo.

three.js r.63