在IK链中实现拉伸效果之早古方法
程序员文章站
2022-03-19 14:59:40
...
在构建身体骨骼绑定的时候,手脚腰腹部都对绑定有拉伸效果的需求,在此总结一个很古早的拉伸实现方法,利用骨骼的单轴向的缩放实现IK链的拉伸效果。
原理
在IK链中,我们通过对ik曲线的控制来控制骨骼的运动来实现,所以我们需要做的就是在曲线伸缩的同时使骨骼也同步伸缩,此时我们就可以利用曲线的长度的变化来确认骨骼缩放的倍数,只需运用如下的数学公式:
joint scale = current curve length / original curve length
实现
获取曲线的长度信息
选择曲线并运行下列mel语句,给曲线添加一个节点 curveInfo:
arclen -ch 1;
然后选择此节点,打开属性编辑器,就可以看见 Arc Length 属性;
设置骨骼的缩放
在这里有两种方法可以实现:
1.写表达式:
假设缩放的轴向为X轴,并已知曲线原始长度为18.432
//Curve Scale Expression
float $scale = curveInfo1.arcLength / 18.432;
back_1_joint.scaleX = $scale;
back_2_joint.scaleX = $scale;
back_3_joint.scaleX = $scale;
//...........
//back_X_joint.scaleX = $scale;
2.直接使用乘除节点:
创建一个multiplyDivide节点,并做如下图链接
然后把曲线的原始长度填写在multiplyDivide节点的Input 2属性里,并将Operation属性修改为Divide,如下图所示
就此完成IK链伸缩功能!
ps:同时设置其他两个轴向的缩放可以实现在伸缩的同时又有体积的变化,如下图
利用指数函数就可以实现我们需要的体积变化,表达式实现如下
back_1_joint.scaleZ = pow($scale,1);
back_1_joint.scaleY = pow($scale,1);
back_2_joint.scaleZ = pow($scale,1.3);
back_2_joint.scaleY = pow($scale,1.3);
back_3_joint.scaleZ = pow($scale,1.5);
back_3_joint.scaleY = pow($scale,1.5);
back_4_joint.scaleZ = pow($scale,1.3);
back_4_joint.scaleY = pow($scale,1.3);
back_5_joint.scaleZ = pow($scale,1);
back_5_joint.scaleY = pow($scale,1);
//................
//...............
(1,1.3,1.5,1.3,1)所实现的变化曲线可能不够完美而且不方便调整,可以考虑利用获取非线性动画曲线的数值来实现这个功能。
推荐阅读