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
)
截图:
如果像这样的事情发生,我真的非常绝望,所以我将不胜感激任何可以指导和教导我的帮助。
感谢您的宝贵时间,
米歇尔.
我认为您的方向是正确的,但是为了获得方向,您至少需要两个向量。根据我在文档中收集的信息,获取 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 的边界体积之间的向量进行偏移。
工作流程:
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
)
截图:
如果像这样的事情发生,我真的非常绝望,所以我将不胜感激任何可以指导和教导我的帮助。
感谢您的宝贵时间, 米歇尔.
我认为您的方向是正确的,但是为了获得方向,您至少需要两个向量。根据我在文档中收集的信息,获取 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 的边界体积之间的向量进行偏移。