def addSetupAttr(self, name, attrType, value, minValue=None, maxValue=None, keyable=True, writable=True): '''Helper Method. Create a new Animation attributes This attribute is NOT meant to be accssible by animators Args: name (str): Unique part name of the system object attrType (str): 'bool', 'string', 'short', 'float'... value (): Default value matching the type defined minValue (float||int): Minimum value of the attribute (for float and integer) maxValue (float||int): Maximum value of the attribute (for float and integer) keyable (bool): Is keyable writable (bool): Is writable Returns: str ''' if "Setup" not in self._uiHosts: self._uiHosts["Setup"] = self.addRig(self.nodes("setup"), "Setup") attributes.setKeyables(self._uiHosts["Setup"], []) a = self.addAttr(self._uiHosts["Setup"], name, attrType, value, minValue, maxValue, keyable, writable) return a
def createObjects(self): self.bfr = [] self.ctl = [] parent = None color = self.colorIk() if self.settings( "useIkColor") else self.colorFk() axis = self.sign() + "yz" self.jntparent = [] self.splitParent = [] # for i, tfm in enumerate(self.transforms("Part"), start=1): for i, (t, dy, dz) in enumerate(izip(self.translations("Part"), self.directions("Part", "y"), self.directions("Part", "z")), start=1): tfm = Transformation.lookAt(t, dy, dz, axis, negativeSide=self.negate()) part = "Part{}".format(i) bfr = self.addBfr(None, part, tfm=tfm) self.bfr.append(bfr) if self.settings("addControllers"): ctl = self.addCtl(bfr, part, tfm=tfm, icon="cube", color=color) self.ctl.append(ctl) attributes.setRotOrder(ctl, self.settings("defaultRotationOrder")) keyables = [ attr for attr in constants.ATTRS_TRS if self.settings(attr) ] attributes.setKeyables(ctl, keyables) jntparent = ctl else: jntparent = bfr if self.settings("dynamic"): harmonic = self.addRig(jntparent, "Harmonic{}".format(i), tfm=tfm) jntparent = harmonic self.jntparent.append(jntparent) if self.settings("splitRotation"): splitParent = self.addRig(jntparent, "Split{}".format(i), tfm=tfm) self.splitParent.append(splitParent)
def _createTangentObjects(self, prefix, i, size, bone, btfm, dist, icon): pos = Vector3([dist,0,0]) * btfm.asMatrix() tfm = btfm.copy(translation=pos) tanBfr = self.addBfr(bone, "{s}{i}".format(s=prefix,i=i+1), tfm=tfm) tanSolve = self.addRig(tanBfr, "{s}Solve{i}".format(s=prefix,i=i+1), tfm=tfm) tanCtl = self.addCtl(tanSolve, "{s}{i}".format(s=prefix,i=i+1), tfm, icon, size=size * 0.5, color=self.colorIk()) attributes.setKeyables(tanCtl, ["posx","posy","posz"]) # self.addToSubControllers(tanCtl) return tanBfr, tanSolve, tanCtl
def createObjects(self): # TRANSFORMATION rootTfm = self.transforms("Rail") posTfm = [ tfm.copy(translation=pos) for tfm, pos in izip(rootTfm, self.translations("Pos")) ] negTfm = [ tfm.copy(translation=pos) for tfm, pos in izip(rootTfm, self.translations("Neg")) ] # CONTROLLERS self._lmts = [] self._slds = [] self._ctls = [] for i, (rtfm, ptfm, ntfm) in enumerate(izip(rootTfm, posTfm, negTfm), start=1): irtfm = rtfm.asMatrix().inverse() irtfm = irtfm.asTransform() p = ptfm * irtfm limit_max = p.translation.x p = ntfm * irtfm limit_min = p.translation.x length = limit_max - limit_min offset = length * .5 + limit_min self._lmts.append([limit_min, limit_max]) rail = self.addRig(None, "Rail{}".format(i), rtfm, "cube", size=1, po=(offset, 0, 0), so=(abs(length), .5, .5)) slider = self.addRig(rail, "Slider{}".format(i), rtfm, "cube") if self.settings("addControllers"): ctl = self.addCtl(slider, "Slider{}".format(i), rtfm, "cube", color=self.colorIk()) self._ctls.append(ctl) attributes.setKeyables(slider) self._slds.append(slider)
def createObjects(self): # SIZE size = self.translations("Root").distance(self.translations("Eff")) # TRANSFORMATION # Normal normal = self.directions("Root", "z") direction = self.translations("Eff") - self.translations("Root") rootTfm = Transformation.lookAt(self.translations("Root"), direction, normal, self.nsign() + "yz", self.negate()) dynTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "xz", self.negate()) posTfm = dynTfm.copy(translation=self.translations("Eff")) upvPos = Vector3([0, 0, 10]) * dynTfm.asMatrix() # OBJECTS # Controller self.dynBfr = self.addBfr(None, "Part1", dynTfm) self.dynCtl = self.addCtl(self.dynBfr, "Part1", dynTfm, "sphere", size=size, po=(self.factor(), 0, 0), so=(1, 1, 0), color=self.colorFk()) attributes.setKeyables(self.dynCtl) # self.setInversedParameters(self.dynCtl, middle=["posz", "rotx", "roty"]) self.posBfr = self.addBfr(self.dynBfr, "Part2", posTfm) self.posCtl = self.addCtl(self.posBfr, "Part2", posTfm, "sphere", size=size * 1.5, so=[0, 1, 1], color=self.colorIk()) attributes.setKeyables(self.posCtl) # self.setInversedParameters(self.posCtl, middle=["posz", "rotx", "roty"]) # Dynamic ---------------------------- self.harmonic = self.addRig(self.posCtl, "Harmonic", posTfm, "diamond", size=1)
def createObjects(self): # TRANSFORMATION rootTfm = self.transforms("Rail") posTfm = self.transforms("Pos") negTfm = self.transforms("Neg") for i, (root, pos, neg) in enumerate(izip(rootTfm, posTfm, negTfm), start=1): root.scale = self.scales("Rail{}".format(i)) pos.scale = self.scales("Pos{}".format(i)) neg.scale = self.scales("Neg{}".format(i)) # CONTROLLERS self._rails = [] self._psts = [] self._ngts = [] self._slds = [] self._bfrs = [] for i, (rtfm, ptfm, ntfm) in enumerate(izip(rootTfm, posTfm, negTfm), start=1): rail = self.addRig(None, "Rail{}".format(i), rtfm, "cube", size=1) pos = self.addRig(rail, "Pos{}".format(i), ptfm, "null", size=1) neg = self.addRig(rail, "Neg{}".format(i), ntfm, "cube", size=1) bfr = self.addBfr(rail, "Slider{}".format(i), rtfm) if self.settings("addControllers"): slider = self.addCtl(bfr, "Part{}".format(i), rtfm, "sphere", color=self.colorIk()) attributes.setKeyables(slider) else: slider = self.addRig(bfr, "Part{}".format(i), rtfm, "sphere", size=1) create.cnsCurve("Crv{}".format(i), [neg, rail, pos], degree=1) self._bfrs.append(bfr) self._rails.append(rail) self._slds.append(slider) self._psts.append(pos) self._ngts.append(neg)
def createObjects(self): # TRANSFORMATION normal = self.directions("Root", "z") positions = Vector3Array( [self.translations("Root"), self.translations("Eff")]) ctlTfm = TransformationArray.chain(positions, normal, negativeSide=self.negate(), endTransform=True) self.length = self.translations("Root").distance( self.translations("Eff")) # CONTROLLERS startBfr = self.addBfr(None, "Start", ctlTfm[0]) endBfr = self.addBfr(None, "End", ctlTfm[1]) if self.settings("addControllers"): startCtl = self.addCtl(startBfr, "Start", ctlTfm[0], "cube", color=self.colorIk()) attributes.setKeyables(startCtl, constants.ATTRS_TR) endCtl = self.addCtl(endBfr, "End", ctlTfm[1], "cube", color=self.colorIk()) attributes.setKeyables(endCtl, constants.ATTRS_TR) self.centers = [startCtl, endCtl] else: self.centers = [startBfr, endBfr] # Stretch self.bone = self.addRig(self.centers[0], "Bone", ctlTfm[0], "cube", po=(self.length * .5, 0, 0), so=(self.length, 1, 1))
def addAnimAttr(self, name, attrType, value, minValue=None, maxValue=None, keyable=True): '''Helper Method. Create a new Animation attributes This attribute is meant to be accessible by animators Args: name (str): Unique part name of the system object attrType (str): 'bool', 'string', 'short', 'float'... value (): Default value matching the type defined minValue (float||int): Minimum value of the attribute (for float and integer) maxValue (float||int): Maximum value of the attribute (for float and integer) keyable (bool): Is keyable Returns: str ''' # For now we only support one UIHost, but we could # pass an argument for which host to crete the attr to if "UI" not in self._uiHosts: self._uiHosts["UI"] = self.addRig(self.nodes("setup"), "Anim") attributes.setKeyables(self._uiHosts["UI"], []) a = self.addAttr(self._uiHosts["UI"], name, attrType, value, minValue, maxValue, keyable, writable=True) return a
def createObjects(self): # TRANSFORMATIONS normal = Vector3.planeNormal(self.translations("Root"), self.translations("Part")[-1], self.translations("Heel")) if self.negate(): normal *= -1 rootTfm = Transformation.lookAt(self.translations("Root"), constants.AXIS_Y, normal, "y-x", self.negate()) direction = self.translations("Part")[-1] - self.translations("Heel") heelTfm = Transformation.lookAt(self.translations("Heel"), direction, normal, "xz", self.negate()) if self.count("Part") > 1: B = self.translations("Heel") - self.translations("Part")[-1] C = self.translations("Part")[0] - self.translations("Part")[-1] a = 1 - ((math.cos(B.angle(C)) * C.length()) / B.length()) else: a = .5 swivel_pos = self.translations("Heel").lerp( self.translations("Part")[-1], a) swivelTfm = heelTfm.copy(translation=swivel_pos) direction = self.translations("Part")[0] - self.translations("Root") fkrefTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "xz", self.negate()) fkTfm = TransformationArray.chain(self.translations("Part"), normal, axis="xz", negativeSide=self.negate(), endTransform=False) fkTfm = fkTfm.appended( heelTfm.copy(translation=self.translations("Part")[-1])) # CONTROLLERS # Root self._root = self.addRig(None, "Root", rootTfm) # Heel self.heelBfr = self.addBfr(self._root, "Heel", heelTfm) self.heelRol = self.addRig(self.heelBfr, "HeelRoll", tfm=heelTfm) self.heelCtl = self.addCtl(self.heelRol, "Heel", heelTfm, "sphere", so=[1, 1, 0], color=self.colorIk()) attributes.setKeyables(self.heelCtl, constants.ATTRS_TR) # self.setInversedParameters(self.heelCtl, middle=["posz", "rotx", "roty"]) # Swivel self.swivelBfr = self.addBfr(self.heelCtl, "Swivel", swivelTfm) self.swivelCtl = self.addCtl(self.swivelBfr, "Swivel", swivelTfm, "sphere", so=[3, 0, 3], color=self.colorIk()) attributes.setKeyables(self.swivelCtl, constants.ATTRS_TR) # self.setInversedParameters(self.swivelCtl, middle=["posz", "rotx", "roty"]) # Roll self.rollCtl = self.addCtl(self._root, "Roll", rootTfm, "sphere", color=self.colorIk(), so=[0, 2, 2]) # self.addToSubControllers(self.rollCtl) attributes.setKeyables(self.rollCtl, ["rotx", "rotz"]) # self.setInversedParameters(self.rollCtl, middle=["rotz"]) # Backward Controllers parent = self.swivelCtl self.bkBfr = [] self.bkRol = [] self.bkCtl = [] for i, tfm in enumerate(reversed(fkTfm)): index = i + 1 bkBfr = self.addBfr(parent, "Bk%s" % index, tfm=tfm) bkRol = self.addRig(bkBfr, "Bk%sRoll" % index, tfm=tfm) bkCtl = self.addCtl(bkRol, "Bk%s" % index, tfm, "sphere", color=self.colorIk(), so=[1, 1, 0]) attributes.setKeyables(bkCtl, constants.ATTRS_R) # self.setInversedParameters(bkCtl, middle=["rotx", "roty"]) self.bkBfr.append(bkBfr) self.bkRol.append(bkRol) self.bkCtl.append(bkCtl) parent = bkCtl # Forward Controllers self.fkRef = self.addRig(self.bkCtl[-1], "FkRef", fkrefTfm) self.fkBfr = [] self.fkCtl = [] parent = self.fkRef for i, (tfm, bkCtl) in enumerate(izip(fkTfm, self.bkCtl[:-1]), start=1): fkBfr = self.addBfr(parent, "Fk%s" % i, tfm=tfm) fkCtl = self.addCtl(fkBfr, "Fk%s" % i, tfm, "sphere", color=self.colorFk(), so=[0, 2, 4]) attributes.setKeyables( fkCtl, [t + s for t, s in product(["scl", "rot", "pos"], "xyz")]) # self.setInversedParameters(fkCtl, middle=["posz", "rotx", "roty"]) parent = fkCtl self.fkBfr.append(fkBfr) self.fkCtl.append(fkCtl)
def createObjects(self): # Search for optional Upv marker to determine normal if "Upv" in self.translations(): upv_pos = self.translations("Upv") normal = self.translations("Upv") - self.translations("Root") else: normal = self.directions("Root", "z") upv_pos = None # Transformation direction = self.translations("Eff") - self.translations("Root") dirTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "xz", self.negate()) ctlTfm = Transformation.lookAt(self.translations("Ctrl"), self.directions("Ctrl", "x"), self.directions("Ctrl", "z"), "xz", self.negate()) trgTfm = Transformation.lookAt(self.translations("Eff"), self.directions("Eff", "x"), self.directions("Eff", "z"), "xz", self.negate()) rigTfm = ctlTfm.copy(translation=self.translations("Root")) if self.settings("extraOffsetController") and self.settings( "keepRotationOffset"): offTfm = Transformation.lookAt(self.translations("Root"), self.directions("Root", "x"), self.directions("Root", "z"), "zy", self.negate()) offctlTfm = offTfm.copy(translation=self.translations("Ctrl")) else: offTfm = rigTfm offctlTfm = ctlTfm if not upv_pos: upv_pos = Vector3([0, 0, 10]) * dirTfm.asMatrix() upvTfm = dirTfm.copy(translation=upv_pos) # Direction self.dirRig = self.addRig(None, "Direction", dirTfm) # Up Vector upvBfr = self.addBfr(None, "Upv", upvTfm) if self.settings("addUpVController"): self.parentUpv = self.addCtl(upvBfr, "Upv", upvTfm, "diamond", size=.5, color=self.colorIk()) # self.addToSubControllers(self.parentUpv) else: self.parentUpv = upvBfr # Target self.targetBfr = self.addBfr(None, "Target", trgTfm) if self.settings("addTargetController"): # Target self.targetCtl = self.addCtl(self.targetBfr, "Target", trgTfm, "cube", size=1, color=self.colorIk()) # self.addToSubControllers(self.targetCtl) attributes.setKeyables(self.targetCtl, constants.ATTRS_T) # self.setInversedsettings(self.targetCtl, middle=["posy"]) if self.settings("addLocalController"): # Local Controller localBfr = self.addBfr(self.dirRig, "LocalNP", rigTfm) self.localRig = self.addRig(localBfr, "Local", rigTfm, "cube") # self.setNeutralPose(self.localRig) localBfr = self.addBfr(None, "Local", ctlTfm) self.localCtl = self.addCtl(localBfr, "Local", ctlTfm, "sphere", size=1, color=self.colorFk()) # self.setInversedsettings(self.localCtl, middle=["posx", "roty", "rotz"]) # Extra Offset Controller if self.settings("extraOffsetController"): self.offsetRig = self.addRig(self.localRig, "Offset", offTfm, "cube", size=.5) self.offsetCtl = self.addCtl(self.localCtl, "Offset", offctlTfm, "sphere", size=.5, color=self.colorIk())
def createObjects(self): # TRANSFORMATIONS positions = Vector3Array([ self.translations("Root"), self.translations("Knee"), self.translations("Ankle"), self.translations("Toe") ]) normal = Vector3.planeNormal(*positions[:3]) oriNormal = normal.copy() if self.negate(): normal *= -1 d = [(positions[i], positions[i + 1]) for i in range(3)] self.lengths = [Vector3.distance(a, b) for a, b in d] self.lengths.append(1) ratio = self.lengths[0] / sum(self.lengths[:2]) self.setSettings(lengths=self.lengths[:3]) # root rootTfm = Transformation.fromParts( translation=self.translations("Root")) # fk fkTfm = TransformationArray.chain(positions, normal, axis="xz", negativeSide=self.negate(), endTransform=False) lookAtEff = self.translations("Eff") - self.translations("Toe") fk3Tfm = Transformation.lookAt(self.translations("Toe"), lookAtEff, constants.AXIS_Y, "y-x", self.negate()) fkTfm = fkTfm.appended(fk3Tfm) for tfm, dist in izip(fkTfm, self.lengths): tfm.scale = Vector3( [dist * self.factor(), self.factor(), self.factor()]) bfrTfm = [ tfm.copy(rotation=fkTfm[max(i - 1, 0)].rotation) for i, tfm in enumerate(fkTfm) ] bfrTfm[0] = Transformation.lookAt(self.translations("Root"), constants.AXIS_NY, constants.AXIS_X, "x" + self.nsign() + "z", self.negate()) scale = bfrTfm[0].scale scale.x *= self.lengths[0] bfrTfm[0].scale = scale # ik ikbfrPos = Vector3([ self.translations("Root").x, self.translations("Toe").y, self.translations("Root").z ]) ikbfrTfm = Transformation.fromParts(translation=ikbfrPos) ikTfm = Transformation.lookAt(self.translations("Toe"), lookAtEff, constants.AXIS_Y, "zy", False) upvbfrTfm = Transformation.fromParts( translation=umath.upVector(self.translations("Root"), ikbfrPos, constants.AXIS_NX, ratio, False)) upvTfm = Transformation.fromParts( translation=umath.upVector(self.translations( "Root"), self.translations("Ankle"), oriNormal, ratio)) rollNormal = Vector3.planeNormal(self.translations("Root"), upvTfm.translation, self.translations("Toe")) if self.negate(): rollNormal *= -1 direction = self.translations("Root") - self.translations("Toe") rollbfrTfm = Transformation.lookAt(self.translations("Toe"), direction, rollNormal, "y-x", self.negate()) direction = self.translations("Ankle") - self.translations("Toe") rollTfm = Transformation.lookAt(self.translations("Toe"), direction, normal, "y-x", self.negate()) # extras scale = Vector3([self.factor(), self.factor(), self.factor()]) twisterTfm = {} interTfm = {} for i, (p, pos) in enumerate(izip(self.twp, positions[1:4])): twisterTfm[p] = [ fkTfm[i].copy(scale=scale), fkTfm[i].copy(translation=pos, scale=scale) ] interPos = twisterTfm[p][0].translation.lerp( twisterTfm[p][1].translation, .5) interTfm[p] = twisterTfm[p][0].copy(translation=interPos) ctrATfm = twisterTfm["Mid"][0] ctrBTfm = twisterTfm["Lwr"][0] # CONTROLLERS # Root self.rootBfr = self.addBfr(None, "Root", rootTfm) self.rootCtl = self.addCtl(self.rootBfr, "Root", rootTfm, "sphere", size=4, color=self.colorIk()) # self.addToSubControllers(self.rootCtl) attributes.setKeyables(self.rootCtl, constants.ATTRS_T) # self.setInversedParameters(self.rootCtl, middle=["posx"], side=["posx"]) # Fk Ref # Used as a reference for the upr start twist # We cannot use the fk1Bfr cause this one get constrained when fk ref changes self.fkRef = self.addRig(self.rootBfr, "FkRef", bfrTfm[0]) # FK Controlers and Bones fkParent = self.fkRef boneParent = self.fkRef self.fkBfr = [] self.fkCtl = [] self.bones = [] self.stretches = [] for i, (tfm, btfm) in enumerate(izip(fkTfm, bfrTfm), start=1): bfr = self.addBfr(fkParent, "Fk%s" % i, btfm) ctl = self.addCtl(bfr, "Fk%s" % i, tfm, "sphere", size=8, so=[0, 1, 1], color=self.colorFk()) if self.settings("lockKneeRotation") and i == 2: keyables = [ "posx", "posy", "posz", "rotz", "sclx", "scly", "sclz" ] else: keyables = constants.ATTRS_TRS if i == 1: attributes.setRotOrder(ctl, "XZY") attributes.setKeyables(ctl, keyables) # self.setInversedParameters(ctl, middle=["posz", "roty", "rotx"]) fkParent = ctl self.fkBfr.append(bfr) self.fkCtl.append(ctl) bone = self.addRig(boneParent, "Bone{}".format(i), tfm=tfm, icon="bone", so=(self.factor(), 1, 1)) boneParent = bone self.bones.append(bone) # IK Controllers self.rollBfr = self.addBfr(self.rootBfr, "Roll", rollbfrTfm) self.rollCtl = self.addCtl(self.rollBfr, "Roll", rollTfm, "jaw", size=1, ro=(-90, 0, 0), color=self.colorIk()) #self.rollCtl = self.addCtl(self.rollBfr, "Roll", rollTfm, "jaw", size=2, po=(4,6,0), color=self.colorIk()) # self.setNeutralPose(self.rollCtl) attributes.setKeyables(self.rollCtl, ["rotx", "roty", "rotz", "rotorder", "scly"]) self.ikRef = self.addRig(self.rollCtl, "IkRef", fkTfm[-2]) self.ikBfr = self.addBfr(None, "Ik", ikbfrTfm) self.ikCtl = self.addCtl(self.ikBfr, "Ik", ikTfm, "cube", size=6, color=self.colorIk()) attributes.setKeyables(self.ikCtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ikCtl, middle=["posx", "rotz", "roty"], side=["posx", "rotz", "roty"]) attributes.setRotOrder(self.ikCtl, "XZY") self.ikoffCtl = self.addCtl(self.ikCtl, "IkOffset", ikTfm, "null", size=4, color=self.colorIk()) # self.addToSubControllers(self.ikoffCtl) attributes.setKeyables(self.ikoffCtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ikoffCtl, middle=["posx", "rotz", "roty"], side=["posx", "rotz", "roty"]) attributes.setRotOrder(self.ikoffCtl, "XZY") self.upvBfr = self.addBfr(None, "Upv", upvbfrTfm) self.upvCtl = self.addCtl(self.upvBfr, "Upv", upvTfm, "diamond", size=2, color=self.colorIk()) attributes.setKeyables(self.upvCtl, constants.ATTRS_T) # self.setInversedParameters(self.upvCtl, middle=["posx"], side=["posx"]) self.ctrABfr = self.addBfr(self.bones[0], "CenterA", ctrATfm) self.ctrACtl = self.addCtl(self.ctrABfr, "CenterA", ctrATfm, "sphere", size=5, color=self.colorIk()) # self.addToSubControllers(self.ctrACtl) attributes.setKeyables(self.ctrACtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ctrACtl, middle=["posz", "roty", "rotx"]) self.ctrBBfr = self.addBfr(self.bones[1], "CenterB", ctrBTfm) self.ctrBCtl = self.addCtl(self.ctrBBfr, "CenterB", ctrBTfm, "sphere", size=5, color=self.colorIk()) # self.addToSubControllers(self.ctrBCtl) attributes.setKeyables(self.ctrBCtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ctrBCtl, middle=["posz", "roty", "rotx"]) self.upvCrv = create.cnsCurve( self.getObjectName(config.USE_RIG, "UpvCrv"), [self.upvCtl, self.ctrACtl]) cmds.setAttr(self.upvCrv + ".template", True) self.footRef = self.addRig(self.ikoffCtl, "FootRef", ikTfm) # Twisters self.twisters = defaultdict(list) for p in self.twp: for s, tfm, factor in izip(["Start", "End"], twisterTfm[p], [1, -1]): twister = self.addRig(self.rootBfr, "Tw" + p + s, tfm, "sphere", po=[factor, 0, 0], so=[2, 1, 1]) # self.setNeutralPose(twister) self.twisters[p].append(twister) # Inter self.inters = {} for p in self.twp: self.inters[p] = self.addRig(self.rootBfr, "Inter" + p, interTfm[p], "pyramid")
def createObjects(self): north = self.settings("north") south = self.settings("south") east = self.settings("east") west = self.settings("west") # TRANSFORMATION tfm = Transformation.lookAt(self.translations("Root"), self.directions("Root", "y"), self.directions("Root", "z"), axis="y" + self.sign() + "z", negativeSide=False) tfm.scale *= .5 if north != south and False in [ east, west ] or east != west and False in [north, south]: tfm.scale *= 2 # Label if not north and not south: dirn = .20 dirs = -.20 else: dirn = int(north) dirs = -int(south) if not east and not west: dire = .20 dirw = -.20 else: dire = int(east) dirw = -int(west) if self.settings("labelPosition") == "North": labelTfm = Transformation.fromParts( translation=Vector3([(dire + dirw) * .5, dirn + .1, 0])) align = "center" elif self.settings("labelPosition") == "South": labelTfm = Transformation.fromParts( translation=Vector3([(dire + dirw) * .5, dirs - .5, 0])) align = "center" elif self.settings("labelPosition") == "East": labelTfm = Transformation.fromParts( translation=Vector3([dire + .1, -.15, 0])) align = "left" elif self.settings("labelPosition") == "West": labelTfm = Transformation.fromParts( translation=Vector3([dirw - .1, -.15, 0])) align = "right" labelTfm *= tfm # CREATE OBJECTS # Frame scly = 1 * (north + south) if (north or south) else 0 sclx = 1 * (east + west) if (east or west) else 0 offy = .5 * (north - south) offx = .5 * (east - west) frame = self.addRig(None, "Frame", tfm, "cube", size=1, po=(offx, offy, 0), so=(sclx, scly, 0)) # Controller self.ctl = self.addCtl(frame, "1", tfm, "cube", size=1, so=(.5, .5, 0), color=self.colorFk()) attributes.setKeyables( self.ctl, ["posx", "posy"] ) # Faceware doesn't like if the posx is not keyable, so we make it keyable all the time... # Label labelText = self.settings("label") if ( self.settings("customLabel") and self.settings("label") != "") else self.settings("name") label = create.text(self.getObjectName(config.USE_RIG, "Label"), frame, labelTfm, labelText, size=.2, align=align) # RECONNECT for source, destination in self._connections: cmds.connectAttr(source, destination)
def createObjects(self): self.axis = self.settings("axis").lower() # TRANSFORMATIONS positions = self.translations("Part") # Normal if self.count("Part") > 2: normal = Vector3.planeNormal(*positions[:3]) if normal.length() < 1E-6: normal = self.directions("Part1", "z") else: normal = self.directions("Part1", "z") ctlTfm = TransformationArray.chain(positions, normal, axis=self.axis+"z", negativeSide=self.negate(), endTransform=True) divTfm = Transformation() if self.negate(): divTfm.scaling = Vector3([-1,-1,-1]) length = self.translations("Part1").distance(self.translations("Part2")) / 5.0 # CONTROLLERS self._centers = [] # Left this dictionary in here, just in case we wanna revert back shdScl = [length,length,length] shdScl["xyz".index(self.axis)] = 0 se_keyableParameters = list(constants.ATTRS_TR) int_keyableParameters = list(constants.ATTRS_T) if self.settings("scaleWithControllers"): se_keyableParameters += ["scl"+s for s in "xyz" if s != self.axis] if self.settings("scaleWithInterControllers"): int_keyableParameters += ["scl"+s for s in "xyz" if s != self.axis] # Start Controller bfr = self.addBfr(None, "Start", ctlTfm[0]) if self.settings("startController"): ctl = self.addCtl(bfr, "Start", ctlTfm[0], "sphere", so=shdScl, color=self.colorFk()) attributes.setKeyables(ctl, se_keyableParameters) self._centers.append(ctl) else: self._centers.append(bfr) # Inter Controller for i, tfm in enumerate(ctlTfm[1:-1], start=1): bfr = self.addBfr(None, "Part%s"%i, tfm) if self.settings("interControllers"): ctl = self.addCtl(bfr, "Part%s"%i, tfm, "cube", size=2, so=shdScl, color=self.colorFk()) attributes.setKeyables(ctl, int_keyableParameters) self._centers.append(ctl) else: self._centers.append(bfr) # End Controller bfr = self.addBfr(None, "End", ctlTfm[-1]) if self.settings("endController"): ctl = self.addCtl(bfr, "End", ctlTfm[-1], "sphere", so=shdScl, color=self.colorFk()) attributes.setKeyables(ctl, se_keyableParameters) self._centers.append(ctl) else: self._centers.append(bfr) # CURVE # tangent = self.settings("tangentDistance") if self.settings("tangent") else None self.crv = create.cnsCurve(self.getObjectName(config.USE_RIG, "Crv"), self._centers, closed=False, degree=3) self.length = cmds.arclen(self.crv) # DIVISIONS parent = self._centers[0] self.start_iter = 0 if self.settings("startDeformer") and not self.settings("tangent") else 1 if self.settings("tangent"): self.interDiv = [self.addRig(parent, "Div%s"%i, divTfm, "cube", size=2) for i in xrange(1, self.settings("interDeformers")+1)] if self.settings("untwistDeformers"): self.unTwistDiv = [self.addRig(parent, "Untwist%s"%i, divTfm, "cube", size=1) for i in xrange(1, self.settings("interDeformers")+1)] self.unTwistStart = self.addRig(self._centers[0], "UntwistStart", ctlTfm[0], "cube", size=1) self.unTwistEnd = self.addRig(self._centers[-1], "UntwistEnd", ctlTfm[-1], "cube", size=1) else: div_count = self.settings("interDeformers") + self.settings("startDeformer") + self.settings("endDeformer") self.interDiv = [self.addRig(parent, "Div%s"%i, divTfm, "cube", size=2) for i in xrange(self.start_iter, div_count+self.start_iter)] if self.settings("untwistDeformers"): self.unTwistDiv = [self.addRig(parent, "Untwist%s"%i, divTfm, "cube", size=1) for i in xrange(self.start_iter, div_count+self.start_iter)]
def createObjects(self): # SIZE size = self.translations("Root").distance(self.translations("Knee")) fkSize = size * .25 ikSize = size * .25 upvSize = size * .1 rootSize = size * .15 # TRANSFORMATIONS positions = Vector3Array([ self.translations("Root"), self.translations("Knee"), self.translations("Ankle") ]) normal = Vector3.planeNormal(*positions) oriNormal = normal.copy() if self.negate(): normal *= -1 isInversed = constants.AXIS_X.dot(oriNormal) >= 0 d = [(positions[i], positions[i + 1]) for i in range(2)] self.lengths = [Vector3.distance(a, b) for a, b in d] self.lengths.append(1) ratio = self.lengths[0] / sum(self.lengths[:2]) self.setSettings(lengths=self.lengths[:2]) # root rootTfm = Transformation.fromParts( translation=self.translations("Root")) # fk fkTfm = TransformationArray.chain(positions, normal, axis="xz", negativeSide=self.negate(), endTransform=False) axis = "-y-x" if isInversed else "y-x" if self.settings("ankleUpVector") == "World Y": upaxis = constants.AXIS_Y else: upaxis = -1 * self.directions("Ankle", "z") direction = self.translations("Eff") - self.translations("Ankle") fk2Tfm = Transformation.lookAt(self.translations("Ankle"), direction, upaxis, axis, self.negate()) fkTfm = fkTfm.appended(fk2Tfm) bfrTfm = [ tfm.copy(rotation=fkTfm[max(i - 1, 0)].rotation) for i, tfm in enumerate(fkTfm) ] xaxis = constants.AXIS_NX if isInversed else constants.AXIS_X bfrTfm[0] = Transformation.lookAt(self.translations("Root"), constants.AXIS_NY, xaxis, "x" + self.nsign() + "z", self.negate()) # ik ikbfr_pos = Vector3([ self.translations("Root").x, self.translations("Ankle").y, self.translations("Root").z ]) ikbfrTfm = Transformation.fromParts(translation=ikbfr_pos) ikTfm = Transformation.lookAt(self.translations("Ankle"), direction, upaxis, "zy", False) upvbfrTfm = Transformation.fromParts( translation=umath.upVector(self.translations("Root"), ikbfr_pos, constants.AXIS_NX, ratio, False)) upvTfm = Transformation.fromParts( translation=umath.upVector(self.translations( "Root"), self.translations("Ankle"), oriNormal, ratio)) # extras scale = Vector3([1, 1, 1]) twisterTfm = {} interTfm = {} for i, (p, pos) in enumerate(izip(self.twp, positions[1:3])): twisterTfm[p] = [ fkTfm[i].copy(scale=scale), fkTfm[i].copy(translation=pos, scale=scale) ] inter_pos = twisterTfm[p][0].translation.lerp( twisterTfm[p][1].translation, .5) interTfm[p] = twisterTfm[p][0].copy(translation=inter_pos) ctrTfm = twisterTfm["Lwr"][0] # CONTROLLERS # Root self.rootBfr = self.addBfr(None, "Root", rootTfm) self.rootCtl = self.addCtl(self.rootBfr, "Root", rootTfm, "sphere", color=self.colorIk(), size=rootSize) # self.addToSubControllers(self.rootCtl) attributes.setKeyables(self.rootCtl, constants.ATTRS_T) # Fk Ref # Used as a reference for the upr start twist # We cannot use the fk1Bfr cause this one get constrained when fk ref changes self.fkRef = self.addRig(self.rootBfr, "FkRef", bfrTfm[0]) # FK Controlers and Bones fkParent = self.fkRef boneParent = self.fkRef self.fkBfr = [] self.fkCtl = [] self.bones = [] self.stretches = [] for i, (tfm, btfm) in enumerate(izip(fkTfm, bfrTfm), start=1): bfr = self.addBfr(fkParent, "Fk%s" % i, btfm) ctl = self.addCtl(bfr, "Fk%s" % i, tfm, "sphere", color=self.colorFk(), size=fkSize, so=(0, 1, 1)) if self.settings("lockKneeRotation") and i == 2: keyableParams = [ "posx", "posy", "posz", "rotz", "sclx", "scly", "sclz" ] else: keyableParams = constants.ATTRS_TRS attributes.setKeyables(ctl, keyableParams) fkParent = ctl self.fkBfr.append(bfr) self.fkCtl.append(ctl) bone = self.addRig(boneParent, "Bone{}".format(i), tfm=tfm, icon="bone", so=(self.factor(), 1, 1)) boneParent = bone self.bones.append(bone) # IK Controllers self.ikBfr = self.addBfr(None, "Ik", ikbfrTfm) self.ikCtl = self.addCtl(self.ikBfr, "Ik", ikTfm, "cube", color=self.colorIk(), size=ikSize) attributes.setKeyables(self.ikCtl, constants.ATTRS_TRS) attributes.setRotOrder(self.ikCtl, "XZY") self.ikoffCtl = self.addCtl(self.ikCtl, "IkOffset", ikTfm, "cube", color=self.colorIk(), size=ikSize) # self.addToSubControllers(self.ikoffCtl) attributes.setKeyables(self.ikoffCtl, constants.ATTRS_TRS) self.ikRef = self.addRig(self.ikoffCtl, "IkRef", fkTfm[-1]) attributes.setRotOrder(self.ikoffCtl, "XZY") self.upvBfr = self.addBfr(None, "Upv", upvbfrTfm) self.upvCtl = self.addCtl(self.upvBfr, "Upv", upvTfm, "diamond", color=self.colorIk(), size=upvSize) attributes.setKeyables(self.upvCtl, constants.ATTRS_T) self.ctrBfr = self.addBfr(self.bones[0], "Center", ctrTfm) self.ctrCtl = self.addCtl(self.ctrBfr, "Center", ctrTfm, "sphere", size=rootSize, color=self.colorIk()) # self.addToSubControllers(self.ctrCtl) attributes.setKeyables(self.ctrCtl, constants.ATTRS_TRS) self.upvCrv = create.cnsCurve( self.getObjectName(config.USE_RIG, "UpvCrv"), [self.upvCtl, self.ctrCtl]) # Twisters self.twisters = defaultdict(list) for p in self.twp: for s, tfm, factor in izip(["Start", "End"], twisterTfm[p], [1, -1]): twisterBfr = self.addBfr(self.rootBfr, "Tw" + p + s, tfm) twister = self.addRig(twisterBfr, "Tw" + p + s, tfm, "pyramid") self.twisters[p].append(twister) # Inter self.inters = {} for p in self.twp: self.inters[p] = self.addRig(self.rootBfr, "Inter" + p, interTfm[p], "cube")
def createObjects(self): # Settings self.isFk = "FK" in self.settings("kinematic") self.isIk = "IK" in self.settings("kinematic") self.isFkIk = self.isFk and self.isIk self.isNotIk = self.isFk and not self.isIk self.isNotFk = not self.isFk and self.isIk size = self.translations("Part")[0].distance(self.translations("Part")[1]) * 0.25 # TRANSFORMATION # Normal if self.count("Part") > 2: normal = Vector3.planeNormal(*self.translations("Part")[:3]) direction = self.translations("Part")[-1] - self.translations("Part")[0] if normal.length() < 1E-6: normal = self.directions("Part1", "z") if self.negate(): normal *= -1 else: direction = self.directions("Part1", "x") normal = self.directions("Part1", "z") boneTfm = TransformationArray.chain(self.translations("Part"), normal, negativeSide=self.negate(), endTransform=False) d = [(self.translations("Part")[i],self.translations("Part")[i+1]) for i in range(self.count("Part")-1)] self.distances = [Vector3.distance(a,b) for a,b in d] endTfm = boneTfm[-1].copy(translation=self.translations("Part")[-1]) boneTfm = boneTfm.appended(endTfm) self.distances.append(0.0) # Create extra transforms on end points for i in xrange(self.settings("extraControllers")): extraPos = Vector(self.settings("extraControllerSpacing")*(i+1),0,0) * endTfm extraTfm = endTfm.copy(translation=extraPos) boneTfm = boneTfm.appended(extraTfm) self.distances.append(0.0) self.setSettings(count=len(self.distances), lengths=self.distances) self.initialCount = self.count("Part") if self.settings("setNeutralPose"): bfrTfm = boneTfm else: bfrTfm = [tfm.copy(rotation=boneTfm[max(i-1,0)].quaternion) for i, tfm in enumerate(boneTfm)] if self.settings("dynamic"): dynTfm = [] for i, posA in enumerate(self.translations()[:-1]): posB = self.translations()[i+1] dynTfm.append(Transform.LookingAt(posA, posB, normal, self.nsign()+"yz", self.negate())) self.normal = normal.copy() self.normal.normalize() self.direction = direction.copy() self.direction.normalize() # OBJECTS # Root rootBfr = self.addBfr(None, "Root", tfm=boneTfm[0]) if self.settings("addRootCtrl"): self._root = self.addCtl(rootBfr, "Root", boneTfm[0], "sphere", size=size*1.5, color=self.colorFk()) else: self._root = rootBfr # FK Controllers ----------------------------------------- if self.isFk: self.fkBfr = [] self.fkCtl = [] parent = self._root for i, (tfm, btfm, dist) in enumerate(izip(boneTfm, bfrTfm, self.distances), start=1): if self.negate(): dist *= -1 fkBfr = self.addBfr(parent, "Fk{}".format(i), tfm=btfm) fkCtl = self.addCtl(fkBfr, "Fk{}".format(i), tfm, "cube", po=[dist*0.5,0,0], so=[dist*0.9,size,size], color=self.colorFk()) # self.setInversedsettings(fkCtl, middle=["posz", "rotx", "roty"]) attributes.setRotOrder(fkCtl, self.settings("defaultRotationOrder")) parent = fkCtl self.fkBfr.append(fkBfr) self.fkCtl.append(fkCtl) else: self.fkCtl = len(boneTfm) * [None] # IK Controllers -------------------------------------- if self.isIk: self.ikBfr = [] self.ikCtl = [] self.ikRoot = self.addBfr(self._root, "IkRoot", boneTfm[0]) for i, (tfm, btfm) in enumerate(izip(boneTfm, bfrTfm), start=1): if i == 1: parent = self._root else: parent = self.ikRoot ikBfr = self.addBfr(parent, "Ik{}".format(i), tfm=btfm) ikCtl = self.addCtl(ikBfr, "Ik{}".format(i), tfm, "sphere", size=size, color=self.colorIk()) # self.setInversedsettings(ikCtl, middle=["posz","rotx","roty"]) attributes.setRotOrder(ikCtl, self.settings("defaultRotationOrder")) self.ikBfr.append(ikBfr) self.ikCtl.append(ikCtl) else: self.ikCtl = len(boneTfm) * [None] # Bones ------------------------------- if self.isFkIk or (self.isFk and self.settings("dynamic")): self.bones = [] parent = self._root for i, (tfm, dist) in enumerate(izip(boneTfm, self.distances), start=1): if self.negate(): dist *= -1 bone = self.addRig(parent, "Bone{}".format(i), tfm, "cube", size=1, po=[dist*.5,0,0], so=[0,.5 * size,.5 * size]) self.bones.append(bone) parent = bone elif self.isFk: self.bones = self.fkCtl else: self.bones = self.ikCtl # Dynamic ---------------------------- if self.settings("dynamic"): self.dfmHost = [] self.dynCns = [] self.target = [] self.harmonic = [] self.dynBone = [] parent = self._root for i, (bone, tfmA, tfmB) in enumerate(izip(self.bones[:-1], boneTfm[:-1], boneTfm[1:]), start=1): dynCns = self.addRig(parent, "DynCns{}".format(i), tfmA, "cube", size=1) self.dynCns.append(dynCns) target = self.addRig(dynCns, "Target{}".format(i), tfmB, "null", size=1) self.target.append(target) harmonic = self.addRig(target, "Harmonic{}".format(i), tfmB, "diamond", size=1) self.harmonic.append(harmonic) dynBone = self.addRig(parent, "Dynamic{}".format(i), tfmA, "pyramid", size=1, ro=[0,0,-90], so=[1,self.factor(),1]) self.dynBone.append(dynBone) parent = dynBone self.dfmHost.append(dynBone) # Add the tip, since the tentacle has the tip dynBone = self.addRig(parent, "Dynamic{}".format(len(self.bones)), boneTfm[-1], "pyramid", size=1, ro=[0,0,-90], so=[1,self.factor(),1]) self.dynBone.append(dynBone) self.dfmHost.append(dynBone) else: self.dfmHost = self.bones # Roll Controllers ---------------------------- self.rollBfr = [] self.rollCtl = [] # self.upv = [] if self.settings("addRoll"): for i, (bone, tfm) in enumerate(izip(self.dfmHost, boneTfm), start=1): if self.negate(): rollScl = -2 else: rollScl = 2 rollBfr = self.addBfr(bone, "Roll{}".format(i), tfm=tfm) rollCtl = self.addCtl(rollBfr, "Roll{}".format(i), tfm, "pyramid", size=size, so=[1,rollScl,0], color=self.colorIk()) # self.setInversedsettings(rollCtl, middle=["posz","rotx","roty"]) attributes.setRotOrder(rollCtl, self.settings("defaultRotationOrder")) attributes.setKeyables(rollCtl, ["rotx"]) # self.addToSubControllers(rollCtl) upvPar = rollCtl self.rollBfr.append(rollBfr) self.rollCtl.append(rollCtl) # UI Hosts ---------------------------- self.hosts = [] for i, (bone, btfm) in enumerate(izip(self.dfmHost, boneTfm), start=1): host = self.addCtl(bone, "Host{}".format(i), btfm, "gear", size=size*1.5, color=self.colorFk()) attributes.setKeyables(host, []) self.hosts.append(host) # Tangents ---------------------------- self.tangentBfr = [] self.tangentSolvers = [] self.tangentCtl = [] self.tanCrvs = [] points = [] for i, (bone, btfm, dist) in enumerate(izip(self.dfmHost, boneTfm, self.distances)): tanBfrs = [] tanSolvers = [] tanCtls = [] if i: tangent = self._createTangentObjects("InTangent", i, size, bone, btfm, -self.distances[i-1]*0.333, "cube") tanBfrs.append(tangent[0]) tanSolvers.append(tangent[1]) tanCtls.append(tangent[2]) else: tanBfrs.append(None) tanSolvers.append(None) tanCtls.append(None) if i != len(self.bones)-1: tangent = self._createTangentObjects("OutTangent", i, size, bone, btfm, dist*0.333, "diamond") tanBfrs.append(tangent[0]) tanSolvers.append(tangent[1]) tanCtls.append(tangent[2]) else: tanBfrs.append(None) tanSolvers.append(None) tanCtls.append(None) self.tangentBfr.append(tanBfrs) self.tangentSolvers.append(tanSolvers) self.tangentCtl.append(tanCtls) # Draw helper lines for the tangents. Start by filtering out empty entries from the centers list centers = [item for item in [tanCtls[0], bone, tanCtls[1]] if item] tanCrv = create.cnsCurve("TanCrv{}".format(i+1), centers, degree=1) cmds.setAttr(tanCrv+".template", True) self.tanCrvs.append(tanCrv) # Curve ---------------------------- self.curvePar = self.addRig(None, "Curve") cmds.setAttr(self.curvePar+".template", True)
def createObjects(self): # Settings self.isFk = "FK" in self.settings("kinematic") self.isIk = "IK" in self.settings("kinematic") self.isFkIk = self.isFk and self.isIk # TRANSFORMATION # Positions positions = self.translations("Part") # Normal if self.count("Part") > 2: normal = Vector3.planeNormal(*positions[:3]) if normal.length() < 1E-6: normal = self.directions("Part1", "z") if self.negate(): normal *= -1 else: normal = self.directions("Part1", "z") boneTfm = TransformationArray.chain(positions, normal, axis="xz", negativeSide=self.negate(), endTransform=False) d = [(positions[i], positions[i + 1]) for i in range(self.count("Part") - 1)] boneLen = [Vector3.distance(a, b) for a, b in d] self.setSettings(count=len(boneLen), lengths=boneLen) if self.settings("setNeutralPose"): bfrTfm = boneTfm else: bfrTfm = [ tfm.copy(rotation=boneTfm[max(i - 1, 0)].rotation) for i, tfm in enumerate(boneTfm) ] if self.isIk: ikTfm = boneTfm[-1].copy(translation=positions[-1]) # Up Vector if self.count("Part") > 2: upvTfm = Transformation.fromParts( translation=umath.upVector(positions[0], positions[2], normal, ratio=1, negate=self.negate())) else: upvTfm = Transformation.fromParts( translation=umath.upVector(positions[0], positions[1], normal, ratio=1, negate=self.negate())) if self.settings("dynamic"): tgtTfm = boneTfm[1:] tgtTfm = tgtTfm.appended( boneTfm[-1].copy(translation=positions[-1])) # OBJECTS # Root self._root = self.addRig(None, "Root", tfm=boneTfm[0]) # FK Controllers ----------------------------------------- if self.isFk: self.fkBfr = [] self.fkCtl = [] self.fkDir = [] parent = self._root for i, (tfm, btfm, dist) in enumerate(izip(boneTfm, bfrTfm, boneLen), start=1): fkBfr = self.addBfr(parent, "Fk{}".format(i), tfm=btfm) fkCtl = self.addCtl(fkBfr, "Fk{}".format(i), tfm, "sphere", so=[0, 1, 1], color=self.colorFk()) # self.setInversedsettings(fkCtl, middle=["posz", "rotx", "roty"]) attributes.setRotOrder(fkCtl, self.settings("defaultRotationOrder")) parent = fkCtl self.fkBfr.append(fkBfr) self.fkCtl.append(fkCtl) bone = self.addRig(fkCtl, "Dir{}".format(i), tfm, "pyramid", size=1, ro=[0, 0, -90], so=[.5, self.factor() * dist, .5]) self.fkDir.append(bone) # Add the end reference for ikfk matching tfm = boneTfm[-1].copy(translation=positions[-1]) self._tip = self.addRig(self.fkCtl[-1], "Tip", tfm) # IK Controllers -------------------------------------- if self.isIk: # Ik Controller self.ikBfr = self.addBfr(self._root, "Ik", tfm=ikTfm) self.ikCtl = self.addCtl(self.ikBfr, "Ik", ikTfm, "cube", size=2, color=self.colorIk()) attributes.setKeyables(self.ikCtl, constants.ATTRS_TR) # UpVector Controller self.upvBfr = self.addBfr(self._root, "UpV", upvTfm) self.upvCtl = self.addCtl(self.upvBfr, "UpV", upvTfm, "diamond", color=self.colorIk()) attributes.setKeyables(self.upvCtl, constants.ATTRS_T) # Ik Chain self.ikBones, self.effector, self.handle = create.chain( self.getObjectName(config.USE_RIG, "Ik"), self._root, positions, normal, negate=self.negate()) self.upvCrv = create.cnsCurve( [self.ikChn.root(), self.upvCtl, self.ikChn.effector()], "UpvCrv") cmds.setAttr(self.upvCrv + ".template", True) # Bones ------------------------------- if self.isFkIk: # or (self.isFk and self.settings("dynamic")): self.bones = [] parent = self._root for i, (tfm, dist) in enumerate(izip(boneTfm, boneLen), start=1): bone = self.addRig(parent, "Bone{}".format(i), tfm, "cube", size=1, po=[self.factor() * dist * .5, 0, 0], so=[dist, .5, .5]) self.bones.append(bone) parent = bone elif self.isFk: self.bones = self.fkCtl else: self.bones = self.ikChn.bones() # Dynamic ---------------------------- if self.settings("dynamic"): self.dfmHost = [] self.dynCns = [] self.target = [] self.harmonic = [] self.dynBone = [] parent = self._root for i, (bone, tfmA, tfmB) in enumerate(izip(self.bones, boneTfm, tgtTfm), start=1): dynCns = self.addRig(parent, "DynCns{}".format(i), tfmA, "cube", size=1) self.dynCns.append(dynCns) target = self.addRig(dynCns, "Target{}".format(i), tfmB, "null", size=1) self.target.append(target) harmonic = self.addRig(target, "Harmonic{}".format(i), tfmB, "diamond", size=1) self.harmonic.append(harmonic) dynBone = self.addRig(parent, "Dynamic{}".format(i), tfmA, "pyramid", size=1, ro=[0, 0, -90], so=[1, self.factor(), 1]) self.dynBone.append(dynBone) parent = dynBone self.dfmHost.append(dynBone) else: self.dfmHost = self.bones # Strap ---------------------------- if self.settings("strap"): endTfm = boneTfm[-1].copy(translation=positions[-1]) self.end = self.addRig(self.dfmHost[-1], "End", endTfm)
def createObjects(self): # Settings self.isFk = "FK" in self.settings("kinematic") self.isIk = "IK" in self.settings("kinematic") self.isFkIk = self.isFk and self.isIk self.isNotIk = self.isFk and not self.isIk self.isNotFk = not self.isFk and self.isIk # TRANSFORMATIONS positions = Vector3Array([self.translations("Root"), self.translations("Head"), self.translations("Eff")]) normal = Vector3.planeNormal(*positions) if self.negate(): normal *= -1 self.neckLength = self.translations("Root").distance(self.translations("Head")) headLength = self.translations("Head").distance(self.translations("Eff")) direction = self.translations("Eff") - self.translations("Head") ikTfm = Transformation.lookAt(self.translations("Head"), direction, normal, "yx", self.negate()) if self.settings("orientToWorld"): headTfm = Transformation.fromParts(translation=self.translations("Head")) else: headTfm = ikTfm crvPos = Vector3Array([self.translations("Root").lerp(self.translations("Head"), i/3.0) for i in xrange(4)]) refPos = Vector3Array([self.translations("Root").lerp(self.translations("Head"), i/2.0) for i in xrange(3)]) direction = self.translations("Head") - self.translations("Root") rootTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "yx", self.negate()) midTfm = rootTfm.copy(translation=refPos[1]) endTfm = rootTfm.copy(translation=refPos[2]) tan0Tfm = rootTfm.copy(translation=crvPos[1]) tan1Tfm = ikTfm.copy(translation=crvPos[-2]) bonePos = refPos.appended(self.translations("Eff")) boneTfm = TransformationArray.chain(bonePos, normal, axis="yx", negativeSide=self.negate(), endTransform=False) # CONTROLLERS # Root self.rootRig = self.addRig(None, "Root", rootTfm) self.tan0 = self.addRig(self.rootRig, "Tan0", tan0Tfm) # Ik self.ikBfr = self.addBfr(self.rootRig, "Ik", headTfm) self.ikOri = self.addBfr(self.ikBfr, "IkOri", headTfm) # Maya requires an extra object for the ori cns self.ikCtl = self.addCtl(self.ikOri, "Ik", ikTfm, "cube", size=1, po=(0,headLength*.5,0), so=(8, headLength, 8),color=self.colorIk()) # self.setInversedsettings(self.ikCtl, middle=["posx", "roty", "rotz"]) attributes.setRotOrder(self.ikCtl, "XZY") self.tan1 = self.addRig(self.ikCtl, "Tan1", tan1Tfm) if self.settings("gimbalControllers"): self.ikOffCtl = self.addCtl(self.ikCtl, "IkOff", ikTfm, "cube", size=.9, po=(0,headLength*.5,0), so=(8, headLength, 8),color=self.colorIk()) # self.setInversedsettings(self.ikOffCtl, middle=["posx", "roty", "rotz"]) attributes.setKeyables(self.ikOffCtl, constants.ATTRS_R) attributes.setRotOrder(self.ikOffCtl, "XZY") self.lastIkCtl = self.ikOffCtl # self.addToSubControllers(self.ikOffCtl) else: self.lastIkCtl = self.ikCtl # Curve self.crv = create.curve(self.getObjectName(config.USE_RIG,"Crv"), crvPos, closed=False, degree=3, parent=self.rootRig) # References self.baseBfr = self.addBfr(self.rootRig, "Base", rootTfm) self.baseCtl = self.addCtl(self.baseBfr, "Base", rootTfm, "sphere", size=4, so=(1,0,1), color=self.colorIk()) # self.setInversedsettings(self.baseCtl, middle=["posx", "roty", "rotz"]) attributes.setRotOrder(self.baseCtl, "XZY") self.midBfr = self.addBfr(self.crv, "Mid", midTfm) self.midCtl = self.addCtl(self.midBfr, "Mid", midTfm, "sphere", size=4, so=(1,0,1), color=self.colorIk()) attributes.setKeyables(self.midCtl, constants.ATTRS_TS) # self.setInversedsettings(self.midCtl, middle=["posx"]) self.headBfr = self.addBfr(self.crv, "Head", endTfm) if self.settings("extraHeadController"): self.headCtl = self.addCtl(self.headBfr, "Head", rootTfm, "sphere", so=(1,0,1), color=self.colorIk()) # self.addToSubControllers(self.headCtl) # self.setInversedsettings(self.headCtl, middle=["posx", "roty", "rotz"]) attributes.setRotOrder(self.headCtl, "XZY") self.headRef = self.headCtl else: self.headRef = self.headBfr # Fk if self.isFk: self.fkCtl = [] parent = self.rootRig for i, tfm in enumerate(boneTfm, start=1): if self.settings("orientToWorld") and i == len(boneTfm): bfr = self.addBfr(parent, "Fk%s"%i, headTfm) else: bfr = self.addBfr(parent, "Fk%s"%i, tfm) ctl = self.addCtl(bfr, "Fk%s"%i, tfm, "cube", size=8, so=(1,.1,1), color=self.colorFk()) attributes.setRotOrder(ctl, "XZY") parent = ctl self.fkCtl.append(ctl) if self.settings("gimbalControllers"): self.fkOffCtl = self.addCtl(self.fkCtl[-1], "fkOffCtl", boneTfm[-1], "cube", size=7.5, so=(1,.1,1), color=self.colorFk()) attributes.setKeyables(self.fkOffCtl, constants.ATTRS_R) attributes.setRotOrder(self.fkOffCtl, "XZY") # Hooks self.ikParents = [self.baseCtl, self.midCtl, self.headRef] self.hooks = [] for i, (tfm, parent) in enumerate(izip(boneTfm, self.ikParents), start=1): hk = self.addRig(parent, "Hook%s"%i, tfm) self.hooks.append(hk)