~~完美动力作品~~
1. 首先看看效果,嘴唇的粘念效果是增加唇部真实感的好方法,
虽然不是时刻发生。动画师有很多办法做出真实感觉的唇部
动画,但是这里做的唇部的粘念的装配是不同于传统的,和
非动力学的,自动粘念,非常简单,而且一劳永逸的方法。其
关键是找上唇,和下唇部中线,这里将使用一个非常cool的 rivet
脚本来解决这个问题。(rivet)

2.一个脸部的装配,一般包含了一个控制下颚运动的joint,和有很
多的融合变形(在这个练习里面,这个些融合变形并不重要,但是
一个非常好的下颚的权重却非常的重要)。

3.开始的时候,要稍微的打开下颚的joint , 我们将要固定上嘴唇和下
嘴唇的顶部的边(这里将要使用一个叫rivet的mel脚本来做)确定
选择你选择了唇的最外面的边,这些连续的边构成了唇的轮廓。
并确定你选择的边没有直接连接到任何你要计划做粘性唇的点
只要选择不会直接影响你要做为粘念嘴唇的点的边。
选择上唇和下唇的边缘的,一对边,用rivet来创建locator.每对边依
次创建,(当唇张开的时候,这些被唇边缘约束的locator形成了一
条上唇和下唇的中剖线)。

4.删除rivets的aim约束,并把rivets的locator的方向约束到上颚和下颚
的joint上,这也许要花半个小时来做,我们可以使用一个简单的
循环mel来做这个,几秒钟完成,而且不容易出错。(使用的时候
注意你的joint命名和mel中一致)。
// sticky lips -- after all the rivets have been applied to
// form the center line of the lips, use some simple
// MEL scripting to automate an otherwise tedious rigging task:
// select the all the rivet locators first, and then run this code:
string $constraint_objs[] = { "jaw_lower", "jaw_upper" };
string $selected_rivets[] = `ls -sl`;
for($each in $selected_rivets)
{ delete `listRelatives -type aimConstraint $each`;
select -r $constraint_objs;
select -add $each;
orientConstraint -offset 0 0 0 -weight 1 ;
scale -r 0.2 0.2 0.2 $each;
}
下面开始,从原始的模型复制出一个新的模型,重命名为“sticky_lips_head”,用原始的有下颚joint的模型来blendshape驱动这个新
的 sticky_lips_head模型。
在这个sticky_lips_head模型上选择你要做粘念效果的点,

注意:我们使用原始的有下颚joint的模型来blendshape驱动这个新sticky_lips_head模型的目的是:可以稍微的打开嘴,为了可以容易的选择这些点,仅此而已。
稍微旋转原始下颚joint打开sticky_lips_head模型的嘴,选择好你要做粘念效果的点,
把这些点做成选择集,以便我们以后选择它们。
把点的选择,转换成面的选择,使用命令:Edit Polygons->Selection->Convert Selection To Face
然后使用分离显示命令:Show->Isolate Select->View Selection
和 Show->Isolate Select->Auto Load New Objects
选择上唇和下唇要做粘念的点,每条边是取3个点做成cluster。

记得嘛,开始我们说过,如果你做一个有下颚joint的模型来blendshape控制另一个模型,是为了暂时的打开嘴,方便选择用,在做下一步前你必须确认你完全闭合了嘴吧,然后删除它的blendshape节点, 注意不要删除了全部历史使用edit blendshapere remove 来删除。
把每个cluster给它最近的rivet的locator做子物体,那么所有的locator控制的点将都会跟随rivet的locator移动,
注意:这时做父子物体操作的时候maye会有一条警告:
告诉cluster使用组来保护它的0.0.0的位置,这是正常的。
建立一个locator命名为“skicky_lips”并添加一个浮点属性,最小为0,最大为1,这个属性命名为“skicky_lips”这个控制最后将会作为最终的属性控制器。
现在从原始的有下颚joint模型复制出一个干净的没有历史的模型
命名这个模型为"output_head"把有下颚joint的原始模型作为他的
blendshape目标变形模型,设置这个blendshape节点属性为1.
这时当你旋转下颚jiont时,这个"output_head"模型就可以和真的有帮定下颚joint一样变形。
这时场景里面有3个模型了,一个做了rivet,一个做了cluster,
最后这个为最终的效果输出模型,做这个几个模型的原因是
把rivet约束和cluster变形独立出来,这样可以消除玛雅的从属
图表的循环错误和警告。
下面是关键的地方,我们将创建一系列单独的世界空间(blendshape里面的worldspace选项)的blendshape,变形顺序是节点流的最上段,blendshape 节点放在tweak节点的后面。
从"sticky_lip"模型的每一个做cluster的点做一个blendshape目标型驱动"output_head"模型,这样做是为了使用清楚的曲线驱动
每个点来表现粘念嘴的效果。
这个时候再创建一个单独的locator,命名为"stickyLipsControl"添加一个属性列表,把它连接到每一个点的blendshape的权重属性,使用开始创建“skicky_lips"的skicky_lips"属性来驱动它们。呵呵,不可思议这样一来有几十个blendshape,估计有人会说这么愚蠢的方法,呵呵,作者解释说这其实是非常简单的,看似复杂而已,因为有mel嘛!
选择我们开始做的点的选择集,然后执行下面的mel,
string $sourceModel = "sticky_lips_head";
string $targetModel = "output_head";
string $controller = "stickyLipsControl";
string $selected[] = `ls -sl -fl`;
$selected = sort( $selected );
for ( $vert in $selected )
{
string $targetVert = `substitute
$sourceModel $vert $targetModel`;
string $attrName = `substitute "^.*\\[" $vert ""`;
$attrName = "SL_"+`substitute "\\]$" $attrName ""` ;
addAttr -ln $attrName -at double -min 0 -max 1 -dv 0 $controller;
setAttr -e -keyable true ($controller+"."+$attrName);
string $blendShapeNode[]; select -r $vert $targetVert ;
$blendShapeNode = `blendShape -tc 0 -o world -name ($attrName
+"_BS"

`;
connectAttr ($controller+"."+$attrName) ($blendShapeNode[0]+".w[0]"

;
}

打开驱动关键帧面板,
加载“ skicky_lips "的“skicky_lips”属性为驱动者,
加载"stickyLipsControl"的所有blendshape属性为被驱动者,
设置当“skicky_lips”为0时,"stickyLipsControl"的所有blendshape属性为0,
设置当“skicky_lips”为10时,"stickyLipsControl"的所有blendshape属性为1,
打开驱动关键帧动画曲线图表,在第3帧,和第8帧添加关键帧,
然后手动整理关键帧,调整点的blendshape属性,调节出如图的
形状,
第三帧的形状如图:

第八帧的形状如图:

驱动关键帧曲线如图:

原作者:Erick Miller
翻译,整理,场景文件制作: 牛搞
ricvet mel 和场景下载l
http://bbs.cgpower.com.cn/user/download/29584/mel_and_scene.rar