Изменение оси вращения
Допустим есть объект, состоящий из 6-ти спрайтов, каждый из которых имеет св-ва x, y, z, rotationX, rotationY, rotationZ, таким образом из них составлен куб, как показано на рис. Все эти шесть сторон куба помещены в контейнер «cube» Этот куб вращаю вокруг оси Y X или Z так:

Код AS3:
cube.rotationX+=0.7;
Но при попытке повернуть куб например сначала по оси Z на 30 градусов, а потом каждый кадр вращать по оси Y, допустим на 1,0 получается совсем не то, что ожидалось, как я понял при вращении объекта его оси не вращаются и остаются на месте, и это правильно.
Но тогда возникает вопрос, а как вращать объект по другой оси, назовем ее «A», она отличается от осей Z X и У.
Пробовал вращать по одной оси быстрее, по другой медленнее:

Код AS3:
cube.rotationZ+=0.7;
cube.rotationX+=0.3;
Получается тоже нечто очень странное.
Вопрос 1: Как вращать объект по оси «A» ? см. рисунок.
Вращение через Matrix3D
Возьмем к примеру тот же самый cube из предыдущего вопроса.
Каждый кадр поворачиваю его с помощью Matrix3D:

Код AS3:
var matrixCube:Matrix3D = cube.transform.matrix3D;
matrixCube.appendRotation(0.7, Vector3D.Y_AXIS);
cube.transform.matrix3D = matrixCube;
Все понятно, кроме одного. Куб вращается не вокруг своей оси и не вокруг точки регистрации, а вокруг точки, которая находится далеко от куба, неизвестно где.
Вопрос 2: Что это за точка? Как изменить эту точку? Или я что-то делаю неправильно?
Z-сортировка между плоскостью и другой плоскостью большего размера
Происходит сортировка всех плоскостей по величине Z.
Вот функция, вызывается каждый кадр.

Код AS3:
function sortByZMatrix(c:DisplayObjectContainer):void {
var sortArray:Array = new Array();
var objectsCount:int = c.numChildren;
for (var i:int = 0; i < objectsCount; i++){
var currentFace:DisplayObject = c.getChildAt(i);
var m:Matrix3D = currentFace.transform.matrix3D.clone();
m.append(c.transform.matrix3D);
sortArray[i] = { obj:currentFace, z:m.position.z };
}
sortArray.sortOn("z", Array.NUMERIC | Array.DESCENDING);
for (i = 0; i < objectsCount; i++){
c.setChildIndex(sortArray[i].obj, i);
}
sortArray = null;
}//sort
Все работает замечательно, без глюков.
Но только в том случае, если все плоскости одинакового размера и не пересекаются между собой.
Если же сделать одну большую плоскость, допустим это каменный пол комнаты, то не всегда получается нужный результат.
Например на этом рисунке координата Z плоскости находится от нас дальше в глубь, чем координаты плоскостей куба, обведенного красным цветом → childIndex плоскостей куба больше чем childIndex плоскости пола и все отображается нормально.
Но если повернуть контейнер, в котором размещены все объекты, то...
Координаты Z плоскостей куба стали дальше, чем Z плоскости пола → плоскость пола отображается поверх плоскостей куба. Все логично, НО. Куб есть, а его не видно.
Можно решить эту проблему, создав пол из кучи таких же маленьких плоскостей, и тогда все отображается нормально.
Но колисчество плоскостей значительно возрастает
(10 х 10 плиток пола = 100 плоскостей)
И все начинает жутко тормозить.
Вопрос 3: Можно ли организовать сортировку таким образом,
чтобы она корректно работала с разными размерами плоскостей и не возникало ситуаций, описанных выше?
Если можно, то как примерно она должна быть устроена?
Или же все-таки остается собирать из маленьких плоскостей?
Каков вообще правильный подход к решению таких задач?
Производительность
Делаю следующим образом:
Собираю из плоскостей трехмерные объекты путем размещения и поворота этих плоскостей.
Каждая плоскость — это Shape, создается следующей функцией:

Код AS3:
function createPlane(ox:Number = 0, oy:Number = 0, oz:Number = 0, rtx:Number = 0, rty:Number =
0,rtz:Number=0,b:BitmapData=null,size:Number=0):void {
stor = new Shape();
stor.graphics.beginFill(0xFFFFFF);
stor.graphics.beginBitmapFill(b);
stor.graphics.lineStyle(1, 0x000000, 1.0);
stor.graphics.drawTriangles(
Vector.<Number>([-50-size, -50-size, 50+size, -50-size, -50+size, 50+size, 50+size, 50+size]),
Vector.<int>([0, 1, 2, 1, 3, 2]))
stor.x = ox; stor.y = oy; stor.z = oz;
stor.rotationX = rtx; stor.rotationY = rty; stor.rotationZ = rtz;
cube.addChild(stor);
stors.push(stor);
stc++;
}
Такой функцией строится куб:

Код AS3:
function createBox(ox:Number = 0,oy:Number=0,oz:Number=0):void {
createPlane(ox+0, oy+0, oz+-50, 0, 0, 0,textureBitmapData);
createPlane(ox+0, oy+0, oz+50, 0, 0, 0,textureBitmapData);
createPlane(ox+50, oy+0, oz+0, 0, 90, 0,textureBitmapData);
createPlane(ox+-50, oy+0, oz+0, 0, 90, 0,textureBitmapData);
createPlane(ox+0, oy+50, oz+0, 90, 0, 0,textureBitmapData);
createPlane(ox+0, oy+-50, oz+0, 90, 0, 0,textureBitmapData);
}
Создаю 10 кубов. В итоге получается 60 плоскостей. При 31 кадр/сек
все работает нормально, без подвисаний.

Код AS3:
for (t = 0; t < 10;t++){
createBox(-500+Math.random()*1000,-500+Math.random()*1000,-500+Math.random()*1000);
}
Но если создать 100 кубиков — все начинает жутко тормозить.
Вопрос 4: Нужно ли создавать каждую плоскость как отдельный Shape?
Как вообще можно повысить скорость отрисовки всего этого?
Ясно, что-то я делаю неправильно, как будет сделать разумнее и оптимизировать хоть как-то все это?
Каков правильный подход
Все яснее становится, что используя готовые классы Shape или там Sprite и создавая трехмерность таким образом, как описано выше — неправильный путь.
Вопрос 5: Так каков же тогда правильный путь? Писать все 3D вручную?
Как вообще устроены простейшие 3D-движки на флеше?
И если уж все идет на то, что нужно писать все самому, какую литературу посоветуете?
Я уже нашел статьи, но хочется именно книгу, в которой бы описывалось программирование 3D-графики с азов.
Ну, конечно, кроме учебников по математике и геометрии 