Maxscript - 来自 objB.face_normal 的 objA.object_rotation

Maxscript - objA.object_rotation from 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

问题:

无法从 targetObj 的面法向 sceneObj 设置正确的轴/旋转。转型笨拙。

详情:

我正在开发一个简单的导入插件,它将自定义网格从另一个应用程序导入到 3ds Max 中。在 3ds Max 场景中,我有一个助手(一个用于测试的立方体),我需要将位置和旋转调整到导入的另一个(相同大小,6 个多边形)。事实证明这对我来说非常困难,虽然位置完全没有问题 (sceneObj.pos = targetObj.pos) 我完全迷失在 matrix3、eulerangles 和 quat 值。并且 (sceneObj.rotation = targetObj.rotation) 不是一个选项,因为简单导入的 *.obj 文件根本没有旋转。

所以 - 我认为获取 targetObj 的面 3(前面)的法线的矩阵 3。我设法以某种方式将旋转转换为我的场景对象,但我认为轴都是错误的 - 其中一些使 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
)

截图:

Screenshot-1

Screenshot-2

如果像这样的事情发生,我真的非常绝望,所以我将不胜感激任何可以指导和教导我的帮助。

感谢您的宝贵时间, 米歇尔.

我认为您的方向是正确的,但是为了获得方向,您至少需要两个向量。根据我在文档中收集的信息,获取 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

请注意,这会将面的法线与sourceObj 的X 轴对齐,Y 轴与面的切线对齐。如果要更改它,只需更改周围的行或更改切线的方向即可。

如果您需要面对面对齐,则需要做更多的工作。我相信你可以从给出的信息中弄清楚。

另请注意,我假设 targetObj 具有世界方向,但具有与其几何相关的位置(从原点偏移)。如果不是,您可以修改上面函数中的 row4,方法是平均面部顶点的位置,然后用上述平均位置和 targetObj 的边界体积之间的向量进行偏移。