I am trying to build a working Rubikscube with ThreeJS. Now I have a problem with rotating the sides. At the moment, I am adding the smaller cubes to the Rubikscube and create it like this:
const rubikscube = new THREE.Group();
for (var i = 0; i < 27; i++) {
// 3x3x3 (0,0,0) is on the top left corner
var cube = createPartOfCube(i, scene);
cube.name = i;
cube.position.x = (i % 3) * gap;
cube.position.y = Math.floor(i / 9) * gap;
cube.position.z = (Math.floor(i / 3) % 3) * gap;
rubikscube.add(cube);
}
scene.add(rubikscube);
And this all works fine until I try to rotate, e.g. the right side. I select the pieces on the right side and add them to their own group. Now, when I try to rotate the group, it's rotating around the x axes. Here is the method I want to use for moving a side (just ignore the bool and eval part, its just for getting the right pieces):
function move(direction) {
var bool = moves[direction];
var pivot = new THREE.Group();
pivot.updateMatrixWorld();
for (var i = 0; i < 27; i++) {
if (eval(format(bool, i))) {
pivot.add(scene.getObjectByName(i));
}
}
scene.add(pivot);
animateMove(pivot);
}
And animating it:
function animateMove(pivot) {
requestAnimationFrame(() => {
animateMove(pivot);
});
// missing part
renderer.render(scene, camera);
}
What I've tried:
I have tried different methods, to rotate it the right way but nothing worked and moving the cube is also not the right answer.
One thing I tried was on this thread, but when I tried to rotate it this way, the side just moved, so it's still rotating around the x-axes.
Minimal reproducible example
function main() {
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const gap = 1.1;
scene.add(new THREE.AxesHelper(100));
scene.background = new THREE.Color('white');
camera.position.z = 5;
renderer.setSize(window.innerWidth, window.innerHeight);
const rubikscube = new THREE.Group();
for (var i = 0; i < 27; i++) {
// 3x3x3 (0,0,0) is on the top left corner
var cube = createPartOfCube(i, scene);
cube.name = i;
cube.position.x = (i % 3) * gap;
cube.position.y = Math.floor(i / 9) * gap;
cube.position.z = (Math.floor(i / 3) % 3) * gap;
rubikscube.add(cube);
}
scene.add(rubikscube);
animate();
}
function animate() {
requestAnimationFrame(animate);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(1, 1, 1);
controls.update();
var movingIds = [2, 5, 8, 11, 14, 17, 20, 23, 26]; // IDs of the pieces needed to rotate
var group = new THREE.Group();
movingIds.forEach((i) => {
group.add(scene.getObjectByName(i));
});
scene.add(group);
animateMove(group);
}
function animateMove(group) {
requestAnimationFrame(() => {
animateMove(group);
});
group.rotation.x = 2; // Wrong part I need help with
renderer.render(scene, camera);
}
function createPartOfCube() {
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 'black' });
var cube = new THREE.Mesh(geometry, material);
return cube;
}
main();
I hope that someone understands my issue and helps me to solve it. Thanks!