def addObjects(self): """Add all the objects needed to create the component.""" if self.settings["neutralRotation"]: t = transform.getTransformFromPos(self.guide.pos["root"]) else: t = self.guide.tra["root"] if self.settings["mirrorBehaviour"] and self.negate: scl = [1, 1, -1] else: scl = [1, 1, 1] t = transform.setMatrixScale(t, scl) self.ik_cns = primitive.addTransform(self.root, self.getName("ik_cns"), t) self.SDKctl = self.addCtl( self.ik_cns, "SDK_ctl", t, self.color_ik, "cube", w=self.settings["ctlSize"] * self.size * 1.35, h=self.settings["ctlSize"] * self.size * 0.75, d=self.settings["ctlSize"] * self.size * 0.75, tp=self.parentCtlTag) self.ctl = self.addCtl(self.SDKctl, "ctl", t, self.color_fk, "sphere", w=self.settings["ctlSize"] * self.size, h=self.settings["ctlSize"] * self.size, d=self.settings["ctlSize"] * self.size, tp=self.parentCtlTag) # we need to set the rotation order before lock any rotation axis if self.settings["k_ro"]: rotOderList = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] attribute.setRotOrder( self.ctl, rotOderList[self.settings["default_rotorder"]]) attribute.setRotOrder( self.SDKctl, rotOderList[self.settings["default_rotorder"]]) params = [ s for s in ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"] if self.settings["k_" + s] ] attribute.setKeyableAttributes(self.ctl, params) attribute.setKeyableAttributes(self.SDKctl, params) if self.settings["joint"]: self.jnt_pos.append([self.ctl, 0, None, self.settings["uniScale"]])
def addObjects(self): """Add all the objects needed to create the component.""" if self.settings["neutralRotation"]: t = transform.getTransformFromPos(self.guide.pos["root"]) else: t = self.guide.tra["root"] if self._needToMirror(): scl = [1, 1, 1] scl[0] = -1 if self.settings["mirrorAxisX"] else 1 scl[1] = -1 if self.settings["mirrorAxisY"] else 1 scl[2] = -1 if self.settings["mirrorAxisZ"] else 1 t = transform.setMatrixScale(t, scl) rx = self.settings["mirrorAxisX"] * math.pi ry = self.settings["mirrorAxisY"] * math.pi rz = self.settings["mirrorAxisZ"] * math.pi # t = pm.datatypes.TransformationMatrix(t) # t.addRotation((rx, ry, rz), 'XYZ', 'object') else: scl = [1, 1, 1] t = transform.setMatrixScale(t, scl) self.ik_cns = primitive.addTransform( self.root, self.getName("ik_cns"), t) self.ctl = self.addCtl(self.ik_cns, "ctl", t, self.color_ik, self.settings["icon"], w=self.settings["ctlSize"] * self.size, h=self.settings["ctlSize"] * self.size, d=self.settings["ctlSize"] * self.size, tp=self.parentCtlTag) # we need to set the rotation order before lock any rotation axis if self.settings["k_ro"]: rotOderList = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] attribute.setRotOrder( self.ctl, rotOderList[self.settings["default_rotorder"]]) params = [s for s in ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"] if self.settings["k_" + s]] ymt_util.setKeyableAttributesDontLockVisibility(self.ctl, params) if self.settings["joint"]: self.jnt_pos.append([self.ctl, 0, None, self.settings["uniScale"]])
def addObjects(self): """Add all the objects needed to create the component.""" if self.settings["neutralRotation"]: t = transform.getTransformFromPos(self.guide.pos["root"]) else: t = self.guide.tra["root"] if self.settings["mirrorBehaviour"] and self.negate: scl = [1, 1, -1] else: scl = [1, 1, 1] t = transform.setMatrixScale(t, scl) if self.settings["joint"] and self.settings["leafJoint"]: pm.displayInfo("Skipping ctl creation, just leaf joint") self.have_ctl = False else: self.have_ctl = True self.ik_cns = primitive.addTransform(self.root, self.getName("ik_cns"), t) self.ctl = self.addCtl(self.ik_cns, "ctl", t, self.color_ik, self.settings["icon"], w=self.settings["ctlSize"] * self.size, h=self.settings["ctlSize"] * self.size, d=self.settings["ctlSize"] * self.size, tp=self.parentCtlTag, guide_loc_ref="root") # we need to set the rotation order before lock any rotation axis if self.settings["k_ro"]: rotOderList = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] attribute.setRotOrder( self.ctl, rotOderList[self.settings["default_rotorder"]]) params = [ s for s in ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"] if self.settings["k_" + s] ] attribute.setKeyableAttributes(self.ctl, params) if self.settings["joint"]: # TODO WIP: add new attr for seeting leaf joint + not build objcts if self.settings["leafJoint"]: self.jnt_pos.append([t, 0, None, self.settings["uniScale"]]) else: self.jnt_pos.append( [self.ctl, 0, None, self.settings["uniScale"]])
def initialHierarchy(self): """Build the initial hierarchy of the rig. Create the rig model, the main properties, and a couple of base organisation nulls. Get the global size of the rig. """ mgear.log("Initial Hierarchy") # -------------------------------------------------- # Model self.model = primitive.addTransformFromPos(None, self.options["rig_name"]) attribute.lockAttribute(self.model) # -------------------------------------------------- # INFOS self.isRig_att = attribute.addAttribute(self.model, "is_rig", "bool", True) self.rigName_att = attribute.addAttribute(self.model, "rig_name", "string", self.options["rig_name"]) self.user_att = attribute.addAttribute(self.model, "user", "string", getpass.getuser()) self.isWip_att = attribute.addAttribute(self.model, "wip", "bool", self.options["mode"] != 0) self.date_att = attribute.addAttribute(self.model, "date", "string", str(datetime.datetime.now())) self.mayaVersion_att = attribute.addAttribute( self.model, "maya_version", "string", str(pm.mel.eval("getApplicationVersionAsFloat"))) self.gearVersion_att = attribute.addAttribute(self.model, "gear_version", "string", mgear.getVersion()) self.synoptic_att = attribute.addAttribute( self.model, "synoptic", "string", str(self.options["synoptic"])) self.comments_att = attribute.addAttribute( self.model, "comments", "string", str(self.options["comments"])) self.ctlVis_att = attribute.addAttribute(self.model, "ctl_vis", "bool", True) if versions.current() >= 201650: self.ctlVisPlayback_att = attribute.addAttribute( self.model, "ctl_vis_on_playback", "bool", True) self.jntVis_att = attribute.addAttribute(self.model, "jnt_vis", "bool", True) self.qsA_att = attribute.addAttribute(self.model, "quickselA", "string", "") self.qsB_att = attribute.addAttribute(self.model, "quickselB", "string", "") self.qsC_att = attribute.addAttribute(self.model, "quickselC", "string", "") self.qsD_att = attribute.addAttribute(self.model, "quickselD", "string", "") self.qsE_att = attribute.addAttribute(self.model, "quickselE", "string", "") self.qsF_att = attribute.addAttribute(self.model, "quickselF", "string", "") self.rigGroups = self.model.addAttr("rigGroups", at='message', m=1) self.rigPoses = self.model.addAttr("rigPoses", at='message', m=1) self.rigCtlTags = self.model.addAttr("rigCtlTags", at='message', m=1) self.rigScriptNodes = self.model.addAttr("rigScriptNodes", at='message', m=1) # ------------------------- ------------------------- # Global Ctl if self.options["worldCtl"]: if self.options["world_ctl_name"]: name = self.options["world_ctl_name"] else: name = "world_ctl" icon_shape = "circle" else: name = "global_C0_ctl" icon_shape = "crossarrow" self.global_ctl = self.addCtl(self.model, name, datatypes.Matrix(), self.options["C_color_fk"], icon_shape, w=10) attribute.setRotOrder(self.global_ctl, "ZXY") # Connect global visibility pm.connectAttr(self.ctlVis_att, self.global_ctl.attr("visibility")) if versions.current() >= 201650: pm.connectAttr(self.ctlVisPlayback_att, self.global_ctl.attr("hideOnPlayback")) attribute.lockAttribute(self.global_ctl, ['v']) # -------------------------------------------------- # Setup in world Space self.setupWS = primitive.addTransformFromPos(self.model, "setup") attribute.lockAttribute(self.setupWS) # -------------------------------------------------- # Basic set of null if self.options["joint_rig"]: self.jnt_org = primitive.addTransformFromPos(self.model, "jnt_org") pm.connectAttr(self.jntVis_att, self.jnt_org.attr("visibility"))
def addObjects(self): """Add all the objects needed to create the component.""" self.WIP = self.options["mode"] self.up_axis = pm.upAxis(q=True, axis=True) self.normal = self.getNormalFromPos(self.guide.apos) self.length0 = vector.getDistance( self.guide.apos[0], self.guide.apos[1]) self.length1 = vector.getDistance( self.guide.apos[1], self.guide.apos[2]) self.length2 = vector.getDistance( self.guide.apos[2], self.guide.apos[3]) # 1 bone chain for upv ref self.legChainUpvRef = primitive.add2DChain( self.root, self.getName("legUpvRef%s_jnt"), [self.guide.apos[0], self.guide.apos[2]], self.normal, False, self.WIP) self.legChainUpvRef[1].setAttr( "jointOrientZ", self.legChainUpvRef[1].getAttr("jointOrientZ") * -1) # extra neutral pose t = transform.getTransformFromPos(self.guide.apos[0]) self.root_npo = primitive.addTransform(self.root, self.getName("root_npo"), t) self.root_ctl = self.addCtl(self.root_npo, "root_ctl", t, self.color_fk, "circle", w=self.length0 / 6, tp=self.parentCtlTag) # FK Controlers ----------------------------------- t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) if self.settings["FK_rest_T_Pose"]: if self.negate: x_dir = 1 else: x_dir = -1 if self.up_axis == "y": x = datatypes.Vector(0, x_dir, 0) else: x = datatypes.Vector(0, 0, x_dir) z = datatypes.Vector(-1, 0, 0) t_npo = transform.getRotationFromAxis(x, z, "xz", False) t_npo = transform.setMatrixPosition(t_npo, self.guide.apos[0]) else: t_npo = t self.fk0_npo = primitive.addTransform(self.root_ctl, self.getName("fk0_npo"), t_npo) po_vec = datatypes.Vector(.5 * self.length0 * self.n_factor, 0, 0) self.fk0_ctl = self.addCtl(self.fk0_npo, "fk0_ctl", t, self.color_fk, "cube", w=self.length0, h=self.size * .1, d=self.size * .1, po=po_vec, tp=self.root_ctl) attribute.setKeyableAttributes( self.fk0_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate) if self.settings["FK_rest_T_Pose"]: t_npo = transform.setMatrixPosition( transform.getTransform(self.fk0_ctl), self.guide.apos[1]) else: t_npo = t self.fk1_npo = primitive.addTransform( self.fk0_ctl, self.getName("fk1_npo"), t_npo) po_vec = datatypes.Vector(.5 * self.length1 * self.n_factor, 0, 0) self.fk1_ctl = self.addCtl(self.fk1_npo, "fk1_ctl", t, self.color_fk, "cube", w=self.length1, h=self.size * .1, d=self.size * .1, po=po_vec, tp=self.fk0_ctl) attribute.setKeyableAttributes( self.fk1_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) t = transform.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate) if self.settings["FK_rest_T_Pose"]: t_npo = transform.setMatrixPosition( transform.getTransform(self.fk0_ctl), self.guide.apos[2]) else: t_npo = t self.fk2_npo = primitive.addTransform( self.fk1_ctl, self.getName("fk2_npo"), t_npo) if self.settings["FK_rest_T_Pose"]: self.fk2_npo.rz.set(90) po_vec = datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0) self.fk2_ctl = self.addCtl(self.fk2_npo, "fk2_ctl", t, self.color_fk, "cube", w=self.length2, h=self.size * .1, d=self.size * .1, po=po_vec, tp=self.fk1_ctl) attribute.setKeyableAttributes(self.fk2_ctl) self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl] for x in self.fk_ctl: attribute.setInvertMirror(x, ["tx", "ty", "tz"]) # IK Controlers ----------------------------------- self.ik_cns = primitive.addTransformFromPos(self.root_ctl, self.getName("ik_cns"), self.guide.pos["ankle"]) self.ikcns_ctl = self.addCtl( self.ik_cns, "ikcns_ctl", transform.getTransformFromPos(self.guide.pos["ankle"]), self.color_ik, "null", w=self.size * .12, tp=self.root_ctl) attribute.setInvertMirror(self.ikcns_ctl, ["tx"]) # m = transform.getTransformLookingAt(self.guide.pos["ankle"], # self.guide.pos["eff"], # self.x_axis, # "zx", # False) # if self.settings["FK_rest_T_Pose"]: # t_ik = transform.getTransformLookingAt(self.guide.pos["ankle"], # self.guide.pos["eff"], # self.normal * -1, # "zx", # False) # else: t_ik = transform.getTransformFromPos(self.guide.pos["ankle"]) self.ik_ctl = self.addCtl( self.ikcns_ctl, "ik_ctl", t_ik, self.color_ik, "cube", w=self.size * .12, h=self.size * .12, d=self.size * .12) attribute.setKeyableAttributes(self.ik_ctl) attribute.setRotOrder(self.ik_ctl, "XZY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) # upv v = self.guide.apos[2] - self.guide.apos[0] v = self.normal ^ v v.normalize() v *= self.size * .5 v += self.guide.apos[1] self.upv_cns = primitive.addTransformFromPos(self.ik_ctl, self.getName("upv_cns"), v) self.upv_ctl = self.addCtl( self.upv_cns, "upv_ctl", transform.getTransform(self.upv_cns), self.color_ik, "diamond", w=self.size * .12, tp=self.root_ctl) self.add_controller_tag(self.ik_ctl, self.upv_ctl) if self.settings["mirrorMid"]: if self.negate: self.upv_cns.rz.set(180) self.upv_cns.sy.set(-1) else: attribute.setInvertMirror(self.upv_ctl, ["tx"]) attribute.setKeyableAttributes(self.upv_ctl, self.t_params) # References -------------------------------------- self.ik_ref = primitive.addTransform( self.ik_ctl, self.getName("ik_ref"), transform.getTransform(self.ik_ctl)) self.fk_ref = primitive.addTransform( self.fk_ctl[2], self.getName("fk_ref"), transform.getTransform(self.ik_ctl)) # Chain -------------------------------------------- # The outputs of the ikfk2bone solver self.bone0 = primitive.addLocator( self.root_ctl, self.getName("0_bone"), transform.getTransform(self.fk_ctl[0])) self.bone0_shp = self.bone0.getShape() self.bone0_shp.setAttr("localPositionX", self.n_factor * .5) self.bone0_shp.setAttr("localScale", .5, 0, 0) self.bone0.setAttr("sx", self.length0) self.bone0.setAttr("visibility", False) self.bone1 = primitive.addLocator( self.root_ctl, self.getName("1_bone"), transform.getTransform(self.fk_ctl[1])) self.bone1_shp = self.bone1.getShape() self.bone1_shp.setAttr("localPositionX", self.n_factor * .5) self.bone1_shp.setAttr("localScale", .5, 0, 0) self.bone1.setAttr("sx", self.length1) self.bone1.setAttr("visibility", False) self.ctrn_loc = primitive.addTransformFromPos(self.root_ctl, self.getName("ctrn_loc"), self.guide.apos[1]) self.eff_loc = primitive.addTransformFromPos(self.root_ctl, self.getName("eff_loc"), self.guide.apos[2]) # tws_ref t = transform.getRotationFromAxis( datatypes.Vector(0, -1, 0), self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["ankle"]) # addind an npo parent transform to fix flip in Maya 2018.2 self.tws_npo = primitive.addTransform( self.eff_loc, self.getName("tws_npo"), t) self.tws_ref = primitive.addTransform( self.tws_npo, self.getName("tws_ref"), t) # Mid Controler ------------------------------------ t = transform.getTransform(self.ctrn_loc) self.mid_cns = primitive.addTransform( self.ctrn_loc, self.getName("mid_cns"), t) self.mid_ctl = self.addCtl(self.mid_cns, "mid_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.root_ctl) attribute.setKeyableAttributes(self.mid_ctl, params=["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) if self.settings["mirrorMid"]: if self.negate: self.mid_cns.rz.set(180) self.mid_cns.sz.set(-1) else: attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"]) # Twist references --------------------------------- x = datatypes.Vector(0, -1, 0) x = x * transform.getTransform(self.eff_loc) z = datatypes.Vector(self.normal.x, self.normal.y, self.normal.z) z = z * transform.getTransform(self.eff_loc) m = transform.getRotationFromAxis(x, z, "xz", self.negate) m = transform.setMatrixPosition( m, transform.getTranslation(self.ik_ctl)) self.rollRef = primitive.add2DChain(self.root, self.getName("rollChain"), self.guide.apos[:2], self.normal, self.negate, self.WIP) t = transform.getTransformLookingAt(self.guide.pos["base"], self.guide.apos[1], self.normal, "xz", self.negate) self.tws0_loc = primitive.addTransform( self.root_ctl, self.getName("tws0_loc"), t) self.tws0_rot = primitive.addTransform( self.tws0_loc, self.getName("tws0_rot"), t) self.tws1_loc = primitive.addTransform( self.ctrn_loc, self.getName("tws1_loc"), transform.getTransform(self.ctrn_loc)) self.tws1_rot = primitive.addTransform( self.tws1_loc, self.getName("tws1_rot"), transform.getTransform(self.ctrn_loc)) self.tws2_loc = primitive.addTransform( self.root_ctl, self.getName("tws2_loc"), transform.getTransform(self.tws_ref)) self.tws2_rot = primitive.addTransform( self.tws2_loc, self.getName("tws2_rot"), transform.getTransform(self.tws_ref)) self.tws2_rot.setAttr("sx", .001) # Divisions ---------------------------------------- self.divisions = self.settings["div0"] + self.settings["div1"] + 2 self.div_cns = [] if self.settings["extraTweak"]: tagP = self.parentCtlTag self.tweak_ctl = [] for i in range(self.divisions): div_cns = primitive.addTransform(self.root_ctl, self.getName("div%s_loc" % i)) self.div_cns.append(div_cns) if self.settings["extraTweak"]: t = transform.getTransform(div_cns) tweak_ctl = self.addCtl(div_cns, "tweak%s_ctl" % i, t, self.color_fk, "square", w=self.size * .15, d=self.size * .15, ro=datatypes.Vector([0, 0, 1.5708]), tp=tagP) attribute.setKeyableAttributes(tweak_ctl) tagP = tweak_ctl self.tweak_ctl.append(tweak_ctl) driver = tweak_ctl else: driver = div_cns # setting the joints if i == 0: self.jnt_pos.append([driver, "thigh"]) current_parent = "root" twist_name = "thigh_twist_" twist_idx = 1 increment = 1 elif i == self.settings["div0"] + 1: self.jnt_pos.append([driver, "calf", current_parent]) twist_name = "calf_twist_" current_parent = "knee" twist_idx = self.settings["div1"] increment = -1 else: self.jnt_pos.append( [driver, twist_name + str(twist_idx).zfill(2), current_parent]) twist_idx += increment # End reference ------------------------------------ # To help the deformation on the ankle self.end_ref = primitive.addTransform(self.tws2_rot, self.getName("end_ref"), m) # set the offset rotation for the hand self.end_jnt_off = primitive.addTransform(self.end_ref, self.getName("end_off"), m) if self.up_axis == "z": self.end_jnt_off.rz.set(-90) self.jnt_pos.append([self.end_jnt_off, 'foot', current_parent]) # match IK FK references self.match_fk0_off = self.add_match_ref(self.fk_ctl[1], self.root, "matchFk0_npo", False) self.match_fk0 = self.add_match_ref(self.fk_ctl[0], self.match_fk0_off, "fk0_mth") self.match_fk1_off = self.add_match_ref(self.fk_ctl[2], self.root, "matchFk1_npo", False) self.match_fk1 = self.add_match_ref(self.fk_ctl[1], self.match_fk1_off, "fk1_mth") self.match_fk2 = self.add_match_ref(self.fk_ctl[2], self.ik_ctl, "fk2_mth") self.match_ik = self.add_match_ref(self.ik_ctl, self.fk2_ctl, "ik_mth") self.match_ikUpv = self.add_match_ref(self.upv_ctl, self.fk0_ctl, "upv_mth") # add visual reference self.line_ref = icon.connection_display_curve( self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # 1 bone chain Upv ref ============================================== self.ikHandleUpvRef = primitive.addIkHandle( self.root, self.getName("ikHandleArmChainUpvRef"), self.armChainUpvRef, "ikSCsolver") pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef) pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True) # Visibilities ------------------------------------- # fk fkvis_node = node.createReverseNode(self.blend_att) for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.line_ref.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) if self.settings["ikTR"]: for shp in self.ikRot_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.roll_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- attribute.setRotOrder(self.fk0_ctl, "XZY") attribute.setRotOrder(self.fk1_ctl, "XYZ") attribute.setRotOrder(self.fk2_ctl, "YZX") attribute.setRotOrder(self.ik_ctl, "XYZ") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc] o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk_ctl[0], self.fk_ctl[1], self.fk_ref, self.length0, self.length1, self.negate) # NOTE: Ideally we should not change hierarchy or move object after # object generation method. But is much easier this way since every # part is in the final and correct position # after the ctrn_loc is in the correct position with the ikfk2bone op # point constrain tip reference pm.pointConstraint(self.ik_ctl, self.tip_ref, mo=False) # interpolate transform mid point locator int_matrix = applyop.gear_intmatrix_op( self.armChainUpvRef[0].attr("worldMatrix"), self.tip_ref.attr("worldMatrix"), .5) applyop.gear_mulmatrix_op( int_matrix.attr("output"), self.interpolate_lvl.attr("parentInverseMatrix[0]"), self.interpolate_lvl) # match roll ctl npo to ctrn_loc current transform (so correct orient) transform.matchWorldTransform(self.ctrn_loc, self.roll_ctl_npo) # match roll ctl npo to interpolate transform current position pos = self.interpolate_lvl.getTranslation(space="world") self.roll_ctl_npo.setTranslation(pos, space="world") # parent constraint roll control npo to interpolate trans pm.parentConstraint(self.interpolate_lvl, self.roll_ctl_npo, mo=True) if self.settings["ikTR"]: # connect the control inputs outEff_dm = o_node.listConnections(c=True)[-1][1] inAttr = self.ikRot_npo.attr("translate") outEff_dm.attr("outputTranslate") >> inAttr outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale") dm_node = node.createDecomposeMatrixNode(o_node.attr("outB")) dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate") # rotation mulM_node = applyop.gear_mulmatrix_op( self.ikRot_ctl.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) intM_node = applyop.gear_intmatrix_op(o_node.attr("outEff"), mulM_node.attr("output"), o_node.attr("blend")) dm_node = node.createDecomposeMatrixNode(intM_node.attr("output")) dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate") transform.matchWorldTransform(self.fk2_ctl, self.ikRot_cns) # scale: this fix the scalin popping issue intM_node = applyop.gear_intmatrix_op( self.fk2_ctl.attr("worldMatrix"), self.ik_ctl_ref.attr("worldMatrix"), o_node.attr("blend")) mulM_node = applyop.gear_mulmatrix_op( intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix")) dm_node = node.createDecomposeMatrixNode(mulM_node.attr("output")) dm_node.attr("outputScale") >> self.eff_loc.attr("scale") pm.connectAttr(self.blend_att, o_node + ".blend") if self.negate: mulVal = -1 rollMulVal = 1 else: mulVal = 1 rollMulVal = -1 roll_m_node = node.createMulNode(self.roll_att, mulVal) roll_m_node2 = node.createMulNode(self.roll_ctl.attr("rx"), rollMulVal) node.createPlusMinusAverage1D( [roll_m_node.outputX, roll_m_node2.outputX], operation=1, output=o_node + ".roll") pm.connectAttr(self.scale_att, o_node + ".scaleA") pm.connectAttr(self.scale_att, o_node + ".scaleB") pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch") pm.connectAttr(self.slide_att, o_node + ".slide") pm.connectAttr(self.softness_att, o_node + ".softness") pm.connectAttr(self.reverse_att, o_node + ".reverse") # Twist references --------------------------------- pm.pointConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX) pm.connectAttr(self.mid_ctl.scaleX, self.tws1B_loc.scaleX) pm.orientConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) applyop.oriCns(self.mid_ctl, self.tws1_rot, maintainOffset=False) applyop.oriCns(self.mid_ctl, self.tws1B_rot, maintainOffset=False) if self.negate: axis = "xz" axisb = "-xz" else: axis = "-xz" axisb = "xz" applyop.aimCns(self.tws1_loc, self.root, axis=axis, wupType=4, wupVector=[0, 0, 1], wupObject=self.mid_ctl, maintainOffset=False) applyop.aimCns(self.tws1B_loc, self.eff_loc, axis=axisb, wupType=4, wupVector=[0, 0, 1], wupObject=self.mid_ctl, maintainOffset=False) pm.pointConstraint(self.thick_ctl, self.tws1B_loc, maintainOffset=False) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.root.attr("worldInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.tws2_npo.attr("translate")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate")) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.tws2_rot.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") attribute.setRotOrder(self.tws2_rot, "XYZ") pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate") self.tws0_rot.setAttr("sx", .001) self.tws2_rot.setAttr("sx", .001) add_node = node.createAddNode(self.roundness_att, .001) pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx")) pm.connectAttr(add_node + ".output", self.tws1B_rot.attr("sx")) pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX") # Roll Shoulder applyop.splineIK(self.getName("rollRef"), self.rollRef, parent=self.root, cParent=self.bone0) # Volume ------------------------------------------- distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc) distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc) add_node = node.createAddNode(distA_node + ".distance", distB_node + ".distance") div_node = node.createDivNode(add_node + ".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix") div_node2 = node.createDivNode(div_node + ".outputX", dm_node + ".outputScaleX") self.volDriver_att = div_node2 + ".outputX" if self.settings["extraTweak"]: for tweak_ctl in self.tweak_ctl: for shp in tweak_ctl.getShapes(): pm.connectAttr(self.tweakVis_att, shp.attr("visibility")) # Divisions ---------------------------------------- # at 0 or 1 the division will follow exactly the rotation of the # controler.. and we wont have this nice tangent + roll b_twist = False for i, div_cns in enumerate(self.div_cns): if self.settings["supportJoints"]: if i < (self.settings["div0"] + 1): perc = i * .5 / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = .49 elif i < (self.settings["div0"] + 3): perc = .50 elif i < (self.settings["div0"] + 4): b_twist = True perc = .51 else: perc = .5 + \ (i - self.settings["div0"] - 3.0) * .5 / \ (self.settings["div1"] + 1.0) else: if i < (self.settings["div0"] + 1): perc = i * .5 / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): b_twist = True perc = .501 else: perc = .5 + \ (i - self.settings["div0"] - 1.0) * .5 / \ (self.settings["div1"] + 1.0) perc = max(.001, min(.990, perc)) # mid twist distribution if b_twist: mid_twist = self.tws1B_rot else: mid_twist = self.tws1_rot # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws2_rot, mid_twist, self.tws0_rot], 1.0 - perc, 40) else: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws0_rot, mid_twist, self.tws2_rot], perc, 40) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") # Squash n Stretch o_node = applyop.gear_squashstretch2_op( div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, o_node + ".blend") pm.connectAttr(self.volDriver_att, o_node + ".driver") pm.connectAttr(self.st_att[i], o_node + ".stretch") pm.connectAttr(self.sq_att[i], o_node + ".squash") # match IK/FK ref pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True) pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True) if self.settings["ikTR"]: transform.matchWorldTransform(self.ikRot_ctl, self.match_ikRot) transform.matchWorldTransform(self.fk_ctl[2], self.match_fk2) # connect_reader pm.parentConstraint(self.bone0, self.readerA, mo=True) pm.parentConstraint(self.bone1, self.readerB, mo=True) # connect auto thickness if self.negate and not self.settings["mirrorMid"]: d_val = 180 / self.length1 else: d_val = -180 / self.length1 div_thick_node = node.createDivNode(self.elbow_thickness_att, d_val) node.createMulNode(div_thick_node.outputX, self.readerB.ry, self.thick_lvl.tx) return
def addObjects(self): """Add all the objects needed to create the component.""" self.div_count = len(self.guide.apos) - 5 plane = [self.guide.apos[0], self.guide.apos[-4], self.guide.apos[-3]] self.normal = self.getNormalFromPos(plane) self.binormal = self.getBiNormalFromPos(plane) # Heel --------------------------------------------- # bank pivot # Aim the heel towards the first locator, but flat to the world. # So get the y component from itself. #TODO: Try to see if the self.normal and self.binormal can be used to do this more intelligently. heelLook = [ self.guide.apos[-4][0], self.guide.pos["heel"][1], self.guide.apos[-4][2] ] t = transform.getTransformLookingAt(self.guide.pos["heel"], heelLook, self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["inpivot"]) self.in_npo = primitive.addTransform(self.root, self.getName("in_npo"), t) self.in_piv = primitive.addTransform(self.in_npo, self.getName("in_piv"), t) t = transform.setMatrixPosition(t, self.guide.pos["outpivot"]) self.out_piv = primitive.addTransform(self.in_piv, self.getName("out_piv"), t) # heel t = transform.getTransformLookingAt(self.guide.pos["heel"], heelLook, self.normal, "xz", self.negate) self.heel_loc = primitive.addTransform(self.out_piv, self.getName("heel_loc"), t) attribute.setRotOrder(self.heel_loc, "YZX") self.heel_ctl = self.addCtl(self.heel_loc, "heel_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.heel_ctl, self.r_params) # Tip ---------------------------------------------- v = datatypes.Vector(self.guide.apos[-5].x, self.guide.apos[-1].y, self.guide.apos[-5].z) t = transform.setMatrixPosition(t, v) self.tip_ctl = self.addCtl(self.heel_ctl, "tip_ctl", t, self.color_ik, "circle", w=self.size, tp=self.heel_ctl) attribute.setKeyableAttributes(self.tip_ctl, self.r_params) # Roll --------------------------------------------- if self.settings["useRollCtl"]: t = transform.getTransformLookingAt(self.guide.pos["heel"], heelLook, self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["root"]) self.roll_np = primitive.addTransform(self.root, self.getName("roll_npo"), t) self.roll_ctl = self.addCtl(self.roll_np, "roll_ctl", t, self.color_ik, "cylinder", w=self.size * .5, h=self.size * .5, ro=datatypes.Vector(3.1415 * .5, 0, 0), tp=self.tip_ctl) attribute.setKeyableAttributes(self.roll_ctl, ["rx", "rz"]) # Backward Controlers ------------------------------ bk_pos = self.guide.apos[1:-3] bk_pos.reverse() parent = self.tip_ctl self.bk_ctl = [] self.bk_loc = [] self.previousTag = self.tip_ctl for i, pos in enumerate(bk_pos): if i == 0: t = transform.getTransform(self.heel_ctl) t = transform.setMatrixPosition(t, pos) else: dir = bk_pos[i - 1] t = transform.getTransformLookingAt(pos, dir, self.normal, "xz", self.negate) bk_loc = primitive.addTransform(parent, self.getName("bk%s_loc" % i), t) bk_ctl = self.addCtl(bk_loc, "bk%s_ctl" % i, t, self.color_ik, "sphere", w=self.size * .15, tp=self.previousTag) attribute.setKeyableAttributes(bk_ctl, self.r_params) self.previousTag = bk_ctl self.bk_loc.append(bk_loc) self.bk_ctl.append(bk_ctl) parent = bk_ctl # FK Reference ------------------------------------ self.fk_ref = primitive.addTransformFromPos(self.bk_ctl[-1], self.getName("fk_ref"), self.guide.apos[0]) self.fk_npo = primitive.addTransform( self.fk_ref, self.getName("fk0_npo"), transform.getTransform(self.bk_ctl[-1])) # Forward Controlers ------------------------------ self.fk_ctl = [] self.fk_loc = [] parent = self.fk_npo self.previousTag = self.tip_ctl for i, bk_ctl in enumerate(reversed(self.bk_ctl[1:])): t = transform.getTransform(bk_ctl) dist = vector.getDistance(self.guide.apos[i + 1], self.guide.apos[i + 2]) fk_loc = primitive.addTransform(parent, self.getName("fk%s_loc" % i), t) po_vec = datatypes.Vector(dist * .5 * self.n_factor, 0, 0) fk_ctl = self.addCtl(fk_loc, "fk%s_ctl" % i, t, self.color_fk, "cube", w=dist, h=self.size * .5, d=self.size * .5, po=po_vec, tp=self.previousTag) self.previousTag = fk_ctl attribute.setKeyableAttributes(fk_ctl) self.jnt_pos.append([fk_ctl, i]) parent = fk_ctl self.fk_ctl.append(fk_ctl) self.fk_loc.append(fk_loc)
def addObjects(self): """Add all the objects needed to create the component.""" self.up_axis = pm.upAxis(q=True, axis=True) # Auto bend with position controls ------------------- if self.settings["autoBend"]: self.autoBendChain = primitive.add2DChain( self.root, self.getName("autoBend%s_jnt"), [self.guide.apos[1], self.guide.apos[-2]], self.guide.blades["blade"].z * -1, False, True) for j in self.autoBendChain: j.drawStyle.set(2) # Ik Controlers ------------------------------------ if self.settings["IKWorldOri"]: t = datatypes.TransformationMatrix() t = transform.setMatrixPosition(t, self.guide.apos[1]) else: t = transform.getTransformLookingAt( self.guide.apos[1], self.guide.apos[-2], self.guide.blades["blade"].z * -1, "yx", self.negate) self.ik_off = primitive.addTransform(self.root, self.getName("ik_off"), t) # handle Z up orientation offset if self.up_axis == "z" and self.settings["IKWorldOri"]: self.ik_off.rx.set(90) t = transform.getTransform(self.ik_off) self.ik0_npo = primitive.addTransform(self.ik_off, self.getName("ik0_npo"), t) self.ik0_ctl = self.addCtl(self.ik0_npo, "ik0_ctl", t, self.color_ik, "compas", w=self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params) attribute.setRotOrder(self.ik0_ctl, "ZXY") attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"]) # pelvis self.length0 = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) vec_po = datatypes.Vector(0, .5 * self.length0 * -1, 0) self.pelvis_npo = primitive.addTransform(self.ik0_ctl, self.getName("pelvis_npo"), t) self.pelvis_ctl = self.addCtl(self.pelvis_npo, "pelvis_ctl", t, self.color_ik, "cube", h=self.length0, w=self.size * .1, d=self.size * .1, po=vec_po, tp=self.parentCtlTag) self.pelvis_lvl = primitive.addTransform( self.pelvis_ctl, self.getName("pelvis_lvl"), transform.setMatrixPosition(t, self.guide.apos[0])) self.jnt_pos.append([self.pelvis_lvl, "pelvis"]) t = transform.setMatrixPosition(t, self.guide.apos[-2]) if self.settings["autoBend"]: self.autoBend_npo = primitive.addTransform( self.root, self.getName("spinePosition_npo"), t) self.autoBend_ctl = self.addCtl(self.autoBend_npo, "spinePosition_ctl", t, self.color_ik, "square", w=self.size, d=.3 * self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.autoBend_ctl, ["tx", "ty", "tz", "ry"]) attribute.setInvertMirror(self.autoBend_ctl, ["tx", "ry"]) self.ik1_npo = primitive.addTransform(self.autoBendChain[0], self.getName("ik1_npo"), t) self.ik1autoRot_lvl = primitive.addTransform( self.ik1_npo, self.getName("ik1autoRot_lvl"), t) self.ik1_ctl = self.addCtl(self.ik1autoRot_lvl, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.autoBend_ctl) else: t = transform.setMatrixPosition(t, self.guide.apos[-2]) self.ik1_npo = primitive.addTransform(self.root, self.getName("ik1_npo"), t) self.ik1_ctl = self.addCtl(self.ik1_npo, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params) attribute.setRotOrder(self.ik1_ctl, "ZXY") attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"]) # Tangent controllers ------------------------------- if self.settings["centralTangent"]: vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_off = primitive.addTransform(self.tan0_npo, self.getName("tan0_off"), t) self.tan0_ctl = self.addCtl(self.tan0_off, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_off = primitive.addTransform(self.tan1_npo, self.getName("tan1_off"), t) self.tan1_ctl = self.addCtl(self.tan1_off, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) # Tangent mid control vec_pos = vector.linearlyInterpolate(self.guide.apos[1], self.guide.apos[-2], .5) t = transform.setMatrixPosition(t, vec_pos) self.tan_npo = primitive.addTransform(self.tan0_npo, self.getName("tan_npo"), t) self.tan_ctl = self.addCtl(self.tan_npo, "tan_ctl", t, self.color_fk, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan_ctl, self.t_params) attribute.setInvertMirror(self.tan_ctl, ["tx"]) else: vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_ctl = self.addCtl(self.tan0_npo, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_ctl = self.addCtl(self.tan1_npo, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_transforms = [] self.twister = [] self.ref_twist = [] t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[-2], self.guide.blades["blade"].z * -1, "yx", self.negate) parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root)) self.jointList = [] self.preiviousCtlTag = self.parentCtlTag for i in range(self.settings["division"]): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns t = transform.getTransform(parentctl) fk_npo = primitive.addTransform(parentctl, self.getName("fk%s_npo" % (i)), t) fk_ctl = self.addCtl(fk_npo, "fk%s_ctl" % (i), transform.getTransform(parentctl), self.color_fk, "cube", w=self.size, h=self.size * .05, d=self.size, tp=self.preiviousCtlTag) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl self.fk_npo.append(fk_npo) parentctl = fk_ctl if i == self.settings["division"] - 1: t = transform.getTransformLookingAt( self.guide.pos["spineTop"], self.guide.pos["chest"], self.guide.blades["blade"].z * -1, "yx", False) scl_ref_parent = self.root else: t = transform.getTransform(parentctl) scl_ref_parent = parentctl scl_ref = primitive.addTransform(scl_ref_parent, self.getName("%s_scl_ref" % i), t) self.scl_transforms.append(scl_ref) # Deformers (Shadow) self.jnt_pos.append([scl_ref, "spine_" + str(i + 1).zfill(2)]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Connections (Hooks) ------------------------------ self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx")) self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx")) self.jnt_pos.append([self.cnx1, "spine_" + str(i + 2).zfill(2)])
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # Visibilities ------------------------------------- # fk fkvis_node = node.createReverseNode(self.blend_att) for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk0_roll_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_roll_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) fkvis2_node = node.createReverseNode(self.blend2_att) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis2_node + ".outputX", shp.attr("visibility")) # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.line_ref.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # jnt ctl for ctl in (self.div_ctls): for shp in ctl.getShapes(): pm.connectAttr(self.jntctl_vis_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- attribute.setRotOrder(self.fk0_ctl, "YZX") attribute.setRotOrder(self.fk1_ctl, "XYZ") attribute.setRotOrder(self.fk2_ctl, "YZX") attribute.setRotOrder(self.ik_ctl, "XYZ") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_npo] o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk0_mtx, self.fk1_mtx, self.fk2_mtx, self.length0, self.length1, self.negate) pm.connectAttr(self.blend_att, o_node + ".blend") pm.connectAttr(self.roll_att, o_node + ".roll") pm.connectAttr(self.scale_att, o_node + ".scaleA") pm.connectAttr(self.scale_att, o_node + ".scaleB") pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch") pm.connectAttr(self.slide_att, o_node + ".slide") pm.connectAttr(self.softness_att, o_node + ".softness") pm.connectAttr(self.reverse_att, o_node + ".reverse") # update issue on effector scale interpol, disconnect for stability pm.disconnectAttr(self.eff_npo.scale) # auto upvector ------------------------------------- if self.negate: o_node = applyop.aimCns(self.upv_auv, self.ik_ctl, axis="-xy", wupType=4, wupVector=[0, 1, 0], wupObject=self.upv_auv, maintainOffset=False) else: o_node = applyop.aimCns(self.upv_auv, self.ik_ctl, axis="xy", wupType=4, wupVector=[0, 1, 0], wupObject=self.upv_auv, maintainOffset=False) o_node = applyop.gear_mulmatrix_op( self.upv_auv.attr("worldMatrix"), self.upv_mtx.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pb_node = pm.createNode("pairBlend") pb_node.attr("rotInterpolation").set(1) pm.connectAttr(dm_node + ".outputTranslate", pb_node + ".inTranslate2") pm.connectAttr(dm_node + ".outputRotate", pb_node + ".inRotate2") pm.connectAttr(pb_node + ".outRotate", self.upv_mtx.attr("rotate")) pm.connectAttr(pb_node + ".outTranslate", self.upv_mtx.attr("translate")) pm.connectAttr(self.auv_att, pb_node + ".weight") # fk0 mtx connection o_node = applyop.gear_mulmatrix_op( self.fk0_roll_ctl.attr("worldMatrix"), self.fk0_mtx.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.fk0_mtx.attr("translate")) pm.connectAttr(dm_node + ".outputRotate", self.fk0_mtx.attr("rotate")) # fk1 loc connect to fk1 ref @ pos and rot, not scl to avoid shearing o_node = applyop.gear_mulmatrix_op( self.fk1_ref.attr("worldMatrix"), self.fk1_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.fk1_loc.attr("translate")) pm.connectAttr(dm_node + ".outputRotate", self.fk1_loc.attr("rotate")) # fk1 mtx orient cns to fk1 roll pm.connectAttr(self.fk1_roll_ctl.attr("rotate"), self.fk1_mtx.attr("rotate")) # fk2_loc position constraint to effector------------------------ o_node = applyop.gear_mulmatrix_op( self.eff_npo.attr("worldMatrix"), self.fk2_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.fk2_loc.attr("translate")) # fk2_loc rotation constraint to bone1 (bugfixed) -------------- o_node = applyop.gear_mulmatrix_op( self.bone1.attr("worldMatrix"), self.fk2_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.fk2_loc.attr("rotate")) # hand ikfk blending from fk ref to ik ref (serious bugfix)-------- o_node = applyop.gear_mulmatrix_op( self.fk_ref.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pb_node = pm.createNode("pairBlend") pb_node.attr("rotInterpolation").set(1) pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", pb_node + ".inRotate1") pm.connectAttr(self.blend2_att, pb_node + ".weight") pm.connectAttr(pb_node + ".outRotate", self.eff_loc.attr("rotate")) o_node = applyop.gear_mulmatrix_op( self.ik_ref.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) dm_node1 = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node1 + ".inputMatrix") pm.connectAttr(dm_node1 + ".outputRotate", pb_node + ".inRotate2") # use blendcolors to blend scale bc_node = pm.createNode("blendColors") pm.connectAttr(self.blend_att, bc_node + ".blender") pm.connectAttr(dm_node + ".outputScale", bc_node + ".color2") pm.connectAttr(dm_node1 + ".outputScale", bc_node + ".color1") pm.connectAttr(bc_node + ".output", self.eff_loc.attr("scale")) # Twist references --------------------------------- pm.connectAttr(self.mid_ctl.attr("translate"), self.tws1_npo.attr("translate")) pm.connectAttr(self.mid_ctl.attr("rotate"), self.tws1_npo.attr("rotate")) pm.connectAttr(self.mid_ctl.attr("scale"), self.tws1_npo.attr("scale")) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.tws3_npo.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.tws3_npo.attr("translate")) pm.connectAttr(dm_node + ".outputRotate", self.tws3_npo.attr("rotate")) attribute.setRotOrder(self.tws3_rot, "XYZ") # elbow thickness connection if self.negate: o_node = node.createMulNode( [self.elbow_thickness_att, self.elbow_thickness_att], [0.5, -0.5, 0], [self.tws1_loc + ".translateX", self.tws2_loc + ".translateX"]) else: o_node = node.createMulNode( [self.elbow_thickness_att, self.elbow_thickness_att], [-0.5, 0.5, 0], [self.tws1_loc + ".translateX", self.tws2_loc + ".translateX"]) # connect both tws1 and tws2 (mid tws) self.tws0_rot.setAttr("sx", .001) self.tws3_rot.setAttr("sx", .001) add_node = node.createAddNode(self.roundness0_att, .001) pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx")) add_node = node.createAddNode(self.roundness1_att, .001) pm.connectAttr(add_node + ".output", self.tws2_rot.attr("sx")) pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX") # Roll Shoulder--use aimconstraint withour uovwctor to solve # the stable twist if self.negate: o_node = applyop.aimCns(self.tws0_loc, self.mid_ctl, axis="-xy", wupType=4, wupVector=[0, 1, 0], wupObject=self.tws0_npo, maintainOffset=False) else: o_node = applyop.aimCns(self.tws0_loc, self.mid_ctl, axis="xy", wupType=4, wupVector=[0, 1, 0], wupObject=self.tws0_npo, maintainOffset=False) # Volume ------------------------------------------- distA_node = node.createDistNode(self.tws0_loc, self.tws1_npo) distB_node = node.createDistNode(self.tws1_npo, self.tws3_loc) add_node = node.createAddNode(distA_node + ".distance", distB_node + ".distance") div_node = node.createDivNode(add_node + ".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix") div_node2 = node.createDivNode(div_node + ".outputX", dm_node + ".outputScaleX") self.volDriver_att = div_node2 + ".outputX" # Divisions ---------------------------------------- # div mid constraint to mid ctl o_node = applyop.gear_mulmatrix_op( self.mid_ctl.attr("worldMatrix"), self.div_mid.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.div_mid.attr("translate")) pm.connectAttr(dm_node + ".outputRotate", self.div_mid.attr("rotate")) # at 0 or 1 the division will follow exactly the rotation of the # controler.. and we wont have this nice tangent + roll # linear scaling percentage (1) to effector (2) to elbow scl_1_perc = [] scl_2_perc = [] for i, div_cnsUp in enumerate(self.div_cnsUp): if i < (self.settings["div0"] + 1): perc = i / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = .95 perc = max(.001, min(.99, perc)) # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cnsUp, [self.tws1_rot, self.tws0_rot], 1 - perc, 20) else: o_node = applyop.gear_rollsplinekine_op( div_cnsUp, [self.tws0_rot, self.tws1_rot], perc, 20) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") scl_1_perc.append(perc / 2) scl_2_perc.append(perc) scl_1_perc.append(0.5) scl_2_perc.append(1) for i, div_cnsDn in enumerate(self.div_cnsDn): if i == (0): perc = .05 elif i < (self.settings["div1"] + 1): perc = i / (self.settings["div1"] + 1.0) elif i < (self.settings["div1"] + 2): perc = .95 perc = max(.001, min(.990, perc)) # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cnsDn, [self.tws3_rot, self.tws2_rot], 1 - perc, 20) else: o_node = applyop.gear_rollsplinekine_op( div_cnsDn, [self.tws2_rot, self.tws3_rot], perc, 20) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") scl_1_perc.append(perc / 2 + 0.5) scl_2_perc.append(1 - perc) # Squash n Stretch for i, div_cns in enumerate(self.div_cns): o_node = applyop.gear_squashstretch2_op( div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, o_node + ".blend") pm.connectAttr(self.volDriver_att, o_node + ".driver") pm.connectAttr(self.st_att[i], o_node + ".stretch") pm.connectAttr(self.sq_att[i], o_node + ".squash") # get the first mult_node after sq op mult_node = pm.listHistory(o_node, future=True)[1] # linear blend effector scale bc_node = pm.createNode("blendColors") bc_node.setAttr("color2R", 1) bc_node.setAttr("color2G", 1) bc_node.setAttr("blender", scl_1_perc[i]) pm.connectAttr(self.eff_loc.attr("scale"), bc_node + ".color1") # linear blend mid scale bc_node2 = pm.createNode("blendColors") bc_node2.setAttr("color2R", 1) bc_node2.setAttr("color2G", 1) bc_node2.setAttr("blender", scl_2_perc[i]) pm.connectAttr(self.mid_ctl.attr("scale"), bc_node2 + ".color1") # mid_ctl scale * effector scale mult_node2 = pm.createNode("multiplyDivide") pm.connectAttr(bc_node2 + ".output", mult_node2 + ".input1") pm.connectAttr(bc_node + ".output", mult_node2 + ".input2") # plug to sq scale pm.connectAttr(mult_node2 + ".output", mult_node + ".input2") # match IK/FK ref pm.connectAttr(self.bone0.attr("rotate"), self.match_fk0.attr("rotate")) pm.connectAttr(self.bone0.attr("translate"), self.match_fk0.attr("translate")) pm.connectAttr(self.bone1.attr("rotate"), self.match_fk1.attr("rotate")) pm.connectAttr(self.bone1.attr("translate"), self.match_fk1.attr("translate")) return
def addObjects(self): """Add all the objects needed to create the component.""" self.WIP = self.options["mode"] self.normal = self.getNormalFromPos(self.guide.apos) self.binormal = self.getBiNormalFromPos(self.guide.apos) self.length0 = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) self.length1 = vector.getDistance(self.guide.apos[1], self.guide.apos[2]) self.length2 = vector.getDistance(self.guide.apos[2], self.guide.apos[3]) # 1 bone chain for upv ref self.legChainUpvRef = primitive.add2DChain( self.root, self.getName("legUpvRef%s_jnt"), [self.guide.apos[0], self.guide.apos[2]], self.normal, False, self.WIP) self.legChainUpvRef[1].setAttr( "jointOrientZ", self.legChainUpvRef[1].getAttr("jointOrientZ") * -1) # extra neutral pose t = transform.getTransformFromPos(self.guide.apos[0]) self.root_npo = primitive.addTransform(self.root, self.getName("root_npo"), t) self.root_ctl = self.addCtl(self.root_npo, "root_ctl", t, self.color_fk, "circle", w=self.length0 / 6, tp=self.parentCtlTag) # FK Controlers ----------------------------------- t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) self.fk0_npo = primitive.addTransform(self.root_ctl, self.getName("fk0_npo"), t) po_vec = datatypes.Vector(.5 * self.length0 * self.n_factor, 0, 0) self.fk0_ctl = self.addCtl(self.fk0_npo, "fk0_ctl", t, self.color_fk, "cube", w=self.length0, h=self.size * .1, d=self.size * .1, po=po_vec, tp=self.root_ctl) attribute.setKeyableAttributes( self.fk0_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate) self.fk1_npo = primitive.addTransform(self.fk0_ctl, self.getName("fk1_npo"), t) po_vec = datatypes.Vector(.5 * self.length1 * self.n_factor, 0, 0) self.fk1_ctl = self.addCtl(self.fk1_npo, "fk1_ctl", t, self.color_fk, "cube", w=self.length1, h=self.size * .1, d=self.size * .1, po=po_vec, tp=self.fk0_ctl) attribute.setKeyableAttributes( self.fk1_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) t = transform.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate) self.fk2_npo = primitive.addTransform(self.fk1_ctl, self.getName("fk2_npo"), t) po_vec = datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0) self.fk2_ctl = self.addCtl(self.fk2_npo, "fk2_ctl", t, self.color_fk, "cube", w=self.length2, h=self.size * .1, d=self.size * .1, po=po_vec, tp=self.fk1_ctl) attribute.setKeyableAttributes(self.fk2_ctl) self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl] for x in self.fk_ctl: attribute.setInvertMirror(x, ["tx", "ty", "tz"]) # IK Controlers ----------------------------------- self.ik_cns = primitive.addTransformFromPos(self.root_ctl, self.getName("ik_cns"), self.guide.pos["ankle"]) self.ikcns_ctl = self.addCtl(self.ik_cns, "ikcns_ctl", transform.getTransformFromPos( self.guide.pos["ankle"]), self.color_ik, "null", w=self.size * .12, tp=self.root_ctl) attribute.setInvertMirror(self.ikcns_ctl, ["tx"]) m = transform.getTransformLookingAt(self.guide.pos["ankle"], self.guide.pos["eff"], self.x_axis, "zx", False) self.ik_ctl = self.addCtl(self.ikcns_ctl, "ik_ctl", transform.getTransformFromPos( self.guide.pos["ankle"]), self.color_ik, "cube", w=self.size * .12, h=self.size * .12, d=self.size * .12) attribute.setKeyableAttributes(self.ik_ctl) attribute.setRotOrder(self.ik_ctl, "XZY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) # upv v = self.guide.apos[2] - self.guide.apos[0] v = self.normal ^ v v.normalize() v *= self.size * .5 v += self.guide.apos[1] self.upv_cns = primitive.addTransformFromPos(self.ik_ctl, self.getName("upv_cns"), v) self.upv_ctl = self.addCtl(self.upv_cns, "upv_ctl", transform.getTransform(self.upv_cns), self.color_ik, "diamond", w=self.size * .12, tp=self.root_ctl) self.add_controller_tag(self.ik_ctl, self.upv_ctl) if self.settings["mirrorMid"]: if self.negate: self.upv_cns.rz.set(180) self.upv_cns.sy.set(-1) else: attribute.setInvertMirror(self.upv_ctl, ["tx"]) attribute.setKeyableAttributes(self.upv_ctl, self.t_params) # References -------------------------------------- self.ik_ref = primitive.addTransform( self.ik_ctl, self.getName("ik_ref"), transform.getTransform(self.ik_ctl)) self.fk_ref = primitive.addTransform( self.fk_ctl[2], self.getName("fk_ref"), transform.getTransform(self.ik_ctl)) # Chain -------------------------------------------- # The outputs of the ikfk2bone solver self.bone0 = primitive.addLocator( self.root_ctl, self.getName("0_bone"), transform.getTransform(self.fk_ctl[0])) self.bone0_shp = self.bone0.getShape() self.bone0_shp.setAttr("localPositionX", self.n_factor * .5) self.bone0_shp.setAttr("localScale", .5, 0, 0) self.bone0.setAttr("sx", self.length0) self.bone0.setAttr("visibility", False) self.bone1 = primitive.addLocator( self.root_ctl, self.getName("1_bone"), transform.getTransform(self.fk_ctl[1])) self.bone1_shp = self.bone1.getShape() self.bone1_shp.setAttr("localPositionX", self.n_factor * .5) self.bone1_shp.setAttr("localScale", .5, 0, 0) self.bone1.setAttr("sx", self.length1) self.bone1.setAttr("visibility", False) self.ctrn_loc = primitive.addTransformFromPos(self.root_ctl, self.getName("ctrn_loc"), self.guide.apos[1]) self.eff_loc = primitive.addTransformFromPos(self.root_ctl, self.getName("eff_loc"), self.guide.apos[2]) # tws_ref t = transform.getRotationFromAxis(datatypes.Vector(0, -1, 0), self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["ankle"]) # addind an npo parent transform to fix flip in Maya 2018.2 self.tws_npo = primitive.addTransform(self.eff_loc, self.getName("tws_npo"), t) self.tws_ref = primitive.addTransform(self.tws_npo, self.getName("tws_ref"), t) # Mid Controler ------------------------------------ t = transform.getTransform(self.ctrn_loc) self.mid_cns = primitive.addTransform(self.ctrn_loc, self.getName("mid_cns"), t) self.mid_ctl = self.addCtl(self.mid_cns, "mid_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.root_ctl) attribute.setKeyableAttributes( self.mid_ctl, params=["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) if self.settings["mirrorMid"]: if self.negate: self.mid_cns.rz.set(180) self.mid_cns.sz.set(-1) else: attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"]) # Twist references --------------------------------- x = datatypes.Vector(0, -1, 0) x = x * transform.getTransform(self.eff_loc) z = datatypes.Vector(self.normal.x, self.normal.y, self.normal.z) z = z * transform.getTransform(self.eff_loc) m = transform.getRotationFromAxis(x, z, "xz", self.negate) m = transform.setMatrixPosition(m, transform.getTranslation(self.ik_ctl)) self.rollRef = primitive.add2DChain(self.root, self.getName("rollChain"), self.guide.apos[:2], self.normal, self.negate, self.WIP) self.tws0_loc = primitive.addTransform( self.rollRef[0], self.getName("tws0_loc"), transform.getTransform(self.fk_ctl[0])) self.tws0_rot = primitive.addTransform( self.tws0_loc, self.getName("tws0_rot"), transform.getTransform(self.fk_ctl[0])) self.tws1_loc = primitive.addTransform( self.ctrn_loc, self.getName("tws1_loc"), transform.getTransform(self.ctrn_loc)) self.tws1_rot = primitive.addTransform( self.tws1_loc, self.getName("tws1_rot"), transform.getTransform(self.ctrn_loc)) # thickness control self.thick_lvl = primitive.addTransform( self.mid_ctl, self.getName("thickness_lvl"), transform.getTransform(self.ctrn_loc)) self.thick_ctl = self.addCtl(self.thick_lvl, "thickness_ctl", transform.getTransform(self.mid_ctl), self.color_ik, "arrow", w=self.size * .1, ro=datatypes.Vector([0, 1.5708, 0]), tp=self.mid_ctl) if self.negate and not self.settings["mirrorMid"]: self.thick_ctl.rz.set(180) self.thick_ctl.sz.set(-1) attribute.setKeyableAttributes(self.thick_ctl, ["tx", "ty"]) self.tws1B_loc = primitive.addTransform( self.ctrn_loc, self.getName("tws1B_loc"), transform.getTransform(self.ctrn_loc)) self.tws1B_rot = primitive.addTransform( self.tws1B_loc, self.getName("tws1B_rot"), transform.getTransform(self.ctrn_loc)) self.tws2_loc = primitive.addTransform( self.root_ctl, self.getName("tws2_loc"), transform.getTransform(self.tws_ref)) self.tws2_rot = primitive.addTransform( self.tws2_loc, self.getName("tws2_rot"), transform.getTransform(self.tws_ref)) self.tws2_rot.setAttr("sx", .001) # angle reader ---------------------------------------- t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[0], self.binormal, "yz") self.readerA = primitive.addTransform(self.root, self.getName("readerA_loc"), t) self.readerB = primitive.addTransform(self.readerA, self.getName("readerB_loc"), t) self.readerB.rotateOrder.set(2) # Divisions ---------------------------------------- # We have at least one division at the start, the end and one for # the elbow. + 2 for knee angle control if self.settings["supportJoints"]: ej = 2 else: ej = 0 self.divisions = self.settings["div0"] + self.settings["div1"] + 3 + ej self.div_cns = [] if self.settings["extraTweak"]: tagP = self.parentCtlTag self.tweak_ctl = [] for i in range(self.divisions): div_cns = primitive.addTransform(self.root_ctl, self.getName("div%s_loc" % i)) self.div_cns.append(div_cns) if self.settings["extraTweak"]: t = transform.getTransform(div_cns) tweak_ctl = self.addCtl(div_cns, "tweak%s_ctl" % i, t, self.color_fk, "square", w=self.size * .15, d=self.size * .15, ro=datatypes.Vector([0, 0, 1.5708]), tp=tagP) attribute.setKeyableAttributes(tweak_ctl) tagP = tweak_ctl self.tweak_ctl.append(tweak_ctl) self.jnt_pos.append([tweak_ctl, i, None, False]) else: self.jnt_pos.append([div_cns, i]) # End reference ------------------------------------ # To help the deformation on the ankle self.end_ref = primitive.addTransform(self.tws2_rot, self.getName("end_ref"), m) self.jnt_pos.append([self.end_ref, 'end']) # match IK FK references self.match_fk0_off = self.add_match_ref(self.fk_ctl[1], self.root, "matchFk0_npo", False) self.match_fk0 = self.add_match_ref(self.fk_ctl[0], self.match_fk0_off, "fk0_mth") self.match_fk1_off = self.add_match_ref(self.fk_ctl[2], self.root, "matchFk1_npo", False) self.match_fk1 = self.add_match_ref(self.fk_ctl[1], self.match_fk1_off, "fk1_mth") self.match_fk2 = self.add_match_ref(self.fk_ctl[2], self.ik_ctl, "fk2_mth") self.match_ik = self.add_match_ref(self.ik_ctl, self.fk2_ctl, "ik_mth") self.match_ikUpv = self.add_match_ref(self.upv_ctl, self.fk0_ctl, "upv_mth") # add visual reference self.line_ref = icon.connection_display_curve( self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # 1 bone chain Upv ref ============================================== self.ikHandleUpvRef = primitive.addIkHandle( self.root, self.getName("ikHandleArmChainUpvRef"), self.armChainUpvRef, "ikSCsolver") pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef) pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True) # Visibilities ------------------------------------- # fk fkvis_node = node.createReverseNode(self.blend_att) for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.line_ref.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) if self.settings["ikTR"]: for shp in self.ikRot_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- attribute.setRotOrder(self.fk0_ctl, "XZY") attribute.setRotOrder(self.fk1_ctl, "XYZ") attribute.setRotOrder(self.fk2_ctl, "YZX") attribute.setRotOrder(self.ik_ctl, "XYZ") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc] o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk_ctl[0], self.fk_ctl[1], self.fk_ref, self.length0, self.length1, self.negate) if self.settings["ikTR"]: # connect the control inputs outEff_dm = o_node.listConnections(c=True)[-1][1] inAttr = self.ikRot_npo.attr("translate") outEff_dm.attr("outputTranslate") >> inAttr outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale") dm_node = node.createDecomposeMatrixNode(o_node.attr("outB")) dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate") # rotation mulM_node = applyop.gear_mulmatrix_op( self.ikRot_ctl.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) intM_node = applyop.gear_intmatrix_op(o_node.attr("outEff"), mulM_node.attr("output"), o_node.attr("blend")) dm_node = node.createDecomposeMatrixNode(intM_node.attr("output")) dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate") transform.matchWorldTransform(self.fk2_ctl, self.ikRot_cns) # scale: this fix the scalin popping issue intM_node = applyop.gear_intmatrix_op( self.fk2_ctl.attr("worldMatrix"), self.ik_ctl_ref.attr("worldMatrix"), o_node.attr("blend")) mulM_node = applyop.gear_mulmatrix_op( intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix")) dm_node = node.createDecomposeMatrixNode(mulM_node.attr("output")) dm_node.attr("outputScale") >> self.eff_loc.attr("scale") pm.connectAttr(self.blend_att, o_node + ".blend") if self.negate: mulVal = -1 else: mulVal = 1 node.createMulNode(self.roll_att, mulVal, o_node + ".roll") pm.connectAttr(self.scale_att, o_node + ".scaleA") pm.connectAttr(self.scale_att, o_node + ".scaleB") pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch") pm.connectAttr(self.slide_att, o_node + ".slide") pm.connectAttr(self.softness_att, o_node + ".softness") pm.connectAttr(self.reverse_att, o_node + ".reverse") # Twist references --------------------------------- pm.pointConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX) pm.orientConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.root.attr("worldInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.tws2_npo.attr("translate")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate")) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.tws2_rot.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") attribute.setRotOrder(self.tws2_rot, "XYZ") pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate") self.tws0_rot.setAttr("sx", .001) self.tws2_rot.setAttr("sx", .001) add_node = node.createAddNode(self.roundness_att, .001) pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx")) pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX") # Roll Shoulder applyop.splineIK(self.getName("rollRef"), self.rollRef, parent=self.root, cParent=self.bone0) # Volume ------------------------------------------- distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc) distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc) add_node = node.createAddNode(distA_node + ".distance", distB_node + ".distance") div_node = node.createDivNode(add_node + ".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix") div_node2 = node.createDivNode(div_node + ".outputX", dm_node + ".outputScaleX") self.volDriver_att = div_node2 + ".outputX" if self.settings["extraTweak"]: for tweak_ctl in self.tweak_ctl: for shp in tweak_ctl.getShapes(): pm.connectAttr(self.tweakVis_att, shp.attr("visibility")) # Divisions ---------------------------------------- # at 0 or 1 the division will follow exactly the rotation of the # controler.. and we wont have this nice tangent + roll for i, div_cns in enumerate(self.div_cns): if self.settings["supportJoints"]: if i < (self.settings["div0"] + 1): perc = i * .5 / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = .49 elif i < (self.settings["div0"] + 3): perc = .50 elif i < (self.settings["div0"] + 4): perc = .51 else: perc = .5 + \ (i - self.settings["div0"] - 3.0) * .5 / \ (self.settings["div1"] + 1.0) else: if i < (self.settings["div0"] + 1): perc = i * .5 / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = .501 else: perc = .5 + \ (i - self.settings["div0"] - 1.0) * .5 / \ (self.settings["div1"] + 1.0) perc = max(.001, min(.990, perc)) # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1.0 - perc, 40) else: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc, 40) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") # Squash n Stretch o_node = applyop.gear_squashstretch2_op( div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, o_node + ".blend") pm.connectAttr(self.volDriver_att, o_node + ".driver") pm.connectAttr(self.st_att[i], o_node + ".stretch") pm.connectAttr(self.sq_att[i], o_node + ".squash") # match IK/FK ref pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True) pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True) if self.settings["ikTR"]: transform.matchWorldTransform(self.ikRot_ctl, self.match_ikRot) transform.matchWorldTransform(self.fk_ctl[2], self.match_fk2) return
def addObjects(self): """Add all the objects needed to create the component.""" self.setup = primitive.addTransformFromPos( self.setupWS, self.getName("WS")) attribute.lockAttribute(self.setup) self.WIP = self.options["mode"] self.normal = self.getNormalFromPos(self.guide.apos) self.length0 = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) self.length1 = vector.getDistance(self.guide.apos[1], self.guide.apos[2]) self.length2 = vector.getDistance(self.guide.apos[2], self.guide.apos[3]) self.length3 = vector.getDistance(self.guide.apos[3], self.guide.apos[4]) # 3bones chain self.chain3bones = primitive.add2DChain( self.setup, self.getName("chain3bones%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # 2bones chain self.chain2bones = primitive.add2DChain( self.setup, self.getName("chain2bones%s_jnt"), self.guide.apos[0:3], self.normal, False, self.WIP) # Leg chain self.legBones = primitive.add2DChain( self.root, self.getName("legBones%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # Leg chain FK ref self.legBonesFK = primitive.add2DChain( self.root, self.getName("legFK%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # Leg chain IK ref self.legBonesIK = primitive.add2DChain( self.root, self.getName("legIK%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # 1 bone chain for upv ref self.legChainUpvRef = primitive.add2DChain( self.root, self.getName("legUpvRef%s_jnt"), [self.guide.apos[0], self.guide.apos[3]], self.normal, False, self.WIP) # mid joints self.mid1_jnt = primitive.addJoint( self.legBones[0], self.getName("mid1_jnt"), self.legBones[1].getMatrix(worldSpace=True), self.WIP) self.mid1_jnt.attr("radius").set(3) self.mid1_jnt.setAttr("jointOrient", 0, 0, 0) self.mid2_jnt = primitive.addJoint( self.legBones[1], self.getName("mid2_jnt"), self.legBones[2].getMatrix(worldSpace=True), self.WIP) self.mid2_jnt.attr("radius").set(3) self.mid2_jnt.setAttr("jointOrient", 0, 0, 0) # base Controlers ----------------------------------- t = transform.getTransformFromPos(self.guide.apos[0]) self.root_npo = primitive.addTransform( self.root, self.getName("root_npo"), t) self.root_ctl = self.addCtl(self.root_npo, "root_ctl", t, self.color_fk, "circle", w=self.length0 / 6, tp=self.parentCtlTag) attribute.lockAttribute(self.root_ctl, ["sx", "sy", "sz", "v"]) # FK Controlers ----------------------------------- t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) self.fk0_npo = primitive.addTransform( self.root_ctl, self.getName("fk0_npo"), t) self.fk0_ctl = self.addCtl( self.fk0_npo, "fk0_ctl", t, self.color_fk, "cube", w=self.length0, h=self.size * .1, d=self.size * .1, po=datatypes.Vector(.5 * self.length0 * self.n_factor, 0, 0), tp=self.root_ctl) attribute.setKeyableAttributes(self.fk0_ctl) t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate) self.fk1_npo = primitive.addTransform( self.fk0_ctl, self.getName("fk1_npo"), t) self.fk1_ctl = self.addCtl( self.fk1_npo, "fk1_ctl", t, self.color_fk, "cube", w=self.length1, h=self.size * .1, d=self.size * .1, po=datatypes.Vector(.5 * self.length1 * self.n_factor, 0, 0), tp=self.fk0_ctl) attribute.setKeyableAttributes(self.fk1_ctl) t = transform.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate) self.fk2_npo = primitive.addTransform( self.fk1_ctl, self.getName("fk2_npo"), t) self.fk2_ctl = self.addCtl( self.fk2_npo, "fk2_ctl", t, self.color_fk, "cube", w=self.length2, h=self.size * .1, d=self.size * .1, po=datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0), tp=self.fk1_ctl) attribute.setKeyableAttributes(self.fk2_ctl) t = transform.getTransformLookingAt(self.guide.apos[3], self.guide.apos[4], self.normal, "xz", self.negate) self.fk3_npo = primitive.addTransform( self.fk2_ctl, self.getName("fk3_npo"), t) self.fk3_ctl = self.addCtl( self.fk3_npo, "fk3_ctl", t, self.color_fk, "cube", w=self.length3, h=self.size * .1, d=self.size * .1, po=datatypes.Vector(.5 * self.length3 * self.n_factor, 0, 0), tp=self.fk2_ctl) attribute.setKeyableAttributes(self.fk3_ctl) self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl, self.fk3_ctl] for x in self.fk_ctl: attribute.setInvertMirror(x, ["tx", "ty", "tz"]) # Mid Controlers ------------------------------------ self.knee_lvl = primitive.addTransform( self.root, self.getName("knee_lvl"), transform.getTransform(self.mid1_jnt)) self.knee_ctl = self.addCtl( self.knee_lvl, "knee_ctl", transform.getTransform(self.mid1_jnt), self.color_ik, "sphere", w=self.size * .2, tp=self.root_ctl) attribute.setInvertMirror(self.knee_ctl, ["tx", "ty", "tz"]) attribute.lockAttribute(self.knee_ctl, ["sx", "sy", "sz", "v"]) self.ankle_lvl = primitive.addTransform( self.root, self.getName("ankle_lvl"), transform.getTransform(self.mid2_jnt)) self.ankle_ctl = self.addCtl( self.ankle_lvl, "ankle_ctl", transform.getTransform(self.mid2_jnt), self.color_ik, "sphere", w=self.size * .2, tp=self.knee_ctl) attribute.setInvertMirror(self.ankle_ctl, ["tx", "ty", "tz"]) attribute.lockAttribute(self.ankle_ctl, ["sx", "sy", "sz", "v"]) # IK controls -------------------------------------------------------- # foot IK # "z-x", t_align = transform.getTransformLookingAt(self.guide.apos[3], self.guide.apos[4], self.normal, "zx", False) if self.settings["ikOri"]: t = transform.getTransformFromPos(self.guide.pos["foot"]) # t = transform.getTransformLookingAt(self.guide.pos["foot"], # self.guide.pos["eff"], # self.x_axis, # "zx", # False) else: t = t_align self.ik_cns = primitive.addTransform( self.root_ctl, self.getName("ik_cns"), t) self.ikcns_ctl = self.addCtl(self.ik_cns, "ikcns_ctl", t, self.color_ik, "null", w=self.size * .12, tp=self.ankle_ctl) attribute.setInvertMirror(self.ikcns_ctl, ["tx"]) attribute.lockAttribute(self.ikcns_ctl, ["sx", "sy", "sz", "v"]) self.ik_ctl = self.addCtl(self.ikcns_ctl, "ik_ctl", t, self.color_ik, "cube", w=self.size * .12, h=self.size * .12, d=self.size * .12, tp=self.ikcns_ctl) attribute.setKeyableAttributes(self.ik_ctl) attribute.setRotOrder(self.ik_ctl, "XZY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) attribute.lockAttribute(self.ik_ctl, ["sx", "sy", "sz", "v"]) # 2 bones ik layer self.ik2b_ikCtl_ref = primitive.addTransform( self.ik_ctl, self.getName("ik2B_A_ref"), t_align) self.ik2b_bone_ref = primitive.addTransform( self.chain3bones[3], self.getName("ik2B_B_ref"), t_align) self.ik2b_blend = primitive.addTransform( self.ik_ctl, self.getName("ik2B_blend"), t_align) self.roll_ctl = self.addCtl(self.ik2b_blend, "roll_ctl", t_align, self.color_ik, "crossarrow", w=self.length2 * .5 * self.n_factor, tp=self.ik_ctl) self.ik2b_ik_npo = primitive.addTransform( self.roll_ctl, self.getName("ik2B_ik_npo"), transform.getTransform(self.chain3bones[-1])) self.ik2b_ik_ref = primitive.addTransformFromPos( self.ik2b_ik_npo, self.getName("ik2B_ik_ref"), self.guide.pos["ankle"]) attribute.lockAttribute( self.roll_ctl, ["tx", "ty", "tz", "sx", "sy", "sz", "v"]) # upv v = self.guide.apos[2] - self.guide.apos[0] v = self.normal ^ v v.normalize() v *= self.size * .5 v += self.guide.apos[1] self.upv_lvl = primitive.addTransformFromPos( self.root, self.getName("upv_lvl"), v) self.upv_cns = primitive.addTransformFromPos( self.upv_lvl, self.getName("upv_cns"), v) self.upv_ctl = self.addCtl(self.upv_cns, "upv_ctl", transform.getTransform(self.upv_cns), self.color_ik, "diamond", w=self.size * .12, tp=self.ik_ctl) attribute.setInvertMirror(self.upv_ctl, ["tx"]) attribute.setKeyableAttributes(self.upv_ctl, ["tx", "ty", "tz"]) # Soft IK objects 3 bones chain -------------------------------- t = transform.getTransformLookingAt(self.guide.pos["root"], self.guide.pos["foot"], self.x_axis, "zx", False) self.aim_tra = primitive.addTransform( self.root_ctl, self.getName("aimSoftIK"), t) t = transform.getTransformFromPos(self.guide.pos["foot"]) self.wristSoftIK = primitive.addTransform( self.aim_tra, self.getName("wristSoftIK"), t) self.softblendLoc = primitive.addTransform( self.root, self.getName("softblendLoc"), t) # Soft IK objects 2 Bones chain ---------------------------- t = transform.getTransformLookingAt(self.guide.pos["root"], self.guide.pos["ankle"], self.x_axis, "zx", False) self.aim_tra2 = primitive.addTransform( self.root_ctl, self.getName("aimSoftIK2"), t) t = transform.getTransformFromPos(self.guide.pos["ankle"]) self.ankleSoftIK = primitive.addTransform( self.aim_tra2, self.getName("ankleSoftIK"), t) self.softblendLoc2 = primitive.addTransform( self.root, self.getName("softblendLoc2"), t) # References -------------------------------------- self.ik_ref = primitive.addTransform( self.ik_ctl, self.getName("ik_ref"), transform.getTransform(self.ik_ctl)) self.fk_ref = primitive.addTransform( self.fk_ctl[3], self.getName("fk_ref"), transform.getTransform(self.ik_ctl)) # twist references -------------------------------------- self.rollRef = primitive.add2DChain(self.root, self.getName("rollChain"), self.guide.apos[:2], self.normal, False, self.WIP) self.tws0_loc = primitive.addTransform( self.rollRef[0], self.getName("tws0_loc"), transform.getTransform(self.legBones[0])) self.tws0_rot = primitive.addTransform( self.tws0_loc, self.getName("tws0_rot"), transform.getTransform(self.legBones[0])) self.tws0_rot.setAttr("sx", .001) self.tws1_loc = primitive.addTransform( self.mid1_jnt, self.getName("tws1_loc"), transform.getTransform(self.mid1_jnt)) self.tws1_rot = primitive.addTransform( self.tws1_loc, self.getName("tws1_rot"), transform.getTransform(self.mid1_jnt)) self.tws1_rot.setAttr("sx", .001) self.tws2_loc = primitive.addTransform( self.mid2_jnt, self.getName("tws2_loc"), transform.getTransform(self.mid2_jnt)) self.tws2_rot = primitive.addTransform( self.tws2_loc, self.getName("tws2_rot"), transform.getTransform(self.mid2_jnt)) self.tws2_rot.setAttr("sx", .001) self.tws3_loc = primitive.addTransform( self.legBones[3], self.getName("tws3_loc"), transform.getTransform(self.legBones[3])) self.tws3_rot = primitive.addTransform( self.tws3_loc, self.getName("tws3_rot"), transform.getTransform(self.legBones[3])) self.tws3_rot.setAttr("sx", .001) # Divisions ---------------------------------------- # We have at least one division at the start, the end and one for # the knee and one ankle o_set = self.settings self.divisions = o_set["div0"] + o_set["div1"] + o_set["div2"] + 4 self.div_cns = [] for i in range(self.divisions): div_cns = primitive.addTransform(self.root_ctl, self.getName("div%s_loc" % i)) self.div_cns.append(div_cns) self.jnt_pos.append([div_cns, i]) # End reference ------------------------------------ # To help the deformation on the foot self.end_ref = primitive.addTransform( self.tws3_rot, self.getName("end_ref"), transform.getTransform(self.legBones[3])) self.jnt_pos.append([self.end_ref, 'end']) # match IK FK references self.match_fk0_off = primitive.addTransform( self.root, self.getName("matchFk0_npo"), transform.getTransform(self.fk_ctl[1])) self.match_fk0 = primitive.addTransform( self.match_fk0_off, self.getName("fk0_mth"), transform.getTransform(self.fk_ctl[0])) self.match_fk1_off = primitive.addTransform( self.root, self.getName("matchFk1_npo"), transform.getTransform(self.fk_ctl[2])) self.match_fk1 = primitive.addTransform( self.match_fk1_off, self.getName("fk1_mth"), transform.getTransform(self.fk_ctl[1])) self.match_fk2_off = primitive.addTransform( self.root, self.getName("matchFk2_npo"), transform.getTransform(self.fk_ctl[3])) self.match_fk2 = primitive.addTransform( self.match_fk2_off, self.getName("fk2_mth"), transform.getTransform(self.fk_ctl[2])) self.match_fk3 = primitive.addTransform( self.ik_ctl, self.getName("fk3_mth"), transform.getTransform(self.fk_ctl[3])) self.match_ik = primitive.addTransform( self.fk3_ctl, self.getName("ik_mth"), transform.getTransform(self.ik_ctl)) self.match_ikUpv = primitive.addTransform( self.fk0_ctl, self.getName("upv_mth"), transform.getTransform(self.upv_ctl)) # add visual reference self.line_ref = icon.connection_display_curve( self.getName("visalRef"), [self.upv_ctl, self.knee_ctl])
def addObjects(self): """Add all the objects needed to create the component.""" self.normal = self.guide.blades["blade"].z * -1 self.binormal = self.guide.blades["blade"].x self.WIP = self.options["mode"] if self.negate and self.settings["overrideNegate"]: self.negate = False self.n_factor = 1 if self.settings["overrideNegate"]: self.mirror_conf = [0, 0, 1, 1, 1, 0, 0, 0, 0] else: self.mirror_conf = [0, 0, 0, 0, 0, 0, 0, 0, 0] # IK controls --------------------------------------------- self.ik_ctl = [] # tOld = False self.previusTag = self.parentCtlTag for i, t in enumerate( transform.getChainTransform2(self.guide.apos, self.normal, self.negate)): ik_npo = primitive.addTransform(self.root, self.getName("ik%s_npo" % i), t) ik_ctl = self.addCtl(ik_npo, "ik%s_ctl" % i, t, self.color_ik, "square", w=self.size * .15, h=self.size * .15, d=self.size * .15, ro=datatypes.Vector([0, 0, 1.5708]), tp=self.previusTag, mirrorConf=self.mirror_conf) attribute.setKeyableAttributes(ik_ctl, self.tr_params) self.ik_ctl.append(ik_ctl) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve(self.root, self.getName("mst_crv"), self.ik_ctl, 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_transforms = [] self.twister = [] self.ref_twist = [] parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root)) self.jointList = [] self.preiviousCtlTag = self.parentCtlTag for i in range(self.settings["fkNb"]): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns if i in [0, self.settings["fkNb"] - 1] and False: fk_ctl = primitive.addTransform( parentctl, self.getName("%s_loc" % i), transform.getTransform(parentctl)) fk_npo = fk_ctl if i in [self.settings["fkNb"] - 1]: self.fk_ctl.append(fk_ctl) else: m = transform.getTransform(self.root) t = transform.getTransform(parentctl) m.inverse() fk_npo = primitive.addTransform(parentctl, self.getName("fk%s_npo" % (i)), t) fk_ctl = self.addCtl(fk_npo, "fk%s_ctl" % (i), transform.getTransform(parentctl), self.color_fk, "cube", w=self.size * .1, h=self.size * .1, d=self.size * .1, tp=self.preiviousCtlTag, mirrorConf=self.mirror_conf) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl self.fk_npo.append(fk_npo) parentctl = fk_ctl scl_ref = primitive.addTransform(parentctl, self.getName("%s_scl_ref" % i), transform.getTransform(parentctl)) self.scl_transforms.append(scl_ref) # Deformers (Shadow) self.jnt_pos.append([scl_ref, i]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"])
def addObjects(self): """Add all the objects needed to create the component.""" t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.guide.blades["blade"].z * -1, "yx", self.negate) t2 = transform.setMatrixPosition(t, self.guide.apos[1]) int_t = t self.preiviousCtlTag = self.parentCtlTag # FK Controlers ------------------------------------ self.fk_ctl = [] self.fk_npo = [] parentctl = self.root blend_increment = 1.0 / (self.settings["division"] - 1) blend_val = 0.0 for i in range(self.settings["division"]): fk_npo = primitive.addTransform(parentctl, self.getName("fk%s_npo" % (i)), int_t) self.fk_npo.append(fk_npo) fk_ctl = self.addCtl(fk_npo, "fk%s_ctl" % (i), int_t, self.color_fk, "cube", w=self.size, h=self.size * .05, d=self.size, tp=self.preiviousCtlTag) self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl parentctl = fk_ctl blend_val = blend_val + blend_increment int_t = transform.getInterpolateTransformMatrix(t, t2, blend=blend_val) for x in self.fk_ctl: attribute.setKeyableAttributes(x) attribute.setRotOrder(x, "ZXY") attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Ik Controlers ------------------------------------ self.ik0_npo = primitive.addTransform(self.fk_ctl[0], self.getName("ik0_npo"), t) self.ik0_ctl = self.addCtl(self.ik0_npo, "ik0_ctl", t, self.color_ik, "compas", w=self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params) attribute.setRotOrder(self.ik0_ctl, "ZXY") attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"]) t = transform.setMatrixPosition(t, self.guide.apos[1]) self.ik1_npo = primitive.addTransform(self.fk_ctl[-1], self.getName("ik1_npo"), t) self.ik1_ctl = self.addCtl(self.ik1_npo, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params) attribute.setRotOrder(self.ik1_ctl, "ZXY") attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"]) # Tangent controllers ------------------------------- if self.settings["centralTangent"]: vec_pos = vector.linearlyInterpolate(self.guide.apos[0], self.guide.apos[1], .33) t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_off = primitive.addTransform(self.tan0_npo, self.getName("tan0_off"), t) self.tan0_ctl = self.addCtl(self.tan0_off, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) vec_pos = vector.linearlyInterpolate(self.guide.apos[0], self.guide.apos[1], .66) t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_off = primitive.addTransform(self.tan1_npo, self.getName("tan1_off"), t) self.tan1_ctl = self.addCtl(self.tan1_off, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) # Tangent mid control vec_pos = vector.linearlyInterpolate(self.guide.apos[0], self.guide.apos[1], .5) t = transform.setMatrixPosition(t, vec_pos) self.tan_npo = primitive.addTransform(self.tan0_npo, self.getName("tan_npo"), t) self.tan_ctl = self.addCtl(self.tan_npo, "tan_ctl", t, self.color_fk, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan_ctl, self.t_params) attribute.setInvertMirror(self.tan_ctl, ["tx"]) else: vec_pos = vector.linearlyInterpolate(self.guide.apos[0], self.guide.apos[1], .33) t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_ctl = self.addCtl(self.tan0_npo, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) vec_pos = vector.linearlyInterpolate(self.guide.apos[0], self.guide.apos[1], .66) t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_ctl = self.addCtl(self.tan1_npo, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.scl_transforms = [] self.twister = [] self.ref_twist = [] t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.guide.blades["blade"].z * -1, "yx", self.negate) parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root)) self.jointList = [] self.preiviousCtlTag = self.parentCtlTag for i in range(self.settings["division"]): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns parentctl = div_cns scl_ref = primitive.addTransform(parentctl, self.getName("%s_scl_ref" % i), transform.getTransform(parentctl)) self.scl_transforms.append(scl_ref) # Deformers (Shadow) self.jnt_pos.append([scl_ref, i]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) # Connections (Hooks) ------------------------------ self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx")) self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
def addObjects(self): self.normal = self.guide.blades["blade"].z * -1. # Ik Controlers ------------------------------------ t = tra.getTransform(self.root) t = tra.setMatrixPosition(t, self.guide.pos["neck"]) self.neck_cns = pri.addTransform(self.root, self.getName("neck_cns"), t) t = tra.getTransformLookingAt(self.guide.pos["neck"], self.guide.pos["eff0"], self.normal, "yx", self.negate) t = tra.setMatrixPosition(t, self.guide.pos["neck"]) self.neck_npo = pri.addTransform(self.neck_cns, self.getName("neck_npo"), t) w = self.size * 0.5 # for compatibility reason, this name is not neck_ctl, but ik_ctl self.neck_ctl = self.addCtl(self.neck_npo, "ik_ctl", t, self.color_ik, "compas", w=w) att.setKeyableAttributes(self.neck_ctl) att.setRotOrder(self.neck_ctl, "ZXY") self.jnt_pos.append([self.neck_ctl, 0]) t = tra.getTransformLookingAt(self.guide.pos["head"], self.guide.pos["eff1"], self.normal, "yx", self.negate) self.head_pos_ref = pri.addTransform(self.neck_ctl, self.getName("head_pos_ref"), t) # TODO: Division ----------------------------------------- # Head --------------------------------------------- t = tra.getTransform(self.root) t = tra.setMatrixPosition(t, self.guide.pos["head"]) self.head_cns = pri.addTransform(self.root, self.getName("head_cns"), t) t = tra.getTransformLookingAt(self.guide.pos["head"], self.guide.pos["eff1"], self.normal, "yx", self.negate) self.head_npo = pri.addTransform(self.head_cns, self.getName("head_npo"), t) dist = vec.getDistance(self.guide.pos["head"], self.guide.pos["eff1"]) w = self.size * 0.5 h = dist d = self.size * 0.5 po = dt.Vector(0, dist * 0.5, 0) self.head_ctl = self.addCtl(self.head_npo, "head_ctl", t, self.color_fk, "cube", w=w, h=h, d=d, po=po) att.setRotOrder(self.head_ctl, "ZXY") att.setInvertMirror(self.neck_ctl, ["tx", "ry", "rz"]) att.setInvertMirror(self.head_ctl, ["tx", "ry", "rz"]) self.jnt_pos.append([self.head_ctl, "head"])
def addObjects(self): """Add all the objects needed to create the component.""" self.div_count = len(self.guide.apos) - 5 plane = [self.guide.apos[0], self.guide.apos[-4], self.guide.apos[-3]] self.normal = self.getNormalFromPos(plane) self.binormal = self.getBiNormalFromPos(plane) # Heel --------------------------------------------- # bank pivot t = transform.getTransformLookingAt(self.guide.pos["heel"], self.guide.apos[-4], self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["inpivot"]) self.in_npo = primitive.addTransform( self.root, self.getName("in_npo"), t) self.in_piv = primitive.addTransform( self.in_npo, self.getName("in_piv"), t) t = transform.setMatrixPosition(t, self.guide.pos["outpivot"]) self.out_piv = primitive.addTransform( self.in_piv, self.getName("out_piv"), t) # heel t = transform.getTransformLookingAt(self.guide.pos["heel"], self.guide.apos[-4], self.normal, "xz", self.negate) self.heel_loc = primitive.addTransform( self.out_piv, self.getName("heel_loc"), t) attribute.setRotOrder(self.heel_loc, "YZX") self.heel_ctl = self.addCtl(self.heel_loc, "heel_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.parentCtlTag) ymt_util.setKeyableAttributesDontLockVisibility(self.heel_ctl, self.r_params) # Tip ---------------------------------------------- v = datatypes.Vector(self.guide.apos[1].x, self.guide.apos[-1].y, self.guide.apos[1].z) t = transform.setMatrixPosition(t, v) self.tip_ctl = self.addCtl(self.heel_ctl, "tip_ctl", t, self.color_ik, "circle", w=self.size, tp=self.heel_ctl) ymt_util.setKeyableAttributesDontLockVisibility(self.tip_ctl, self.r_params) # Roll --------------------------------------------- if self.settings["useRollCtl"]: t = transform.getTransformLookingAt(self.guide.pos["heel"], self.guide.apos[-4], self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["root"]) self.roll_np = primitive.addTransform( self.root, self.getName("roll_npo"), t) self.roll_ctl = self.addCtl(self.roll_np, "roll_ctl", t, self.color_ik, "cylinder", w=self.size * .5, h=self.size * .5, ro=datatypes.Vector(3.1415 * .5, 0, 0), tp=self.tip_ctl) ymt_util.setKeyableAttributesDontLockVisibility(self.roll_ctl, ["rx", "rz"]) # Backward Controlers ------------------------------ bk_pos = self.guide.apos[1:-3] bk_pos.reverse() parent = self.tip_ctl self.bk_ctl = [] self.bk_loc = [] self.previousTag = self.tip_ctl def _add_loc_ctl(i, t, parent): loc = primitive.addTransform(parent, self.getName("bk%s_loc" % i), t) self.bk_loc.append(loc) if 0 < i: return loc ctl = self.addCtl(loc, "bk%s_ctl" % i, t, self.color_ik, "sphere", w=self.size * .15, tp=self.previousTag) ymt_util.setKeyableAttributesDontLockVisibility(ctl, self.r_params) self.previousTag = ctl self.bk_ctl.append(ctl) return ctl for i, pos in enumerate(bk_pos): if i == 0: t = transform.getTransform(self.heel_ctl) t = transform.setMatrixPosition(t, bk_pos[0]) else: dir = bk_pos[i - 1] t = transform.getTransformLookingAt( pos, dir, self.normal, "xz", self.negate) parent = _add_loc_ctl(i, t, parent) # FK Reference ------------------------------------ self.fk_ref = primitive.addTransformFromPos(self.bk_loc[-1], self.getName("fk_ref"), self.guide.apos[0]) self.fk_npo = primitive.addTransform( self.fk_ref, self.getName("fk0_npo"), transform.getTransform(self.bk_loc[-1])) # Forward Controlers ------------------------------ self.fk_ctl = [] self.fk_loc = [] parent = self.fk_npo self.previousTag = self.tip_ctl for i, bk_loc in enumerate(reversed(self.bk_loc[2:])): t = transform.getTransform(bk_loc) dist = vector.getDistance(self.guide.apos[i + 1], self.guide.apos[i + 2]) fk_loc = primitive.addTransform( parent, self.getName("fk%s_loc" % i), t) po_vec = datatypes.Vector(dist * .5 * self.n_factor, 0, 0) fk_ctl = self.addCtl(fk_loc, "fk%s_ctl" % i, t, self.color_fk, "cube", w=dist, h=self.size * .5, d=self.size * .5, po=po_vec, tp=self.previousTag) self.previousTag = fk_ctl ymt_util.setKeyableAttributesDontLockVisibility(fk_ctl) self.jnt_pos.append([fk_ctl, i]) parent = fk_ctl self.fk_ctl.append(fk_ctl) self.fk_loc.append(fk_loc)
def addObjects(self): """Add all the objects needed to create the component.""" # joint Description Names jd_names = ast.literal_eval( self.settings["jointNamesDescription_custom"]) jdn_neck = jd_names[0] jdn_head = jd_names[1] self.normal = self.guide.blades["blade"].z * -1 self.up_axis = pm.upAxis(q=True, axis=True) # Ik Controlers ------------------------------------ if self.settings["IKWorldOri"]: t = datatypes.TransformationMatrix() else: t = transform.getTransformLookingAt( self.guide.pos["tan1"], self.guide.pos["neck"], self.normal, "yx", self.negate, ) t = transform.setMatrixPosition(t, self.guide.pos["neck"]) self.ik_off = primitive.addTransform(self.root, self.getName("ik_off"), t) # handle Z up orientation offset if self.up_axis == "z" and self.settings["IKWorldOri"]: self.ik_off.rx.set(90) t = transform.getTransform(self.ik_off) self.ik_cns = primitive.addTransform(self.ik_off, self.getName("ik_cns"), t) self.ik_ctl = self.addCtl( self.ik_cns, "ik_ctl", t, self.color_ik, "compas", w=self.size * 0.5, tp=self.parentCtlTag, ) attribute.setKeyableAttributes(self.ik_ctl, self.tr_params) attribute.setRotOrder(self.ik_ctl, "ZXY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) # Tangents ----------------------------------------- if self.settings["tangentControls"]: t = transform.setMatrixPosition(t, self.guide.pos["tan1"]) self.tan1_loc = primitive.addTransform(self.ik_ctl, self.getName("tan1_loc"), t) self.tan1_ctl = self.addCtl( self.tan1_loc, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * 0.2, tp=self.ik_ctl, ) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["tan0"], self.normal, "yx", self.negate, ) t = transform.setMatrixPosition(t, self.guide.pos["tan0"]) self.tan0_loc = primitive.addTransform(self.root, self.getName("tan0_loc"), t) self.tan0_ctl = self.addCtl( self.tan0_loc, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * 0.2, tp=self.ik_ctl, ) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.root, self.tan0_ctl, self.tan1_ctl, self.ik_ctl], 3, ) self.slv_crv = curve.addCurve( self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3, ) self.mst_crv.setAttr("visibility", False) else: t = transform.setMatrixPosition(t, self.guide.pos["tan1"]) self.tan1_loc = primitive.addTransform(self.ik_ctl, self.getName("tan1_loc"), t) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["tan0"], self.normal, "yx", self.negate, ) t = transform.setMatrixPosition(t, self.guide.pos["tan0"]) self.tan0_loc = primitive.addTransform(self.root, self.getName("tan0_loc"), t) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.root, self.tan0_loc, self.tan1_loc, self.ik_ctl], 3, ) self.slv_crv = curve.addCurve( self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3, ) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_npo = [] self.twister = [] self.ref_twist = [] # adding 1 for the head self.divisions = self.settings["division"] + 1 parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root), ) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["neck"], self.normal, "yx", self.negate, ) self.intMRef = primitive.addTransform(self.root, self.getName("intMRef"), t) self.previousCtlTag = self.parentCtlTag for i in range(self.divisions): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i), t) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns scl_npo = primitive.addTransform( parentctl, self.getName("%s_scl_npo" % i), transform.getTransform(parentctl), ) # Controlers (First and last one are fake) if i in [self.divisions - 1]: # 0, fk_ctl = primitive.addTransform( scl_npo, self.getName("%s_loc" % i), transform.getTransform(parentctl), ) fk_npo = fk_ctl else: fk_npo = primitive.addTransform( scl_npo, self.getName("fk%s_npo" % i), transform.getTransform(parentctl), ) fk_ctl = self.addCtl( fk_npo, "fk%s_ctl" % i, transform.getTransform(parentctl), self.color_fk, "cube", w=self.size * 0.2, h=self.size * 0.05, d=self.size * 0.2, tp=self.previousCtlTag, ) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.previousCtlTag = fk_ctl self.fk_ctl.append(fk_ctl) self.scl_npo.append(scl_npo) self.fk_npo.append(fk_npo) parentctl = fk_ctl if i != self.divisions - 1: self.jnt_pos.append( [fk_ctl, string.replaceSharpWithPadding(jdn_neck, i + 1)]) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["neck"], self.guide.blades["blade"].z * -1, "yx", self.negate, ) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(0.0, 0, 1.0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Head --------------------------------------------- t = transform.getTransformLookingAt( self.guide.pos["head"], self.guide.pos["eff"], self.normal, "yx", self.negate, ) self.head_cns = primitive.addTransform(self.root, self.getName("head_cns"), t) dist = vector.getDistance(self.guide.pos["head"], self.guide.pos["eff"]) self.head_ctl = self.addCtl( self.head_cns, "head_ctl", t, self.color_fk, "cube", w=self.size * 0.5, h=dist, d=self.size * 0.5, po=datatypes.Vector(0, dist * 0.5, 0), tp=self.previousCtlTag, ) attribute.setRotOrder(self.head_ctl, "ZXY") attribute.setInvertMirror(self.head_ctl, ["tx", "rz", "ry"]) self.jnt_pos.append([self.head_ctl, jdn_head])
def addObjects(self): """Add all the objects needed to create the component.""" self.WIP = self.options["mode"] self.normal = self.getNormalFromPos(self.guide.apos) self.length0 = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) self.length1 = vector.getDistance(self.guide.apos[1], self.guide.apos[2]) self.length2 = vector.getDistance(self.guide.apos[2], self.guide.apos[3]) # 1 bone chain for upv ref self.legChainUpvRef = primitive.add2DChain( self.root, self.getName("legUpvRef%s_jnt"), [self.guide.apos[0], self.guide.apos[2]], self.normal, False, self.WIP) self.legChainUpvRef[1].setAttr( "jointOrientZ", self.legChainUpvRef[1].getAttr("jointOrientZ") * -1) # extra neutral pose t = transform.getTransformFromPos(self.guide.apos[0]) self.root_npo = primitive.addTransform(self.root, self.getName("root_npo"), t) self.root_ctl = self.addCtl(self.root_npo, "root_ctl", t, self.color_fk, "circle", w=self.length0 / 6, tp=self.parentCtlTag) # FK Controlers ----------------------------------- t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) self.fk0_npo = primitive.addTransform(self.root_ctl, self.getName("fk0_npo"), t) self.fk0_ctl = self.addCtl(self.fk0_npo, "fk0_ctl", t, self.color_fk, "cube", w=self.length0, h=self.size * .1, d=self.size * .1, po=datatypes.Vector( .5 * self.length0 * self.n_factor, 0, 0), tp=self.root_ctl) attribute.setKeyableAttributes( self.fk0_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate) self.fk1_npo = primitive.addTransform(self.fk0_ctl, self.getName("fk1_npo"), t) self.fk1_ctl = self.addCtl(self.fk1_npo, "fk1_ctl", t, self.color_fk, "cube", w=self.length1, h=self.size * .1, d=self.size * .1, po=datatypes.Vector( .5 * self.length1 * self.n_factor, 0, 0), tp=self.fk0_ctl) attribute.setKeyableAttributes( self.fk1_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"]) t = transform.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate) self.fk2_npo = primitive.addTransform(self.fk1_ctl, self.getName("fk2_npo"), t) self.fk2_ctl = self.addCtl(self.fk2_npo, "fk2_ctl", t, self.color_fk, "cube", w=self.length2, h=self.size * .1, d=self.size * .1, po=datatypes.Vector( .5 * self.length2 * self.n_factor, 0, 0), tp=self.fk1_ctl) attribute.setKeyableAttributes(self.fk2_ctl) self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl] for x in self.fk_ctl: attribute.setInvertMirror(x, ["tx", "ty", "tz"]) # IK Controlers ----------------------------------- self.ik_cns = primitive.addTransformFromPos(self.root_ctl, self.getName("ik_cns"), self.guide.pos["ankle"]) self.ikcns_ctl = self.addCtl(self.ik_cns, "ikcns_ctl", transform.getTransformFromPos( self.guide.pos["ankle"]), self.color_ik, "null", w=self.size * .12, tp=self.root_ctl) attribute.setInvertMirror(self.ikcns_ctl, ["tx"]) m = transform.getTransformLookingAt(self.guide.pos["ankle"], self.guide.pos["eff"], self.x_axis, "zx", False) self.ik_ctl = self.addCtl(self.ikcns_ctl, "ik_ctl", transform.getTransformFromPos( self.guide.pos["ankle"]), self.color_ik, "cube", w=self.size * .12, h=self.size * .12, d=self.size * .12, tp=self.ikcns_ctl) attribute.setKeyableAttributes(self.ik_ctl) attribute.setRotOrder(self.ik_ctl, "XZY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) # upv v = self.guide.apos[2] - self.guide.apos[0] v = self.normal ^ v v.normalize() v *= self.size * .5 v += self.guide.apos[1] self.upv_cns = primitive.addTransformFromPos(self.ik_ctl, self.getName("upv_cns"), v) self.upv_ctl = self.addCtl(self.upv_cns, "upv_ctl", transform.getTransform(self.upv_cns), self.color_ik, "diamond", w=self.size * .12, tp=self.root_ctl) if self.settings["mirrorMid"]: if self.negate: self.upv_cns.rz.set(180) self.upv_cns.sy.set(-1) else: attribute.setInvertMirror(self.upv_ctl, ["tx"]) attribute.setKeyableAttributes(self.upv_ctl, self.t_params) # References -------------------------------------- self.ik_ref = primitive.addTransform( self.ik_ctl, self.getName("ik_ref"), transform.getTransform(self.ik_ctl)) self.fk_ref = primitive.addTransform( self.fk_ctl[2], self.getName("fk_ref"), transform.getTransform(self.ik_ctl)) # Chain -------------------------------------------- # The outputs of the ikfk2bone solver self.bone0 = primitive.addLocator( self.root_ctl, self.getName("0_bone"), transform.getTransform(self.fk_ctl[0])) self.bone0_shp = self.bone0.getShape() self.bone0_shp.setAttr("localPositionX", self.n_factor * .5) self.bone0_shp.setAttr("localScale", .5, 0, 0) self.bone0.setAttr("sx", self.length0) self.bone0.setAttr("visibility", False) self.bone1 = primitive.addLocator( self.root_ctl, self.getName("1_bone"), transform.getTransform(self.fk_ctl[1])) self.bone1_shp = self.bone1.getShape() self.bone1_shp.setAttr("localPositionX", self.n_factor * .5) self.bone1_shp.setAttr("localScale", .5, 0, 0) self.bone1.setAttr("sx", self.length1) self.bone1.setAttr("visibility", False) tA = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) tA = transform.setMatrixPosition(tA, self.guide.apos[1]) tB = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate) t = transform.getInterpolateTransformMatrix(tA, tB) self.ctrn_loc = primitive.addTransform(self.root, self.getName("ctrn_loc"), t) self.eff_loc = primitive.addTransformFromPos(self.root_ctl, self.getName("eff_loc"), self.guide.apos[2]) # tws_ref t = transform.getRotationFromAxis(datatypes.Vector(0, -1, 0), self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["ankle"]) self.tws_ref = primitive.addTransform(self.eff_loc, self.getName("tws_ref"), t) # Mid Controler ------------------------------------ t = transform.getTransform(self.ctrn_loc) self.mid_cns = primitive.addTransform(self.ctrn_loc, self.getName("mid_cns"), t) self.mid_ctl = self.addCtl(self.mid_cns, "mid_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.root_ctl) if self.settings["mirrorMid"]: if self.negate: self.mid_cns.rz.set(180) self.mid_cns.sz.set(-1) else: attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"]) attribute.setKeyableAttributes(self.mid_ctl, self.t_params) # Twist references --------------------------------- x = datatypes.Vector(0, -1, 0) x = x * transform.getTransform(self.eff_loc) z = datatypes.Vector(self.normal.x, self.normal.y, self.normal.z) z = z * transform.getTransform(self.eff_loc) m = transform.getRotationFromAxis(x, z, "xz", self.negate) m = transform.setMatrixPosition(m, transform.getTranslation(self.ik_ctl)) self.tws0_loc = primitive.addTransform( self.root_ctl, self.getName("tws0_loc"), transform.getTransform(self.fk_ctl[0])) self.tws0_rot = primitive.addTransform( self.tws0_loc, self.getName("tws0_rot"), transform.getTransform(self.fk_ctl[0])) self.tws1_loc = primitive.addTransform( self.ctrn_loc, self.getName("tws1_loc"), transform.getTransform(self.ctrn_loc)) self.tws1_rot = primitive.addTransform( self.tws1_loc, self.getName("tws1_rot"), transform.getTransform(self.ctrn_loc)) self.tws1A_npo = primitive.addTransform(self.mid_ctl, self.getName("tws1A_npo"), tA) self.tws1A_loc = primitive.addTransform(self.tws1A_npo, self.getName("tws1A_loc"), tA) self.tws1B_npo = primitive.addTransform(self.mid_ctl, self.getName("tws1B_npo"), tB) self.tws1B_loc = primitive.addTransform(self.tws1B_npo, self.getName("tws1B_loc"), tB) self.tws2_npo = primitive.addTransform( self.root, self.getName("tws2_npo"), transform.getTransform(self.fk_ctl[2])) self.tws2_loc = primitive.addTransform( self.tws2_npo, self.getName("tws2_loc"), transform.getTransform(self.fk_ctl[2])) self.tws2_rot = primitive.addTransform( self.tws2_npo, self.getName("tws2_rot"), transform.getTransform(self.fk_ctl[2])) # Roll twist chain --------------------------------- # Arm self.uplegChainPos = [] ii = 1.0 / (self.settings["div0"] + 1) i = 0.0 for p in range(self.settings["div0"] + 2): self.uplegChainPos.append( vector.linearlyInterpolate(self.guide.pos["root"], self.guide.pos["knee"], blend=i)) i = i + ii self.uplegTwistChain = primitive.add2DChain( self.root, self.getName("uplegTwist%s_jnt"), self.uplegChainPos, self.normal, False, self.WIP) # Forearm self.lowlegChainPos = [] ii = 1.0 / (self.settings["div1"] + 1) i = 0.0 for p in range(self.settings["div1"] + 2): self.lowlegChainPos.append( vector.linearlyInterpolate(self.guide.pos["knee"], self.guide.pos["ankle"], blend=i)) i = i + ii self.lowlegTwistChain = primitive.add2DChain( self.root, self.getName("lowlegTwist%s_jnt"), self.lowlegChainPos, self.normal, False, self.WIP) pm.parent(self.lowlegTwistChain[0], self.mid_ctl) # Hand Aux chain and nonroll self.auxChainPos = [] ii = .5 i = 0.0 for p in range(3): self.auxChainPos.append( vector.linearlyInterpolate(self.guide.pos["ankle"], self.guide.pos["eff"], blend=i)) i = i + ii t = self.root.getMatrix(worldSpace=True) self.aux_npo = primitive.addTransform(self.root, self.getName("aux_npo"), t) self.auxTwistChain = primitive.add2DChain( self.aux_npo, self.getName("auxTwist%s_jnt"), self.lowlegChainPos[:3], self.normal, False, self.WIP) # Non Roll join ref --------------------------------- self.uplegRollRef = primitive.add2DChain( self.root, self.getName("uplegRollRef%s_jnt"), self.uplegChainPos[:2], self.normal, False, self.WIP) self.lowlegRollRef = primitive.add2DChain( self.aux_npo, self.getName("lowlegRollRef%s_jnt"), self.lowlegChainPos[:2], self.normal, False, self.WIP) # Divisions ---------------------------------------- # We have at least one division at the start, the end and one for the # elbow. + 2 for knee angle control self.divisions = self.settings["div0"] + self.settings["div1"] + 4 self.div_cns = [] for i in range(self.divisions): div_cns = primitive.addTransform(self.root_ctl, self.getName("div%s_loc" % i)) self.div_cns.append(div_cns) self.jnt_pos.append([div_cns, i]) # End reference ------------------------------------ # To help the deformation on the ankle self.end_ref = primitive.addTransform(self.eff_loc, self.getName("end_ref"), m) for a in "xyz": self.end_ref.attr("s%s" % a).set(1.0) if self.negate: self.end_ref.attr("ry").set(-180.0) self.jnt_pos.append([self.end_ref, 'end']) # Tangent controls t = transform.getInterpolateTransformMatrix(self.fk_ctl[0], self.tws1A_npo, .5) self.uplegTangentA_loc = primitive.addTransform( self.root_ctl, self.getName("uplegTangentA_loc"), self.fk_ctl[0].getMatrix(worldSpace=True)) self.uplegTangentA_npo = primitive.addTransform( self.uplegTangentA_loc, self.getName("uplegTangentA_npo"), t) self.uplegTangentA_ctl = self.addCtl(self.uplegTangentA_npo, "uplegTangentA_ctl", t, self.color_ik, "circle", w=self.size * .2, ro=datatypes.Vector( 0, 0, 1.570796), tp=self.mid_ctl) if self.negate: self.uplegTangentA_npo.rz.set(180) self.uplegTangentA_npo.sz.set(-1) attribute.setKeyableAttributes(self.uplegTangentA_ctl, self.t_params) t = transform.getInterpolateTransformMatrix(self.fk_ctl[0], self.tws1A_npo, .9) self.uplegTangentB_npo = primitive.addTransform( self.tws1A_loc, self.getName("uplegTangentB_npo"), t) self.uplegTangentB_ctl = self.addCtl(self.uplegTangentB_npo, "uplegTangentB_ctl", t, self.color_ik, "circle", w=self.size * .1, ro=datatypes.Vector( 0, 0, 1.570796), tp=self.mid_ctl) if self.negate: self.uplegTangentB_npo.rz.set(180) self.uplegTangentB_npo.sz.set(-1) attribute.setKeyableAttributes(self.uplegTangentB_ctl, self.t_params) tC = self.tws1B_npo.getMatrix(worldSpace=True) tC = transform.setMatrixPosition(tC, self.guide.apos[2]) t = transform.getInterpolateTransformMatrix(self.tws1B_npo, tC, .1) self.lowlegTangentA_npo = primitive.addTransform( self.tws1B_loc, self.getName("lowlegTangentA_npo"), t) self.lowlegTangentA_ctl = self.addCtl(self.lowlegTangentA_npo, "lowlegTangentA_ctl", t, self.color_ik, "circle", w=self.size * .1, ro=datatypes.Vector( 0, 0, 1.570796), tp=self.mid_ctl) if self.negate: self.lowlegTangentA_npo.rz.set(180) self.lowlegTangentA_npo.sz.set(-1) attribute.setKeyableAttributes(self.lowlegTangentA_ctl, self.t_params) t = transform.getInterpolateTransformMatrix(self.tws1B_npo, tC, .5) self.lowlegTangentB_loc = primitive.addTransform( self.root, self.getName("lowlegTangentB_loc"), tC) self.lowlegTangentB_npo = primitive.addTransform( self.lowlegTangentB_loc, self.getName("lowlegTangentB_npo"), t) self.lowlegTangentB_ctl = self.addCtl(self.lowlegTangentB_npo, "lowlegTangentB_ctl", t, self.color_ik, "circle", w=self.size * .2, ro=datatypes.Vector( 0, 0, 1.570796), tp=self.mid_ctl) if self.negate: self.lowlegTangentB_npo.rz.set(180) self.lowlegTangentB_npo.sz.set(-1) attribute.setKeyableAttributes(self.lowlegTangentB_ctl, self.t_params) t = self.mid_ctl.getMatrix(worldSpace=True) self.kneeTangent_npo = primitive.addTransform( self.mid_ctl, self.getName("kneeTangent_npo"), t) self.kneeTangent_ctl = self.addCtl(self.kneeTangent_npo, "kneeTangent_ctl", t, self.color_fk, "circle", w=self.size * .25, ro=datatypes.Vector(0, 0, 1.570796), tp=self.mid_ctl) if self.negate: self.kneeTangent_npo.rz.set(180) self.kneeTangent_npo.sz.set(-1) attribute.setKeyableAttributes(self.kneeTangent_ctl, self.t_params) # match IK FK references self.match_fk0_off = self.add_match_ref(self.fk_ctl[1], self.root, "matchFk0_npo", False) self.match_fk0 = self.add_match_ref(self.fk_ctl[0], self.match_fk0_off, "fk0_mth") self.match_fk1_off = self.add_match_ref(self.fk_ctl[2], self.root, "matchFk1_npo", False) self.match_fk1 = self.add_match_ref(self.fk_ctl[1], self.match_fk1_off, "fk1_mth") self.match_fk2 = self.add_match_ref(self.fk_ctl[2], self.ik_ctl, "fk2_mth") self.match_ik = self.add_match_ref(self.ik_ctl, self.fk2_ctl, "ik_mth") self.match_ikUpv = self.add_match_ref(self.upv_ctl, self.fk0_ctl, "upv_mth") # add visual reference self.line_ref = icon.connection_display_curve( self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
def addObjects(self): """Add all the objects needed to create the component.""" self.normal = self.getNormalFromPos(self.guide.apos) self.binormal = self.getBiNormalFromPos(self.guide.apos) self.length0 = vector.getDistance( self.guide.apos[0], self.guide.apos[1]) self.length1 = vector.getDistance( self.guide.apos[1], self.guide.apos[2]) self.length2 = vector.getDistance( self.guide.apos[2], self.guide.apos[3]) # FK Controlers ----------------------------------- # *ms* set npo @ Tpose, to make the fk rotation work # best with rot order"yzx" self.fk_cns = primitive.addTransformFromPos( self.root, self.getName("fk_cns"), self.guide.apos[0]) vec_offset = ((self.guide.apos[1] - self.guide.apos[0]) * [1, 0, 0]) tpv = self.guide.apos[0] + vec_offset t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) # *ms* add FK isolation self.fk0_npo = primitive.addTransform( self.fk_cns, self.getName("fk0_npo"), t) t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) po_off = datatypes.Vector(.35 * self.length0 * self.n_factor, 0, 0) self.fk0_ctl = self.addCtl(self.fk0_npo, "fk0_ctl", t, self.color_fk, "cube", w=self.length0 * .7, h=self.size * .1, d=self.size * .1, po=po_off, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.fk0_ctl) # *ms* add fk roll control Simage style po_off = datatypes.Vector(.85 * self.length0 * self.n_factor, 0, 0) self.fk0_roll_ctl = self.addCtl(self.fk0_ctl, "fk0_roll_ctl", t, self.color_fk, "cube", w=self.length0 * .3, h=self.size * .1, d=self.size * 0.1, po=po_off, tp=self.fk0_ctl) attribute.setRotOrder(self.fk0_roll_ctl, "YZX") attribute.setKeyableAttributes(self.fk0_roll_ctl, ["rx"]) self.fk0_mtx = primitive.addTransform( self.root, self.getName("fk0_mtx"), t) t = transform.setMatrixPosition(t, self.guide.apos[1]) self.fk1_ref = primitive.addTransform( self.fk0_roll_ctl, self.getName("fk1_ref"), t) self.fk1_loc = primitive.addTransform( self.root, self.getName("fk1_loc"), t) t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate) self.fk1_npo = primitive.addTransform( self.fk1_loc, self.getName("fk1_npo"), t) po_off = datatypes.Vector(.35 * self.length1 * self.n_factor, 0, 0) self.fk1_ctl = self.addCtl(self.fk1_npo, "fk1_ctl", t, self.color_fk, "cube", w=self.length1 * .7, h=self.size * .1, d=self.size * .1, po=po_off, tp=self.fk0_roll_ctl) attribute.setKeyableAttributes(self.fk1_ctl) self.fk1_mtx = primitive.addTransform( self.fk1_ctl, self.getName("fk1_mtx"), t) po_off = datatypes.Vector(.85 * self.length1 * self.n_factor, 0, 0) self.fk1_roll_ctl = self.addCtl(self.fk1_ctl, "fk1_roll_ctl", t, self.color_fk, "cube", w=self.length1 * .3, h=self.size * .1, d=self.size * .1, po=po_off, tp=self.fk1_ctl) attribute.setRotOrder(self.fk1_roll_ctl, "XYZ") attribute.setKeyableAttributes(self.fk1_roll_ctl, ["rx"]) t = transform.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate) # *ms* buffer object to feed into ikfk solver for hand seperation self.fk2_mtx = primitive.addTransform(self.fk1_roll_ctl, self.getName("fk2_mtx"), t) # fk2_loc is need to take the effector position + bone1 rotation t1 = transform.getTransformLookingAt(self.guide.apos[2], self.guide.apos[1], self.normal, "-xz", self.negate) self.fk2_loc = primitive.addTransform( self.root, self.getName("fk2_loc"), t1) self.fk2_npo = primitive.addTransform(self.fk2_loc, self.getName("fk2_npo"), t) po_off = datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0) self.fk2_ctl = self.addCtl(self.fk2_npo, "fk2_ctl", t, self.color_fk, "cube", w=self.length2, h=self.size * .1, d=self.size * .1, po=po_off, tp=self.fk1_roll_ctl) attribute.setKeyableAttributes(self.fk2_ctl) self.fk_ctl = [self.fk0_roll_ctl, self.fk1_mtx, self.fk2_ctl] self.fk_ctls = [self.fk0_ctl, self.fk0_roll_ctl, self.fk1_ctl, self.fk1_roll_ctl, self.fk2_ctl] for x in self.fk_ctls: attribute.setInvertMirror(x, ["tx", "ty", "tz"]) # IK Controlers ----------------------------------- self.ik_cns = primitive.addTransformFromPos( self.root, self.getName("ik_cns"), self.guide.pos["wrist"]) self.ikcns_ctl = self.addCtl( self.ik_cns, "ikcns_ctl", transform.getTransformFromPos(self.guide.pos["wrist"]), self.color_ik, "null", w=self.size * .12, tp=self.parentCtlTag) attribute.setInvertMirror(self.ikcns_ctl, ["tx", "ty", "tz"]) if self.negate: m = transform.getTransformLookingAt(self.guide.pos["wrist"], self.guide.pos["eff"], self.normal, "x-y", True) else: m = transform.getTransformLookingAt(self.guide.pos["wrist"], self.guide.pos["eff"], self.normal, "xy", False) self.ik_ctl = self.addCtl(self.ikcns_ctl, "ik_ctl", m, self.color_ik, "cube", w=self.size * .12, h=self.size * .12, d=self.size * .12, tp=self.ikcns_ctl) attribute.setKeyableAttributes(self.ik_ctl) attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) # upv v = self.guide.apos[2] - self.guide.apos[0] v = self.normal ^ v v.normalize() v *= self.size * .5 v += self.guide.apos[1] # *ms* auto up vector ------------------------------ self.upv_cns = primitive.addTransformFromPos(self.root, self.getName("upv_cns"), self.guide.apos[0]) self.upv_auv = primitive.addTransformFromPos(self.root, self.getName("upv_auv"), self.guide.apos[0]) self.upv_mtx = primitive.addTransformFromPos(self.upv_cns, self.getName("upv_mtx"), self.guide.apos[0]) self.upv_npo = primitive.addTransformFromPos(self.upv_mtx, self.getName("upv_npo"), v) self.upv_ctl = self.addCtl(self.upv_npo, "upv_ctl", transform.getTransform(self.upv_npo), self.color_ik, "diamond", w=self.size * .12, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.upv_ctl, self.t_params) attribute.setInvertMirror(self.upv_ctl, ["tx"]) # References -------------------------------------- # Calculate again the transfor for the IK ref. This way align with FK trnIK_ref = transform.getTransformLookingAt(self.guide.pos["wrist"], self.guide.pos["eff"], self.normal, "xz", self.negate) self.ik_ref = primitive.addTransform(self.ik_ctl, self.getName("ik_ref"), trnIK_ref) self.fk_ref = primitive.addTransform(self.fk_ctl[2], self.getName("fk_ref"), trnIK_ref) # Chain -------------------------------------------- # take outputs of the ikfk2bone solver self.bone0 = primitive.addLocator( self.root, self.getName("0_bone"), transform.getTransform(self.fk_ctl[0])) self.bone0_shp = self.bone0.getShape() self.bone0_shp.setAttr("localPositionX", self.n_factor * .5) self.bone0_shp.setAttr("localScale", .5, 0, 0) self.bone0.setAttr("sx", self.length0) self.bone0.setAttr("visibility", False) self.bone1 = primitive.addLocator( self.root, self.getName("1_bone"), transform.getTransform(self.fk_ctl[1])) self.bone1_shp = self.bone1.getShape() self.bone1_shp.setAttr("localPositionX", self.n_factor * .5) self.bone1_shp.setAttr("localScale", .5, 0, 0) self.bone1.setAttr("sx", self.length1) self.bone1.setAttr("visibility", False) self.ctrn_loc = primitive.addTransformFromPos(self.root, self.getName("ctrn_loc"), self.guide.apos[1]) # eff npo --- take the effector output of gear ik solver self.eff_npo = primitive.addTransformFromPos(self.root, self.getName("eff_npo"), self.guide.apos[2]) # eff loc --- take the fk ik blend result self.eff_loc = primitive.addTransformFromPos(self.eff_npo, self.getName("eff_loc"), self.guide.apos[2]) # Mid Controler ------------------------------------ self.mid_ctl = self.addCtl(self.ctrn_loc, "mid_ctl", transform.getTransform(self.ctrn_loc), self.color_ik, "sphere", w=self.size * .2, tp=self.parentCtlTag) attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"]) # *ms* add elbow thickness # Roll join ref self.tws0_npo = primitive.addTransform( self.root, self.getName("tws0_npo"), transform.getTransform(self.fk_ctl[0])) self.tws0_loc = primitive.addTransform( self.tws0_npo, self.getName("tws0_loc"), transform.getTransform(self.fk_ctl[0])) self.tws0_rot = primitive.addTransform( self.tws0_loc, self.getName("tws0_rot"), transform.getTransform(self.fk_ctl[0])) self.tws1_npo = primitive.addTransform( self.ctrn_loc, self.getName("tws1_npo"), transform.getTransform(self.ctrn_loc)) self.tws1_loc = primitive.addTransform( self.tws1_npo, self.getName("tws1_loc"), transform.getTransform(self.ctrn_loc)) self.tws1_rot = primitive.addTransform( self.tws1_loc, self.getName("tws1_rot"), transform.getTransform(self.ctrn_loc)) self.tws2_loc = primitive.addTransform( self.tws1_npo, self.getName("tws2_loc"), transform.getTransform(self.ctrn_loc)) self.tws2_rot = primitive.addTransform( self.tws2_loc, self.getName("tws2_rot"), transform.getTransform(self.ctrn_loc)) self.tws3_npo = primitive.addTransform( self.root, self.getName("tws3_npo"), transform.getTransform(self.fk_ctl[2])) self.tws3_loc = primitive.addTransform( self.tws3_npo, self.getName("tws3_loc"), transform.getTransform(self.fk_ctl[2])) self.tws3_rot = primitive.addTransform( self.tws3_loc, self.getName("tws3_rot"), transform.getTransform(self.fk_ctl[2])) # Divisions ---------------------------------------- # We have at least one division at the start, the end and one for the # elbow. + 2 for elbow angle control # separate up and dn limb self.divisions = self.settings["div0"] + self.settings["div1"] + 3 + 2 self.divisions0 = self.settings["div0"] + 2 self.divisions1 = self.settings["div1"] + 2 self.div_cns = [] self.div_cnsUp = [] self.div_cnsDn = [] self.div_ctls = [] self.div_org = primitive.addTransform( self.root, self.getName("div_org"), transform.getTransform(self.root)) self.previousTag = self.parentCtlTag for i in range(self.divisions0): div_cns = primitive.addTransform( self.div_org, self.getName("div%s_loc" % i)) if self.negate: div_ctl = self.addCtl( div_cns, self.getName("div%s_ctl" % i), transform.getTransform(div_cns), self.color_fk, "square", d=self.size * .05, w=self.size * .1, po=datatypes.Vector(0, self.size * -0.05, 0), ro=datatypes.Vector(0, 0, datatypes.radians(90)), tp=self.previousTag) else: div_ctl = self.addCtl( div_cns, self.getName("div%s_ctl" % i), transform.getTransform(div_cns), self.color_fk, "square", d=self.size * .05, w=self.size * .1, po=datatypes.Vector(0, self.size * 0.05, 0), ro=datatypes.Vector(0, 0, datatypes.radians(90)), tp=self.previousTag) attribute.setKeyableAttributes(div_ctl) self.previousTag = div_ctl self.div_cns.append(div_cns) self.div_cnsUp.append(div_cns) self.jnt_pos.append([div_ctl, i]) self.div_ctls.append(div_ctl) # mid division d = self.divisions0 self.div_mid = primitive.addTransform( self.div_org, self.getName("div%s_loc" % d), transform.getTransform(self.mid_ctl)) if self.negate: self.div_mid_ctl = self.addCtl( self.div_mid, self.getName("div%s_ctl" % d), transform.getTransform(self.div_mid), self.color_fk, "square", d=self.size * .05, w=self.size * .1, po=datatypes.Vector(0, self.size * -0.05, 0), ro=datatypes.Vector(0, 0, datatypes.radians(90)), tp=self.previousTag) else: self.div_mid_ctl = self.addCtl( self.div_mid, self.getName("div%s_ctl" % d), transform.getTransform(self.div_mid), self.color_fk, "square", d=self.size * .05, w=self.size * .1, po=datatypes.Vector(0, self.size * 0.05, 0), ro=datatypes.Vector(0, 0, datatypes.radians(90)), tp=self.previousTag) attribute.setKeyableAttributes(self.div_mid_ctl) self.previousTag = div_ctl self.div_cns.append(self.div_mid) self.jnt_pos.append([self.div_mid_ctl, self.divisions0]) self.div_ctls.append(self.div_mid_ctl) # down division for i in range(self.divisions1): dd = i + self.divisions1 + 1 div_cns = primitive.addTransform( self.div_org, self.getName("div%s_loc" % dd)) if self.negate: div_ctl = self.addCtl( div_cns, self.getName("div%s_ctl" % dd), transform.getTransform(div_cns), self.color_fk, "square", d=self.size * .05, w=self.size * .1, po=datatypes.Vector(0, self.size * -0.05, 0), ro=datatypes.Vector(0, 0, datatypes.radians(90)), tp=self.previousTag) else: div_ctl = self.addCtl( div_cns, self.getName("div%s_ctl" % dd), transform.getTransform(div_cns), self.color_fk, "square", d=self.size * .05, w=self.size * .1, po=datatypes.Vector(0, self.size * 0.05, 0), ro=datatypes.Vector(0, 0, datatypes.radians(90)), tp=self.previousTag) attribute.setKeyableAttributes(div_ctl) self.previousTag = div_ctl self.div_cns.append(div_cns) self.div_cnsDn.append(div_cns) self.jnt_pos.append([div_ctl, i + self.divisions0 + 1]) self.div_ctls.append(div_ctl) # End reference ------------------------------------ # To help the deformation on the wrist self.jnt_pos.append([self.eff_loc, 'end']) # match IK FK references self.match_fk0 = self.add_match_ref(self.fk_ctl[0], self.root, "fk0_mth") self.match_fk1 = self.add_match_ref(self.fk_ctl[1], self.root, "fk1_mth") self.match_fk2 = self.add_match_ref(self.fk_ctl[2], self.ik_ctl, "fk2_mth") self.match_ik = self.add_match_ref(self.ik_ctl, self.fk2_ctl, "ik_mth") self.match_ikUpv = self.add_match_ref(self.upv_ctl, self.fk0_roll_ctl, "upv_mth") # add visual reference self.line_ref = icon.connection_display_curve( self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
def addObjects(self): """Add all the objects needed to create the component.""" self.up_axis = pm.upAxis(q=True, axis=True) self.div_count = len(self.guide.apos) - 5 plane = [self.guide.apos[0], self.guide.apos[-4], self.guide.apos[-3]] self.normal = self.getNormalFromPos(plane) self.binormal = self.getBiNormalFromPos(plane) # Heel --------------------------------------------- # bank pivot t = transform.getTransformLookingAt(self.guide.pos["heel"], self.guide.apos[-4], self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["inpivot"]) self.in_npo = primitive.addTransform(self.root, self.getName("in_npo"), t) self.in_piv = primitive.addTransform(self.in_npo, self.getName("in_piv"), t) t = transform.setMatrixPosition(t, self.guide.pos["outpivot"]) self.out_piv = primitive.addTransform(self.in_piv, self.getName("out_piv"), t) # heel t = transform.getTransformLookingAt(self.guide.pos["heel"], self.guide.apos[-4], self.normal, "xz", self.negate) self.heel_loc = primitive.addTransform(self.out_piv, self.getName("heel_loc"), t) attribute.setRotOrder(self.heel_loc, "YZX") self.heel_ctl = self.addCtl(self.heel_loc, "heel_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.heel_ctl, self.r_params) # Tip ---------------------------------------------- if self.up_axis == "y": v = datatypes.Vector(self.guide.apos[-5].x, self.guide.pos["heel"].y, self.guide.apos[-5].z) else: v = datatypes.Vector(self.guide.apos[-5].x, self.guide.apos[-5].y, self.guide.pos["heel"].z) t = transform.setMatrixPosition(t, v) self.tip_ctl = self.addCtl(self.heel_ctl, "tip_ctl", t, self.color_ik, "circle", w=self.size, tp=self.heel_ctl) attribute.setKeyableAttributes(self.tip_ctl, self.r_params) # Roll --------------------------------------------- if self.settings["useRollCtl"]: t = transform.getTransformLookingAt(self.guide.pos["heel"], self.guide.apos[-4], self.normal, "xz", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["root"]) self.roll_np = primitive.addTransform(self.root, self.getName("roll_npo"), t) self.roll_ctl = self.addCtl(self.roll_np, "roll_ctl", t, self.color_ik, "cylinder", w=self.size * .5, h=self.size * .5, ro=datatypes.Vector(3.1415 * .5, 0, 0), tp=self.tip_ctl) attribute.setKeyableAttributes(self.roll_ctl, ["rx", "rz"]) # Backward Controlers ------------------------------ bk_pos = self.guide.apos[1:-3] bk_pos.reverse() parent = self.tip_ctl self.bk_ctl = [] self.bk_loc = [] self.previousTag = self.tip_ctl for i, pos in enumerate(bk_pos): if i == 0: t = transform.getTransform(self.heel_ctl) t = transform.setMatrixPosition(t, pos) else: direction = bk_pos[i - 1] t = transform.getTransformLookingAt(pos, direction, self.normal, "xz", self.negate) bk_loc = primitive.addTransform(parent, self.getName("bk%s_loc" % i), t) bk_ctl = self.addCtl(bk_loc, "bk%s_ctl" % i, t, self.color_ik, "sphere", w=self.size * .15, tp=self.previousTag) attribute.setKeyableAttributes(bk_ctl, self.r_params) self.previousTag = bk_ctl self.bk_loc.append(bk_loc) self.bk_ctl.append(bk_ctl) parent = bk_ctl # FK Reference ------------------------------------ self.fk_ref = primitive.addTransformFromPos(self.bk_ctl[-1], self.getName("fk_ref"), self.guide.apos[0]) self.fk_npo = primitive.addTransform( self.fk_ref, self.getName("fk0_npo"), transform.getTransform(self.bk_ctl[-1])) # Forward Controlers ------------------------------ self.fk_ctl = [] self.fk_loc = [] parent = self.fk_npo self.previousTag = self.tip_ctl for i, bk_ctl in enumerate(reversed(self.bk_ctl[1:])): if i == len(self.bk_ctl) - 2: t = transform.getTransform(self.tip_ctl) v = transform.getTranslation(bk_ctl) t = transform.setMatrixPosition(t, v) else: t = transform.getTransform(bk_ctl) dist = vector.getDistance(self.guide.apos[i + 1], self.guide.apos[i + 2]) fk_loc = primitive.addTransform(parent, self.getName("fk%s_loc" % i), t) po_vec = datatypes.Vector(dist * .5 * self.n_factor, 0, 0) fk_ctl = self.addCtl(fk_loc, "fk%s_ctl" % i, t, self.color_fk, "cube", w=dist, h=self.size * .5, d=self.size * .5, po=po_vec, tp=self.previousTag) self.previousTag = fk_ctl attribute.setKeyableAttributes(fk_ctl) if i: name = "ball" + str(i) else: name = "ball" self.jnt_pos.append([fk_ctl, name]) parent = fk_ctl self.fk_ctl.append(fk_ctl) self.fk_loc.append(fk_loc)
def addObjects(self): """Add all the objects needed to create the component.""" # Auto bend with position controls ------------------- if self.settings["autoBend"]: self.autoBendChain = primitive.add2DChain( self.root, self.getName("autoBend%s_jnt"), [self.guide.apos[0], self.guide.apos[-1]], self.guide.blades["blade"].z * -1, False, True) for j in self.autoBendChain: j.drawStyle.set(2) # Ik Controlers ------------------------------------ if self.settings["IKWorldOri"]: t = datatypes.TransformationMatrix() t = transform.setMatrixPosition(t, self.guide.apos[0]) else: t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) self.ik0_npo = primitive.addTransform(self.root, self.getName("ik0_npo"), t) self.ik0_ctl = self.addCtl(self.ik0_npo, "ik0_ctl", t, self.color_ik, "compas", w=self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params) attribute.setRotOrder(self.ik0_ctl, "ZXY") attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"]) # hip base joint # TODO: add option in setting for on/off if True: self.hip_lvl = primitive.addTransform(self.ik0_ctl, self.getName("hip_lvl"), t) self.jnt_pos.append([self.hip_lvl, "hip"]) t = transform.setMatrixPosition(t, self.guide.apos[-1]) if self.settings["autoBend"]: self.autoBend_npo = primitive.addTransform( self.root, self.getName("spinePosition_npo"), t) self.autoBend_ctl = self.addCtl(self.autoBend_npo, "spinePosition_ctl", t, self.color_ik, "square", w=self.size, d=.3 * self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.autoBend_ctl, ["tx", "ty", "tz", "ry"]) attribute.setInvertMirror(self.autoBend_ctl, ["tx", "ry"]) self.ik1_npo = primitive.addTransform(self.autoBendChain[0], self.getName("ik1_npo"), t) self.ik1autoRot_lvl = primitive.addTransform( self.ik1_npo, self.getName("ik1autoRot_lvl"), t) self.ik1_ctl = self.addCtl(self.ik1autoRot_lvl, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.autoBend_ctl) else: t = transform.setMatrixPosition(t, self.guide.apos[-1]) self.ik1_npo = primitive.addTransform(self.root, self.getName("ik1_npo"), t) self.ik1_ctl = self.addCtl(self.ik1_npo, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params) attribute.setRotOrder(self.ik1_ctl, "ZXY") attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"]) # Tangent controllers ------------------------------- if self.settings["centralTangent"]: # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .33) vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_off = primitive.addTransform(self.tan0_npo, self.getName("tan0_off"), t) self.tan0_ctl = self.addCtl(self.tan0_off, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .66) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_off = primitive.addTransform(self.tan1_npo, self.getName("tan1_off"), t) self.tan1_ctl = self.addCtl(self.tan1_off, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) # Tangent mid control vec_pos = vector.linearlyInterpolate(self.guide.apos[0], self.guide.apos[-1], .5) t = transform.setMatrixPosition(t, vec_pos) self.tan_npo = primitive.addTransform(self.tan0_npo, self.getName("tan_npo"), t) self.tan_ctl = self.addCtl(self.tan_npo, "tan_ctl", t, self.color_fk, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan_ctl, self.t_params) attribute.setInvertMirror(self.tan_ctl, ["tx"]) else: # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .33) vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_ctl = self.addCtl(self.tan0_npo, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .66) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_ctl = self.addCtl(self.tan1_npo, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_transforms = [] self.twister = [] self.ref_twist = [] t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root)) self.jointList = [] self.preiviousCtlTag = self.parentCtlTag for i in range(self.settings["division"]): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns # Controlers (First and last one are fake) # if i in [0]: # TODO: add option setting to add or not the first and # last controller for the fk if i in [0, self.settings["division"] - 1] and False: # if i in [0, self.settings["division"] - 1]: fk_ctl = primitive.addTransform( parentctl, self.getName("%s_loc" % i), transform.getTransform(parentctl)) fk_npo = fk_ctl if i in [self.settings["division"] - 1]: self.fk_ctl.append(fk_ctl) else: m = transform.getTransform(self.root) t = transform.getTransform(parentctl) m.inverse() fk_npo = primitive.addTransform(parentctl, self.getName("fk%s_npo" % (i)), t) fk_ctl = self.addCtl(fk_npo, "fk%s_ctl" % (i), transform.getTransform(parentctl), self.color_fk, "cube", w=self.size, h=self.size * .05, d=self.size, tp=self.preiviousCtlTag) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl self.fk_npo.append(fk_npo) parentctl = fk_ctl scl_ref = primitive.addTransform(parentctl, self.getName("%s_scl_ref" % i), transform.getTransform(parentctl)) self.scl_transforms.append(scl_ref) # Deformers (Shadow) self.jnt_pos.append([scl_ref, i]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) # TODO: update this part with the optiona FK controls update for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Connections (Hooks) ------------------------------ self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx")) self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
def _addObjectsFkControl(self, i, parentdiv, parentctl, t, parent_twistRef): # References tm = datatypes.TransformationMatrix(t) tm.addRotation([0., 0., math.pi / -2.], 'XYZ', om.MSpace.kObject) # TODO: align with convention tm.addRotation([0., math.pi / -2., 0], 'XYZ', om.MSpace.kObject) global_t = datatypes.Matrix(tm) # global input div_cns = addTransform(parentdiv, self.getName("%s_cns" % i)) div_cns_npo = addTransform(div_cns, self.getName("%s_cns_npo" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) div_cns.setMatrix(global_t, worldSpace=True) self.div_cns.append(div_cns) self.div_cns_npo.append(div_cns_npo) parentdiv = div_cns # t = getTransform(parentctl) if i == 0: p = parentctl else: # p = self.scl_transforms[i - 1] p = self.fk_local_in[i - 1] fk_npo = addTransform(p, self.getName("fk%s_npo" % (i)), global_t) # local input fk_local_npo = addTransform(fk_npo, self.getName("fk%s_local_npo" % i), global_t) fk_local_in = addTransform(fk_local_npo, self.getName("fk%s_local_in" % i), global_t) self.fk_local_in.append(fk_local_in) if i < len(self.guide.apos) - 1: h = (self.guide.apos[i] - self.guide.apos[i + 1]).length() * .8 else: h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1) # FIXME: rotate by blade po = datatypes.Vector([0, h / 2., 0]) fk_ctl = self.addCtl( fk_local_in, "fk%s_ctl" % (i), global_t, self.color_fk, "cube", w=h * .66, h=h, d=h * 0.3, # ro=datatypes.Vector([0, -math.pi / 2., 0]), po=po, tp=self.preiviousCtlTag, mirrorConf=self.mirror_conf) ymt_util.setKeyableAttributesDontLockVisibility(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl self.fk_npo.append(fk_npo) self.fk_local_npo.append(fk_local_npo) parentctl = fk_ctl scl_ref = addTransform(parentctl, self.getName("%s_scl_ref" % i), getTransform(parentctl)) self.scl_transforms.append(scl_ref) if i == 0 and self.settings["isSplitHip"]: t = self._getTransformWithRollByBlade(getTransform(self.guide.root)) h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1) po = datatypes.Vector([0, self.size / len(self.guide.apos) * -.8, 0]) hip_fk_local_in = addTransform(p, self.getName("hip_fk_local_in"), t) self.hip_fk_local_in = hip_fk_local_in self.fk_hip_ctl = self.addCtl( hip_fk_local_in, "fk_hip_ctl", t, self.color_fk, "cube", w=h * .66, h=h, d=h * 0.3, # ro=datatypes.Vector([0, -math.pi / 2., 0]), po=po, tp=self.preiviousCtlTag, mirrorConf=self.mirror_conf) hip_scl_ref = addTransform(self.fk_hip_ctl, self.getName("hip_scl_ref"), t) # Deformers (Shadow) if self.settings["addJoints"]: if self.settings["isSplitHip"]: if i == 0: self.jnt_pos.append([hip_scl_ref, 0]) self.jnt_pos.append([scl_ref, i + 1]) else: self.jnt_pos.append([scl_ref, i]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = addTransform( parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = addTransform( parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation( datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) attribute.setInvertMirror(self.fk_hip_ctl, ["tx", "rz", "ry"]) return parentdiv, parentctl