Косая перспектива - проекция матризируется при обработке

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

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);
}

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

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

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


person hlg    schedule 11.01.2011    source источник


Ответы (1)


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

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

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: устанавливает матрицы camera и modelview.
  • Строка 3: устанавливает матрицу проекции
  • Строка 4: устанавливает только матрицу камеры, но на самом деле здесь ничего не делается. (читать дальше)

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

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


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

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

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

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

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);
}

скриншот косой проекции в обработке

person Shaun Lebron    schedule 11.03.2011
comment
Спасибо за подробное объяснение и ссылку. Основная ошибка видимо заключалась в установке матрицы камеры вместо матрицы проекции. Тем не менее, я не совсем понимаю, почему вышеизложенное работало именно так и почему отсутствовало наполнение. У меня в методе настройки было все, кроме самого чертежа коробки - поправил свой вопрос, чтобы быть точнее. - person hlg; 14.03.2011