Warm tip: This article is reproduced from serverfault.com, please click

3d-Three.js:使用THREE.SceneUtils.attach / detach函数添加和删除子对象的正确方法

(3d - Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functions)

发布于 2014-04-30 10:24:49

使用three.js,并改编了此处提供的West Langley文章中的说明: Three.js:添加和删除旋转对象的子代,我设置了一个WebGL场景,在该场景中添加了五个立方体网格。最初,所有对象都是场景的子级,然后,将它们附加到第五个“ parentCube”多维数据集,并沿Y轴平移100个单位,从而平移其他四个多维数据集,然后分离它们。

之后,我想独立地将“ parentCube”多维数据集(以前是四个多维数据集的父级)转换回原点,但是,当我执行该转换时,其他四个多维数据集网格也将与前一个父级多维数据集网格一起转换,甚至当我拆下它们时。

这可能是一个非常基本的问题,但是考虑到以上所有详细信息,如何在不影响其他多维数据集的位置的情况下独立转换“ parentCube”呢?我的支队哪里出问题了?任何帮助,将不胜感激。谢谢 :)

这是我用来执行上述所有操作的代码示例:

        //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);
    }
Questioner
The_Obfuscator
Viewed
0
vals 2014-05-04 16:57:37

你的代码行

   THREE.SceneUtils.detach(cubeMesh[i], scene, parentCube);

应该

   THREE.SceneUtils.detach(cubeMesh[i], parentCube, scene);

我已经用你的示例进行了演示,我认为应该是正确的方法。

的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;
    }
}

特别注意,我将孩子直接添加到父对象(而不是场景),并且我认为它们从一开始就是附加的。之后,分离并重新连接它们可以按预期工作

如何将其用于Rubik的立方体模拟?

我只是创建添加到场景中的所有多维数据集。

然后,要执行移动,你必须

  1. 识别枢轴立方体(位于面中心的那个)
  2. 识别周围的立方体
  3. 将那些附加到枢轴上
  4. 旋转枢轴
  5. 拆下立方体