I am currently attempting to construct a functioning Rubik's Cube using ThreeJS. However, I have encountered an issue with rotating the sides. To build the Rubik's Cube, I am adding individual smaller cubes in this manner:
const rubiksCube = new THREE.Group();
for (var i = 0; i < 27; i++) {
// 3x3x3 (0,0,0) is located at 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);
This setup is operating smoothly until I attempt to perform a rotation, such as the right side. When selecting the pieces on the right side and adding them to their own group, the resulting rotation occurs around the x-axis. Below is the method I am employing for moving a side:
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);
}
For animating the movement:
function animateMove(pivot) {
requestAnimationFrame(() => {
animateMove(pivot);
});
// missing part
renderer.render(scene, camera);
}
What I've Attempted:
I have tried various methods to achieve the correct rotation without success. Simply moving the cube is not providing the desired outcome.
One approach I explored was on this thread, but rotating in this manner caused the side to shift instead of rotating properly around the x-axis.
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 located at 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; // Incorrect aspect needing assistance
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 my dilemma is understood, and any help provided in resolving it would be greatly appreciated. Thank you!