马上注册CG织梦网,结交更多CG好友,下载更多CG素材,让你轻松学习。
您需要 登录 才可以下载或查看,没有帐号?立即注册
QQ登录
x
Maya单骨骼FK/IK无缝切换绑定技术教程
本教程假设你已经创建好了这样一套简单的骨骼:
一个名为 L_shoulder_JNT 的骨点
一个名为 L_elbow_JNT 的骨点
一个名为 L_armIk_CON 的手臂控制器 (采用点约束对IK手柄进行控制)
一个名为 L_armPole_CON 的极向量控制器
你也可以下载我做好的 Maya (6.0以上版本) 源文件: armRig_001.ma,下载:.
本教程的目的在于通过对一个简单手臂的绑定来详细阐述FK/IK无缝切换的实现方法,即在进行FK/IK切换的时候不会出现骨骼自己摆动的情况,这对于动画师给角色摆Pose将非常有用(尤其在K动画方面)。切记,此方法只使用一套骨骼。
在本案例中,手臂IK和极向量控制器用Nurbs曲线来制作,但你也可以按自己的喜好用别的物体来代替。当然也可以使用我的源文件: armRig_001.ma.
请记住一定要在一个绝对平面上创骨骼。 肘部弯曲正常,而且不带扭曲(即骨骼不能带旋转值)!
1) 用MEL来绑定:
现在我们已经有了一套简单的骨骼和几个控制器, 下一步来进行绑定. 以下代码用于优化该场景中的骨骼和控制器使其适于做FK/IK切换(其实就是用代码来完成一些手工操作):
// 1) 锁上肘部骨点的Y、Z旋转(这是为了使其像真实肘部那样运动)。
setAttr "L_elbow_JNT.jointTypeY" 0;
//取消骨点L_elbow_JNT的Y轴自由角功能(对应骨骼属性栏里的Degrees of Freedom)
setAttr "L_elbow_JNT.jointTypeZ" 0;
//取消骨点L_elbow_JNT的Z轴自由角功能(对应骨骼属性栏里的Degrees of Freedom)
setAttr -lock true -keyable false "L_elbow_JNT.ry";
//锁上骨点L_elbow_JNT的Y轴旋转,并使其不可K帧
setAttr -lock true -keyable false "L_elbow_JNT.rz";
//锁上骨点L_elbow_JNT的Z轴旋转,并使其不可K帧
//
// 2) 创建IK手柄。
ikHandle -sol ikRPsolver -sj L_shoulder_JNT -ee L_wrist_JNT -n L_arm_IK;
//从骨点L_shoulder_JNT至骨点L_wrist_JNT创建一名为L_arm_IK的IK手柄
//
// 3) 设置手臂IK控制器在世界空间 (默认值不是0,但我们不用担心)。
move -rpr 0 0 0 L_armIk_CON;
//将控制器L_armIk_CON移至世界坐标原点
makeIdentity -a 1 -r 1 -t 1 -s 1 L_armIk_CON;
//对其进行Freeze
vector $wristPos = `xform -query -a -worldSpace -rp L_wrist_JNT`;
//用xform命令提取骨点L_wrist_JNT的世界坐标值,赋予变量$wristPos
move -worldSpace -a ($wristPos.x) ($wristPos.y) ($wristPos.z) L_armIk_CON;
//将控制器L_armIk_CON移至骨点L_wrist_JNT的位置
makeIdentity -a 1 -r 1 -t 1 -s 1 L_armIk_CON;
//对控制器L_armIk_CON进行Freeze
pointConstraint -w 1 -o 0 0 0 L_armIk_CON L_arm_IK;
//控制器L_armIk_CON对IK手柄L_arm_IK进行点约束
//
// 4) 为手臂极向量创建locator进行定位
// (当由FK切换至IK的时候我们用locator来对极向量定位)。
spaceLocator -p 0 0 0 -n "L_armPoleDefault_LOC";
//创建一名为L_armPoleDefault_LOC的locator
vector $elbowPos = `xform -query -a -worldSpace -rp L_elbow_JNT`;
//用xform命令提取骨点L_elbow_JNT的世界坐标值,赋予变量$elbowPos
move -a ($elbowPos.x) ($elbowPos.y) ($elbowPos.z) L_armPoleDefault_LOC;
//将L_armPoleDefault_LOC移至骨点L_elbow_JNT的位置
//
// 5) 将刚创建的locator作为肩膀骨点的子物体,并将其放置在肘部的后面。
parent L_armPoleDefault_LOC L_shoulder_JNT;
//将L_armPoleDefault_LOC P给骨点L_shoulder_JNT
move -r -ws -wd 0 0 -10 "L_armPoleDefault_LOC";
//将L_armPoleDefault_LOC延Z轴反方向移动十个单位
setAttr "L_armPoleDefault_LOC.visibility" 0;
//将L_armPoleDefault_LOC隐藏
//
// 6) 匹配极向量和locator的位置。
pointConstraint -w 1 -o 0 0 0 L_armPoleDefault_LOC L_armPole_CON;
//L_armPoleDefault_LOC对控制器L_armPole_CON进行点约束
delete L_armPole_CON_pointConstraint1;
//删除这个点约束
makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 "L_armPole_CON";
//对控制器L_armPole_CON进行Freeze
//
// 7) 对IK手柄L_arm_IK进行极向量约束。
poleVectorConstraint -w 1 L_armPole_CON L_arm_IK;
//控制器L_armPole_CON对IK手柄L_arm_IK创建极向量约束
//
// 8 ) 连接IK手柄的显示隐藏属性至腕部IK控制器的自定义属性
addAttr -ln enableIk -at bool -k on -dv 0 L_armIk_CON;
//给控制器L_armIk_CON添加名为enableIk的bool类型属性,并设置默认值为0
connectAttr -f L_armIk_CON.enableIk L_arm_IK.ikBlend;
//将控制器L_armIk_CON的enableIk属性连接至IK手柄L_arm_IK的ikBlend属性
connectAttr -f L_armIk_CON.enableIk L_arm_IK.visibility;
//将控制器L_armIk_CON的enableIk属性连接至IK手柄L_arm_IK的visibility属性
connectAttr -f L_armIk_CON.enableIk L_armIk_CON.visibility;
//将控制器L_armIk_CON的enableIk属性连接至自身的visibility属性
//
// 9) 将手臂默认设为FK方式。
setAttr "L_armIk_CON.enableIk" 0;
//设置控制器L_armIk_CON的enableIk属性值为0
2) IK/FK切换:
至此我们已经完成了绑定,可以进行切换的设置了。 如果一切顺利,腕部的IK控制器会消失不见。 这很正常,因为当前骨骼正处在FK状态。因此你可以通过旋转肩膀和肘部的骨点让其运动。
整个手臂的绑定仅需一套骨骼即可实现,并且同时存在FK和IK。技巧在于采用一个locator作为肩膀骨点L_shoulder_JNT的子物体,从而充当一个定位器,每次切换到IK时,将控制器L_armPole_CON吸附到locator上即可达到无缝的目的。
这样做的一个好处在于locator能永远处在正确的位置来帮助定位,从而避免了切换时骨骼自己摆动的问题。
另一个好处就是动画师不必再为切换至IK时寻找极向量控制器而烦恼,因为它会自始至终停留在切换前的位置。
当你想切换至IK时,使用这个脚本: IkFk_switch_002.mel,下载:。你可以将其载入(source)脚本编辑器,或者复制/粘贴进去,做成一个按钮。要运行,仅需执行:
IkFk_switch( "", "L_", "arm" );
该函数自身是一个包含3个参数的命令。第一个是命名空间(除非该绑定是通过参考方式导入,否则保持默认为””),第二个参数是手臂的左右位置 (填”L_” 或 “R_”),最后一个指的是四肢(”arm” 或者 “leg”,本案例中为arm)。代码中包含详细的注释,想了解原理的朋友可以拿来研究一下。
你可以看到无论如何移动、旋转骨骼,当切换时,依然能保持原位。
想切换回FK,仅需用同样的参数执行上述命令。 |