public BoneInfoChain(Transform root) { Transform boneInfoTransform = root; IKFKBlend ikfkBlend = boneInfoTransform.GetComponent <IKFKBlend>(); if (ikfkBlend != null) { _boneInfos.Add(new BoneInfo(boneInfoTransform, ikfkBlend.FK)); } while (boneInfoTransform.childCount == 1 && boneInfoTransform.GetComponent <IKFKBlend>() != null && boneInfoTransform.GetComponent <IKFKBlend>().Handle == null) { //Debug.Log("adding "+ boneInfoTransform.name +" " +count); boneInfoTransform = boneInfoTransform.GetChild(0); ikfkBlend = boneInfoTransform.GetComponent <IKFKBlend>(); if (ikfkBlend != null) { _boneInfos.Add(new BoneInfo(boneInfoTransform, ikfkBlend.FK)); } else { break; } } // Set End Effector ikfkBlend = boneInfoTransform.GetComponent <IKFKBlend>(); if (ikfkBlend != null && ikfkBlend.Handle != null) { Effector = ikfkBlend.Handle; ikControl = Effector.GetComponent <IKControl>(); ik = ikControl.IKFK; EffectorPos = Effector.position; } else { // multi children if (boneInfoTransform.childCount > 1) { foreach (Transform child in boneInfoTransform) { if (ikfkBlend == null && child.GetComponent <IKFKBlend>() == null) { ; } else { _childBoneChains.Add(new BoneInfoChain(child)); } } } } }
public void resetIK(IKControl myTarget) { myTarget.enabled = false; //myTarget.transform.localPosition = Vector3.zero; for (int i = 0; i < 100; i++) { for (int j = 0; j < myTarget.bindBones.Count; j++) { myTarget.bindBones[j].localRotation = Quaternion.Euler(myTarget.bindPose[j]); } } myTarget.enabled = true; }
public void TraverseHierarchy(Transform root) { Control globalControl = root.transform.GetComponent <Control>(); _Controls.Add(globalControl); foreach (Transform child in root) { GameObject Go = child.gameObject; Control control = Go.transform.GetComponent <Control>(); _Controls.Add(control); Bone bone = Go.transform.GetComponent <Bone>(); _Bones.Add(bone); ParentControl newParentCtrl = Go.transform.GetComponent <ParentControl>(); if (newParentCtrl) { _ParentControls.Add(newParentCtrl); } IKControl newIKCtrl = Go.transform.GetComponent <IKControl>(); if (newIKCtrl) { _Ikhandles.Add(newIKCtrl); } SplineControl splineCtrl = Go.transform.GetComponent <SplineControl>(); if (splineCtrl) { _SplineControls.Add(splineCtrl); } IKFKBlend ikfkBlend = Go.transform.GetComponent <IKFKBlend>(); if (ikfkBlend) { _IKFKBlends.Add(ikfkBlend); } DrivenKey newDrivenKey = Go.transform.GetComponent <DrivenKey>(); if (newDrivenKey) { _DrivenKeys.Add(newDrivenKey); } TraverseHierarchy(child); } }
public static void IKCreateTool(bool worldSpace = false, bool IKFK = true, float DefaultSize = 1.5f) { GameObject bone = Selection.activeObject as GameObject; if (bone) { if (!bone.GetComponent <Bone>()) { Debug.LogWarning("This is not a Puppet3D Bone"); return; } } else { Debug.LogWarning("This is not a Puppet3D Bone"); return; } GameObject globalCtrl = CreateGlobalControl(); foreach (ParentControl parentControl in globalCtrl.GetComponent <GlobalControl>()._ParentControls) { if ((parentControl.bone.transform == bone.transform) || (parentControl.bone.transform == bone.transform.parent.transform)) { Debug.LogWarning("Can't create a IK Control on Bone; it alreay has an Parent Control"); return; } } GameObject IKRoot = null; if (bone.transform.parent && bone.transform.parent.transform.parent && bone.transform.parent.transform.parent.GetComponent <Bone>()) { IKRoot = bone.transform.parent.transform.parent.gameObject; } if (IKRoot == null) { //Debug.LogWarning("You need to select the end of a chain of three bones"); IKRoot = bone.transform.parent.gameObject; //return; } // CHECK IF TOP BONE HAS AN IK ATTACHED GlobalControl[] globalCtrls = GameObject.FindObjectsOfType <GlobalControl>(); foreach (GlobalControl glblCtrl in globalCtrls) { foreach (SplineControl splineCtrl in glblCtrl._SplineControls) { foreach (GameObject splineBone in splineCtrl.bones) { if (splineBone.transform == bone.transform.parent.transform.parent) { Debug.LogWarning(bone.transform.parent.transform.parent.name + " has a Spline control attached, please make sure there are at least 3 bones after the spline bone"); return; } } } } GameObject control = new GameObject(); Undo.RegisterCreatedObjectUndo(control, "Created control"); control.name = (bone.name + "_CTRL"); GameObject controlGroup = new GameObject(); Undo.RegisterCreatedObjectUndo(controlGroup, "new control grp"); controlGroup.name = (bone.name + "_CTRL_GRP"); control.transform.parent = controlGroup.transform; controlGroup.transform.position = bone.transform.position; if (!worldSpace) { controlGroup.transform.rotation = bone.transform.rotation; } GameObject poleVector = new GameObject(); Undo.RegisterCreatedObjectUndo(poleVector, "Created polevector"); poleVector.name = (bone.name + "_POLE"); Pole pv = poleVector.AddComponent <Pole>(); pv.HandleRadius = DefaultSize; GameObject poleVectorParent = new GameObject(); Undo.RegisterCreatedObjectUndo(poleVectorParent, "Created polevector Parent"); poleVectorParent.name = (bone.name + "_POLE_GRP"); poleVector.transform.parent = poleVectorParent.transform; float prop = Vector3.Distance(IKRoot.transform.position, bone.transform.parent.transform.position) / (Vector3.Distance(IKRoot.transform.position, bone.transform.parent.transform.position) + Vector3.Distance(bone.transform.parent.transform.position, bone.transform.position)); Vector3 dir2elbow = (1f - prop) * IKRoot.transform.position + prop * bone.transform.position; poleVectorParent.transform.parent = controlGroup.transform; Vector3 dirPole = (bone.transform.parent.position - dir2elbow); poleVectorParent.transform.position = bone.transform.parent.position + 10f * dirPole; IKControl ikHandle = control.AddComponent <IKControl>(); ikHandle.poleVector = poleVector.transform; IK ikDisplay = control.AddComponent <IK>(); ikDisplay.HandleSize = DefaultSize; // Names GameObject TopTransform = IKRoot; GameObject MiddleTransform = bone.transform.parent.gameObject; GameObject BottomTransform = bone; GameObject TopTransformIK = null; GameObject MiddleTransformIK = null; GameObject BottomTransformIK = null; // FK GameObject TopTransformFK = null; GameObject MiddleTransformFK = null; GameObject BottomTransformFK = null; // IK if (IKFK) { TopTransformIK = new GameObject(); Undo.RegisterCreatedObjectUndo(TopTransformIK, "Created control"); IKHidden ikTop = TopTransformIK.AddComponent <IKHidden>(); ikTop.IKHandle = ikHandle; TopTransformIK.name = IKRoot.name + "_IK"; TopTransformIK.transform.parent = TopTransform.transform.parent; TopTransformIK.transform.position = TopTransform.transform.position; TopTransformIK.transform.rotation = TopTransform.transform.rotation; TopTransformIK.transform.localScale = TopTransform.transform.localScale; MiddleTransformIK = new GameObject(); Undo.RegisterCreatedObjectUndo(MiddleTransformIK, "Created control"); IKHidden ikMid = MiddleTransformIK.AddComponent <IKHidden>(); ikMid.IKHandle = ikHandle; MiddleTransformIK.name = MiddleTransform.name + "_IK"; MiddleTransformIK.transform.parent = TopTransformIK.transform; MiddleTransformIK.transform.position = MiddleTransform.transform.position; MiddleTransformIK.transform.rotation = MiddleTransform.transform.rotation; MiddleTransformIK.transform.localScale = MiddleTransform.transform.localScale; BottomTransformIK = new GameObject(); Undo.RegisterCreatedObjectUndo(BottomTransformIK, "Created control"); BottomTransformIK.name = bone.name + "_IK"; IKHidden ikBot = BottomTransformIK.AddComponent <IKHidden>(); ikBot.IKHandle = ikHandle; BottomTransformIK.transform.parent = MiddleTransformIK.transform; BottomTransformIK.transform.position = BottomTransform.transform.position; BottomTransformIK.transform.rotation = BottomTransform.transform.rotation; BottomTransformIK.transform.localScale = BottomTransform.transform.localScale; // FK TopTransformFK = new GameObject(); Undo.RegisterCreatedObjectUndo(TopTransformFK, "Created control"); ikHandle.fks[0] = TopTransformFK.AddComponent <FK>(); ikHandle.fks[0].IKHandle = ikHandle; ikHandle.fks[0].HandleSize = DefaultSize * .9f; TopTransformFK.name = IKRoot.name + "_FK"; TopTransformFK.transform.parent = TopTransform.transform.parent; TopTransformFK.transform.position = TopTransform.transform.position; TopTransformFK.transform.rotation = TopTransform.transform.rotation; TopTransformFK.transform.localScale = TopTransform.transform.localScale; MiddleTransformFK = new GameObject(); Undo.RegisterCreatedObjectUndo(MiddleTransformFK, "Created control"); ikHandle.fks[1] = MiddleTransformFK.AddComponent <FK>(); ikHandle.fks[1].IKHandle = ikHandle; ikHandle.fks[1].HandleSize = DefaultSize * .9f; MiddleTransformFK.name = bone.transform.parent.name + "_FK"; MiddleTransformFK.transform.parent = TopTransformFK.transform; MiddleTransformFK.transform.position = MiddleTransform.transform.position; MiddleTransformFK.transform.rotation = MiddleTransform.transform.rotation; MiddleTransformFK.transform.localScale = MiddleTransform.transform.localScale; BottomTransformFK = new GameObject(); Undo.RegisterCreatedObjectUndo(BottomTransformFK, "Created control"); ikHandle.fks[2] = BottomTransformFK.AddComponent <FK>(); ikHandle.fks[2].IKHandle = ikHandle; ikHandle.fks[2].HandleSize = DefaultSize * .9f; BottomTransformFK.name = bone.name + "_FK"; BottomTransformFK.transform.parent = MiddleTransformFK.transform; BottomTransformFK.transform.position = BottomTransform.transform.position; BottomTransformFK.transform.rotation = BottomTransform.transform.rotation; BottomTransformFK.transform.localScale = BottomTransform.transform.localScale; } // store middle bone position to check if it needs flipping //Vector3 middleBonePos = bone.transform.parent.transform.position; Quaternion topRotBefore = IKRoot.transform.rotation; ikHandle.IK_CTRL = control.transform; if (IKFK) { ikHandle.topJointTransformIK = TopTransformIK.transform; ikHandle.middleJointTransformIK = MiddleTransformIK.transform; ikHandle.bottomJointTransformIK = BottomTransformIK.transform; ikHandle.topJointTransformFK = TopTransformFK.transform; ikHandle.middleJointTransformFK = MiddleTransformFK.transform; ikHandle.bottomJointTransformFK = BottomTransformFK.transform; ikHandle.topJointTransform = IKRoot.transform; ikHandle.middleJointTransform = bone.transform.parent.transform; ikHandle.bottomJointTransform = bone.transform; } else { ikHandle.topJointTransformIK = TopTransform.transform; ikHandle.middleJointTransformIK = MiddleTransform.transform; ikHandle.bottomJointTransformIK = BottomTransform.transform; } ikHandle.scaleStart[0] = IKRoot.transform.localScale; ikHandle.scaleStart[1] = IKRoot.transform.GetChild(0).localScale; ikHandle.OffsetScale = bone.transform.localScale; if (worldSpace) { ikHandle.Offset = ikHandle.bottomJointTransform.rotation; } if (bone.GetComponent <Bone>()) { ikHandle.AimDirection = Vector3.forward; ikHandle.UpDirection = Vector3.right; } else { Debug.LogWarning("This is not a Puppet3D Bone"); ikHandle.AimDirection = Vector3.right; ikHandle.UpDirection = Vector3.up; } Quaternion middleRotBefore = MiddleTransform.transform.rotation; ikHandle.DisableRotateAround = true; ikHandle.CalculateIK(); Quaternion topRotAfter = TopTransform.transform.rotation; Quaternion topOffset = (Quaternion.Inverse(topRotAfter) * topRotBefore); ikHandle.topJointTransform_OffsetRotation = topOffset; ikHandle.DisableRotateAround = false; ikHandle.CalculateIK(); Quaternion topRotAfter2 = TopTransform.transform.rotation; Quaternion topOffset2 = (Quaternion.Inverse(topRotAfter2) * topRotBefore); ikHandle.topJointTransform_OffsetRotation2 = topOffset2; ikHandle.CalculateIK(); Quaternion middleRotAfter = MiddleTransform.transform.rotation; //Debug.Log("rot " + middleRotAfter); Quaternion middleOffset = (Quaternion.Inverse(middleRotAfter) * middleRotBefore); ikHandle.middleJointTransform_OffsetRotation = middleOffset; //if (bone.transform.parent.transform.position.x < IKRoot.transform.position.x) Selection.activeObject = ikHandle; controlGroup.transform.parent = globalCtrl.transform; //poleVector.transform.parent = globalCtrl.transform; if (globalCtrl.GetComponent <GlobalControl>().AutoRefresh) { globalCtrl.GetComponent <GlobalControl>().Init(); } else { globalCtrl.GetComponent <GlobalControl>()._Ikhandles.Add(ikHandle); } //fix from now on for 180 flip globalCtrl.GetComponent <GlobalControl>()._flipCorrection = -1; globalCtrl.GetComponent <GlobalControl>().Run(); }
public void setEndBone(IKControl myTarget) { myTarget.angleLimits.Clear(); myTarget.angleLimitTransform.Clear(); if (myTarget.numberOfBones < 2) { myTarget.numberOfBones = 2; } GlobalControl[] globalCtrlScripts = Transform.FindObjectsOfType <GlobalControl>(); myTarget.endTransform = myTarget.bottomJointTransform; myTarget.startTransform = myTarget.endTransform; bool unlockedBone = true; for (int i = 0; i < myTarget.numberOfBones - 1; i++) { if (myTarget.startTransform.parent != null) { for (int j = 0; j < globalCtrlScripts.Length; j++) { if (myTarget.startTransform.parent.GetComponent <GlobalControl>()) { myTarget.numberOfBones = i + 1; unlockedBone = false; } foreach (ParentControl ParentControl in globalCtrlScripts[j]._ParentControls) { if (ParentControl.bone.transform == myTarget.startTransform.parent) { myTarget.numberOfBones = i + 1; unlockedBone = false; } } foreach (SplineControl splineCtrl in globalCtrlScripts[j]._SplineControls) { foreach (GameObject bone in splineCtrl.bones) { if (bone.transform == myTarget.startTransform.parent) { myTarget.numberOfBones = i + 1; unlockedBone = false; } } } } if (unlockedBone) { if (myTarget.startTransform != myTarget.endTransform && myTarget.limitBones) { Vector2 limit = new Vector2(); Transform limitTransform = myTarget.startTransform; Vector3 newEulerAngle = new Vector3(limitTransform.localEulerAngles.x % 360, limitTransform.localEulerAngles.y % 360, limitTransform.localEulerAngles.z % 360); if (newEulerAngle.x < 0) { newEulerAngle.x += 360; } if (newEulerAngle.y < 0) { newEulerAngle.y += 360; } if (newEulerAngle.z < 0) { newEulerAngle.z += 360; } myTarget.startTransform.localEulerAngles = newEulerAngle; float rangedVal = limitTransform.localEulerAngles.z % 360; if (rangedVal > 0 && rangedVal < 180) { limit = new Vector2(0, 180); myTarget.angleLimits.Add(limit); myTarget.angleLimitTransform.Add(limitTransform); } else if (rangedVal > 180 && rangedVal < 360) { limit = new Vector2(180, 360); myTarget.angleLimits.Add(limit); myTarget.angleLimitTransform.Add(limitTransform); } else if (rangedVal > -180 && rangedVal < 0) { limit = new Vector2(-180, 0); myTarget.angleLimits.Add(limit); myTarget.angleLimitTransform.Add(limitTransform); } else if (rangedVal > -360 && rangedVal < -180) { limit = new Vector2(-360, -180); myTarget.angleLimits.Add(limit); myTarget.angleLimitTransform.Add(limitTransform); } } myTarget.startTransform = myTarget.startTransform.parent; } } else { myTarget.numberOfBones = i + 1; } } }
public void OnEnable() { IKControl myTarget = (IKControl)target; myTarget.endTransform = myTarget.bottomJointTransform; }