编辑:我认为需要进一步澄清我正在尝试做的事情:
我在Maya中使用线变形器来控制扭曲。线变形器位于skinCluster的顶部。腕关节具有称为“扭曲”的额外角度属性,其与父关节相关联,该关节与手腕处于相同位置但保持肘关节的方向。 twist属性还连接到wire的dropoffLocatorTwist [1]属性。随着下降到100,线将前臂扭曲到无限远,并且关节仍然代表手腕和手的“姿势”。为了补偿skinCluster的过度旋转,我添加了一个重复的手腕层次结构,并将扭曲连接到旋转x。将重复层次结构的worldInverseMatrix连接到skinClusters bindPreMatrix属性可以有效地抵消手腕/手关节围绕肘骨轴的任何旋转。
现在我想进一步推动它。为了减少动画师的麻烦,我想删除额外的扭曲属性,并在关节本身的所有三个欧拉旋转值之间进行插值,以生成扭曲值。假设动画师直接在通道盒中设置值或仅仅相对旋转手腕,那么这些值可以轻松超过1000pi(以度为单位)。如果多边形网格足够密集,则线变形器可以容易地沿曲线扭转到该大小而没有任何伪影。问题是如何插入欧拉旋转以获得准确表示姿势和扭曲的单个角度值。我已经尝试使用曲线切线和腕部矩阵进行插值,方法是将每个euler值乘以矩阵中伴随行向量的euler旋转的切线的点积,但这不能完全发挥作用:
twist = rx *(矩阵的切线点1)+ ry *(矩阵的切点dot2)+ rz *(矩阵的切点dot3)
特别是,它不喜欢围绕Y轴的旋转。任何人都可以告诉我为什么会这样,以及如何正确地将欧拉旋转分解为扭转角度而不将扭曲约束到-pi< - > PI?
以前的要求:
我正在使用Maya线(曲线)变形器,并希望根据关节的欧拉旋转沿线的切线找到扭曲值。 Maya中的关节实际上是变换矩阵,但是以一种方式组合,用户可以输入最大浮点值作为任何欧拉旋转分量的度数值。我想取这些euler值(xyz),并以这样的方式组合它们,使得结果是轴角度旋转,其中轴是父矩阵的第一行(或线的切线),以及角度是围绕该轴的未绑定扭曲值,允许无限制的无翻转扭曲网格。问题是我找不到一种方法来插值x,y和z值,这样得到的角度只代表扭曲而没有别的。更简单地说,我想找到旋转的旋转器的'x'旋转值,其中x轴已经旋转,因此现在由'y','z'或所有三个组件之间的东西表示。有没有办法做到这一点,而不会失去x的值到一个较小但等价的值(ex 270 == 90,但我们想要270)?
答案 0 :(得分:3)
出于几个原因,这是一个非常重要的问题。
首先,矩阵的有效化可以产生许多无法正确插值的有效解决方案(如果你曾经在Maya图形编辑器中使用过空白的Euler滤镜,你知道我是什么意思)。有许多欧拉组合会产生给定的四元数或旋转矩阵。这意味着很难创建一个涵盖所有可能性的确定性解决方案。
其次,沿样条曲线的切线是矢量,但是您不能将矢量转换为矩阵,而不需要至少一个其他矢量来调整解。如果您熟悉maya的样条线IK以及为扭曲控制找到合适参考框架的复杂性,那么您将在此处看到相同的问题。
第三,也是最重要的目的:扭曲不能表示为三维空间中的旋转 - 在原始非欧几里德空间中的相对旋转曲线与一致的世界空间矩阵不对应。
如果你想使用曲折,你需要为你想要采样的曲线上的任何一点构建一个参考框架变换,你需要提供一些额外的信息来启动它。由于扭曲是相对的,因此您需要提供一个测量扭曲的起点。您会注意到所有用于沿曲线(运动路径,样条线IK)工作的本机maya工具都可以执行此操作。
创建矩阵非常简单。得到曲线正切的归一化向量,另一个用于向上向量'。向上矢量是您必须按照惯例定义的 - 这就是为什么所有使用曲线几何切线的maya工具都需要您选择或提供一个。如果您的曲线或多或少地位于XZ平面上,则可以使用世界向上矢量。如果它或多或少是垂直的,你可以使用X或Z.但是你得到它,你需要标准化向上矢量。你的一方'向量,最终矩阵的局部z轴,是切向量和侧向量的叉积。现在用切向和侧向量的交叉向量替换原始向上向量(否则将剪切矩阵)。最后,您需要曲线上您获得切线的点的世界空间位置。
现在像这样组装你的矩阵:
tangent.x tangent.y tangent.z 0
up.x up.y up.z 0
side.x side.y side.z 0
pos.x pos.y pos.z 1
在样本点处创建矩阵,其中局部x指向沿着曲线的切线,局部y或多或少指向原始向上矢量。在该矩阵的上下文中,扭转轴是局部X旋转。通过创建两个变换来控制扭曲更容易:使用此矩阵提供引用框架的父级和锁定在Y和Z上且仅在X上旋转的子级。来自切线框架的euler数字矩阵将不成为扭曲值 - 在这种情况下,twiat是一个完全相对概念,无法在单个矩阵中表达!
老实说,对于这种事情,使用内置工具可能更容易解决。我尝试使用运动路径将参考变换(关节或定位器)约束到曲线:动画>运动路径>附加到运动路径。这将完成您默认情况下的问题,您的X轴将是曲线的切线,Y将是世界上的。您可以将第二个关节设为第一个关节(局部为零' ed out),它的局部X将是扭转轴,您可以锁定其他两个轴并使用该值。
根据曲线的形状,您可以遇到两组不同的问题。如果向上矢量太靠近曲线方向,则解决方案不稳定。您可以通过选择不同的'来解决这个问题。矢量 - 对于垂直方向的曲线,您可以使用世界Z而不是世界Y.但是如果曲线在所有3维中循环,则没有数学上完整的解。
第二种策略是使用挤压几何体来提供“向上”。向量。如果沿原始曲线挤出线段,形成一条带有原始曲线的色带作为V = 0 isoparm,那么在沿曲线的任何点,您都可以使用U isoparm作为向上矢量。这样你就可以看到并在必要时纠正曲线上的扭曲,以避免翻转和摆动 - 否则在这种情况下会非常普遍。您可以使用pointOnSurface命令从表面抓取矢量。只要您的挤出历史记录已开启,您就可以对原始曲线进行编辑或设置动画,此解决方案仍然有效。
<强>更新强>
回应OP的进一步资料:
1)我不会太担心非常大的旋转。正如jooja指出的那样,在现实世界中,你需要建模并没有确切的含义 - 作为一个实际问题,只有非常特殊的目的角色才会需要它。手腕扭转的生物学限制小于+/- 90,肩部甚至更小。一个卡通人物可以超越它 - 但可能只是在扭曲的橡皮筋特效,而不是通用钻机的情况下。
2)Euler扭曲相对温和,即使对于3轴关节,只要它是第一个euler项(即XYZ旋转中的X)。如果您的手臂沿第一轴没有任何额外的关节方向布置,您可以通过跟踪第一个欧拉旋转来测量累积的扭曲(即,对于XYZ骨骼,链是一个直的长度的关节,沿着局部X布置零旋转)。在该配置中,通过简单表达式或基于节点的数学运算,可以很容易地添加存根骨骼以抵消扭曲旋转。您可以将扭转旋转分布在几个骨骼上以保持平滑(尽管使用现代双四元数皮肤,这不是问题,肩部和手腕周围的两三个骨头可能就足够了)。由于骨骼是短柱,因此他们不必进行复杂的三维数学运算来弄清楚扭曲:二头肌中的骨骼,例如,从肩部传播扭曲,只是旋转( - 。 5 * x)与肩部的x旋转相比。你皮肤到短骨,而不是主线骨骼,所以你得到主骨的YZ旋转,但是存根的调制X扭曲。
这种安排的主要缺点是你的绑定姿势也可能是你的归零姿势:你需要链条上的局部轴在“未扭曲”的情况下是连续的。状态 - 这意味着肩膀上的0,0,0是与世界X对齐的刚性T姿势,而不是大多数模型所获得的更轻松的姿势。动画师往往不喜欢那些零姿势(当然,如果你匹配现有的模型你不能做出选择)。但是,您可以使用dagPose提供备用零姿势,这些姿势实际上已归零。但是要把角色放回中立姿势。
答案 1 :(得分:0)
3D图形不是现实。在数学建模方面,现实真的很讨厌。在这种特殊情况下,完成的简化是表面模型Maya和几乎所有3D应用程序实际上不会在最后旋转任何东西。看到曲面要么完全离散(多边形,体素),要么将连续曲面简化为一堆离散控制点(样条曲线)。关于这一点的好处是它易于操作,因为一切都只是矢量移动,甚至是旋转。这是正确的,在整个过程中确实没有旋转,而一些节点知道旋转后的最终结果,并且节点和它发送的渲染器不知道节点做了什么。
所以你的要求是什么:
“对一个轴投射的总旋转总和是多少?”
而不是:
“如何正确地将欧拉旋转分解为扭曲角度而不将扭曲约束到-pi&lt; - &gt; pi?”
后者更难理解,数学定义不明确。后面问题的基本答案是你不能。前者的形式是更好的定义,但仍然像我今天走多远,知道我从床上开始,在床上结束了这一天。原因是你不知道我是如何介入的。所以真正的答案实际上是随着时间的积分,这取决于之前的所有帧,换句话说,你需要一个模拟来解决这个问题。您需要做出一些假设和角落约束来帮助您解决问题。
最琐碎的是,您可以强制一个轴始终沿着扭转方向指向。然后使该轴成为最后评估的Euler(实际上Maya不使用Euler角度,它使用Tait-Bryan角度)现在,扭曲可以简单地假设为这些单独通道的总和。为了使这个工作变得艰难,你的旋转顺序需要与你的方向相匹配,所以如果它沿着x然后旋转顺序需要是一个以字母x开头的例如xyz。
以上操作假设其他角度实际上没有旋转多次旋转。当然,对于动画师来说,只要它能够完全正确,它是否完全正确并不重要。并且即使您不计算扭曲,也可以任意旋转其他轴将导致奇怪的插值问题。
如果这还不够,那么因为我需要画画而有点乏味。基本上问题是Euler或Tait-Bryan角度不是插值事物的好模型,只是点方向。插值摆动如此直接是一个非常奇怪的混乱。其中一些有非常不直观的角落情况。
因此每个点不能超过360度才能返回原点。由于点是连接的,它似乎回弹开始。确实,所使用的矩阵计算最终具有类似的限制,但如果您查看单个点,则点移动是限制因素无关紧要。现在,如果你有一个点链,这样没有任何点“旋转”不超过45度(越少越好,越多点越平滑),那么你没有问题。但它仍然没有成功。为什么呢?
Bones通过称为聚类的加权向量移动移动点的位置,因为移动每个单独的点是很多工作。净效应是每个关节跨度只能绕&lt; 180度。这是由向量移动引起的。同样不是矩阵,尽管如果矢量移动可以做到这一点,矩阵将是一个限制因素。所以群集不能做到这一点,但有一种称为双四元数插值的东西,它可以用来代替普通的群集。它的作用是它实际存储2个深蹲并在它们之间进行插值。这可以通过一些噱头两种方式解决整个360度切片。距离无限扭曲还有很远的距离(假设有足够的扭曲点数),肯定会更难。
双四元插值可以做到这一点,所以也许你应该使用双quat皮肤。