Здравствуйте! Мне необходимо вращать и поступательно перемешать 3D контент в пространстве. Исходные данные: есть мешЪ. Его размеры составляют по ширине 320, по высоте 240, а в глубину доходит до 4000. Все треугольники направлены в одну сторону (на экран). Выглядит меш как плоскость, только в отдельных местах, как бы обрывы из-за того, что в этих местах треугольники отдалены от остальных по оси Z (облако точек). Меш состоит из 320*240*2 = 153600 треугольников. Формат вектора вершин [x, y, z, r, g, b]. Класс, который я использую для перспективы com.adobe.utils.PerspectiveMatrix3D.
agal код как у всех для таких случаев:
Код AS3:
const VERTEX_SHADER:String =
"m44 op, va0, vc0 \n" +
"mov v0, va1";
const FRAGMENT_SHADER:String =
"mov oc, v0";
Я думал, что я возьму матрицу 4 на 4 (3D матрицу) и буду выполнять с ней все манипуляции касающиеся 3D ориентаций и все будет клево как в Away3d, однако не выходит. Появляются какие-то необычные эффекты:
1. При вращении вокруг осей X и Y меш визуально обрезается (см. изображение).
2. При сдвиге по X и по Y происходит не поступательное перемещение, а какая-то деформация похожая на изменение угла обзора с одновременным поворотом.
3. Те треугольники, которые находятся на отдалении (z > 100) не видны вообще. То есть они конечно есть, но находятся на таком отдалении(до 4000), что превращаются в точку.
Должен отметить, что перемещение вдоль Z происходит правильно.
Привожу кусок кода (цикл рендера):
Код AS3:
public function render(e:Event):void
{
if(!contextChanged)return;
context3D.clear(0,0,0);
//Матрица для меша
var matrix3D:Matrix3D = new Matrix3D();
//Поворачиваем меш вокруг осей x, y, z
matrix3D.appendRotation(rY, Vector3D.Y_AXIS);
matrix3D.appendRotation(rX, Vector3D.X_AXIS);
matrix3D.appendRotation(rZ, Vector3D.Z_AXIS);
//Перемещаем меш вдоль осей x, y, z
matrix3D.appendTranslation(offsetX, offsetY, offsetZ);
var aspect:Number = 3/3;
//Так и не понял в чем суть этих zNear и zFar - визуально одна и та же хрень.
var zNear:Number = -5000;
var zFar:Number = 5000;
var fov:Number = this.fov*Math.PI/180;
perspective.identity();
perspective.perspectiveFieldOfViewLH(fov, aspect, zNear, zFar);
//Добавляем перспективу
matrix3D.append(perspective);
//Чтобы не переполнился вершинный буфер разбросал точки по нескольким вершинным буферам.
for(var i:uint=0;i<amountOfSprites;i++)
{
//Геометрия
сontext3D.setVertexBufferAt(0,sprite3Ds[i].vertexBuffer3D,0,Context3DVertexBufferFormat.FLOAT_3);
context3D.setVertexBufferAt(1,sprite3Ds[i].vertexBuffer3D,3,Context3DVertexBufferFormat.FLOAT_3);
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,0,matrix3D);
//Отрисовка
context3D.drawTriangles(sprite3Ds[i].indexBuffer3D,0,sprite3Ds[i].numTriangles);
}
//Окончательный вывод изображения.
context3D.present();
contextChanged = false;
log("render OK");
}