public override void UpdateTracking() { if (_animator.runtimeAnimatorController == null) { for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { GetIKSolver(ikBone).ResetIKChain(); } } QuickIKSolver ikSolverHips = GetIKSolver(IKBone.Hips); QuickIKSolver ikSolverHead = GetIKSolver(IKBone.Head); //float chainLength = Vector3.Distance(_animator.GetBoneTransform(HumanBodyBones.Hips).position, _animator.GetBoneTransform(HumanBodyBones.Head).position); //Vector3 v = (ikSolverHips._targetLimb.position - ikSolverHead._targetLimb.position).normalized; //ikSolverHips._targetLimb.position = ikSolverHead._targetLimb.position + v * chainLength; //Update the IK for the body controllers ikSolverHips.UpdateIK(); ikSolverHead.UpdateIK(); GetIKSolver(IKBone.LeftHand).UpdateIK(); GetIKSolver(IKBone.RightHand).UpdateIK(); GetIKSolver(IKBone.LeftFoot).UpdateIK(); GetIKSolver(IKBone.RightFoot).UpdateIK(); //Update the IK for the fingers controllers UpdateIKFingers(); //Update the IK for the face controllers for (IKBone ikBone = IKBone.LeftEye; ikBone <= IKBone.RightEye; ikBone++) { GetIKSolver(ikBone).UpdateIK(); } }
protected virtual void DrawIKSolver(QuickIKSolver ikSolver, bool isSolverFinger) { Handles.color = Color.magenta; if (ikSolver._boneUpper && ikSolver._boneMid) { Handles.DrawLine(ikSolver._boneUpper.position, ikSolver._boneMid.position); } if (ikSolver._boneMid && ikSolver._boneLimb) { Handles.DrawLine(ikSolver._boneMid.position, ikSolver._boneLimb.position); } Handles.color = Color.yellow; if (ikSolver._boneMid && ikSolver._targetHint) { Handles.DrawLine(ikSolver._boneMid.position, ikSolver._targetHint.position); } Handles.color = Color.cyan; if (ikSolver._boneUpper && ikSolver._targetLimb) { float chainLength = Vector3.Distance(ikSolver._boneUpper.position, ikSolver._boneMid.position) + Vector3.Distance(ikSolver._boneMid.position, ikSolver._boneLimb.position); Vector3 v = ikSolver._targetLimb.position - ikSolver._boneUpper.position; Vector3 p = ikSolver._boneUpper.position + (v.normalized * Mathf.Min(v.magnitude, chainLength)); Handles.DrawLine(ikSolver._boneUpper.position, p); } DrawIKTarget(ikSolver._targetLimb, Handles.CubeHandleCap, isSolverFinger); DrawIKTarget(ikSolver._targetHint, Handles.SphereHandleCap, isSolverFinger); }
private static void SelectIKTarget(Transform ikTarget, QuickIKSolver ikSolver, IKBone ikBone) { _selectedIKTarget._transform = ikTarget; _selectedIKTarget._ikSolver = ikSolver; _selectedIKTarget._ikBone = ikBone; Selection.activeTransform = ikTarget; }
protected virtual void DrawIKSolverProperties(QuickIKSolver ikSolver, string name) { ikSolver._enableIK = EditorGUILayout.Toggle(name, ikSolver._enableIK); if (ikSolver._enableIK) { DrawIKSolverPropertiesBase(ikSolver); } }
public virtual void UpdateIKTargets() { if (Application.isPlaying) { //1) Update all the IKTargets taking into consideration its ControlType. for (IKBone ikBone = IKBone.Hips; ikBone < IKBone.LastBone; ikBone++) { ControlType cType = GetIKControl(ikBone); HumanBodyBones boneID = ToHumanBodyBones(ikBone); GetIKSolver(ikBone)._enableIK = cType != ControlType.Animation; if (cType == ControlType.Tracking) { QuickVRNode node = _vrPlayArea.GetVRNode(boneID); if (node.IsTracked()) { //Update the QuickVRNode's position UpdateIKTargetPosFromUser(node, boneID); //Update the QuickVRNode's rotation UpdateIKTargetRotFromUser(node, boneID); if (boneID == HumanBodyBones.Head) { QuickIKSolver ikSolverHead = GetIKSolver(IKBone.Head); if (!_applyHeadPosition) { ikSolverHead._weightIKPos = 0; } if (!_applyHeadRotation) { ikSolverHead._weightIKRot = 0; } } else if (boneID == HumanBodyBones.LeftEye || boneID == HumanBodyBones.RightEye) { QuickIKSolverEye ikSolver = (QuickIKSolverEye)_animator.GetComponent <QuickIKManager>().GetIKSolver(boneID); ikSolver._weightBlink = ((QuickVRNodeEye)node).GetBlinkFactor(); } } } } //2) Special case. If the Hips is set to Tracking mode, we need to adjust the IKTarget position of the hips //in a way that the head will match the position of the camera provided by the HMD if (GetIKControl(IKBone.Hips) == ControlType.Tracking) { QuickIKSolver ikSolverHips = GetIKSolver(IKBone.Hips); QuickIKSolver ikSolverHead = GetIKSolver(IKBone.Head); float chainLength = Vector3.Distance(_animator.GetBoneTransform(HumanBodyBones.Hips).position, _animator.GetBoneTransform(HumanBodyBones.Head).position); Vector3 v = (ikSolverHips._targetLimb.position - ikSolverHead._targetLimb.position).normalized; ikSolverHips._targetLimb.position = ikSolverHead._targetLimb.position + v * chainLength; } UpdateVRCursors(); _footprints.gameObject.SetActive(_useFootprints); } }
private static void DrawIKTargets() { foreach (QuickIKManagerExecuteInEditMode ikManagerEditor in _ikManagers) { QuickIKManager ikManager = ikManagerEditor._ikManager; if (ikManager && ikManager.gameObject.activeInHierarchy) { for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { QuickIKSolver ikSolver = ikManager.GetIKSolver(ikBone); float size; if (ikBone >= IKBone.Hips && ikBone <= IKBone.RightFoot) { size = 0.05f; } else { size = 0.01f; } Handles.color = new Color(1, 0, 0, 0.5f); if (Handles.Button(ikSolver._targetLimb.position, ikSolver._targetLimb.rotation, size, size, Handles.CubeHandleCap)) { SelectIKTarget(ikSolver._targetLimb, ikSolver, ikBone); } if (ikSolver._targetHint) { Handles.color = new Color(0, 1, 0, 0.5f); if (Handles.Button(ikSolver._targetHint.position, ikSolver._targetHint.rotation, size, size, Handles.SphereHandleCap)) { SelectIKTarget(ikSolver._targetHint, ikSolver, ikBone); } } } } } }
public virtual void LoadTPose() { _animator.EnforceTPose(); //Reset the IKTargets for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { QuickIKSolver ikSolver = GetIKSolver(ikBone); HumanBodyBones boneID = ToHumanBodyBones(ikBone); ResetIKTarget(boneID, ikSolver._targetLimb); ikSolver._targetLimb.parent = GetIKTargetParent(boneID); if (ikSolver._targetLimb.childCount > 0) { ikSolver._targetLimb.GetChild(0).rotation = ikSolver._boneLimb.rotation; } if (ikSolver._targetHint) { ResetIKTarget(QuickHumanTrait.GetParentBone(boneID), ikSolver._targetHint); } } }
protected virtual void OnDrawGizmos() { Gizmos.color = Color.cyan; for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { QuickIKSolver ikSolver = GetIKSolver(ikBone); if (ikSolver._boneUpper && ikSolver._targetLimb) { Gizmos.DrawLine(ikSolver._boneUpper.position, ikSolver._targetLimb.position); } } Gizmos.color = Color.magenta; for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { QuickIKSolver ikSolver = GetIKSolver(ikBone); if (ikSolver._boneUpper && ikSolver._boneMid) { Gizmos.DrawLine(ikSolver._boneUpper.position, ikSolver._boneMid.position); } if (ikSolver._boneMid && ikSolver._boneLimb) { Gizmos.DrawLine(ikSolver._boneMid.position, ikSolver._boneLimb.position); } } Gizmos.color = Color.yellow; for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { QuickIKSolver ikSolver = GetIKSolver(ikBone); if (ikSolver._boneMid && ikSolver._targetHint) { Gizmos.DrawLine(ikSolver._boneMid.position, ikSolver._targetHint.position); } } }
protected virtual void MirrorPose(QuickIKSolver srcIKSolver, QuickIKSolver dstIKSolver) { Transform srcParent = srcIKSolver._targetLimb.parent; Transform dstParent = dstIKSolver._targetLimb.parent; srcIKSolver._targetLimb.parent = dstIKSolver._targetLimb.parent = transform; Transform srcHintParent = null; Transform dstHintParent = null; if (srcIKSolver._targetHint && dstIKSolver._targetHint) { srcHintParent = srcIKSolver._targetHint.parent; dstHintParent = dstIKSolver._targetHint.parent; srcIKSolver._targetHint.parent = dstIKSolver._targetHint.parent = transform; } MirrorIKTarget(srcIKSolver._targetLimb, dstIKSolver._targetLimb); MirrorIKTarget(srcIKSolver._targetHint, dstIKSolver._targetHint); srcIKSolver.UpdateIK(); dstIKSolver.UpdateIK(); //Restore the parent for the IKTargetLimbs srcIKSolver._targetLimb.parent = srcParent; dstIKSolver._targetLimb.parent = dstParent; srcIKSolver._targetLimb.localScale = dstIKSolver._targetLimb.localScale = Vector3.one; //Restore the parent for the IKTargetHints if (srcIKSolver._targetHint && dstIKSolver._targetHint) { srcIKSolver._targetHint.parent = srcHintParent; dstIKSolver._targetHint.parent = dstHintParent; srcIKSolver._targetHint.localScale = dstIKSolver._targetHint.localScale = Vector3.one; } }
protected virtual void CreateIKSolvers() { //Ensure that the ikSolvers are childs of _ikSolversRoot. foreach (QuickIKSolver ikSolver in GetComponentsInChildren <QuickIKSolver>(true)) { ikSolver.transform.parent = _ikSolversRoot; } for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { QuickIKSolver ikSolver = CreateIKSolver(ikBone); ikSolver.transform.SetSiblingIndex((int)ikBone); } for (IKBone ikBone = IKBone.LeftThumbDistal; ikBone <= IKBone.LeftLittleDistal; ikBone++) { GetIKSolver(ikBone)._targetHint.parent = _animator.GetBoneTransform(HumanBodyBones.LeftHand); } for (IKBone ikBone = IKBone.RightThumbDistal; ikBone <= IKBone.RightLittleDistal; ikBone++) { GetIKSolver(ikBone)._targetHint.parent = _animator.GetBoneTransform(HumanBodyBones.RightHand); } }
protected override void UpdateIKFingers() { if (_vrPlayArea) { //if (_boneFingers == null) //{ // InitBoneFingers(); //} //for (int j = 0; j < _boneFingers.Count; j+= 4) //{ // if (_boneFingers[j].Key != null) // { // for (int i = 0; i < 3; i++) // { // if ((i == 0 && (j == 0 || j == 20)) && QuickVRManager._handTrackingMode == QuickVRManager.HandTrackingMode.Controllers) // { // //HACK // //Avoid applying the rotation to the thumb distal fingers as the results look weird. Look for a better method // //of transfering the bone rotations when using the controllers. // continue; // } // ApplyFingerRotation(_boneFingers[j + i], _boneFingers[j + i + 1]); // } // } //} //foreach (bool b in new bool[] { true, false }) //{ // foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) // { // List<QuickHumanBodyBones> fingerBones = QuickHumanTrait.GetBonesFromFinger(f, b); // List<Quaternion> initialFingerBonesLocalRotations = new List<Quaternion>(); // for (int i = 0; i < fingerBones.Count - 1; i++) // { // QuickHumanBodyBones fBoneID = fingerBones[i]; // initialFingerBonesLocalRotations.Add(_animator.GetBoneTransform(fBoneID).localRotation); // if (_animator.GetBoneTransform(fBoneID) && _vrPlayArea.GetVRNode(fBoneID).IsTracked()) // { // ApplyFingerRotation(fBoneID, fingerBones[i + 1]); // } // } // //At this point the finger is correctly aligned. Set the targets to match this. // //HumanBodyBones boneID = (HumanBodyBones)fingerBones[2]; // //QuickIKSolver ikSolver = GetIKSolver(boneID); // //Transform tBone = _animator.GetBoneTransform(boneID); // //ikSolver._targetLimb.position = tBone.position; // //ikSolver._targetLimb.GetChild(0).rotation = tBone.rotation; // //ikSolver._targetHint.position = ikSolver._boneMid.position + (ikSolver._boneMid.position - ikSolver._boneUpper.position) + (ikSolver._boneMid.position - ikSolver._boneLimb.position); // ////Restore the rotation of the bone fingers // //ikSolver._boneUpper.localRotation = initialFingerBonesLocalRotations[0]; // //ikSolver._boneMid.localRotation = initialFingerBonesLocalRotations[1]; // //ikSolver._boneLimb.localRotation = initialFingerBonesLocalRotations[2]; // } //} //foreach (bool b in new bool[] { true, false }) //{ // foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) // { // List<QuickHumanBodyBones> fingerBones = QuickHumanTrait.GetBonesFromFinger(f, b); // List<Quaternion> initialFingerBonesLocalRotations = new List<Quaternion>(); // for (int i = 0; i < fingerBones.Count - 1; i++) // { // QuickHumanBodyBones fBoneID = fingerBones[i]; // initialFingerBonesLocalRotations.Add(_animator.GetBoneTransform(fBoneID).localRotation); // if (_animator.GetBoneTransform(fBoneID) && _vrPlayArea.GetVRNode(fBoneID).IsTracked()) // { // ApplyFingerRotation(fBoneID, fingerBones[i + 1]); // } // } // //At this point the finger is correctly aligned. Set the targets to match this. // //HumanBodyBones boneID = (HumanBodyBones)fingerBones[2]; // //QuickIKSolver ikSolver = GetIKSolver(boneID); // //Transform tBone = _animator.GetBoneTransform(boneID); // //ikSolver._targetLimb.position = tBone.position; // //ikSolver._targetLimb.GetChild(0).rotation = tBone.rotation; // //ikSolver._targetHint.position = ikSolver._boneMid.position + (ikSolver._boneMid.position - ikSolver._boneUpper.position) + (ikSolver._boneMid.position - ikSolver._boneLimb.position); // ////Restore the rotation of the bone fingers // //ikSolver._boneUpper.localRotation = initialFingerBonesLocalRotations[0]; // //ikSolver._boneMid.localRotation = initialFingerBonesLocalRotations[1]; // //ikSolver._boneLimb.localRotation = initialFingerBonesLocalRotations[2]; // } //} //foreach (bool isLeft in new bool[] { true, false }) //{ // foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) // { // float fLength = _vrPlayArea.GetFingerLength(f, isLeft); // if (fLength > 0) // { // List<QuickHumanBodyBones> fingerBones = QuickHumanTrait.GetBonesFromFinger(f, isLeft); // QuickVRNode n0 = _vrPlayArea.GetVRNode(fingerBones[0]); // QuickVRNode n1 = _vrPlayArea.GetVRNode(fingerBones[1]); // QuickVRNode n2 = _vrPlayArea.GetVRNode(fingerBones[2]); // QuickIKSolver ikSolver = GetIKSolver((HumanBodyBones)fingerBones[2]); // if (n0.IsTracked() && n2.IsTracked()) // { // float sf = ikSolver.GetChainLength() / fLength; // Vector3 v = sf * (n2.transform.position - n0.transform.position); // ikSolver._targetLimb.position = ikSolver._boneUpper.position + v; // ikSolver._targetHint.position = ikSolver._boneMid.position + (n1.transform.position - n0.transform.position) + (n1.transform.position - n2.transform.position); // } // } // } //} foreach (bool isLeft in new bool[] { true, false }) { foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) { List <QuickHumanBodyBones> fingerBones = QuickHumanTrait.GetBonesFromFinger(f, isLeft); QuickVRNode n0 = _vrPlayArea.GetVRNode(fingerBones[0]); QuickVRNode n1 = _vrPlayArea.GetVRNode(fingerBones[1]); QuickVRNode n2 = _vrPlayArea.GetVRNode(fingerBones[2]); if (n0.IsTracked() && n1.IsTracked() && n2.IsTracked()) { QuickIKSolver ikSolver = GetIKSolver((HumanBodyBones)fingerBones[2]); Vector3 v = (n1.transform.position - n0.transform.position).normalized; Vector3 w = (n2.transform.position - n1.transform.position).normalized; ikSolver._targetLimb.position = ikSolver._boneUpper.position + v * ikSolver.GetUpperLength() + w * ikSolver.GetMidLength(); ikSolver._targetLimb.rotation = n2.transform.rotation; ikSolver._targetHint.position = ikSolver._boneMid.position + n1.transform.up * DEFAULT_TARGET_HINT_FINGER_DISTANCE; ikSolver._targetHint.rotation = n1.transform.rotation; //ikSolver._targetHint.position = ikSolver._boneMid.position + (n1.transform.position - n0.transform.position) + (n1.transform.position - n2.transform.position); } } } } base.UpdateIKFingers(); }
public virtual void LoadAnimPose() { //Restore the TPose LoadTPose(); _ikTargetsRoot.ResetTransformation(); //Temporally set the parent of each ikTargetLimb to be the boneLimb. This way, the //target is automatically moved to the bone position when the animation is applied. for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { QuickIKSolver ikSolver = GetIKSolver(ikBone); ikSolver._targetLimb.parent = ikSolver._boneLimb; } //If we have an animatorcontroller defined, the targets are moved at the position of the //initial frame of the current animation in such controller. if (_animator.runtimeAnimatorController) { Quaternion jawLocalRot = Quaternion.identity; Transform tJaw = _animator.GetBoneTransform(HumanBodyBones.Jaw); if (tJaw) { jawLocalRot = tJaw.localRotation; } _animator.Update(0); //Force the mouth to be closed if (tJaw) { tJaw.localRotation = jawLocalRot; } } //Check the rotation of the parents of the targets of the finger bones for (HumanBodyBones boneID = HumanBodyBones.LeftThumbDistal; boneID <= HumanBodyBones.LeftLittleDistal; boneID += 3) { Transform t = GetIKTargetParent(boneID); t.position = _animator.GetBoneTransform(boneID - 2).position; t.LookAt(_animator.GetBoneTransform(boneID - 1), transform.up); } for (HumanBodyBones boneID = HumanBodyBones.RightThumbDistal; boneID <= HumanBodyBones.RightLittleDistal; boneID += 3) { Transform t = GetIKTargetParent(boneID); t.position = _animator.GetBoneTransform(boneID - 2).position; t.LookAt(_animator.GetBoneTransform(boneID - 1), transform.up); } //Restore the ikTargetLimb real parent. for (IKBone ikBone = 0; ikBone < IKBone.LastBone; ikBone++) { HumanBodyBones boneID = ToHumanBodyBones(ikBone); QuickIKSolver ikSolver = GetIKSolver(ikBone); ikSolver._targetLimb.parent = GetIKTargetParent(boneID); ikSolver._targetLimb.localScale = Vector3.one; } //Recalculate the ikTargetHint position of the arms and legs for (IKBone ikBone = IKBone.LeftHand; ikBone <= IKBone.RightFoot; ikBone++) { QuickIKSolver ikSolver = GetIKSolver(ikBone); if (ikSolver._targetHint) { Vector3 u = (ikSolver._boneMid.position - ikSolver._boneLimb.position).normalized; Vector3 v = (ikSolver._boneMid.position - ikSolver._boneUpper.position).normalized; if (Vector3.Angle(u, v) < 175) { ikSolver._targetHint.position = ikSolver._boneMid.position + (u + v).normalized * DEFAULT_TARGET_HINT_DISTANCE; } } } }
protected virtual void DrawIKSolverPropertiesBase(QuickIKSolver ikSolver) { EditorGUILayout.BeginHorizontal(); GUI.enabled = false; EditorGUILayout.ObjectField("IKTarget", ikSolver._targetLimb, typeof(Transform), true); GUI.enabled = true; if (DrawButton("Reset", GUILayout.Width(52))) { ikSolver.LoadPose(); //_target.ResetIKTarget(boneID); } EditorGUILayout.EndHorizontal(); ikSolver._weightIKPos = EditorGUILayout.Slider("IKPosWeight", ikSolver._weightIKPos, 0, 1); ikSolver._weightIKRot = EditorGUILayout.Slider("IKRotWeight", ikSolver._weightIKRot, 0, 1); if (ikSolver.GetType() == typeof(QuickIKSolverEye)) { QuickIKSolverEye ikSolverEye = (QuickIKSolverEye)ikSolver; if (ikSolverEye._showAngleLimits = FoldoutBolt(ikSolverEye._showAngleLimits, "Angle Limits")) { EditorGUI.indentLevel++; ikSolverEye._angleLimitLeft = EditorGUILayout.FloatField("Left", ikSolverEye._angleLimitLeft); ikSolverEye._angleLimitRight = EditorGUILayout.FloatField("Right", ikSolverEye._angleLimitRight); ikSolverEye._angleLimitDown = EditorGUILayout.FloatField("Down", ikSolverEye._angleLimitDown); ikSolverEye._angleLimitUp = EditorGUILayout.FloatField("Up", ikSolverEye._angleLimitUp); EditorGUI.indentLevel--; } ikSolverEye._leftRight = EditorGUILayout.Slider("Left - Right", ikSolverEye._leftRight, ikSolverEye._angleLimitLeft, ikSolverEye._angleLimitRight); ikSolverEye._downUp = EditorGUILayout.Slider("Down - Up", ikSolverEye._downUp, ikSolverEye._angleLimitDown, ikSolverEye._angleLimitUp); if (ikSolverEye._showBlinking = FoldoutBolt(ikSolverEye._showBlinking, "Blinking")) { EditorGUI.indentLevel++; EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); if (DrawButton("Add")) { ikSolverEye._blinking.Add(new QuickIKSolverEye.BlinkData()); } if (DrawButton("Remove Last")) { if (ikSolverEye._blinking.Count > 0) { ikSolverEye._blinking.RemoveAt(ikSolverEye._blinking.Count - 1); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); for (int i = 0; i < ikSolverEye._blinking.Count; i++) { QuickIKSolverEye.BlinkData bData = ikSolverEye._blinking[i]; if (bData._showInInspector = FoldoutBolt(bData._showInInspector, "Element " + i.ToString())) { EditorGUI.indentLevel++; bData._renderer = (SkinnedMeshRenderer)EditorGUILayout.ObjectField("Mesh", bData._renderer, typeof(SkinnedMeshRenderer), true); if (bData._renderer && bData._renderer.sharedMesh) { Mesh mesh = bData._renderer.sharedMesh; List <string> bNames = new List <string>(); bNames.Add("None"); for (int j = 0; j < mesh.blendShapeCount; j++) { bNames.Add(mesh.GetBlendShapeName(j)); } bData._blendshapeID = EditorGUILayout.Popup("Blendshape ID", bData._blendshapeID + 1, bNames.ToArray()) - 1; } EditorGUI.indentLevel--; } } EditorGUILayout.Space(); EditorGUI.indentLevel--; } ikSolverEye._weightBlink = EditorGUILayout.Slider("BlinkWeight", ikSolverEye._weightBlink, 0, 1); } }