Maxscript:撰写转换
Maxscript: Compose Transformations
我正在尝试修复具有负比例的动画模型(我知道这可能是个坏主意)。在查看 max 脚本中的变换时,我注意到一些有趣的事情,这可能与 3ds max 中左手坐标系的内部使用有关。我将节点的变换与节点的 PRS 值进行了比较:我的期望是通过乘以 PRS 值,我也应该得到变换。但是,如果对象被旋转或镜像,则情况并非如此,请参阅:
$.transform =
row1 [0.866,-0.500,0.000]
row2 [-0.500,-0.866,0.000]
row3 [0.000,0.000,1.000]
row4 [13.000,-3.000,1.000]
...scale * ...rotation * ...pos =
row1 [-0.866,0.500,0.000]
row2 [-0.500,-0.866,0.000]
row3 [0.000,0.000,-1.000]
row4 [13.000,-3.000,1.000]
...transform.scalepart * ...transform.rotationpart * ...transform.translationpart =
row1 [-0.866,0.500,0.000]
row2 [0.500,0.866,0.000]
row3 [0.000,0.000,-1.000]
row4 [13.000,-3.000,1.000]
任何想法,为什么这些转换不一样?我试图了解 3ds max 的幕后工作原理。非常感谢您的任何见解!
这里发生了一些事情。
首先,MaxScript $.transform.scalepart
和 $.transform.rotationpart
似乎有问题并且不支持反向缩放。这些可能与 this post 上的第一个答案类似地实现,它总是给出正比例坐标,而负比例矩阵的答案是错误的。
其次,当请求 $.scale.controller.value
和 $.rotation.controller.value
时,旋转部分也有问题,returns 与镜像之前的值相同,而比例 returns 是镜像的价值。如果您考虑(缩放 * 旋转 * 位置)矩阵组合的工作原理,您会发现,例如,X 中的镜像需要反转缩放的第一个分量,但也需要反转围绕 X 轴的所有旋转。
显然(我在这里推测)镜像模式在应用时会做两件事。 (1) 它激活 PRS 控制器内部的特殊情况处理,这样,当将 scale/rotation/transform 子控制器值组合成矩阵时,它会翻转一些坐标而不进行真正的矩阵组合。例如,X 方向的镜像反转变换矩阵前三行中每一行的第一个坐标,否则 PRS 控制器期望预镜像旋转值作为输入。 (2) 它翻转比例子控制器值的组件。例如,X 中的镜像会反转第一个坐标。但旋转子控制器不受影响。
所有这一切的结果是您在向 MaxScript 请求转换部分时获得了不正确的 maxtrix 合成。当直接组合 position/rotation/scale 子控制器值时,您也会得到不正确的组合。
您需要的是一种更好的方法来分解 position/rotation/scale 组件中的最终(正确)转换。这是基于所示算法的 MaxScript here。它returns 是一个包含ScaleMatrix、RotationMatrix、PositionMatrix 的数组,因此可以用(result[1] * result[2]) * result[3]
再次获得原始变换。将 $.transform
作为输入传递。
fn matrixDecompose t =
(
trans = t.pos
trn = ( matrix3 [1,0,0] [0,1,0] [0,0,1] trans )
scaleX = length [ t[1][1], t[2][1], t[3][1] ]
scaleY = length [ t[1][2], t[2][2], t[3][2] ]
scalez = length [ t[1][3], t[2][3], t[3][3] ]
tempZ = cross t[1] t[2]
if( (dot tempZ t[3]) < 0 ) then
(
scaleX = -scaleX
t[1] = -t[1]
)
scl = ( matrix3 [scaleX,0,0] [0,scaleY,0] [0,0,scaleZ] [0,0,0] )
t[1] = normalize t[1]
t[2] = normalize t[2]
t[3] = normalize t[3]
rot = t.rotationPart as matrix3
#( scl, rot, trn )
)
我正在尝试修复具有负比例的动画模型(我知道这可能是个坏主意)。在查看 max 脚本中的变换时,我注意到一些有趣的事情,这可能与 3ds max 中左手坐标系的内部使用有关。我将节点的变换与节点的 PRS 值进行了比较:我的期望是通过乘以 PRS 值,我也应该得到变换。但是,如果对象被旋转或镜像,则情况并非如此,请参阅:
$.transform =
row1 [0.866,-0.500,0.000]
row2 [-0.500,-0.866,0.000]
row3 [0.000,0.000,1.000]
row4 [13.000,-3.000,1.000]
...scale * ...rotation * ...pos =
row1 [-0.866,0.500,0.000]
row2 [-0.500,-0.866,0.000]
row3 [0.000,0.000,-1.000]
row4 [13.000,-3.000,1.000]
...transform.scalepart * ...transform.rotationpart * ...transform.translationpart =
row1 [-0.866,0.500,0.000]
row2 [0.500,0.866,0.000]
row3 [0.000,0.000,-1.000]
row4 [13.000,-3.000,1.000]
任何想法,为什么这些转换不一样?我试图了解 3ds max 的幕后工作原理。非常感谢您的任何见解!
这里发生了一些事情。
首先,MaxScript $.transform.scalepart
和 $.transform.rotationpart
似乎有问题并且不支持反向缩放。这些可能与 this post 上的第一个答案类似地实现,它总是给出正比例坐标,而负比例矩阵的答案是错误的。
其次,当请求 $.scale.controller.value
和 $.rotation.controller.value
时,旋转部分也有问题,returns 与镜像之前的值相同,而比例 returns 是镜像的价值。如果您考虑(缩放 * 旋转 * 位置)矩阵组合的工作原理,您会发现,例如,X 中的镜像需要反转缩放的第一个分量,但也需要反转围绕 X 轴的所有旋转。
显然(我在这里推测)镜像模式在应用时会做两件事。 (1) 它激活 PRS 控制器内部的特殊情况处理,这样,当将 scale/rotation/transform 子控制器值组合成矩阵时,它会翻转一些坐标而不进行真正的矩阵组合。例如,X 方向的镜像反转变换矩阵前三行中每一行的第一个坐标,否则 PRS 控制器期望预镜像旋转值作为输入。 (2) 它翻转比例子控制器值的组件。例如,X 中的镜像会反转第一个坐标。但旋转子控制器不受影响。
所有这一切的结果是您在向 MaxScript 请求转换部分时获得了不正确的 maxtrix 合成。当直接组合 position/rotation/scale 子控制器值时,您也会得到不正确的组合。
您需要的是一种更好的方法来分解 position/rotation/scale 组件中的最终(正确)转换。这是基于所示算法的 MaxScript here。它returns 是一个包含ScaleMatrix、RotationMatrix、PositionMatrix 的数组,因此可以用(result[1] * result[2]) * result[3]
再次获得原始变换。将 $.transform
作为输入传递。
fn matrixDecompose t =
(
trans = t.pos
trn = ( matrix3 [1,0,0] [0,1,0] [0,0,1] trans )
scaleX = length [ t[1][1], t[2][1], t[3][1] ]
scaleY = length [ t[1][2], t[2][2], t[3][2] ]
scalez = length [ t[1][3], t[2][3], t[3][3] ]
tempZ = cross t[1] t[2]
if( (dot tempZ t[3]) < 0 ) then
(
scaleX = -scaleX
t[1] = -t[1]
)
scl = ( matrix3 [scaleX,0,0] [0,scaleY,0] [0,0,scaleZ] [0,0,0] )
t[1] = normalize t[1]
t[2] = normalize t[2]
t[3] = normalize t[3]
rot = t.rotationPart as matrix3
#( scl, rot, trn )
)