Jump to content
Search Community

Tweening a rotation with quaternions

BladePoint test
Moderator Tag

Recommended Posts

I have a 3D object that is rotating randomly about it's x, y, and z axes. I want to be able to stop it in place, then tween its rotation it to a specified rotation taking the shortest possible route. It seems quaternions are the right tool for the job, but I'm not sure how to tween it properly. I'm trying to tween axis-angle rotations, then convert it to a quaternion. Here's my test code so far.

var startV3DV:Vector.<Vector3D> = new <Vector3D>[positionV3D, new Vector3D(0,1,0,0), scaleV3D];
var endV3DV:Vector.<Vector3D> = new <Vector3D>[positionV3D, new Vector3D(0,1,0,Math.PI), scaleV3D];
var recomposeV3DV:Vector.<Vector3D> = new <Vector3D>[positionV3D, new Vector3D(0,0,0,0), scaleV3D];

TweenMax.to(startV3DV[1], 2, {x:endV3DV[1].x, y:endV3D[1].y, z:endV3D[1].z, w:endV3D[1].w, onUpdate:quat});

var quatV3D:Vector3D = new Vector3D();
function quat():void {
    quatV3D.x = currentV3D[1].x * Math.sin(currentV3D[1].w * .5);
    quatV3D.y = currentV3D[1].y * Math.sin(currentV3D[1].w * .5);
    quatV3D.z = currentV3D[1].z * Math.sin(currentV3D[1].w * .5);
    quatV3D.w = Math.cos(currentV3D[1].w * .5);
    recomposeV3DV[1] = quatV3D;
    myMatrix3D.recompose(recomposeV3DV,"quaternion");
}

It actually tweens the rotation of the object about its y axis for a little while, but when it hits PI/2, it bugs out and I get "ArgumentError: Error #2004: One of the parameters is invalid" on the recompose line, which I think means one of the quatV3D properties doesn't fit the quaternion formula. Any ideas on how to do this properly?

Link to comment
Share on other sites

No, the QuaternionPlugin doesn't require any special Quaternion class - it just requires that the object have x, y, z, and w properties. Please make sure you're following the syntax defined in the API docs, like TweenLite.to(yourObject, 1, {quaternions:{yourProperty:{x:1, y:0, z:2, w:3}}});

 

If you're still having trouble, please post a very simple FLA that demonstrates the issue so that we can publish it on our end and see what's happening. Please keep it as simple and isolated as possible. Thanks!

Link to comment
Share on other sites

import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.display.Shape;

import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
TweenPlugin.activate([QuaternionsPlugin]);

var rectShape:Shape = new Shape();
rectShape.graphics.beginFill(0x000000);
rectShape.graphics.drawRect(0,0,100,200);
rectShape.graphics.endFill();
rectShape.x = 225; rectShape.y = 100; rectShape.z = 0;
addChild(rectShape);

var rectObj:Object = new Object();
var decompose:Vector.<Vector3D> = rectShape.transform.matrix3D.decompose("quaternion");
rectObj.quat = decompose[1];
trace("x:" + rectObj.quat.x + ",y:" + rectObj.quat.y + ",z:" + rectObj.quat.z + ",w:" + rectObj.quat.w);
//x:0,y:0,z:0,w:1
TweenLite.to(rectObj, 2, {quaternions:{quat:{x:1, y:0.5, z:0.25, w:0.5}}, onUpdate:recompose});

function recompose():void {
	decompose[1] = rectObj.quat;
	rectShape.transform.matrix3D.recompose(decompose,"quaternion");
}

*

I get this error a bunch of times:

*

ReferenceError: Error #1069: Property x not found on Number and there is no default value.
	at com.greensock.plugins::QuaternionsPlugin/_initQuaternion()
	at com.greensock.plugins::QuaternionsPlugin/_onInitTween()
	at com.greensock::TweenLite/_initProps()
	at com.greensock::TweenLite/_init()
	at com.greensock::TweenLite/render()
	at com.greensock.core::SimpleTimeline/render()
	at com.greensock.core::Animation$/_updateRoot()
Link to comment
Share on other sites

Ah yes, there was one variable that was cast to a Number() that shouldn't have been. I've attached an updated plugin. However, it looks like you'll still run into an argument error in Adobe's recompose() method which is something on their end (I'm not sure why they're refusing to allow new values on the quaternion). You can see this by removing GSAP completely from the equation, like:

import flash.geom.*;
import flash.display.Shape;

var rectShape:Shape = new Shape();
rectShape.graphics.beginFill(0x000000);
rectShape.graphics.drawRect(0,0,100,200);
rectShape.graphics.endFill();
rectShape.x = 225; rectShape.y = 100; rectShape.z = 0;
rectShape.rotation = 200;
addChild(rectShape);

var decompose:Vector.<Vector3D> = rectShape.transform.matrix3D.decompose(Orientation3D.QUATERNION);

decompose[1].x = 1;
decompose[1].y = 0.5;
decompose[1].z = 0.25;
decompose[1].w = 0.5;

rectShape.transform.matrix3D.recompose(decompose, Orientation3D.QUATERNION);
//THROWS ERROR!

It does, however, look like the revised plugin file tweens the quaternion values just fine. I wish I knew an easy answer for the Adobe class argument error thing. 

QuaternionsPlugin.as.zip

Link to comment
Share on other sites

Oh thanks! I'll give the new plugin a shot. Actually I know what's causing the recompose error. You can't just make up random numbers for x, y, z, and w for a quaternion. They must  follow this relationship:

 

x = v1 * sin (theta / 2)
y = v2 * sin (theta / 2)
z = v3 * sin (theta / 2)
w = cos(theta / 2)
 
Where v1, v2, and v3 make up the axis of rotation and theta is the rotation angle.
 
If they don't, you get the "ArgumentError: Error #2004: One of the parameters is invalid." message.
 
UPDATE: The plugin works with proper x, y, z, and w values. For example {x:0, y:1, z:0, w:0} rotates it 180 degrees about the y axis. Oh and the invalid values that I was using earlier are from the QuaternionPlugin docs page at https://www.greensock.com/as/docs/tween/com/greensock/plugins/QuaternionsPlugin.html. You probably want to change those.
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...