matrix3d local to global coordinates for rotation problem

Hello.

I made a cube with as3. I wanted it to rotate in the Y Axis according to the horizontal mouse movement. It works nice when this is all I want. But if I try to also make it rotate on the X axis with the vertical mouse movement, things get screwy.

This happens because the transformations are added in the global coordinates, not the local ones.

So, for Example, if I wanted the cube to rotate 30 degrees along its Y axis, I have to find a way to translate that into the global coordinates, and then apply that to the matrix3D of each face. I need a local to global translator.

I’ve been reading the manual for decompose(), recompose(), Vector3D, and matrix3D, but I haven’t the slightest idea of how to get what I want. Please help me.

I’m adding an image that may help explain my problem.

http://img707.imageshack.us/img707/6783/cubeyaxis.jpg

This is my current code. I’m sure it’s messy, but nevermind that.


/*
the origin vars define the center of the cube, which in this 
case is the center of the stage. The Odis variable is the distance
from the center of the cube to the center of each of the 6 faces.
*/
var originX=300;
var originY=200;
var originZ=0;
var Odis=100;

var MouseDown=false;
var mouseCenterX=0;
var mouseCenterY=0;
var xmouse=0;
var ymouse=0;


/*
There are 6 faces/MovieClips, width and height 
are 200. Their identifiers:
s1
s2
s3
s4
s5 =top
s6 =bottom
*/

/*now it's time to put each face in it's corresponding 3d place.
Note: at starting position, s4 is the face in front of the viewer. 
s1 is the one to the right, then s2 at the back, and s3 to the left
of s4. s5 in the top and s6 is the bottom, or was it s6 at top?
doesn't matter...*/

var OdisPerFace:Array=[["O",,],[,,"O"],["-O",,],[,,"-O"],[,"-O",],[,"O",]];

for (var i=1; i<=6; i++) {
	for (var j=0; j<3; j++) {
		var Symbol:String;
		if (j==0) {
			Symbol="x";
		} else if (j==1) {
			Symbol="y";
		} else if (j==2) {
			Symbol="z";
		}
		root["s"+i].x=originX;
		root["s"+i].y=originY;
		root["s"+i].z=originZ;
		if (OdisPerFace[i-1][j]=="O") {
			root["s"+i][Symbol]+=Odis;
			break;
		} else if (OdisPerFace[i-1][j]=="-O") {
			root["s"+i][Symbol]-=Odis;
			break;
		}
	}
}

/* What you just saw up there is the same as saying:

s1.x=originX+Odis;
s1.y=originY;
s1.z=originZ;

s2.x=originX;
s2.y=originY;
s2.z=originZ+Odis;

s3.x=originX-Odis;
s3.y=originY;
s3.z=originZ;

s4.x=originX;
s4.y=originY;
s4.z=originZ-Odis;

s5.x=originX;
s5.y=originY-Odis;
s5.z=originZ;

s6.x=originX;
s6.y=originY+Odis;
s6.z=originZ;
*/

/*Each face is an instance of the same movieclip.
Here we set each face to a corresponding frame,
so that each looks unique*/

for (var f=0; f<6; f++) {
	var g=f+1;
	root["s"+g].gotoAndStop(f+2);
	//root[f+1].stop()
}


//now we create each 3d matrix object, or something like that
var m1:Matrix3D=s1.transform.matrix3D;
var m2:Matrix3D=s2.transform.matrix3D;
var m3:Matrix3D=s3.transform.matrix3D;
var m4:Matrix3D=s4.transform.matrix3D;
var m5:Matrix3D=s5.transform.matrix3D;
var m6:Matrix3D=s6.transform.matrix3D;



/*
this is the function for rotating a face along an axis.



-------------THIS IS THE START OF EVERYTHING THAT IS WRONG-------------


*/
function rot(Matrixx,X,Y,Z,R,A) {
	if (A=="X") {
		A=Vector3D.X_AXIS;
	} else if (A=="Y") {
		A=Vector3D.Y_AXIS;
	} else if (A=="Z") {
		A=Vector3D.Z_AXIS;
	}
	Matrixx.appendTranslation(-X,-Y,-Z);
	Matrixx.appendRotation(R, A);
	Matrixx.appendTranslation(X,Y,Z);
}



//we use the rotation function to set each face to their starting rotations.
rot(m1,originX+Odis,originY,originZ,-90,"Y");
rot(m2,originX,originY,originZ+Odis,180,"Y");
rot(m3,originX-Odis,originY,originZ,90,"Y");
//m5 needs no rotation, it's default one is the right one
rot(m5,originX,originY-Odis,originZ,-90,"X");
rot(m6,originX,originY+Odis,originZ,90,"X");


function ClickDown(event:MouseEvent):void {
	MouseDown=true;
	mouseCenterX=mouseX;
	mouseCenterY=mouseY;
}
function ClickUp(event:MouseEvent):void {
	MouseDown=false;
	mouseCenterX=0;
	mouseCenterY=0;
}
function movingMouse(event:MouseEvent):void {
	var lokx=mouseCenterX;
	var loky=mouseCenterY;
	if (MouseDown==true) {
		mouseCenterX=mouseX;
		mouseCenterY=mouseY;

		xmouse=(mouseCenterX-lokx);
		ymouse=(mouseCenterY-loky);
		
               /*And things here have to change.
               also keep note that I want the Y rotation to be according to the local Y axis,
               but the X rotation I want it according to the GLOBAL X axis.
               it's only the Y axis rotation that I want local*/

		rot(m1,originX,originY,originZ,-xmouse,"Y");
		rot(m2,originX,originY,originZ,-xmouse,"Y");
		rot(m3,originX,originY,originZ,-xmouse,"Y");
		rot(m4,originX,originY,originZ,-xmouse,"Y");
		rot(m5,originX,originY,originZ,-xmouse,"Y");
		rot(m6,originX,originY,originZ,-xmouse,"Y");


		rot(m1,originX,originY,originZ,ymouse,"X");
		rot(m2,originX,originY,originZ,ymouse,"X");
		rot(m3,originX,originY,originZ,ymouse,"X");
		rot(m4,originX,originY,originZ,ymouse,"X");
		rot(m5,originX,originY,originZ,ymouse,"X");
		rot(m6,originX,originY,originZ,ymouse,"X");
	}
}


root.stage.addEventListener(MouseEvent.MOUSE_MOVE, movingMouse);
root.stage.addEventListener(MouseEvent.MOUSE_DOWN, ClickDown);
root.stage.addEventListener(MouseEvent.MOUSE_UP, ClickUp);