【Maya绑定】三点式IK骨架的比例拉伸

您所在的位置:网站首页 mayaik控制器怎么绑定 【Maya绑定】三点式IK骨架的比例拉伸

【Maya绑定】三点式IK骨架的比例拉伸

2024-06-29 01:57| 来源: 网络整理| 查看: 265

前言

原理之前在这篇文档讲过,纯属于自嗨产物,大概只有自己能看得懂写了啥。然后根据这个思路实现。这篇主要目的就是复习下节点编辑器。maya节点编辑器的手感真的稀烂。

这个系列都是挖的国外的某个教程,不太适合我这种彩笔,操作真的飞快。 代码实现

我还是觉得代码最清晰,先放代码

def add_ik_stretch(side, part, ik_chain, base_ctrl, local_ctrl, world_ctrl,primary_axis): base_name = side +'_' + part # start to end distance limb_dist = cmds.createNode('distanceBetween', name=base_name+'_DIST') # cinditon node limb_cnd = cmds.createNode('condition', name=base_name+'CND') # allocate locater, get transform node start_LOC = cmds.spaceLocator(name=base_name+'_start_LOC')[0] end_LOC = cmds.spaceLocator(name=base_name+'_end_LOC')[0] stretch_mdn = cmds.createNode('multiplyDivide', name=base_name+'_stretch_MDN') # calculate section length length_a = distance_between(ik_chain[0],ik_chain[1]) length_b = distance_between(ik_chain[1], ik_chain[2]) total_length = length_b + length_a # measure start-end desired direct distance # move the loc first cmds.pointConstraint(base_ctrl, start_LOC, maintainOffset=False) cmds.pointConstraint(local_ctrl, end_LOC, maintainOffset=False) connectAttr(start_LOC, 'worldMatrix[0]', limb_dist, 'inMatrix1') connectAttr(end_LOC, 'worldMatrix[0]', limb_dist, 'inMatrix2') # length ratio connectAttr(limb_dist, 'distance', stretch_mdn,'input1X') cmds.setAttr(stretch_mdn+'.input2X', total_length)#set devision cmds.setAttr(stretch_mdn+'.operation', 2) connectAttr(limb_dist,'distance',limb_cnd,'firstTerm') connectAttr(stretch_mdn,'outputX', limb_cnd,'colorIfTrueR') cmds.setAttr(limb_cnd+'.secondTerm', total_length) cmds.setAttr(limb_cnd+'.operation',3) # switch stretch cmds.addAtter(world_ctrl, attributeType='double', min=0, max=1, defaultValue=1, keyable=True, longName='stretch') up_name = 'up' + part.title() lo_name = 'lo' + part.title() cmds.addAtter(world_ctrl, attributeType='double', defaultValue=1, keyable=True, longName='up_name') cmds.addAtter(world_ctrl, attributeType='double', defaultValue=1, keyable=True, longName='lo_name') stretch_bta = cmds.createNode('blendTwoAttr', name = base_name+'_BTA') cmds.setAttr(stretch_bta+'.input[0]', 1) connectAttr(limb_cnd,'outColorR',stretch_bta,'input[1]') connectAttr(world_ctrl,'stretch',stretch_bta,'attributesBlender') up_pma = cmds.createNode('plusMinusAverage', name=up_name+'_PMA') lo_pma = cmds.createNode('plusMinusAverage', name=lo_name + '_PMA') connectAttr(world_ctrl, up_name, up_pma, 'input1D[0]') connectAttr(world_ctrl, lo_name, lo_pma, 'input1D[0]') connectAttr(stretch_bta, 'output', up_pma, 'input1D[1]') connectAttr(stretch_bta, 'output', lo_pma, 'input1D[1]') cmds.setAttr(up_pma+'.input1D[2]', -1) cmds.setAttr(lo_pma + '.input1D[2]', -1) connectAttr(up_pma,'output1D', ik_chain[0],'scale'+primary_axis[-1]) connectAttr(lo_pma,'output1D', ik_chain[1],'scale'+primary_axis[-1]) return_dict = {'measure_locs': [start_LOC, end_LOC], 'total_length': total_length, 'mdn': stretch_mdn, 'cnd': limb_cnd} return return_dict 过程解释 获取effectors变换信息

我们首先创建两个个定位器,将定位器移动到start以及end effector的位置。 start_effector位置事先被base_ctrl(start_effector)记录了 在这里插入图片描述 同理end_effector被local_ctrl记录了,这个local_ctrl的作用是控制手,不过这里没有增加手的关节。 在这里插入图片描述

