Косая перспектива - проекция матриц в обработке - PullRequest
1 голос
/ 11 января 2011

Я хочу расширить обработку, чтобы можно было визуализировать трехмерные объекты с помощью наклонных проекций (кабинет или кавалер). После просмотра источника методов camera () ,pective () и ortho () мне удалось настроить ортографическую перспективу, а затем с частичным успехом настроить матрицу камеры PGraphics3D # на соответствующее значение.

void setup() {
   camera(30, 30, 30, 0, 0, 0, 1, 1, 0);
   ortho(-100, 100, -100, 100, -500, 500);
   p3d.camera.set(1, 0, -0.433f, 0, 0, 1, 0.25f, 0, 0, 0, 0, 0, 0, 0, 0, 1);
}

void draw() {
   box(20);
}

Это дает правильную перспективу, но без заполнения поверхности. При удалении вызовов камеры и метода ortho или обоих, экран пуст, хотя я ожидаю, что камера (...) будет работать с той же матрицей, которая будет перезаписана позже.

Более того, меня немного смущают матрицы в PGraphics3D: камера, модель и проекция. В то время как OpenGL хранит два матричных стека - ModelView и Projection, вот третий - камера. Кто-нибудь может пролить свет на разницу и связь между этими матрицами?

Это было бы полезно для того, чтобы узнать, когда использовать / установить какой.

1 Ответ

2 голосов
/ 11 марта 2011

Отличный вопрос!

Я запустил следующий код, как он у вас, и он выглядел как изометрический вид белого куба.

1: size(300,300,P3D);
2: camera(30, 30, 30, 0, 0, 0, 1, 1, 0);
3: ortho(-100, 100, -100, 100, -500, 500);
4: PGraphics3D p3d = (PGraphics3D)g;
5: p3d.camera.set(1, 0, -0.433f, 0, 0, 1, 0.25f, 0, 0, 0, 0, 0, 0, 0, 0, 1);
6: box(20);

Вот что происходит:

  • Строка 2: устанавливает камеру и модель просмотра матрицы
  • Строка 3: устанавливает проекцию матрицу
  • Строка 4: устанавливает только матрицу камеры , но здесь это на самом деле ничего не делает. (читать дальше)

Преобразования выполняются только с использованием матриц viewview и projection . Матрица camera является просто удобным разделением того, к чему обычно инициализируется viewview .

Если вы использовали функцию draw (), матрица modelview фактически инициализируется в матрицу camera перед каждым ее вызовом. Поскольку вы не использовали функцию draw (), матрица камеры никогда не обновлялась с помощью косого преобразования в матрице camera .


Как создать наклонную проекцию

Как заявление об отказе от ответственности, вы должны действительно понимать, как матрицы используются для преобразования координат. Заказ очень важен. Это хороший ресурс для изучения этого: http://glprogramming.com/red/chapter03.html

Самое быстрое объяснение, которое я могу дать, состоит в том, что матрица модели превращает объект координаты в относительные глаз координаты, затем проекция матрица берет эти глаз координаты и превращает их в экран координаты. Таким образом, вы хотите применить наклонную проекцию до преобразования в экранные координаты.

Вот работающий пример создания проекции шкафа, отображающей несколько кубов:

void setup()
{
  strokeWeight(2);
  smooth();
  noLoop();

  size(600,600,P3D);
  oblique(radians(60),0.5);
}

void draw()
{
  background(100);

  // size of the box
  float w = 100;

  // draw box in the middle
  translate(width/2,height/2);
  fill(random(255),random(255),random(255),100);
  box(w);

  // draw box behind
  translate(0,0,-w*4);
  fill(random(255),random(255),random(255),100);
  box(w);

  // draw box in front
  translate(0,0,w*8);
  fill(random(255),random(255),random(255),100);
  box(w);
}

void oblique(float angle, float zscale)
{
  PGraphics3D p3d = (PGraphics3D)g;

  // set orthographic projection
  ortho(-width/2,width/2,-height/2,height/2,-5000,5000);

  // get camera's z translation
  // ... so we can transform from the original z=0
  float z = p3d.camera.m23;

  // apply z translation
  p3d.projection.translate(0,0,z);

  // apply oblique projection 
  p3d.projection.apply(
    1,0,-zscale*cos(angle),0,
    0,1,zscale*sin(angle),0,
    0,0,1,0,
    0,0,0,1);

  // remove z translation
  p3d.projection.translate(0,0,-z);
}

screenshot of oblique projection in processing

...