如何在 ThreeJS 中围绕其中心旋转一个组?
How to rotate a group in ThreeJS around its center?
我正在尝试使用 ThreeJS 构建一个有效的 Rubikscube。现在我在 旋转侧面时遇到问题。 目前,我正在将 较小的立方体 添加到 Rubikscube 并像这样创建它:
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);
这一切 工作正常 直到我尝试 旋转 ,例如右 侧。我 select 右侧的棋子并将它们添加到 自己的组 中。现在,当我尝试旋转组时,it's rotating around the x axes。这是我想用来移动一侧的方法(忽略 bool 和 eval 部分,它只是为了获得正确的部分):
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);
}
并为其制作动画:
function animateMove(pivot) {
requestAnimationFrame(() => {
animateMove(pivot);
});
// missing part
renderer.render(scene, camera);
}
我尝试过的:
我尝试了不同的方法,以正确的方式旋转它,但没有任何效果,移动立方体也不是正确的答案。
我试过的一件事是 ,但是当我尝试以这种方式旋转它时,侧面只是 移动了 ,所以它仍然是 绕 x 轴旋转.
最小可重现示例
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();
我希望有人理解我的问题并帮助我解决它。谢谢!
所有旋转都围绕对象的原点进行。因此,如果您的对象的位置是 (0, 0, 0),那么这将是枢轴点。
我建议您将每个立方体块嵌套到一个 THREE.Group()
中,这样您就可以将所有 27 个块的轴心点保持在 (0, 0, 0)。然后你可以将其组内的每个棋子移动到所需的位置:
const geom = new THREE.BoxGeometry(1, 1, 1);
const Piece = new THREE.Mesh(geom, mat);
const Group = new THREE.Group();
// Nest Piece inside of its Group
Group.add(Piece);
// Parent Group position is at (0, 0, 0)
// Inner piece position is at (-1, -1, -1)
Piece.position.set(-1, -1, -1);
// Now we can apply rotations to the parent group
// and the child will maintain its distance from the center
Group.rotation.set(Math.PI / 2, 0, 0);
您需要为 X,Y,Z
的 [-1, 0, +1]
的所有值重复此操作。那是 3^3 = 27 件。
我正在尝试使用 ThreeJS 构建一个有效的 Rubikscube。现在我在 旋转侧面时遇到问题。 目前,我正在将 较小的立方体 添加到 Rubikscube 并像这样创建它:
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);
这一切 工作正常 直到我尝试 旋转 ,例如右 侧。我 select 右侧的棋子并将它们添加到 自己的组 中。现在,当我尝试旋转组时,it's rotating around the x axes。这是我想用来移动一侧的方法(忽略 bool 和 eval 部分,它只是为了获得正确的部分):
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);
}
并为其制作动画:
function animateMove(pivot) {
requestAnimationFrame(() => {
animateMove(pivot);
});
// missing part
renderer.render(scene, camera);
}
我尝试过的:
我尝试了不同的方法,以正确的方式旋转它,但没有任何效果,移动立方体也不是正确的答案。
我试过的一件事是
最小可重现示例
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();
我希望有人理解我的问题并帮助我解决它。谢谢!
所有旋转都围绕对象的原点进行。因此,如果您的对象的位置是 (0, 0, 0),那么这将是枢轴点。
我建议您将每个立方体块嵌套到一个 THREE.Group()
中,这样您就可以将所有 27 个块的轴心点保持在 (0, 0, 0)。然后你可以将其组内的每个棋子移动到所需的位置:
const geom = new THREE.BoxGeometry(1, 1, 1);
const Piece = new THREE.Mesh(geom, mat);
const Group = new THREE.Group();
// Nest Piece inside of its Group
Group.add(Piece);
// Parent Group position is at (0, 0, 0)
// Inner piece position is at (-1, -1, -1)
Piece.position.set(-1, -1, -1);
// Now we can apply rotations to the parent group
// and the child will maintain its distance from the center
Group.rotation.set(Math.PI / 2, 0, 0);
您需要为 X,Y,Z
的 [-1, 0, +1]
的所有值重复此操作。那是 3^3 = 27 件。