Non esiste una rotazione reale, si tratta sempre e comunque della simulazione della stessa tramite un effetto ottico..

Prova a creare un file con il flash mx, ed inserire nel primo frame il seguente codice. Quindi esporta il filmato, cliccaci sopra, e poi vai con i tasti freccia:

codice:
LightSource = function (x, y, z, brightness) {
	this.x = x;
	this.y = y;
	this.z = z;
	this.brightness = brightness;
	this.magnitude = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
};

this.createEmptyMovieClip("center", 0);

center._x = Stage.width / 2;
center._y = Stage.height / 2;
inc = .5;
focalLength = 400;
rad = Math.PI/180;

light = new LightSource(-20000, -20000, 20000, 100);

cube = {};

cube.vertexList = [];
cube.side = [];

cube.side.push({vertices:[0, 1, 2, 3], sideColor:0x6600CC});
cube.side.push({vertices:[2, 1, 5, 6], sideColor:0x6600CC});
cube.side.push({vertices:[1, 0, 4, 5], sideColor:0x6600CC});
cube.side.push({vertices:[5, 4, 7, 6], sideColor:0x6600CC});
cube.side.push({vertices:[0, 3, 7, 4], sideColor:0x6600CC});
cube.side.push({vertices:[3, 2, 6, 7], sideColor:0x6600CC});

cube.vertexList.push({x:-50, y:-50, z:50});
cube.vertexList.push({x:50, y:-50, z:50});
cube.vertexList.push({x:50, y:-50, z:-50});
cube.vertexList.push({x:-50, y:-50, z:-50});
cube.vertexList.push({x:-50, y:50, z:50});
cube.vertexList.push({x:50, y:50, z:50});
cube.vertexList.push({x:50, y:50, z:-50});
cube.vertexList.push({x:-50, y:50, z:-50});

vertices = [];

backface = function (x, y) {
	var cax = x[2] - x[0];
	var cay = y[2] - y[0];
	var bcx = x[1] - x[2];
	var bcy = y[1] - y[2];
	return (cax * bcy < cay * bcx);
};

render = function (model) {
	center.clear();
	center.lineStyle(2, 0, 100);
	verts2D = [];
	depthArray = [];
	for (var i = 0; i < model.side.length; i++) {
		var zDepth = 0;
		for (var j = 0; j < model.side[i].vertices.length; j++) {
			var whichVert = model.side[i].vertices[j];
			if (verts2D[whichVert] == undefined) {
				verts2D[whichVert] = {};
				var scale = focalLength / (focalLength - model.vertexList[whichVert].z);
				verts2D[whichVert].x = model.vertexList[whichVert].x * scale;
				verts2D[whichVert].y = model.vertexList[whichVert].y * scale;
			}
			zDepth += model.vertexList[whichVert].z;
		}
		depthArray.push([model.side[i], zDepth]);
	}
	depthArray.sort(function (a, b) { return a[1] > b[1];});
	for (var i = 0; i < depthArray.length; i++) {
		var sideVerts = depthArray[i][0].vertices;
		if (!backface([verts2D[sideVerts[0]].x, verts2D[sideVerts[1]].x, verts2D[sideVerts[2]].x], [verts2D[sideVerts[0]].y, verts2D[sideVerts[1]].y, verts2D[sideVerts[2]].y])) {
			center.moveTo(verts2D[sideVerts[0]].x, verts2D[sideVerts[0]].y);
			center.beginFill(getSideColor(model, depthArray[i][0]), 100);
			for (var j = 1; j < sideVerts.length; j++) {
				center.lineTo(verts2D[sideVerts[j]].x, verts2D[sideVerts[j]].y);
			}
			center.lineTo(verts2D[sideVerts[0]].x, verts2D[sideVerts[0]].y);
			center.endFill();
		}
	}
};

getSideColor = function (model, side) {
	var col = side.sideColor.toString(16);
	while (col.length < 6) {
		col = "0" + col;
	}
	var verts = [model.vertexList[side.vertices[0]], model.vertexList[side.vertices[1]], model.vertexList[side.vertices[2]]];
	var lightFactor = factorLightAngle(verts);
	var r = parseInt(col.substr(0, 2), 16) * lightFactor;
	var g = parseInt(col.substr(2, 2), 16) * lightFactor;
	var b = parseInt(col.substr(4, 2), 16) * lightFactor;
	return r << 16 | g << 8 | b;
};

factorLightAngle = function (vertices) {
	var U = [(vertices[0].x - vertices[1].x), (vertices[0].y - vertices[1].y), (vertices[0].z - vertices[1].z)];
	var V = [(vertices[1].x - vertices[2].x), (vertices[1].y - vertices[2].y), (vertices[1].z - vertices[2].z)];
	var p = [((U[1] * V[2]) - (U[2] * V[1])), -((U[0] * V[2]) - (U[2] * V[0])), ((U[0] * V[1]) - (U[1] * V[0]))];
	var magP = Math.sqrt((p[0] * p[0]) + (p[1] * p[1]) + (p[2] * p[2]));
	var dP = ((p[0] * light.x) + (p[1] * light.y) + (p[2] * light.z));
	return ((Math.acos(dP / (magP * light.magnitude)) / Math.PI) * light.brightness / 100);
};
rotate = function (model, angX, angY, angZ) {
	var sinX = Math.sin(angX * rad);var cosX = Math.cos(angX * rad);
	var sinY = Math.sin(angY * rad);var cosY = Math.cos(angY * rad);
	var sinZ = Math.sin(angZ * rad);var cosZ = Math.cos(angZ * rad);
	for(var i = 0; i < model.vertexList.length; i++){
		var vert = model.vertexList[i];
		var rx1 = vert.x;
		var ry1 = vert.y * cosX - vert.z * sinX;
		var rz1 = vert.z * cosX + vert.y * sinX;
		var rx2 = rx1 * cosY - rz1 * sinY;
		var ry2 = ry1;
		var rz2 = rz1 * cosY + rx1 * sinY;
		var rx3 = rx2 * cosZ - ry2 * sinZ;
		var ry3 = ry2 * cosZ + rx2 * sinZ;
		var rz3 = rz2;
		vert.x = rx3;vert.y = ry3;vert.z = rz3;
	};
}
center.onEnterFrame = function() {
	rotX += Key.isDown(Key.DOWN) * inc - Key.isDown(Key.UP) * inc;
	rotY += Key.isDown(Key.LEFT) * inc - Key.isDown(Key.RIGHT) * inc;
	rotate(cube, rotX, rotY, rotZ);
	render(cube);
};