1

I'm currently trying to tween-rotate a cube in 3D and thanks to this post (How to rotate a object on axis world three.js?) the rotation without tweening works without any problems. So currently I'm trying to transfer the rotation done by setFromRotationMatrix to something I can use as end rotation for my tween.

EDIT:

Here is what I have at the moment:

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

Thanks to WestLangley I think I'm finally close to a solution that is easy to do and will serve my purpose. When initializing the pivot object I set it to the exact same position as the dice, so the rotation will still be around the center of the dice.

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

The solution I have atm (upper snippet) does not attach the dice to the pivot object as parent. I'm probably overlooking something very basic ...

EDIT END

Community
  • 1
  • 1
niceWeather
  • 91
  • 1
  • 8
  • What axis are you rotating around? Is is arbitrary? – WestLangley Nov 30 '15 at 17:03
  • It is arbitrary in the sense that I define the rotation in relation to a world axis. This is how I call the function I posted above: rotateAroundWorldAxis(dice, new THREE.Vector3(0, 0, rotateZ), Math.PI / 2); whereas rotateZ can be either 1 or -1. – niceWeather Dec 01 '15 at 07:46
  • (1) So all you want to do is rotate the object around the world z-axis in either the positive or negative direction? Is is always the z-axis? (2) Is the object's local z-axis always the same as the world z-axis? (3) `Object.rotateZ( radians )` does not work for you? – WestLangley Dec 01 '15 at 16:14
  • unfortunately it's not always the z-axis I want to rotate around, but also the original x-axis (always world x-axis) and that is done accordingly by calling: rotateAroundWorldAxis(dice, new THREE.Vector3(-rotateX, 0, 0), Math.PI / 2); whereas rotateX can also either be 1 or -1. – niceWeather Dec 01 '15 at 16:58
  • You need to make the problem easier. Try this: when you want to tween, add the object to a parent Object3D and tween the parent's rotation.x/y/or z. Then remove the object from the parent and set the parent's rotation back to zero. Reuse the parent for the next tween. See http://stackoverflow.com/questions/20089098/three-js-adding-and-removing-children-of-rotated-objects/20097857#20097857 – WestLangley Dec 01 '15 at 17:31
  • With my current version it should work as far as I can see, but the _.add_ functionality doesn't really work although I (think I) use the _SceneUtils_ correctly. I inserted a log to check the array ( console.log(pivot.children, pivot.children.length); ) If I attach the dice and check the _children_ array of the pivot parent object after attaching, the array supposedly has the Mesh stored because length is at 1 as it should be. But then again it doesn't, because (in Chrome) the details shown of the whole array, depict that there is nothing stored there. ... it really confuses me. – niceWeather Dec 02 '15 at 14:29
  • `THREE.SceneUtils.detach()` needs to be inside an `.onComplete()` callback. You are detatching before the tween starts. – WestLangley Dec 02 '15 at 16:03
  • ...and as I said above, detach the object from the parent and set the parent's rotation back to zero. – WestLangley Dec 02 '15 at 16:24
  • Yep! It clearly was a simple error and I managed to solve it now. Thanks a lot! :) – niceWeather Dec 02 '15 at 16:40

1 Answers1

0

As I thought it was a really simple thing I had to do, to get it working:

I only needed to move the detachment of the child object (the dice) to the beginning of the function, instead of having it at the end of it and it works the charm.

Here's the working code:

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

Thanks a lot for helping!

niceWeather
  • 91
  • 1
  • 8