【问题标题】:Maxscript: Compose TransformationsMaxscript:撰写转换
【发布时间】:2018-09-14 15:35:33
【问题描述】:

我正在尝试修复具有负比例的动画模型(我知道,这可能是个坏主意)。在查看 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 如何在幕后工作。非常感谢您的任何见解!

【问题讨论】:

    标签: transform 3dsmax maxscript


    【解决方案1】:

    这里发生了一些事情。

    首先,MaxScript $.transform.scalepart$.transform.rotationpart 似乎存在错误并且不支持反向缩放。这些可能与this post 上的第一个答案类似,它总是给出正比例坐标,而对于负比例矩阵则给出错误答案。

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

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

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

    您需要一种更好的方法来分解位置/旋转/缩放组件中的最终(正确)变换。这是一个基于here 所示算法的 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 )
    )
    

    【讨论】:

    • 哇,很棒的答案!非常感谢!
    • Michaelson 知道他的东西,他是前 3dsmax 开发人员。
    猜你喜欢
    • 2021-04-06
    • 2011-11-23
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    相关资源
    最近更新 更多