three.js:结合 tween.js 围绕世界轴旋转对象

Posted

技术标签:

【中文标题】three.js:结合 tween.js 围绕世界轴旋转对象【英文标题】:three.js: rotate object around world axis combined with tween.js 【发布时间】:2016-02-29 11:08:53 【问题描述】:

我目前正在尝试在 3D 中对立方体进行补间旋转,并且感谢这篇文章 (How to rotate a object on axis world three.js?) 没有补间的旋转没有任何问题。所以目前我正在尝试将 setFromRotationMatrix 完成的旋转转移到我可以用作补间的结束旋转的东西。

编辑:

这是我目前拥有的:

// function for rotation dice
function moveCube() 

    // reset parent object rotation
    pivot.rotation.set( 0, 0, 0 );
    pivot.updateMatrixWorld();
    // attach dice to pivot object
    THREE.SceneUtils.attach( dice, scene, pivot );

    // set variables for rotation direction
    var rotateZ = -1;
    var rotateX = -1;
    if (targetRotationX < 0) 
        rotateZ = 1;
     else if (targetRotationY < 0) 
        rotateX = 1;
    

    // check what drag direction was higher
    if (Math.abs(targetRotationX) > Math.abs(targetRotationY)) 
            // rotation
            var newPosRotate = z: rotateZ * (Math.PI / 2);
            new TWEEN.Tween(pivot.rotation)
                .to(newPosRotate, 2000)
                .easing(TWEEN.Easing.Sinusoidal.InOut)
                .start();
            //rotateAroundWorldAxis(dice, new THREE.Vector3(0, 0, rotateZ), Math.PI / 2);
     else 
            // rotation
            var newPosRotate = x: -rotateX * (Math.PI / 2);
            new TWEEN.Tween(pivot.rotation)
                .to(newPosRotate, 2000)
                .easing(TWEEN.Easing.Sinusoidal.InOut)
                .start();
            //rotateAroundWorldAxis(dice, new THREE.Vector3(-rotateX, 0, 0), Math.PI / 2);
    

    // detach dice from parent object
    THREE.SceneUtils.detach( dice, pivot, scene );

多亏了 WestLangley,我想我终于接近了一个易于实现且符合我的目的的解决方案。初始化枢轴对象时,我将其设置为与骰子完全相同的位置,因此旋转仍将围绕骰子的中心。

var loader = new THREE.JSONLoader();
loader.load(
    'models/dice.json',
    function ( geometry, materials ) 
        material = new THREE.MeshFaceMaterial( materials );
        dice = new THREE.Mesh( geometry, material );
        dice.scale.set(1.95, 1.95, 1.95);
        dice.position.set(2.88, 0.98, 0.96);
        scene.add( dice );

        pivot = new THREE.Object3D();
        pivot.rotation.set( 0, 0, 0 );
        pivot.position.set(dice.position.x, dice.position.y, dice.position.z);
        scene.add( pivot );
    
);

我有 atm(上 sn-p)的解决方案没有将骰子作为父对象附加到枢轴对象。我可能忽略了一些非常基本的东西......

编辑结束

【问题讨论】:

你在旋转什么轴?是任意的吗? 我定义相对于世界轴的旋转是任意的。这就是我调用上面发布的函数的方式:rotateAroundWorldAxis(dice, new THREE.Vector3(0, 0, rotateZ), Math.PI / 2);而 rotateZ 可以是 1 或 -1。 (1) 所以你想要做的就是围绕世界z轴在正方向或负方向上旋转对象?始终是 z 轴吗? (2) 物体的局部 z 轴是否总是与世界 z 轴相同? (3) Object.rotateZ( radians ) 不适合你? 不幸的是,它并不总是我想要旋转的 z 轴,而是原始的 x 轴(总是世界 x 轴),并且通过调用来相应地完成:rotateAroundWorldAxis(dice, new THREE .Vector3(-rotateX, 0, 0), Math.PI / 2);而 rotateX 也可以是 1 或 -1。 您需要让问题变得更简单。试试这个:当你想要补间时,将对象添加到父 Object3D 并补间父级的 rotation.x/y/或 z。然后从父对象中移除对象并将父对象的旋转设置回零。为下一个补间重用父级。见***.com/questions/20089098/… 【参考方案1】:

因为我认为这是一件非常简单的事情,我必须让它发挥作用:

我只需要将子对象(骰子)的分离移动到函数的开头,而不是将它放在函数的末尾,它就可以发挥魅力。

这是工作代码:

// function for rotating dice
function moveCube() 
    // detach dice from parent object first or attaching child object won't work as expected
    THREE.SceneUtils.detach( dice, pivot, scene );
    // reset parent object rotation
    pivot.rotation.set( 0, 0, 0 );
    pivot.updateMatrixWorld();
    // attach dice to pivot object
    THREE.SceneUtils.attach( dice, scene, pivot );

    // set variables for rotation direction
    var rotateZ = -1;
    var rotateX = -1;
    if (targetRotationX < 0) 
        rotateZ = 1;
     else if (targetRotationY < 0) 
        rotateX = 1;
    

    // check what drag direction was higher
    if (Math.abs(targetRotationX) > Math.abs(targetRotationY)) 
            // rotation
            var newPosRotate = z: rotateZ * (Math.PI / 2);
            new TWEEN.Tween(pivot.rotation)
                .to(newPosRotate, 2000)
                .easing(TWEEN.Easing.Sinusoidal.InOut)
                .start();
     else 
            // rotation
            var newPosRotate = x: -rotateX * (Math.PI / 2);
            new TWEEN.Tween(pivot.rotation)
                .to(newPosRotate, 2000)
                .easing(TWEEN.Easing.Sinusoidal.InOut)
                .start();
    

非常感谢您的帮助!

【讨论】:

以上是关于three.js:结合 tween.js 围绕世界轴旋转对象的主要内容,如果未能解决你的问题,请参考以下文章

WEBGL实现--three.js笔记整理

three.js 在它的中心围绕 Y 轴旋转 Object3d

Three.js - 围绕某个轴旋转球体

three.js 围绕 Y 轴的相机旋转似乎关闭

three.js围绕边缘旋转三角形

使用鼠标围绕中心旋转 Three.js 相机