Last active
September 30, 2023 03:00
-
-
Save yohawing/3f5eb61dffe7713e82bb6acbe46d1b8a to your computer and use it in GitHub Desktop.
[maya] Make Stretchy Spline IK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import maya.cmds as cmds | |
| # StartJointからEndJointに関連付けられているJointをListで取得 | |
| # Childが一つの想定なので骨が複数あるとおかしくなるかも。 | |
| def get_all_spline_joints(joint_list, parent_joint, last_joint): | |
| child = cmds.listRelatives(parent_joint, children=True, type="joint") | |
| joint_list.append(child[0]) | |
| if child and last_joint not in child: | |
| get_all_spline_joints(joint_list, child[0], last_joint) | |
| else: | |
| return joint_list | |
| # StretchySplineIKを自動作成するスクリプト | |
| def create_stretchy_spline_ik(start_joint, end_joint, ik_name): | |
| spline_joints = [start_joint] | |
| get_all_spline_joints(spline_joints, start_joint, end_joint) | |
| # Spline IKの作成 | |
| ik_handle, effector, curve = cmds.ikHandle( | |
| sj=start_joint, | |
| ee=end_joint, | |
| sol='ikSplineSolver', | |
| createCurve=True, | |
| numSpans=2, | |
| n=ik_name) | |
| curve_info = cmds.arclen(curve, ch=True) | |
| # ジョイントチェーンの初期長さを取得 | |
| original_curve_length = cmds.getAttr(curve_info + ".arcLength") | |
| # スケールノードを作成 | |
| mult_node = cmds.shadingNode('multiplyDivide', asUtility=True, n=ik_name + "_multDiv") | |
| cmds.setAttr(mult_node + ".operation", 2) # Divide | |
| cmds.setAttr(mult_node + ".input2X", original_curve_length) | |
| # ノードを接続 | |
| cmds.connectAttr(curve_info + ".arcLength", mult_node + ".input1X") | |
| for jnt in spline_joints: | |
| cmds.connectAttr(mult_node + ".outputX", jnt + ".scaleX") | |
| return ik_handle, curve | |
| # CurveのControlPointにClusterを自動作成するスクリプト | |
| def apply_clusters_to_curve(curve_name): | |
| curveCVs = cmds.ls('{0}.cv[:]'.format(curve_name), fl=True) | |
| for cv in curveCVs: | |
| cmds.cluster(cv) | |
| # How To Use | |
| selected_joints = cmds.ls(sl=True, flatten=True, type="joint") | |
| start_joint = selected_joints[0] | |
| end_joint = selected_joints[1] | |
| ik_name = "{0}_splineIK".format(end_joint.split("_")[-1]) # ex: Character_LeftArm | |
| ik_handle, curve = create_stretchy_spline_ik(start_joint, end_joint, ik_name) | |
| apply_clusters_to_curve(curve) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Unityに持っていったときにSegmentScaleCompensateの問題が出る。
具体的には、親のスケールを打ち消すMatrixを子に渡すというMayaのデフォルトの挙動がUnityだと再現しない。
上で実現しているリグはScaleベースのため階層構造におけるスケールの解決方法が違うため起きる問題
いっぽう↑のサンプルはX軸方向への変化量しか持たないSplineIKを想定しているため、
Scaleを使わない方法でStreachySplineIKを実現する方法にしたほうがよい。
スケールのコネクションを外して、translateXにX軸スケールの掛け算をして同じような挙動を再現できる。