我是Three.js和3D的新手。我正在尝试通过构建3D Rubik's Cube来学习。我很难旋转立方体的平面。
我的Rubik's Cube是3x3立方体单位立方体。任何给定的立方体平面可以作为一组旋转。所有旋转都围绕飞机的中心。
我的策略是在“包装器”Object3D
内创建每个立方体网格,因此每个立方体围绕世界[0,0,0]
旋转。每个包装器只包含一个立方体。当请求给定的平面旋转时,我找到所有包含在世界坐标中的平面上的立方体并旋转四分之一圈的包装。
此方法适用于第一次旋转和一些后续旋转,但经过多次旋转后,立方体似乎重叠并以意想不到的方式旋转。
This JSFiddle(three.js R61)显示了我的问题 - 任何旋转都按预期工作,但是2或3次旋转的组合会导致(对我而言)意外行为。我该如何解决?
我尝试过其他一些方法(比如为每个平面旋转构建一个临时Object3D
,将临时matrixWorld
旋转并应用到平面上的每个立方体然后移除组),但是他们屈服了类似的效果。
构建多维数据集:
var allWrappers = [];
function newCube(x, y, z) {
var cubeGeometry = new THREE.CubeGeometry(cubeSize, cubeSize, cubeSize),
cube = new THREE.Mesh(cubeGeometry, cubeMaterials);
cube.position = new THREE.Vector3(x, y, z),
wrapper = new THREE.Object3D();
wrapper.add(cube);
allWrappers.push(wrapper);
scene.add(wrapper);
}
var increment = cubeSize + spacing;
for(var i = 0; i < dimensions; i ++) {
for(var j = 0; j < dimensions; j ++) {
for(var k = 0; k < dimensions; k ++) {
var x = (i - 1) * increment,
y = (j - 1) * increment,
z = (k - 1) * increment;
newCube(x, y, z);
}
}
}
平面旋转:
//Move all cubes with value 'v' on axis 'axis'
function move(v, axis) {
allWrappers.forEach(function(wrapper) {
var cubePosition = wrapper.children[0].position.clone();
cubePosition.applyMatrix4(wrapper.matrixWorld);
//If the current cube has the right position on this axis,
// rotate it one quarter turn
if(Math.abs(cubePosition[axis] - v) < 0.0001)
wrapper.rotation[axis] += Math.PI / 2;
});
render();
}