three.js:奇怪的子对象旋转

时间:2014-05-06 02:51:27

标签: javascript rotation three.js

我正在尝试实施2x2x2 Rubiks Cube的实验版本。我已经收到了之前两篇文章中关于子对象附件和分离的问题的说明:Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functionsThree.js: Adding and Removing Children of Rotated Objects,并且能够成功地了解如何独立旋转两个面。

然而,当我在代码中实现相同的时候,当连续应用旋转时,我得到奇怪的结果,这表明某些变换在某处出错,尽管我似乎无法理解在哪里。但话说回来,在旋转结束后,与父对象相关的每个矩阵都会重置,所以我真的不明白它为什么会发生。但是,当独立应用时,旋转工作正常,这证实我做了大约50%的事情正确:)。可以在此处查看示例:sample 2x2x2 cube.

以下是相关的代码示例: - >用于旋转右脸的事件处理程序

function rotateR()
{
    for(var i = 0; i < cubies.length; i++)
            if((pos(cubies[i]).x >= 53) && (pos(cubies[i]).x <= 55))
                active.push(cubies[i]);

        for(var i = 0; i < active.length; i++)
            console.log(active[i]);

        //reset pivot rotation
        pivot.rotation.set( 0, 0, 0 );
        pivot.updateMatrixWorld();

        //attach active[i] cubies to the pivot
        for (var i = 0; i < 4; i++)
            THREE.SceneUtils.attach(active[i], scene, pivot);   
        console.log("attached!");
        attachedR = true;
    }

在渲染功能中:

if((pivot.rotation.x <= 1.580000000000001) && (attachedR === true))
{
            pivot.rotation.x += 0.02;
            console.log(pivot.rotation.x);
            if(pivot.rotation.x == 1.580000000000001)
            {
                attachedR = false;
                for(var i = 0; i < active.length; i++)
                    console.log(pos(active[i]).x + ", " + pos(active[i]).y + ", " + pos(active[i]).z);

                //Detach active[i] cubies from the parent pivot
                pivot.updateMatrixWorld();
                for(var i = 0; i < active.length; i++)
                {
                    active[i].updateWorldMatrix();
                    THREE.SceneUtils.detach(active[i], pivot, scene);
                }
            }
        }

上面的事件处理程序和增量动画功能是相同的并且在同一个地方。 pos(cubies [i])函数返回网格对象的世界坐标。面部旋转我哪里错了? 任何帮助将受到高度赞赏。谢谢。

1 个答案:

答案 0 :(得分:1)

我认为最大的问题是主动阵列永远不会被清空

此外,当没有真正需要时,您正在进行大量的矩阵更新

我重做了你的javaScript,现在它只是附加立方体,进行旋转,最后分离立方体并重置旋转。

的JavaScript

        //Rotate Right face of cube
        function rotateR()
        {
            //Find cubies that lie in the right face of cube and store them in active[i]
            for(var i = 0; i < cubies.length; i++) {
                var x = pos(cubies[i]).x; 
                if(x >= 54 && x <= 56)
                    active.push(cubies[i]);
            }

            if (active.length != 4) alert ("active num wrong");
            //attach active[i] cubies to the pivot
            for (var i = 0; i < 4; i++)
                THREE.SceneUtils.attach(active[i], scene, pivot);   
            attachedR = true;
        }

//Rotate Upper face of the cube
function rotateU()
{
    //Find cubies that lie in the up face of cube and store them in active[i]
    for(var i = 0; i < cubies.length; i++) {
        var position = pos(cubies[i]); 
        if(position.y >= 54 && position.y <= 56) {
            active.push(cubies[i]);
        }
    }

    if (active.length != 4) alert ("active num wrong");

    //attach active[i] cubies to the pivot
    for (var i = 0; i < 4; i++)
        THREE.SceneUtils.attach(active[i], scene, pivot);
    attachedU = true;
}

function detachAndReset()
{
    for(var i = 0; i < active.length; i++)
    {
        THREE.SceneUtils.detach(active[i], pivot, scene);
    }
    active.length = 0;
    attachedR = false;
    attachedU = false;
    pivot.rotation.x = 0;
    pivot.rotation.y = 0;

}

        //get world position of cubies[i]
        function pos(object)
        {
            var position = new THREE.Vector3();
            position.setFromMatrixPosition( object.matrixWorld );
            return position;
        }

        function render()
        {
            var endAnimation = false;
            //Math.PI / 2 == 1.580000000000001
            //Rotate Right face of cube
            if(attachedR === true)
            {
                pivot.rotation.x += 0.02;
                if(pivot.rotation.x >= Math.PI / 2.0) {
                    pivot.rotation.x = Math.PI / 2.0;
                    endAnimation = true;
                }
            }

            //Math.PI / 2 == 1.580000000000001
            //Rotate Upper face of cube
            if(attachedU === true)
            {
                pivot.rotation.y += 0.02;
                if(pivot.rotation.y >= Math.PI / 2.0) {
                    pivot.rotation.y = Math.PI / 2.0;
                    endAnimation = true;
                }
            } 
            renderer.render(scene, camera);
            if (endAnimation) {
                detachAndReset();
            }
}