Three.js:正确的方式来添加和使用THREE.SceneUtils.attach /分离功能,删除子对象 [英] Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functions

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

问题描述

使用three.js,并适应从西兰利的职位说明此处提供: <一href="http://stackoverflow.com/questions/20089098/three-js-adding-and-removing-children-of-rotated-objects">Three.js:添加和删​​除儿童旋转的对象,我设立了五个立方体网添加到其中一个WebGL的场景。最初,所有的对象都是场景的孩子,那么,我将它们连接到第五届parentCube立方体,并把它翻译100个单位沿Y轴,从而转换其他四个立方体,随后分离它们。

在这之后,我想单独翻译parentCube立方体(previously四个立方体的母公司)又回到了原点,但是,当我执行的翻译,其他四个立方体网格也翻译与前母公司立方网,甚至当我脱离他们。

这可能是一个很基本的问题,但我怎么能独立翻译parentCube,不影响其他立方体考虑到上述所有细节的位置?我要去哪里错支队?任何帮助将是AP preciated。谢谢:)

下面是我用它来执行所有上述的code样品:<​​/ P>

  //创建parentCube网
        VAR parentCube =新THREE.Mesh(新THREE.CubeGeometry(100,100,100,10,10,10),新THREE.MeshBasicMaterial({颜色:0xa1ff11,线框:真}));
        scene.add(parentCube);

        //...create材料为孩子立方体....

        //创建子立方网
        为(变种I = 0; I&4;;我+ +)
            cubeMesh [I] =新THREE.Mesh(新THREE.CubeGeometry(100,100,100,30,30,30),材料[I]);

        //  - &GT;组子立方体世界的位置之前,附件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));

        //添加子立方体现场
        对于(VAR I = 0; I&LT; cubeMesh.length;我++)
            scene.add(cubeMesh [I]);

        //重视孩子cubeMesh [一] parentCube网
        为(变种I = 0; I&4;;我+ +)
            THREE.SceneUtils.attach(cubeMesh [I]中,场景,parentCube);

        //  - &GT;子元素的附件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));

        //翻译parentCube
        parentCube.position.set(0,150,0)​​;
        parentCube.updateMatrixWorld();

        //尝试拆离parentCube子对象
        //并让他们现场的孩子们
        为(变种I = 0; I&4;;我+ +)
        {
            cubeMesh [I] .updateMatrixWorld();
            THREE.SceneUtils.detach(cubeMesh [I],parentCube,场景);
        }

        //尝试翻译parentCube回原籍
        parentCube.position.set(0,0,0);
    }
 

解决方案

您的code线

  THREE.SceneUtils.detach(cubeMesh [我],场景,parentCube);
 

  THREE.SceneUtils.detach(cubeMesh [我],parentCube,场景);
 

我做了一个演示你的例子,我相信应该是TE正确的做法。

HTML

 &LT;身体GT;
    &LT;按钮的onclick =attachChild();&GT;附加&LT; /按钮&GT;
    &LT;按钮的onclick =detachChild();&GT; dettach&LT; /按钮&GT;
&LT; /身体GT;
 

JavaScript的

  VAR相机,场景,渲染器;
VAR几何,material1,料2;
VAR parentCube;
变种cubeMesh = [];
VAR cameraControls;
VAR附加= TRUE;

在window.onload =功能(){
    在里面();
    动画();
}

功能的init(){

    摄像头=新THREE.PerspectiveCamera(75,2,1,10000);
    camera.position.z = 400;
    camera.position.y = 100;

    现场=新THREE.Scene();

    几何=新THREE.BoxGeometry(200,200,200);
    material1 =新THREE.MeshBasicMaterial({颜色:为0xFF0000,线框:真});

    //创建parentCube网
    parentCube =新THREE.Mesh(新THREE.CubeGeometry(100,100,100,1,1,1),material1);
    scene.add(parentCube);

    //...create材料为孩子立方体....
    料2 =新THREE.MeshBasicMaterial({颜色:0x00ff00});
    //创建子立方网
    cubeMesh [0] =新THREE.Mesh(新THREE.CubeGeometry(100,100,100,1,1,1),料2);
    cubeMesh [1] =新THREE.Mesh(新THREE.CubeGeometry(100,100,100,1,1,1),料2);
    cubeMesh [2] =新THREE.Mesh(新THREE.CubeGeometry(100,100,100,1,1,1),料2);
    cubeMesh [3] =新THREE.Mesh(新THREE.CubeGeometry(100,100,100,1,1,1),料2);

        //  - &GT;组子立方体世界的位置之前,附件parentCube网
    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);

        //添加子立方体现场
    为(变种I = 0; I&4;;我+ +)
        parentCube.add(cubeMesh [I]);


   //翻译parentCube
   parentCube.position.set(0,50,0)​​;


  渲染器=新THREE.CanvasRenderer();
    renderer.setSize(600,300);

    document.body.appendChild(renderer.domElement);

        // CONTROLS
    cameraControls =新THREE.OrbitControls(摄像头);
    cameraControls.addEventListener('变',渲染);


}

功能动画(){
    cameraControls.update();
    requestAnimationFrame(动画);
    parentCube.rotation.z + = 0.01;
    渲染();
}

功能渲染(){
    renderer.render(场景,摄像头);

}

功能attachChild(){
    如果(附后){
        警报(已连接);
    } 其他 {
        为(变种I = 0; I&4;;我+ +)
            THREE.SceneUtils.attach(cubeMesh [I]中,场景,parentCube);
        附加= TRUE;
    }
}

传播detachChild(){
    如果(!附后){
        警报(未连接);
    } 其他 {
        为(变种I = 0; I&4;;我+ +)
            THREE.SceneUtils.detach(cubeMesh [I],parentCube,场景);
        附加= FALSE;
    }
}
 

特别注意,我直接添加了孩子们的家长(不是场景),并且我认为他们的从一开始就附着的。在此之后,分离和重新附加它们按预期工作

这怎么可能被用于魔方模拟?

我只想创造一切添加到场景中的立方体。

然后,执行一招,你必须

  1. 识别枢轴立方体(一个在该面的中心)
  2. 识别周围的立方体
  3. 附那些枢轴
  4. 旋转枢轴
  5. 分离立方体

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.

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.

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

解决方案

your line of code

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

should be

   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. identify the pivot cube (the one at the center of the face)
  2. identify the surrounding cubes
  3. attach those to the pivot
  4. rotate the pivot
  5. detach the cubes

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

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