Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Вычисление новых локальных координат объекта с сохранением позиции в глобальных координатах

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

Страницы: 1 2 Следующая »
mr.DIMASПостоялецwww6 ноя. 201820:50#0
Есть классический граф сцены (в 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]));
  }
}
Однако это само-собой неверно, потому что нельзя однозначно разложить матрицу на исходные составляющие из которых она была получена. Несмотря на это, сей подход работает относительно сносно и в большинстве случаев дает приемлемые результаты. Мне интересно как правильно решается подобная задача?

alorkenПостоялецwww7 ноя. 201812:46#1
mr.DIMAS
От задачи зависит. Если после добавления объекта к родителю ты хочешь чтобы например при обнулении поворота объект выравнивался, то тогда только декомпозиция. Иначе можно сохранить матрицу relativeTransform как некую offsetMatrix для объекта, и для вычисления глобальной матрицы потом еще локальную домножать на оффсет, а потом на родителя. Но собственно хоть и нельзя разложить матрицу однозначно на компоненты, какая разница?
}:+()___ [Smile]Постоялецwww7 ноя. 201815:06#2
mr.DIMAS
> Затем полученную матрицу раскладываю на составляющие (TRS-decomposition):
Произвольную матрицу разложить в TRS невозможно, только в TRSR'.
mr.DIMASПостоялецwww7 ноя. 201815:49#3
alorken
Мне нужно получать именно локальные позицию, поворот и масштаб. Из них я потом уже и собираю матрицы.

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

BingoBongoПостоялецwww7 ноя. 201815:50#4
Я так понимаю, проблема в том, что может существовать новый объект с такими смещением, поворотом и скейлом, что его введение в иерархию не позволит дочерним объектам ни при каких условиях иметь прежние смещение, поворот и скейл в глобальном пространстве (точнее для этого недостаточно смещения, поворота и скейла, нужна, например, еще и трансформация сдвигом).
alexzzzzПостоялецwww7 ноя. 201817:27#5
Допустим, есть такая иерархия, где 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. Проблема только не запутаться в порядке преобразований. Попозже поэкспериментирую.

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

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

}:+()___ [Smile]Постоялецwww7 ноя. 201818:01#7
mr.DIMAS
> Можно немного поподробнее, пожалуйста. Что здесь R' ?
Второй поворот.
alorkenПостоялецwww8 ноя. 201812:12#8
}:+()___ [Smile]
А почему нельзя в TRS разложить? Можно пример? Что-то не могу себе представить.

Правка: 8 ноя. 2018 12:12

}:+()___ [Smile]Постоялецwww8 ноя. 201813:43#9
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]

DelfigamerПостоялецwww8 ноя. 201816:51#10
mr.DIMAS
Тебе точно нужно анизотропное растяжение? Задача была бы гораздо проще, если бы масштаб задавался одним скаляром.
DelfigamerПостоялецwww8 ноя. 201817:01#11
alorken
> А почему нельзя в TRS разложить? Можно пример? Что-то не могу себе представить.
Я дам тебе более наглядный пример:

Изображение

Правка: 8 ноя. 2018 17:01

mr.DIMASПостоялецwww8 ноя. 201819:47#12
Delfigamer
> Тебе точно нужно анизотропное растяжение?
Ага, у меня масштаб может анимирован быть через редактор и он не равномерный - в разных ситуациях нужен разный масштаб по разным осям.

Правка: 8 ноя. 2018 19:47

mr.DIMASПостоялецwww8 ноя. 201819:49#13
В общем-то эту задачу я решаю как раз для редактора, чтобы можно было делать attach/detach узлов сцены с сохранением положения в глобальных координатах.
MrShoorУчастникwww8 ноя. 201820:41#14
mr.DIMAS
> В общем-то эту задачу я решаю как раз для редактора, чтобы можно было делать
> attach/detach узлов сцены с сохранением положения в глобальных координатах.
То, как ты её решил - и есть приемлимое решение. Писал редактор, проходил через те же грабли.
Страницы: 1 2 Следующая »

/ Форум / Программирование игр / Общее

2001—2018 © GameDev.ru — Разработка игр