protected virtual void CopyPoseImp() { //For some obscure reason, we have to set source and dest to null parent in order to work. QuickHumanPoseHandler.GetHumanPose(_source, ref _poseSource); QuickHumanPoseHandler.GetHumanPose(_dest, ref _poseDest); foreach (QuickHumanBodyBones boneID in _allJoints) { if (!IsTrackedJoint(boneID)) { for (int i = 0; i < 3; i++) { int m = QuickHumanTrait.GetMuscleFromBone(boneID, i); if (m != -1) { _poseSource.muscles[m] = _poseDest.muscles[m]; } } } } //The hips is a special case, it modifies the bodyPosition and bodyRotation fields if (!IsTrackedJointBody(TrackedJointBody.Hips)) { _poseSource.bodyPosition = _poseDest.bodyPosition; _poseSource.bodyRotation = _poseDest.bodyRotation; } QuickHumanPoseHandler.SetHumanPose(_dest, ref _poseSource); }
protected virtual void InitFingersData() { Animator animator = QuickSingletonManager.GetInstance <QuickVRManager>().GetAnimatorSource(); QuickHumanFingers[] fingers = QuickHumanTrait.GetHumanFingers(); int numFingers = fingers.Length; _handFingerConfidence = new int[numFingers]; _vrNodeFingers = new QuickVRNode[numFingers * NUM_BONES_PER_FINGER]; _tBoneFingers = new Transform[numFingers * NUM_BONES_PER_FINGER]; for (int i = 0; i < numFingers; i++) { _handFingerConfidence[i] = NUM_FRAMES_CONFIDENCE; List <QuickHumanBodyBones> fingerBones = QuickHumanTrait.GetBonesFromFinger(fingers[i], IsLeft()); for (int j = 0; j < NUM_BONES_PER_FINGER; j++) { int fingerBoneID = (i * NUM_BONES_PER_FINGER) + j; Transform tBone = animator.GetBoneTransform(fingerBones[j]); _vrNodeFingers[fingerBoneID] = _playArea.GetVRNode(fingerBones[j]); _tBoneFingers[fingerBoneID] = tBone; } } }
protected virtual void UpdateVRNodeFingers() { if (IsTracked() && QuickVRManager._handTrackingMode == QuickVRManager.HandTrackingMode.Controllers) { //Update the nodes of the fingers foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) { List <QuickHumanBodyBones> fingerBones = QuickHumanTrait.GetBonesFromFinger(f, _isLeft); for (int i = 0; i < QuickHumanTrait.NUM_BONES_PER_FINGER; i++) { QuickVRNode nFinger = QuickSingletonManager.GetInstance <QuickVRPlayArea>().GetVRNode(fingerBones[i]); //The finger is tracked. Transform t = _handAnimator[(int)f][i]; // .GetBoneFingerTransform(f, i); nFinger.transform.position = t.position; nFinger.transform.rotation = t.rotation; //Correct the rotation //if (IsLeft()) //{ // nFinger.transform.Rotate(Vector3.right, 180, Space.Self); // nFinger.transform.Rotate(Vector3.up, -90, Space.Self); //} //else //{ // nFinger.transform.Rotate(Vector3.up, 90, Space.Self); //} nFinger.SetTracked(true); } } } }
protected virtual void UpdateVRNodeFingers() { if (IsInitialized()) { if (!_physicsInitialized) { CreatePhysics(); _physicsInitialized = true; } if (!_fingersDataInitialized) { InitFingersData(); _fingersDataInitialized = true; } //Update the nodes of the fingers foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) { _handFingerConfidence[(int)f] = IsDataHighConfidence ? Mathf.Min(_handFingerConfidence[(int)f] + 1, NUM_FRAMES_CONFIDENCE) : 0; for (int i = 0; i < NUM_BONES_PER_FINGER; i++) { int boneID = ((int)f) * NUM_BONES_PER_FINGER + i; QuickVRNode nFinger = _vrNodeFingers[boneID]; //_playArea.GetVRNode(fingerBones[i]); if (IsDataHighConfidenceFinger(f)) { //The finger is tracked. OVRSkeleton.BoneId ovrBoneID = _ovrFingerBones[boneID]; Transform ovrBone = GetOVRBoneTransform(ovrBoneID); nFinger.transform.position = ovrBone.position; nFinger.transform.rotation = ovrBone.rotation; //Correct the rotation if (IsLeft()) { nFinger.transform.Rotate(Vector3.right, 180, Space.Self); nFinger.transform.Rotate(Vector3.up, -90, Space.Self); } else { nFinger.transform.Rotate(Vector3.up, 90, Space.Self); } //nFinger.SetTracked(true); } else { //The finger is not tracked. Restore the last valid local rotation. //nFinger.SetTracked(false); } nFinger.SetTracked(true); } } } }
protected virtual bool IsTrackedJoint(QuickHumanBodyBones boneID) { if (QuickHumanTrait.IsBoneFingerLeft(boneID)) { return(IsTrackedJointHandLeft(QuickHumanTrait.GetFingerFromBone(boneID))); } else if (QuickHumanTrait.IsBoneFingerRight(boneID)) { return(IsTrackedJointHandRight(QuickHumanTrait.GetFingerFromBone(boneID))); } return(IsTrackedJointBody(_toTrackedJointBody[boneID])); }
protected virtual Transform GetBoneMid(HumanBodyBones boneLimbID) { if (boneLimbID == HumanBodyBones.Hips || boneLimbID == HumanBodyBones.Head) { return(_animator.GetBoneTransform(HumanBodyBones.Spine)); } else if (boneLimbID == HumanBodyBones.LeftEye || boneLimbID == HumanBodyBones.RightEye) { return(_animator.GetBoneTransform(HumanBodyBones.Head)); } return(_animator.GetBoneTransform(QuickHumanTrait.GetParentBone(boneLimbID))); }
private static void Init() { _allJoints = QuickUtils.ParseEnum <QuickHumanBodyBones, TrackedJointBody>(); foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) { _allJoints.AddRange(QuickHumanTrait.GetBonesFromFinger(f, true)); _allJoints.AddRange(QuickHumanTrait.GetBonesFromFinger(f, false)); } foreach (TrackedJointBody j in QuickUtils.GetEnumValues <TrackedJointBody>()) { _toTrackedJointBody[QuickUtils.ParseEnum <QuickHumanBodyBones>(j.ToString())] = j; } }
protected virtual void InitBoneFingers() { _boneFingers = new List <KeyValuePair <Transform, Transform> >(); foreach (bool b in new bool[] { true, false }) { foreach (QuickHumanFingers f in QuickHumanTrait.GetHumanFingers()) { List <QuickHumanBodyBones> fingerBones = QuickHumanTrait.GetBonesFromFinger(f, b); for (int i = 0; i < fingerBones.Count; i++) { QuickHumanBodyBones fBoneID = fingerBones[i]; _boneFingers.Add(new KeyValuePair <Transform, Transform>(_animator.GetBoneTransform(fBoneID), _vrPlayArea.GetVRNode(fBoneID).GetTrackedObject().transform)); } } } }
public virtual void EvaluateHumanPose(float time, ref HumanPose pose) { if (_animator.isHuman) { pose.bodyPosition = GetAnimationCurve(CURVE_BODY_POSITION).EvaluateVector3(time); pose.bodyRotation = GetAnimationCurve(CURVE_BODY_ROTATION).EvaluateQuaternion(time); List <float> muscles = new List <float>(); for (int i = 0; i < QuickHumanTrait.GetNumMuscles(); i++) { muscles.Add(_curves[QuickHumanTrait.GetMuscleName(i)].Evaluate(time)); } pose.muscles = muscles.ToArray(); } }
protected virtual Transform GetIKTargetParent(HumanBodyBones boneID) { if (boneID == HumanBodyBones.LeftEye || boneID == HumanBodyBones.RightEye) { return(GetIKSolver(IKBone.Head)._targetLimb); } if (QuickHumanTrait.IsBoneFingerLeft(boneID)) { return(GetIKSolver(IKBone.LeftHand)._targetLimb); } if (QuickHumanTrait.IsBoneFingerRight(boneID)) { return(GetIKSolver(IKBone.RightHand)._targetLimb); } return(_ikTargetsRoot); }
protected virtual void CopyPose(QuickHumanBodyBones boneID) { QuickHumanBodyBones nextBoneID = QuickHumanTrait.GetNextBoneInChain(boneID); Transform tBoneSrc = _source.GetBoneTransform(boneID); Transform tBoneSrcNext = _source.GetBoneTransform(nextBoneID); Transform tBoneDst = _dest.GetBoneTransform(boneID); Transform tBoneDstNext = _dest.GetBoneTransform(nextBoneID); Vector3 currentDir = tBoneDstNext.position - tBoneDst.position; Vector3 targetDir = tBoneSrcNext.position - tBoneSrc.position; Vector3 rotAxis = Vector3.Cross(currentDir, targetDir); float rotAngle = Vector3.Angle(currentDir, targetDir); tBoneDst.Rotate(rotAxis, rotAngle, Space.World); }
public virtual AnimationClip ToAnimationClip() { AnimationClip anim = new AnimationClip(); QuickAnimationCurve curvePos = GetAnimationCurve(CURVE_BODY_POSITION); anim.SetCurve("", typeof(Animator), "RootT.x", curvePos[0]); anim.SetCurve("", typeof(Animator), "RootT.y", curvePos[1]); anim.SetCurve("", typeof(Animator), "RootT.z", curvePos[2]); QuickAnimationCurve curveRot = GetAnimationCurve(CURVE_BODY_ROTATION); anim.SetCurve("", typeof(Animator), "RootQ.x", curveRot[0]); anim.SetCurve("", typeof(Animator), "RootQ.y", curveRot[1]); anim.SetCurve("", typeof(Animator), "RootQ.z", curveRot[2]); anim.SetCurve("", typeof(Animator), "RootQ.w", curveRot[3]); curvePos = GetAnimationCurve(CURVE_LEFT_FOOT_IK_GOAL_POSITION); anim.SetCurve("", typeof(Animator), "LeftFootT.x", curvePos[0]); anim.SetCurve("", typeof(Animator), "LeftFootT.y", curvePos[1]); anim.SetCurve("", typeof(Animator), "LeftFootT.z", curvePos[2]); curveRot = GetAnimationCurve(CURVE_LEFT_FOOT_IK_GOAL_ROTATION); anim.SetCurve("", typeof(Animator), "LeftFootQ.x", curveRot[0]); anim.SetCurve("", typeof(Animator), "LeftFootQ.y", curveRot[1]); anim.SetCurve("", typeof(Animator), "LeftFootQ.z", curveRot[2]); anim.SetCurve("", typeof(Animator), "LeftFootQ.w", curveRot[3]); curvePos = GetAnimationCurve(CURVE_RIGHT_FOOT_IK_GOAL_POSITION); anim.SetCurve("", typeof(Animator), "RightFootT.x", curvePos[0]); anim.SetCurve("", typeof(Animator), "RightFootT.y", curvePos[1]); anim.SetCurve("", typeof(Animator), "RightFootT.z", curvePos[2]); curveRot = GetAnimationCurve(CURVE_RIGHT_FOOT_IK_GOAL_ROTATION); anim.SetCurve("", typeof(Animator), "RightFootQ.x", curveRot[0]); anim.SetCurve("", typeof(Animator), "RightFootQ.y", curveRot[1]); anim.SetCurve("", typeof(Animator), "RightFootQ.z", curveRot[2]); anim.SetCurve("", typeof(Animator), "RightFootQ.w", curveRot[3]); for (int i = 0; i < QuickHumanTrait.GetNumMuscles(); i++) { string muscleName = QuickHumanTrait.GetMuscleName(i); anim.SetCurve("", typeof(Animator), muscleName, _curves[muscleName][0]); } return(anim); }
public virtual float GetFingerLength(QuickHumanFingers f, bool isLeft) { List <QuickHumanBodyBones> boneFingers = QuickHumanTrait.GetBonesFromFinger(f, isLeft); HumanBodyBones boneID = (HumanBodyBones)boneFingers[0]; if (_fingerLength[boneID] == 0) { QuickVRNode n0 = GetVRNode(boneFingers[0]); QuickVRNode n1 = GetVRNode(boneFingers[1]); QuickVRNode n2 = GetVRNode(boneFingers[2]); if (n0.IsTracked() && n1.IsTracked() && n2.IsTracked()) { _fingerLength[boneID] = Vector3.Distance(n0.transform.position, n1.transform.position) + Vector3.Distance(n1.transform.position, n2.transform.position); } } return(_fingerLength[boneID]); }
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); } } }
public virtual void AddKey(float time, bool forceAdd = false) { GetAnimationCurve(CURVE_TRANSFORM_POSITION).AddKey(time, _animator.transform.position, forceAdd); GetAnimationCurve(CURVE_TRANSFORM_ROTATION).AddKey(time, _animator.transform.rotation, forceAdd); if (_animator.isHuman) { QuickHumanPoseHandler.GetHumanPose(_animator, ref _pose); Vector3 bodyPosition = _pose.bodyPosition; Quaternion bodyRotation = _pose.bodyRotation; GetAnimationCurve(CURVE_BODY_POSITION).AddKey(time, bodyPosition, forceAdd); GetAnimationCurve(CURVE_BODY_ROTATION).AddKey(time, bodyRotation, forceAdd); Vector3 ikGoalPos; Quaternion ikGoalRot; _animator.GetIKGoalFromBodyPose(AvatarIKGoal.LeftFoot, bodyPosition, bodyRotation, out ikGoalPos, out ikGoalRot); GetAnimationCurve(CURVE_LEFT_FOOT_IK_GOAL_POSITION).AddKey(time, ikGoalPos, forceAdd); GetAnimationCurve(CURVE_LEFT_FOOT_IK_GOAL_ROTATION).AddKey(time, ikGoalRot, forceAdd); _animator.GetIKGoalFromBodyPose(AvatarIKGoal.RightFoot, bodyPosition, bodyRotation, out ikGoalPos, out ikGoalRot); GetAnimationCurve(CURVE_RIGHT_FOOT_IK_GOAL_POSITION).AddKey(time, ikGoalPos, forceAdd); GetAnimationCurve(CURVE_RIGHT_FOOT_IK_GOAL_ROTATION).AddKey(time, ikGoalRot, forceAdd); for (int i = 0; i < _pose.muscles.Length; i++) { string muscleName = QuickHumanTrait.GetMuscleName(i); GetAnimationCurve(muscleName).AddKey(time, _pose.muscles[i], forceAdd); } } if (time > _timeLength) { _timeLength = time; } }
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(); }