three.js - 轮换后的轮换不符合我的预期

标签 three.js

我有一个类似魔方的拼图,我正在尝试使用 Three.js 在 webgl 中建模:

enter image description here

每个双色中心都可以旋转。当他们旋转时,他们会带动周围的所有棋子一起旋转。例如,如果我们旋转橙蓝色中心,会发生以下情况:

rotating around Orange-Blue Center

当你完成一个轮换后,一切都排成一行:

enter image description here

但是,现在当我尝试旋转橙白中心时,第一次旋转后从橙蓝中心继承的两 block 出现奇怪的行为:

enter image description here

我希望它们像其他部分一样旋转,但它们的旋转方式不同。

我正在使用 Three.js 的 Object3D.rotateOnAxis() 函数进行旋转:

function rotate ( center, distance ) {
    var axis = center.axis;
    center.model.rotateOnAxis ( axis, distance );
    for ( var i in center.stickers ) {
        center.stickers[i].rotateOnAxis ( axis, distance  );
    }

    for ( var i in center.children ) {
        center.children[i].model.rotateOnAxis ( axis, distance );

        //Note: the stickers are just the colored faces
        for ( var s in center.children[i].stickers ) {
            center.children[i].stickers[s].rotateOnAxis ( axis, distance );
        }
    }
}

这是我的按键代码:

function showCube() {
    //set stuff up, then...

    count = 0;
    parent.onkeypress = function(event) { 
        if ( count < 6 ) {
            rotate( blocks.centers [ "BO" ],  Math.PI / 6 );

            count++;

            if ( count == 6 ) {
                moveFace ( blocks, "O1", "OY", "BW" );
                moveFace ( blocks, "O2", "OW", "BY" );

                moveFace ( blocks, "B1", "BW", "OY" );
                moveFace ( blocks, "B2", "BY", "OW" );

                moveCorner ( blocks, "BOW", "OW", "OY" );
                moveCorner ( blocks, "BOW", "BW", "BY" );

                moveCorner ( blocks, "BOY", "OY", "OW" );
                moveCorner ( blocks, "BOY", "BY", "BW" );
            }

        } else { 
            rotate( blocks.centers [ "OW" ],  Math.PI / 6 );
        }
    }
}

function moveFace ( blocks, child, oldParent, newParent ) {
    var index = blocks.centers [ oldParent ].children.indexOf ( blocks.faces [ child ] );
    blocks.centers [ oldParent ].children.splice ( index, 1 );
    blocks.centers [ newParent ].children.push ( blocks.faces [ child ] );
}

function moveCorner ( blocks, child, oldParent, newParent ) {
    var index = blocks.centers [ oldParent ].children.indexOf ( blocks.corners [ child ] );
    blocks.centers [ oldParent ].children.splice ( index, 1 );
    blocks.centers [ newParent ].children.push ( blocks.corners [ child ] );
}

有趣的是,为了让蓝-橙-黄角正确旋转,我需要围绕 BO 向量和 OW 向量之间的差异进行旋转。

也就是说:

  • 蓝橙轴是 (0, 1, 1) 的归一化向量
  • 橙白轴是 (1, 0, 1) 的归一化向量
  • 第一次旋转完成后,如果我尝试旋转 BOY 围绕 (1, 0, 1) 的法线转角,我得到如下所示的行为 图片。
  • 但是,如果我尝试围绕 (0, 1, 1) - (1, 0, 1),即 (-1, 1, 0),我得到了想要的行为。

我不明白发生了什么。你能帮我更新我的旋转功能,这样我就可以得到我想要的行为,而不必保留一长串过去某个片段经历过的旋转吗?

我怀疑在我完成第一次旋转后,我需要告诉该部件在不引起任何运动的情况下将其旋转状态“归零”,但我不太确定该怎么做,或者这是否是正确的方法。

你可以在这里玩这个东西:http://joshuad.net/clover-cube/so-question/

谢谢!

最佳答案

我通过将我的旋转方法更改为此来修复它:

function rotate ( center, distance ) {
    var axis = center.axis;
    center.model.rotateOnAxis ( axis, distance );
    applyStatesToMatrixDirectly ( center.model );

    for ( var stickerIndex in center.stickers ) {
        center.stickers[stickerIndex].rotateOnAxis ( axis, distance  );
        applyStatesToMatrixDirectly ( center.stickers[stickerIndex] );
    }

    for ( var childIndex in center.children ) {
        center.children[childIndex].model.rotateOnAxis ( axis, distance );
        applyStatesToMatrixDirectly ( center.children[childIndex].model );

        for ( var childStickerIndex in center.children[childIndex].stickers ) {
            center.children[childIndex].stickers[childStickerIndex].rotateOnAxis ( axis, distance );
            applyStatesToMatrixDirectly ( center.children[childIndex].stickers[childStickerIndex] );
        }
    }
}

function applyStatesToMatrixDirectly ( model ) {
    model.updateMatrix();
    model.geometry.applyMatrix( model.matrix );
    model.position.set( 0, 0, 0 );
    model.rotation.set( 0, 0, 0 );
    model.scale.set( 1, 1, 1 )
    model.updateMatrix();
}

想法是函数 applyStatesToMatrixDirectly() 将旋转直接应用于模型矩阵,然后重置所有旋转数据(以及其他所有数据)。这允许模型“忘记”它已被旋转,从而允许新的 rotateOnAxis 工作。

关于three.js - 轮换后的轮换不符合我的预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35676643/

相关文章:

mobile - 移动设备上是否支持 Canvas 和 WebGL(three.js)?

javascript - Threejs ray cast 获取交点坐标

javascript - 如何反射(reflect)物体本身?

javascript - three.js 问题 : application suddenly wont work on Chrome - old code, 无法与新的 three.js 库一起使用

rotation - 无法读取未定义的 : Three. js 错误的属性 'rotation'

javascript - 三款js黑色 Material 转透明

three.js,服装和形状键

javascript - PointLight 不会照亮任何东西

three.js - 如果数据纹理不是正方形,则会出现奇怪的行为(1 :1)

javascript - Three.js canvas.toDataURL() 在 Chromium 中损坏了吗?