Показать сообщение отдельно
Старый 21.08.2013, 01:37
Vasya Pupkin вне форума Посмотреть профиль Отправить личное сообщение для Vasya Pupkin Найти все сообщения от Vasya Pupkin
  № 16  
Ответить с цитированием
Vasya Pupkin

Регистрация: Dec 2011
Сообщений: 17
По умолчанию У меня вопрос по 3D трансформациям.

Здравствуйте! Мне необходимо вращать и поступательно перемешать 3D контент в пространстве. Исходные данные: у меня есть мешЪ. Его размеры составляют по ширине 320, по высоте 240, а в глубину доходит до 4000. Все треугольники направлены в одну сторону (на экран). Выглядит меш как плоскость, только в отдельных местах, как бы обрывы из-за того, что в этих местах треугольники отдалены от остальных по оси Z (облако точек). Меш состоит из 320*240*2 = 153600 треугольников. Формат вектора вершин [x, y, z, r, g, b].
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 ориентаций. Класс, который я использую для имитации перспективы com.adobe.utils.PerspectiveMatrix3D. Я не ожидал следующих подводных камней:
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();
matrix3D.appendRotation(rY, Vector3D.Y_AXIS);
matrix3D.appendRotation(rX, Vector3D.X_AXIS);
matrix3D.appendRotation(rZ, Vector3D.Z_AXIS);
matrix3D.appendTranslation(offsetX, offsetY, offsetZ);
 
 
var aspect:Number = 3/3;
var zNear:Number = -5000;
var zFar:Number = 5000;
var fov:Number = 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");
}
Миниатюры
Нажмите на изображение для увеличения
Название: rxm20_ry20.png
Просмотров: 40
Размер:	256.7 Кб
ID:	29927