Maxscript:组合转换

tka*_*zik 1 transform maxscript 3dsmax

我正在尝试修复带有负比例的动画模型(我知道这可能是个坏主意)。在查看 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] 
Run Code Online (Sandbox Code Playgroud)

任何想法,为什么这些转换不一样?我试图了解 3ds max 是如何工作的。非常感谢您的任何见解!

Mic*_*itt 5

这里正在发生一些事情。

首先,它出现了 MaxScript$.transform.scalepart并且$.transform.rotationpart有问题并且不支持反向缩放。这些可能与这篇文章的第一个答案类似,它总是给出正比例坐标,而对负比例矩阵给出错误答案。

其次,当请求$.scale.controller.value$.rotation.controller.value旋转部分也被窃听并返回与镜像前相同的值,而比例返回一个镜像值。如果您考虑一下 (scale * rotation * position) 矩阵组合的工作原理,您会发现,例如,X 中的镜子需要反转 scale 的第一个分量,还需要反转所有绕 X 轴的旋转。

显然(我在这里推测)镜像模式在应用时会做两件事。(1) 它激活 PRS 控制器内部的特殊情况处理,这样,当将缩放/旋转/变换子控制器值组合成矩阵时,它会翻转一些坐标而不进行真正的矩阵组合。例如,X 中的镜像反转变换矩阵前三行中每一行的第一个坐标,但除此之外,PRS 控制器期望预镜像的旋转值作为输入。(2) 它翻转 scale 子控制器值的组件。例如,X 方向的镜子反转第一个坐标。但旋转子控制器不受影响。

所有这一切的结果是,在向 MaxScript 询问变换部分时,您获得了不正确的 maxtrix 组合。当直接组合位置/旋转/缩放子控制器值时,您也会得到不正确的组合。

您需要的是一种更好的方法来分解位置/旋转/缩放组件中的最终(正确)变换。这是基于此处所示算法的 MaxScript 。它返回一个包含 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 )
)
Run Code Online (Sandbox Code Playgroud)