Войти
ПрограммированиеФорумОбщее

Вычисление новых локальных координат объекта с сохранением позиции в глобальных координатах

Страницы: 1 2 Следующая »
#0
20:50, 6 ноя. 2018

Есть классический граф сцены (в 2D), у каждого узла соответственно имеется позиция, поворот и масштаб в локальных координатах из которых строится локальная матрица трансформации. Глобальная матрица трансформации для каждого узла строится перемножением матриц по иерархии. Для примера возьмем дерево из N узлов - каждый последующий узел является потомком предыдущего узла. Теперь в произвольное место иерархии вводим дополнительного потомка. Как в таком случае правильно вычислить новые локальные позицию, поворот и масштаб для этого потомка так, чтобы в глобальных координатах объект остался с прежней глобальной матрицей трансформации?

Как я делаю сейчас: беру обратную глобальную матрицу трансформации объекта к которому будет прикреплен новый объект и умножаю на глобальную матрицу нового объекта. Затем полученную матрицу раскладываю на составляющие (TRS-decomposition):

auto relativeTransform = parent->GetGlobalTransform().getInverse() * node->GetGlobalTransform();
...
void DecomposeTransform(const sf::Transform &t, Vec2f *p, Vec2f *s, float *r)
{
  auto m = t.getMatrix();
  if (p)
  {
    p->x = m[12];
    p->y = m[13];
  }
  if (s)
  {
    s->x = Sign(m[0]) * sqrt(m[0] * m[0] + m[4] * m[4]);
    s->y = Sign(m[5]) * sqrt(m[1] * m[1] + m[5] * m[5]);
  }
  if (r)
  {
    *r = Math::Rad2Deg(atan2f(-m[4], m[0]));
  }
}
Однако это само-собой неверно, потому что нельзя однозначно разложить матрицу на исходные составляющие из которых она была получена. Несмотря на это, сей подход работает относительно сносно и в большинстве случаев дает приемлемые результаты. Мне интересно как правильно решается подобная задача?


#1
12:46, 7 ноя. 2018

mr.DIMAS
От задачи зависит. Если после добавления объекта к родителю ты хочешь чтобы например при обнулении поворота объект выравнивался, то тогда только декомпозиция. Иначе можно сохранить матрицу relativeTransform как некую offsetMatrix для объекта, и для вычисления глобальной матрицы потом еще локальную домножать на оффсет, а потом на родителя. Но собственно хоть и нельзя разложить матрицу однозначно на компоненты, какая разница?

#2
15:06, 7 ноя. 2018

mr.DIMAS
> Затем полученную матрицу раскладываю на составляющие (TRS-decomposition):
Произвольную матрицу разложить в TRS невозможно, только в TRSR'.

#3
15:49, 7 ноя. 2018

alorken
Мне нужно получать именно локальные позицию, поворот и масштаб. Из них я потом уже и собираю матрицы.

}:+()___ [Smile]
Можно немного поподробнее, пожалуйста. Что здесь R' ?

#4
15:50, 7 ноя. 2018

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

#5
17:27, 7 ноя. 2018

Допустим, есть такая иерархия, где A - корневой объект и для всех объектов имеются их локальные сдвиг (T), поворот (R) и масштаб (S):

A <- B <- D <- E

Нужно между B и его потомком D вставить новый объект С с локальными Tc, Rc, Sc:

A <- B <- C <- D <- E

Требуется модифицировать у объекта D его локальные Td, Rd, Sd так, чтобы мировые координаты D и всех его потомков не изменились.

--
> Как я делаю сейчас: беру обратную глобальную матрицу трансформации объекта к которому будет прикреплен новый объект и умножаю на глобальную матрицу нового объекта.

Я думаю, с таким же успехом, но проще и быстрее, можно взять обратную локальную матрицу трансформации нового объекта C и домножить её на локальную матрицу трансформации D. Ну или наоборот, зависит от реализации. Смысл в том, чтобы новая матрица для D сначала отменяла трансформации, сделанные появившимся C, а потом к результату применяла старые трансформации D.

Должна получиться новая локальная матрица трансформации для D. Из неё можно достать новые локальные Td, Rd, Sd.

--
Можно обойтись и без матриц, смысл тот же: новые трансформации D должны сначала отменять трансформации C и к результату применять старые трансформации D. Проблема только не запутаться в порядке преобразований. Попозже поэкспериментирую.

#6
17:40, 7 ноя. 2018

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

Всё равно может не получиться. Если новая трансформация схлопывает объёмный объект в плоский, в отрезок или в точку, то достать из них обратно объёмный объект уже не получится никак.

#7
18:01, 7 ноя. 2018

mr.DIMAS
> Можно немного поподробнее, пожалуйста. Что здесь R' ?
Второй поворот.

#8
12:12, 8 ноя. 2018

}:+()___ [Smile]
А почему нельзя в TRS разложить? Можно пример? Что-то не могу себе представить.

#9
13:43, 8 ноя. 2018

alorken
> А почему нельзя в TRS разложить? Можно пример? Что-то не могу себе представить.
Ну вот попробуй разложить в RS ([cht]\alpha[/cht] — произвольный параметр), перенос я выкинул для простоты, с ним все ясно:

[cht]\[\left(\begin{array}1+\alpha&\alpha&\alpha\\\alpha&1+\alpha&\alpha\\\alpha&\alpha&1+\alpha\end{array}\right)\][/cht]

#10
16:51, 8 ноя. 2018

mr.DIMAS
Тебе точно нужно анизотропное растяжение? Задача была бы гораздо проще, если бы масштаб задавался одним скаляром.

#11
17:01, 8 ноя. 2018

alorken
> А почему нельзя в TRS разложить? Можно пример? Что-то не могу себе представить.
Я дам тебе более наглядный пример:

Изображение
#12
19:47, 8 ноя. 2018

Delfigamer
> Тебе точно нужно анизотропное растяжение?
Ага, у меня масштаб может анимирован быть через редактор и он не равномерный - в разных ситуациях нужен разный масштаб по разным осям.

#13
19:49, 8 ноя. 2018

В общем-то эту задачу я решаю как раз для редактора, чтобы можно было делать attach/detach узлов сцены с сохранением положения в глобальных координатах.

#14
20:41, 8 ноя. 2018

mr.DIMAS
> В общем-то эту задачу я решаю как раз для редактора, чтобы можно было делать
> attach/detach узлов сцены с сохранением положения в глобальных координатах.
То, как ты её решил - и есть приемлимое решение. Писал редактор, проходил через те же грабли.

Страницы: 1 2 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.