三.js:子对象的奇怪旋转 [英] three.js: Weird Rotation of child objects

查看:63
本文介绍了三.js:子对象的奇怪旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现 2x2x2 魔方的实验版本.我采用了前两篇关于子对象附加和分离问题的说明:Three.js:使用 THREE.SceneUtils.attach/detach 函数添加和删除子对象的正确方法Three.js:添加和删除旋转对象的子对象并有能够成功理解如何独立旋转两张脸.

I'm trying to implement an experimental version of a 2x2x2 Rubiks Cube. I have adopted instructions from two previous posts with issues regarding child objects attachment and detachment: Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functions and Three.js: Adding and Removing Children of Rotated Objects and have been able to successfully understand how to rotate two faces independently.

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

However, when I implement the same in code, I get weird results when the rotations are applied in succession, which suggests that some transforms are getting wrong somewhere, though I can't seem to understand where. But then again, every matrix related to the parent object is reset after the rotation ends, so I don't really understand why it should happen. The rotations work appropriately when applied independently, though, which confirms that I did about 50% things right :). The sample can viewed here: sample 2x2x2 cube.

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

Here are the relevant code samples: --> For the event handler for rotating the right face

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

Upper face 的事件处理函数和增量动画函数都是一样的,在同一个地方.pos(cubies[i]) 函数返回网格对象的世界坐标.面部旋转哪里出了问题?任何帮助将不胜感激.谢谢.

The event handler and incremental animation functions for the Upper face are the same and in the same place. The pos(cubies[i]) function returns the world coordinates of the mesh object. Where am I going wrong with the rotations of the faces? Any help would be highly appreciated. Thank you.

推荐答案

我认为最大的问题是活动数组从未被清空

I think that the biggest problem was that the active array never got emptied

此外,您正在进行大量矩阵更新,而实际上并不需要

Also, you are doing extensive matrix update, when there is none really needed

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

I have redone your javaScript, now it just attaches the cubes, does the rotation, and finally detaches the cubes and resets the rotation.

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

这篇关于三.js:子对象的奇怪旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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