Three.js:使用 THREE.SceneUtils.attach/detach 函数添加和删除子对象的正确方法 [英] Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functions
问题描述
使用three.js,并改编此处提供的West Langley帖子中的说明:Three.js:添加和删除旋转对象的子对象,我设置了一个 WebGL 场景,其中添加了五个立方体网格.最初,所有对象都是场景的子对象,然后,我将它们附加到第五个parentCube"立方体并沿 Y 轴平移 100 个单位,从而平移其他四个立方体,然后将它们分离.
Using three.js, and adapting instructions from West Langley's post provided here: Three.js: Adding and Removing Children of Rotated Objects, I set up a WebGL scene to which five cube meshes are added. Initially, all objects are children of the scene, then, I attach them to the fifth "parentCube" cube and translate it 100 units along the Y-Axis thereby translating the other four cubes and subsequently detach them.
在那之后,我想独立地将parentCube"立方体(以前是四个立方体的父)转换回原点,但是,当我执行该转换时,其他四个立方体网格也与以前的父立方体一起转换网格,即使我将它们分开.
After that, I want to independently translate the "parentCube" cube (previously the parent of the four cubes) back to the origin, however, when I perform that translation, the other four cube meshes also translate with the former parent cube mesh, even when I detached them.
这可能是一个非常基本的问题,但是考虑到上述所有细节,我如何在不影响其他立方体位置的情况下独立翻译parentCube"?支队哪里出了问题?任何帮助,将不胜感激.谢谢:)
This may be a very basic question, but how can I independently translate "parentCube" without affecting the position of the other cubes considering all of the above details? Where am I going wrong with the detachment? Any help would be appreciated. Thank you :)
这是我用来执行上述所有操作的代码示例:
Here's the code sample which I use to perform all of the above:
//Create parentCube mesh
var parentCube = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 10, 10, 10), new THREE.MeshBasicMaterial({ color: 0xa1ff11, wireframe: true }));
scene.add(parentCube);
//...create materials for the child cubes....
//create child cube mesh
for(var i = 0; i < 4; i++)
cubeMesh[i] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 30, 30, 30), materials[i]);
//--> Set child cube world positions before the attachment to parentCube mesh
cubeMesh[0].position.set((100 / 2),(100 / 2),(100 / 2));
cubeMesh[1].position.set(-(100 / 2),(100 / 2),(100 / 2));
cubeMesh[2].position.set(-(100 / 2),-(100 / 2),(100 / 2));
cubeMesh[3].position.set((100 / 2),-(100 / 2),(100 / 2));
//Add child cubes to the scene
for(var i = 0; i < cubeMesh.length; i++)
scene.add(cubeMesh[i]);
//attach child cubeMesh[i] to parentCube mesh
for(var i = 0; i < 4; i++)
THREE.SceneUtils.attach(cubeMesh[i], scene, parentCube);
//--> Set positions of child elements after attachment to parentCube
cubeMesh[0].position.set((100 / 2),(100 / 2),(100 / 2));
cubeMesh[1].position.set(-(100 / 2),(100 / 2),(100 / 2));
cubeMesh[2].position.set(-(100 / 2),(100 / 2),-(100 / 2));
cubeMesh[3].position.set((100 / 2),(100 / 2),-(100 / 2));
//translate parentCube
parentCube.position.set(0,150,0);
parentCube.updateMatrixWorld();
//Attempt to detach child objects from parentCube
//And make them children of the scene
for(var i = 0; i < 4; i++)
{
cubeMesh[i].updateMatrixWorld();
THREE.SceneUtils.detach(cubeMesh[i], parentCube, scene);
}
//Attempt to translate parentCube back to origin
parentCube.position.set(0,0,0);
}
推荐答案
你的代码行
THREE.SceneUtils.detach(cubeMesh[i], scene, parentCube);
应该是
THREE.SceneUtils.detach(cubeMesh[i], parentCube, scene);
我已经用你的例子做了一个演示,我认为应该是正确的方法.
I have done a demo with your example, and what I believe should be te correct approach.
HTML
<body>
<button onclick="attachChild();">attach</button>
<button onclick="detachChild();">dettach</button>
</body>
JavaScript
var camera, scene, renderer;
var geometry, material1, material2;
var parentCube;
var cubeMesh = [];
var cameraControls;
var attached = true;
window.onload = function() {
init();
animate();
}
function init() {
camera = new THREE.PerspectiveCamera(75, 2, 1, 10000);
camera.position.z = 400;
camera.position.y = 100;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry(200, 200, 200);
material1 = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
//Create parentCube mesh
parentCube = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material1);
scene.add(parentCube);
//...create materials for the child cubes....
material2 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
//create child cube mesh
cubeMesh[0] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
cubeMesh[1] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
cubeMesh[2] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
cubeMesh[3] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
//--> Set child cube world positions before the attachment to parentCube mesh
cubeMesh[0].position.set(100,100,0);
cubeMesh[1].position.set(-100,100,0);
cubeMesh[2].position.set(-100,-100,0);
cubeMesh[3].position.set(100,-100,0);
//Add child cubes to the scene
for (var i = 0; i < 4; i++)
parentCube.add(cubeMesh[i]);
//translate parentCube
parentCube.position.set(0,50,0);
renderer = new THREE.CanvasRenderer();
renderer.setSize(600, 300);
document.body.appendChild(renderer.domElement);
// CONTROLS
cameraControls = new THREE.OrbitControls(camera);
cameraControls.addEventListener( 'change', render );
}
function animate() {
cameraControls.update();
requestAnimationFrame(animate);
parentCube.rotation.z += 0.01;
render ();
}
function render () {
renderer.render(scene, camera);
}
function attachChild () {
if (attached) {
alert ("already attached");
} else {
for (var i = 0; i < 4; i++)
THREE.SceneUtils.attach(cubeMesh[i], scene, parentCube);
attached = true;
}
}
function detachChild () {
if ( ! attached) {
alert ("not attached");
} else {
for (var i = 0; i < 4; i++)
THREE.SceneUtils.detach(cubeMesh[i], parentCube, scene);
attached = false;
}
}
特别注意,我将子项直接添加到父项(而不是场景),并且我认为它们从一开始就附加.之后,分离和重新附加它们按预期工作
Notice specially that I add the children directly to the parent (not the scene), and that I consider them attached from the beginning. After that, detaching and reattaching them works as expected
如何将其用于魔方模拟?
How could this be used for a Rubik's cube simulation ?
我只会创建添加到场景中的所有立方体.
I would just create all the cubes added to the scene.
然后,要执行移动,您必须
Then, to perform a move, you have to
- 识别枢轴立方体(位于面中心的立方体)
- 识别周围的立方体
- 将它们附加到枢轴
- 旋转轴
- 分离立方体
这篇关于Three.js:使用 THREE.SceneUtils.attach/detach 函数添加和删除子对象的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!