Maxscript — objA.object_rotation из objB.face_normal

Рабочий процесс:

1. imported targetObj (cube, poly, *.obj)
2. on-scene sceneObj (cube, poly, later point helper)
3. sceneObj.rotation = targetObj.rotation (the two cubes need to overlap)
4. sceneObj.pos = targetObj.pos

Проблема:

Невозможно установить правильную ось/поворот для sceneObj от нормали к лицу targetObj. Трансформационный нооберизм.

Подробности:

Я работаю над простым плагином импорта, который импортирует пользовательскую сетку из другого приложения в 3ds Max. В сцене 3ds Max у меня есть помощник (куб для тестирования прямо сейчас), и мне нужно подогнать положение и вращение к другому (того же размера, 6 полигонов), который импортируется. Это оказывается чрезвычайно сложным для меня, и хотя положение вообще не проблема (sceneObj.pos = targetObj.pos), я полностью потерялся в значениях matrix3, eulerangles и quat. И (sceneObj.rotation = targetObj.rotation) не вариант, так как простой импортированный файл *.obj вообще НЕ имеет вращения.

Итак, я подумал, что получение матрицы3 нормали грани 3 (лицевой грани) targetObj. Мне удалось каким-то образом перевести вращение на мой объект сцены, но я думаю, что все оси неверны - некоторые из них сохраняют правильное выравнивание sceneObj, в то время как при изменении ориентации targetObj он поворачивает sceneObj в неправильном направлении / вдоль неправильной оси.

Код:

fn getAngleFromNormal targetObj sceneObj =
(
    --RESET sceneObj ROTATION
    oldTranslateMtx = transMatrix sceneObj.transform.pos
    oldScaleMtx = scaleMatrix sceneObj.transform.scale
    sceneObj.transform = oldScaleMtx * oldTranslateMtx
    mtx = matrixFromNormal (polyOp.getFaceNormal targetObj 3)
    sceneObj.transform *= mtx
    eu = mtx as eulerangles
    rx = eu.x
    ry = eu.y
    rz = eu.z
    sceneObj.rotation *= inverse (eu as quat)
    sceneObj.pos = targetObj.pos
)

Скриншоты:

Снимок экрана 1

Снимок экрана 2

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

Спасибо за ваше время, Мишель.


person bitworks    schedule 21.04.2015    source источник
comment
Когда вы говорите, что импортированный узел не имеет вращения, вы имеете в виду, что он выровнен по миру (это то, что я предполагаю)? Также являются ли какие-либо из этих узлов родительскими/связанными? Также обратите внимание, что не рекомендуется преобразовывать в eulerangles, если вам это не нужно, что в данном случае вам не нужно (если только это не нужно анимировать).   -  person Klaudikus    schedule 10.12.2015


Ответы (1)


Я думаю, вы на правильном пути, однако, чтобы получить ориентацию, вам нужно как минимум два вектора. Из того, что я узнал из документации, получение matrixFromNormal использует мировую ось как касательную, поэтому вы получаете странные результаты.

Я уверен, что есть более рациональные подходы, но, надеюсь, это поможет вам встать на правильный путь.

--Returns matrix based on the face of a mesh - aligns X axis with Normal
fn getMatrixFromFace targetObj faceId:10 =
(
    -- here we get the normal and assume it's the first row of the resulting
    -- matrix, hence the x-axis
    local row1 = getFaceNormal targetObj faceId
    -- here we are building a tangent from the vertex positions of the face
    local verts = getFace targetObj faceId
    local row2 = normalize (targetObj.verts[1].pos - targetObj.verts[2].pos)
    -- to get the third axis we get the cross product of X-axis and Y-axis
    local row3 = cross row1 row2
    -- we zero out the position (row4), in case you need to multiply by this 
    -- matrix. Optionally, if you know you will always want the translation,
    -- (matrix3 row1 row2 row3 targetObj.transform.row4)
    (matrix3 row1 row2 row3 [0, 0, 0])
)
mtx = getMatrixFromFace targetObj faceId:10
mtx.row4 = targetObj.transform.row4
sourceObj.transform = mtx

Обратите внимание, что это выравнивает нормаль грани с осью X sourceObj, а ось Y выравнивает по касательной к грани. Если вы хотите изменить это, просто измените ряды вокруг или измените ориентацию касательной.

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

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

person Klaudikus    schedule 10.12.2015