Maxscript——objA。从objB.face_normal object_rotation

时间:2022-09-10 21:23:41

Workflow:

工作流程:

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

Problem:

问题:

Can't set proper axis / rotation to sceneObj from face normal of targetObj. Transformation nooberism.

不能设置正确的轴/旋转到sceneObj,从表面正常的targetObj。转换nooberism。

Details:

细节:

I'm working on a simple import plugin, that imports custom mesh from another app into 3ds Max. In the 3ds Max scene I have a helper (a cube for testing right now) and I need to fit the position and rotation to another one (same size, 6 polys) which is imported. This proves to be extremely difficult for me, and while the position is no problem at all (sceneObj.pos = targetObj.pos) I'm totally lost at matrix3, eulerangles and quat values. And (sceneObj.rotation = targetObj.rotation) is not an option, as the simple imported *.obj file has NO rotation at all.

我正在开发一个简单的导入插件,从另一个应用程序导入自定义网格到3ds Max。在3ds Max场景中,我有一个助手(现在正在进行测试),我需要将位置和旋转调整到另一个(同样大小,6个polys),这是导入的。这对我来说是非常困难的,而这个职位完全没有问题(sceneObj)。我完全迷失在矩阵、欧拉角和quat值中。和(sceneObj。旋转= targetobj旋转)不是一个选项,因为简单的导入*。obj文件没有旋转。

So - I've thought that getting the matrix3 of the normal of face 3 (front face) of the targetObj. I managed to somehow translate the rotation to my scene object but I think the axis are all wrong - some of them keep the sceneObj aligned properly, while when targetObj orientation changes it rotates the sceneObj in the wrong direction / along wrong axis.

所以,我想要得到目标的3(正面)的矩阵的矩阵。我设法将旋转转换为我的场景对象,但我认为坐标轴都是错的——有些是保持sceneObj对齐,而当targetObj方向改变时,它会沿着错误的方向/沿着错误的轴旋转sceneObj。

Code:

代码:

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
)

Screenshots:

截图:

Screenshot-1

Screenshot-1

Screenshot-2

Screenshot-2

I'm really, really hopeless if it goes for things such as these, so I'd appreciate any and all help that can direct and teach me even a bit.

我真的,真的很绝望,如果它是像这样的东西,所以我会感激任何和所有的帮助,可以指导和教我一点。

Thanks for your time, Michelle.

谢谢你的时间,Michelle。

1 个解决方案

#1


1  

I think you're on the right track, however in order to get an orientation you need at least two vectors. From what I gather in the documentation, getting the matrixFromNormal uses the world axis as a tangent, which is why you're getting odd results.

我认为你在正确的轨道上,但是为了得到一个方向你需要至少两个向量。从我在文档中收集到的信息来看,获得矩阵的正常使用世界轴是一个切线,这就是为什么你会得到奇怪的结果。

I'm sure there are more streamlined approaches, but hopefully this gets you on the right track.

我确信有更精简的方法,但希望这能让你走上正轨。

--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

Note that this aligns the normal of the face with the X-axis of the sourceObj, and the Y-axis is aligned to the tangent of the face. If you which to change this, simply change the rows around or change the orientation of the tangent.

注意,这与sourceObj的x轴对齐了脸的法线,y轴与脸的切线对齐。如果你想改变它,只需改变周围的行或者改变切线的方向。

If you need to align face to face, there's more work involved. I'm sure you can figure it out from the information given.

如果你需要面对面交流,你需要做更多的工作。我相信你能从所提供的信息中找到答案。

Also note that I assume that the targetObj has a world orientation, but has a position that relates to its geometry (offset from origin). If not you can modify row4 in the function above by averaging the position of the verts of the faces, and then offsetting by the vector between the aforementioned average pos, and the bounding volume of the targetObj.

还要注意的是,我假设targetObj有一个面向世界的方向,但是它的位置与它的几何形状有关(偏离原点)。如果你不能在上面的函数中对row4进行修改,那么你可以通过平均每个面的位置,然后在上述的平均pos和targetObj的包围量之间进行补偿。

#1


1  

I think you're on the right track, however in order to get an orientation you need at least two vectors. From what I gather in the documentation, getting the matrixFromNormal uses the world axis as a tangent, which is why you're getting odd results.

我认为你在正确的轨道上,但是为了得到一个方向你需要至少两个向量。从我在文档中收集到的信息来看,获得矩阵的正常使用世界轴是一个切线,这就是为什么你会得到奇怪的结果。

I'm sure there are more streamlined approaches, but hopefully this gets you on the right track.

我确信有更精简的方法,但希望这能让你走上正轨。

--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

Note that this aligns the normal of the face with the X-axis of the sourceObj, and the Y-axis is aligned to the tangent of the face. If you which to change this, simply change the rows around or change the orientation of the tangent.

注意,这与sourceObj的x轴对齐了脸的法线,y轴与脸的切线对齐。如果你想改变它,只需改变周围的行或者改变切线的方向。

If you need to align face to face, there's more work involved. I'm sure you can figure it out from the information given.

如果你需要面对面交流,你需要做更多的工作。我相信你能从所提供的信息中找到答案。

Also note that I assume that the targetObj has a world orientation, but has a position that relates to its geometry (offset from origin). If not you can modify row4 in the function above by averaging the position of the verts of the faces, and then offsetting by the vector between the aforementioned average pos, and the bounding volume of the targetObj.

还要注意的是,我假设targetObj有一个面向世界的方向,但是它的位置与它的几何形状有关(偏离原点)。如果你不能在上面的函数中对row4进行修改,那么你可以通过平均每个面的位置,然后在上述的平均pos和targetObj的包围量之间进行补偿。