OpenGL камера зум / масштаб вокруг точки и панорамирования

Я реализовал камеру (вид модели) в своем 2D-приложении opengl, и у меня возникли некоторые проблемы с масштабированием вокруг точки, а также с масштабированием вокруг точки в сочетании с панорамированием. Оба работают с мышью. Панорамирование работает с помощью перетаскивания мышью и масштабирования для наведения масштаба вокруг текущего местоположения мыши.

Панорамирование работает хорошо, пока я еще не масштабировал точку. Если я масштабировал вокруг точки, то в панорамировании есть начальный "прыжок", но тогда он работает плавно. Масштабирование вокруг точки работает нормально для первой точки, но для последующих точек сцена переводится один раз, а затем после этого работает масштабирование вокруг текущей точки мыши. Масштаб вокруг кода точки выглядит так:

public void scaleToPoint(float scale, float x, float y, float z) {
    root.markAsDirty();
    y = drawableHeight - y - 1;

    // (S(Inverse(T))
    matrix.m03 = -x;
    matrix.m13 = -y;
    matrix.m23 = -z;

    matrix.m00 = matrix.m11 = matrix.m22 = scale;
    matrix.m03 *= matrix.m00;
    matrix.m13 *= matrix.m11;
    matrix.m23 *= matrix.m22;
    matrix.m03 += x;
    matrix.m13 += y;
    matrix.m23 += z;
  }

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

Ник

Добавлено в ответ на комментарий:

матрица является javax.matrix.Matrix4f.

Код панорамирования:

public void pan(Vector3f pan) {
    root.markAsDirty();
    matrix.setTranslation(pan);
}

где matrix.setTranslation устанавливает компонент перевода матрицы, т.е.

matrix.m03 = trans.x; 
matrix.m13 = trans.y;
matirx.m23 = trans.z;

Матрица загружается с помощью glLoadMatrix(), чтобы установить верхнюю матрицу в стеке. Ожидаемый результат - нормальное плавное панорамирование без дополнительного скачка в случае панорамирования и без скачка до масштабирования / масштабирования в случае масштабирования. Под прыжком я подразумеваю, что сцена неожиданно меняется. Так, например, если сцена представляет собой один большой квадрат, а мышь расположена в центре квадрата, квадрат должен двигаться в направлении перетаскивания мышью, в то время как центр квадрата остается под мышью. При прыжке мышь начнет центр квадрата, но начало панорамирования переместит сцену так, что другая часть квадрата теперь находится под мышью. Скачок в масштабировании работает аналогично. Первый зум смещает сцену так, что место, которое было первоначально под мышью, теперь больше не под мышью.

Обратите внимание, что панорамирование работает хорошо, если не было масштабирования вокруг точки. Панорамирование также работает нормально, если масштабирование не находится вокруг какой-либо конкретной точки.

1 ответ

Ваша проблема в том, что вместо дельта-перевода вы просто устанавливаете перевод. Это работает, когда дело доходит до панорамирования, однако, когда вы масштабируете, вы не сохраняете перевод из-за масштаба, и он стирается при следующем действии перевода. Итак, что бы я сделал вместо установки перевода, я бы увеличил его. Поэтому, когда вы перетаскиваете мышь, получаете дельту из двух вызовов gluUnProject, а затем добавляете эту дельту к значениям преобразования матрицы. Это предотвратит стирание небольшого перевода, созданного действием масштаба вокруг точки.

Так:

public void pan(Vector3f delta_pan)
{
    root.markAsDirty();
    matrix.m03 += delta_pan.x; 
    matrix.m13 += delta_pan.y;
    matirx.m23 += delta_pan.z;
}
Другие вопросы по тегам