8
votes

I am trying to rotate a Sprite in three dimensions around its centerpoint, and I am struggling to understand some of the behavior of matrix3D.

Ive overridden the set rotationX, rotationY, and rotationZ methods of the Sprite as follows:

override public function set rotationX (_rotationX:Number) : void {  

    this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
    this.transform.matrix3D.prependRotation(-this.rotationX, Vector3D.X_AXIS);
    this.transform.matrix3D.prependRotation(_rotationX, Vector3D.X_AXIS);
    this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);

}

override public function set rotationY (_rotationY:Number) : void {

    this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
    this.transform.matrix3D.prependRotation(-this.rotationY, Vector3D.Y_AXIS);   
    this.transform.matrix3D.prependRotation(_rotationY, Vector3D.Y_AXIS);
    this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);   

}

override public function set rotationZ (_rotationZ:Number) : void {

    this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
    this.transform.matrix3D.prependRotation(-this.rotationZ, Vector3D.Z_AXIS);   
    this.transform.matrix3D.prependRotation(_rotationZ, Vector3D.Z_AXIS);
    this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);   

} 

I am using prependTranslation to correct the centerpoint of the rotation, and the first prependRotation to cancel out any previously-applied rotation.

Testing it out, rotationX works exactly as expected, and the Sprite rotates around its horizontal axis.

rotationY and rotationZ also appear to work fine. However, there is one problem: whenever rotationY or rotationZ are set, all of the other rotation values change as well. This is not a problem with rotationX -- if I set rotationX, nothing else changes. But if I set rotationY or rotationZ all the rotation values change, which is a problem for my app (which is trying to save and restore values).

I think I am just lacking some understanding about what is going on with matrix3D. How can I implement this so there is no interdependence between the values?

3
best thing is to check out UIComponent#transformAround and the related AdvancedLayout.as implementation. They do exactly that, wrapping Matrix3D.Lance Pollard
Not looking through your code, but are you experiencing Gimbal Lock? en.wikipedia.org/wiki/Gimbal_lockMerlyn Morgan-Graham

3 Answers

3
votes

Another easy solution is to add the object and center it within a container sprite and do the 3D transformations on the containing sprite.

1
votes

I know nothing about AS3 etc. But just looking at your code, I wonder why you translate on the z-axis using what I understand to be x and y values (width and height). Shouldn't the z-axis be translated using something like "depth"?

0
votes

This is very simple, you can try use the following code:

var matrix3d:Matrix3D = s.transform.matrix3D;
matrix3d.appendRotation( -1, Vector3D.Z_AXIS , new Vector3D( 390, 360, 0 ) );

while s is your sprite, the third parameter, Vector3D indicate your sprite's center position.

The Above code will make the sprite s rotate more -1 degree.