Three.js:使用 THREE.SceneUtils.attach/detach 函数添加和删除子对象的正确方法 [英] Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functions

查看:40
本文介绍了Three.js:使用 THREE.SceneUtils.attach/detach 函数添加和删除子对象的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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

  1. 识别枢轴立方体(位于面中心的立方体)
  2. 识别周围的立方体
  3. 将它们附加到枢轴
  4. 旋转轴
  5. 分离立方体

这篇关于Three.js:使用 THREE.SceneUtils.attach/detach 函数添加和删除子对象的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