从组中移除并单独添加到场景后,组子位置不保存
Group children position is not saved after removing from group and adding to scene individually
我正在尝试用 three.js 制作一个 rubiks 立方体模拟器,所以我现在的目标是旋转底部,然后旋转中间层。
我旋转底层切换到中间层后,底层又回到原位(旋转后的位置不保存),中间层瞬间断裂
这是我的代码:
import * as THREE from 'three'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas.webgl")});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry(1, 1, 1);
const materials = [
new THREE.MeshBasicMaterial({color: 'white'}),
new THREE.MeshBasicMaterial({color: 'yellow'}),
new THREE.MeshBasicMaterial({color: 'red'}),
new THREE.MeshBasicMaterial({color: 'darkorange'}),
new THREE.MeshBasicMaterial({color: 'blue'}),
new THREE.MeshBasicMaterial({color: 'green'}),
];
for(let i = 0; i < geometry.groups.length; i++)
geometry.groups[i].materialIndex = i;
const cube = [];
for(let y = -1; y <= 1; y++){
for(let x = -1; x <= 1; x++){
for(let z = -1; z <= 1; z++){
const mesh = new THREE.Mesh(geometry, materials);
mesh.position.x = x;
mesh.position.y = y;
mesh.position.z = z;
cube.push(mesh);
scene.add(mesh);
}
}
}
const controls = new TrackballControls( camera, renderer.domElement );
controls.noPan = true;
controls.noZoom = true;
controls.rotateSpeed = 3;
camera.position.z = 7.5;
controls.update();
const face = new THREE.Group();
// get the bottom layer
for(let i = 0; i < 9; i++){
scene.remove(cube[i]);
face.add(cube[i]);
}
scene.add(face);
let moveCount = 0;
function animate() {
requestAnimationFrame( animate );
controls.update();
if(moveCount < 1){
if(face.rotation.y < THREE.MathUtils.degToRad(90)){
face.rotation.y += THREE.MathUtils.degToRad(2);
}
else{
changeFace();
moveCount++;
}
}
renderer.render( scene, camera );
}
function changeFace() {
scene.add(...face.children);
face.remove(...face.children);
for(let i = 9; i < 18; i++){
scene.remove(cube[i]);
face.add(cube[i]);
}
};
animate();
一张gif来说明:
当您旋转网格的 parent 时,网格的旋转不会改变。只有 parent 的旋转变化。因此,当您从 parent 中取出网格时,您将删除它继承的任何变换。
您可以使用 object.getWorldQuaternion()
将 world-space 旋转存储到四元数中,然后将它们应用于 child 网格:
let tempQuaternion = new THREE.Quaternion();
for(let i = 9; i < 18; i++){
// Read world rotations before removal
cube[i].getWorldQuaternion(tempQuaternion);
// Take the cube out of the group, place directly onto scene
scene.add(cube[i]);
// Now we re-apply the world rotations to the cube
cube[i].quaternion.copy(tempQuaternion);
}
请记住,一个网格一次只能有一个 parent。所以添加到组时,不需要将其从场景中移除,vice-versa.
// This line adds all children to scene,
// and automatically removes each one from face when doing so
scene.add(...face.children);
// This line doesn't do anything because all children have already been removed
face.remove(...face.children);
我正在尝试用 three.js 制作一个 rubiks 立方体模拟器,所以我现在的目标是旋转底部,然后旋转中间层。 我旋转底层切换到中间层后,底层又回到原位(旋转后的位置不保存),中间层瞬间断裂
这是我的代码:
import * as THREE from 'three'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas.webgl")});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry(1, 1, 1);
const materials = [
new THREE.MeshBasicMaterial({color: 'white'}),
new THREE.MeshBasicMaterial({color: 'yellow'}),
new THREE.MeshBasicMaterial({color: 'red'}),
new THREE.MeshBasicMaterial({color: 'darkorange'}),
new THREE.MeshBasicMaterial({color: 'blue'}),
new THREE.MeshBasicMaterial({color: 'green'}),
];
for(let i = 0; i < geometry.groups.length; i++)
geometry.groups[i].materialIndex = i;
const cube = [];
for(let y = -1; y <= 1; y++){
for(let x = -1; x <= 1; x++){
for(let z = -1; z <= 1; z++){
const mesh = new THREE.Mesh(geometry, materials);
mesh.position.x = x;
mesh.position.y = y;
mesh.position.z = z;
cube.push(mesh);
scene.add(mesh);
}
}
}
const controls = new TrackballControls( camera, renderer.domElement );
controls.noPan = true;
controls.noZoom = true;
controls.rotateSpeed = 3;
camera.position.z = 7.5;
controls.update();
const face = new THREE.Group();
// get the bottom layer
for(let i = 0; i < 9; i++){
scene.remove(cube[i]);
face.add(cube[i]);
}
scene.add(face);
let moveCount = 0;
function animate() {
requestAnimationFrame( animate );
controls.update();
if(moveCount < 1){
if(face.rotation.y < THREE.MathUtils.degToRad(90)){
face.rotation.y += THREE.MathUtils.degToRad(2);
}
else{
changeFace();
moveCount++;
}
}
renderer.render( scene, camera );
}
function changeFace() {
scene.add(...face.children);
face.remove(...face.children);
for(let i = 9; i < 18; i++){
scene.remove(cube[i]);
face.add(cube[i]);
}
};
animate();
一张gif来说明:
当您旋转网格的 parent 时,网格的旋转不会改变。只有 parent 的旋转变化。因此,当您从 parent 中取出网格时,您将删除它继承的任何变换。
您可以使用 object.getWorldQuaternion()
将 world-space 旋转存储到四元数中,然后将它们应用于 child 网格:
let tempQuaternion = new THREE.Quaternion();
for(let i = 9; i < 18; i++){
// Read world rotations before removal
cube[i].getWorldQuaternion(tempQuaternion);
// Take the cube out of the group, place directly onto scene
scene.add(cube[i]);
// Now we re-apply the world rotations to the cube
cube[i].quaternion.copy(tempQuaternion);
}
请记住,一个网格一次只能有一个 parent。所以添加到组时,不需要将其从场景中移除,vice-versa.
// This line adds all children to scene,
// and automatically removes each one from face when doing so
scene.add(...face.children);
// This line doesn't do anything because all children have already been removed
face.remove(...face.children);