Render.ru
Поддержать

Некоторым объектам присваиваются инвертированные трансформации

Дмитрий Никулин

Пользователь сайта
Рейтинг
2
Приветствую

Обнаружил особенность, при которой некоторым объектам (всегда одним и тем же) присваиваются инвертированные трансформации, при присваивании в цикле. У большей же части объектов координаты получаются верными.

Например, в массиве позиций для третьего по счету объекта следующая позиция:
reader.nodes[3].position
[95.0901,130.09,0]
После присваивания данной позиции объекту в цикле он принимает следующее положение:
$.position
[-130.09,95.0901,0]
Аналогично и с вращением:
reader.nodes[3].rotation
(quat 0 0 -0.707107 -0.707107)

...

$.rotation
(quat 0 0 0.707107 0.707107)
Возможно ли как-нибудь убрать эту нежелательную инверсию?

igorznag

Мастер
Рейтинг
103
Объясните подробнее. Для чего вам это нужно?
Как вы получили данные о позиции и вращении?
Пример: В новой сцене создаем два объекта с названиями "Object1" и "Object2".
Перемещаем и вращаем объект "Object1".
Теперь нужно скопировать позицию и вращение с объекта1 на объект2.
Сначала получаем данные с объекта1 таким способом:
$Object1.position
$Object1.transform.rotation
И получаем:
[50.0314,-49.0581,0]
(quat 0 0 0.422618 0.906308)
Потом применяем данные к объекту2 таким способом:
$Object2.position=[50.0314,-49.0581,0]
in coordsys (transmatrix $Object2.position) $Object2.rotation= inverse (quat 0 0 0.422618 0.906308)
Чтобы проверить данные у объекта2 используем код:
$Object2.position
$Object2.transform.rotation
И получаем:
[50.0314,-49.0581,0]
(quat 0 0 0.422618 0.906308)

Дмитрий Никулин

Пользователь сайта
Рейтинг
2
Пишу импортер кастомного формата. Данные об объектах (вершины, индексы, текстурные координаты..) и их позиции\вращении\масштабе читаются из файла. На их основе в цикле создаются меши и им присваиваются трансформации.
Присваивается все верно:

...

for tempLod in item.lods do
(

    mynode = BuildMesh vertices:tempLod.vertices faces:tempLod.faces \
                        tverts:tempLod.tverts
                                
    mynode.name = nodes[i].name
                   
    mynode.position = nodes[i].position
                                
    format "Node % (%): position in array:%, assigned: %\n" i nodes[i].name \
                                        nodes[i].position mynode.position
                                
    mynode.scale = nodes[i].scale
    mynode.rotation = nodes[i].rotation
                             
)
Node 1 (Loft02): position in array:[40,45,0], assigned: [40,45,0]
Node 2 (Loft08): position in array:[40,185.18,0], assigned: [40,185.18,0]
Node 3 (Loft14): position in array:[95.0901,130.09,0], assigned: [95.0901,130.09,0]
Node 4 (Loft19): position in array:[50.0901,120,0], assigned: [50.0901,120,0]
...

А после построения сцены у некоторых объектов получается вот так:

mynode = getNodeByName "Loft02"
$Editable_Mesh:Loft02 @ [40.000000,45.000000,0.000000]
mynode.position
[40,45,0]

mynode = getNodeByName "Loft08"
$Editable_Mesh:Loft08 @ [40.000000,185.180161,0.000000]
mynode.position
[40,185.18,0]

mynode = getNodeByName "Loft14"
$Editable_Mesh:Loft14 @ [-130.090088,95.090057,0.000000]
mynode.position
[-130.09,95.0901,0]
--- Здесь должно быть [95.0901,130.09,0]

igorznag

Мастер
Рейтинг
103
Если в вашем коде поменять только эту строку:
mynode.rotation = nodes[i].rotation
на такой код:
in coordsys (transmatrix mynode.position) mynode.rotation= inverse nodes[i].rotation
или на такой код:
in coordsys (transmatrix mynode.position) mynode.rotation=nodes[i].rotation
тогда что произойдёт?

Дмитрий Никулин

Пользователь сайта
Рейтинг
2
igorznag
in coordsys (transmatrix mynode.position) mynode.rotation=nodes[i].rotation
Вот это все исправляет. Благодарю!
А я все на позицию грешил.

Дмитрий Никулин

Пользователь сайта
Рейтинг
2
Изменено: 2 #6
Проблема вернулась у объектов с parent'ами.
Но я нашел решение и более верный способ.

Для объектов без parent'ов получаем матрицу трансформаций:
local tempNodeTransform = (scalematrix tempNode.scale) \
          * (tempNode.rotation as Matrix3) * (transmatrix tempNode.position)
Для дочерних объектов умножаем полученную матрицу на матрицу родителя:
myNode.parent = tempNode.parent
tempNodeTransform *= myNode.parent.transform
И соответственно присваиваем матрицу текущему узлу:
myNode.transform = tempNodeTransform