移动locator到effectors cmds.pointConstraint(base_ctrl, start_LOC, maintainOffset=False) cmds.pointConstraint(local_ctrl, end_LOC, maintainOffset=False) 计算一些距离数值 得到effector之间的距离,effector的距离是我们期望将原始的IKhandeler拉长的target,这个数字比较关键limb_dist.distance 在这里插入图片描述 # start to end distance limb_dist = cmds.createNode('distanceBetween', name=base_name+'_DIST') ··· connectAttr(start_LOC, 'worldMatrix[0]', limb_dist, 'inMatrix1') connectAttr(end_LOC, 'worldMatrix[0]', limb_dist, 'inMatrix2')

模型上臂和下臂的距离和他们的总和total_length

length_a = distance_between(ik_chain[0],ik_chain[1]) length_b = distance_between(ik_chain[1], ik_chain[2]) total_length = length_b + length_a 获得拉伸stretch比例

tips:下面的函数connectAttr()是我自己重写的cmds的方法,作用都是一样的

stretch_mdn = cmds.createNode('multiplyDivide', name=base_name+'_stretch_MDN') ··· # length ratio connectAttr(limb_dist, 'distance', stretch_mdn,'input1X') cmds.setAttr(stretch_mdn+'.input2X', total_length)#set devision cmds.setAttr(stretch_mdn+'.operation', 2)

在这里插入图片描述 是加上就是stretch ratio = effectors的距离/模型手臂长,这个部分用了’multiplyDivide’这个节点完成。就很麻烦,要是要实现实时计算就必须用节点,除非是一直固定不变的值,比如模型手臂长这种constant我们可以离线计算

stretch比例的条件分支切换 # cinditon node limb_cnd = cmds.createNode('condition', name=base_name+'CND') ··· connectAttr(limb_dist,'distance',limb_cnd,'firstTerm') connectAttr(stretch_mdn,'outputX', limb_cnd,'colorIfTrueR') cmds.setAttr(limb_cnd+'.secondTerm', total_length) cmds.setAttr(limb_cnd+'.operation',3)

这个道理是: effectors距离>=模型手臂总长时,启用之前计算的strech ratio,否则就是1 在这里插入图片描述

为end effctor添加几个属性

我们这里添加新属性是在local_ctrl的父控制器world_ctrl上,这俩玩意的pivot世界位置是一样的

# switch stretch cmds.addAtter(world_ctrl, attributeType='double', min=0, max=1, defaultValue=1, keyable=True, longName='stretch') up_name = 'up' + part.title() lo_name = 'lo' + part.title() cmds.addAtter(world_ctrl, attributeType='double', defaultValue=1, keyable=True, longName='up_name') cmds.addAtter(world_ctrl, attributeType='double', defaultValue=1, keyable=True, longName='lo_name')

在这里插入图片描述

stretch:IK整体拉伸还是不拉伸的混合比例up Arm: 上臂的拉伸程度因子lo Arm:下臂同理 实现关节拉伸 stretch_bta = cmds.createNode('blendTwoAttr', name = base_name+'_BTA') cmds.setAttr(stretch_bta+'.input[0]', 1) connectAttr(limb_cnd,'outColorR',stretch_bta,'input[1]') connectAttr(world_ctrl,'stretch',stretch_bta,'attributesBlender')

在这里插入图片描述

一个坑点:纯节点编辑器下,BTA节点的input都是要激活的,不激活不能输入constant进去。input[0]=1代表world_ctrlde stretch系数为0,采取不变措施 -在这里插入图片描述 获得部件的拉伸以及实现上下骨架缩放 up_pma = cmds.createNode('plusMinusAverage', name=up_name+'_PMA') lo_pma = cmds.createNode('plusMinusAverage', name=lo_name + '_PMA') connectAttr(world_ctrl, up_name, up_pma, 'input1D[0]') connectAttr(world_ctrl, lo_name, lo_pma, 'input1D[0]') connectAttr(stretch_bta, 'output', up_pma, 'input1D[1]') connectAttr(stretch_bta, 'output', lo_pma, 'input1D[1]') cmds.setAttr(up_pma+'.input1D[2]', -1) cmds.setAttr(lo_pma + '.input1D[2]', -1)

在这里插入图片描述 在这里插入图片描述 我们将已经按上图得到经过上下手臂的缩放因子衰减的stretch ratio用于IK关节的scale实现拉伸

connectAttr(up_pma,'output1D', ik_chain[0],'scale'+primary_axis[-1]) connectAttr(lo_pma,'output1D', ik_chain[1],'scale'+primary_axis[-1]) 结尾

以上就是大致的梳理过程还有很多细节没说,怕自己搞忘了,我也放上了节点编辑器版本的同功能mb文件,2020以上才能打开。 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3