protected virtual void SwapQuickVRNode(QuickVRNode vrNodeA, QuickVRNode vrNodeB) { InputDevice deviceA = vrNodeA._inputDevice; vrNodeA._inputDevice = vrNodeB._inputDevice; vrNodeB._inputDevice = deviceA; }
protected virtual void OnDrawGizmos() { Gizmos.color = Color.green; foreach (var pair in _vrNodes) { QuickVRNode n = pair.Value; if (n.IsTracked()) { DebugExtension.DrawCoordinatesSystem(n.transform.position, n.transform.right, n.transform.up, n.transform.forward, 0.05f); float s = 0.0125f; Vector3 cSize = Vector3.one * s; Gizmos.matrix = n.transform.localToWorldMatrix; Gizmos.DrawCube(Vector3.zero, cSize); QuickTrackedObject tObject = n.GetTrackedObject(); if (tObject.transform.localPosition != Vector3.zero) { Gizmos.DrawSphere(tObject.transform.localPosition, s * 0.5f); Gizmos.DrawLine(Vector3.zero, tObject.transform.localPosition); } Gizmos.matrix = Matrix4x4.identity; } } }
protected virtual void OnCalibrateVRNodeHips(QuickVRNode node) { QuickTrackedObject tObjectHead = _vrPlayArea.GetVRNode(HumanBodyBones.Head).GetTrackedObject(); QuickTrackedObject tObjectHips = node.GetTrackedObject(); tObjectHips.transform.position = new Vector3(tObjectHead.transform.position.x, tObjectHips.transform.position.y, tObjectHead.transform.position.z); }
public virtual QuickVRNode GetVRNodeMain() { QuickVRNode nodeHips = GetVRNode(HumanBodyBones.Hips); QuickVRNode nodeHead = GetVRNode(HumanBodyBones.Head); return(nodeHips.IsTracked() ? nodeHips : nodeHead); }
protected virtual void OnCalibrateVRNodeFoot(QuickVRNode node) { Transform ikTarget = GetIKSolver((HumanBodyBones)node.GetRole())._targetLimb; QuickTrackedObject tObject = node.GetTrackedObject(); tObject.transform.rotation = ikTarget.rotation; }
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 IEnumerator CoUpdate() { //Wait for the node of the head to be created. QuickUnityVR hTracking = GetComponent <QuickUnityVR>(); QuickVRNode nodeHead = null; while (nodeHead == null) { nodeHead = _vrPlayArea.GetVRNode(HumanBodyBones.Head); yield return(null); } _trackedObject = nodeHead.GetTrackedObject(); while (true) { //Debug.Log("disp = " + disp.ToString("f3")); CoUpdateTrackedNode(); //Wait for a new sample yield return(StartCoroutine(CoUpdateSample())); CoUpdateTargetLinearVelocity(); //Check the real displacement of the user in the room. If it is big enough, the contribution //of the WiP is ignored. Vector3 disp = Vector3.Scale(_headTracking.GetDisplacement(), Vector3.forward + Vector3.right); if (disp.magnitude > 0.005f) { _rigidBody.velocity = Vector3.Scale(_rigidBody.velocity, Vector3.up); Init(); } } }
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 IsNodeLeftSide(QuickVRNode vrNode) { QuickVRNode nodeHead = GetVRNode(HumanBodyBones.Head); Vector3 fwd = Vector3.ProjectOnPlane(nodeHead.transform.forward, transform.up); Vector3 v = Vector3.ProjectOnPlane(vrNode.transform.position - nodeHead.transform.position, transform.up); return(Vector3.SignedAngle(fwd, v, transform.up) < 0); }
protected virtual void UpdateVRNode(HumanBodyBones role, Transform t) { QuickVRNode vrNode = _vrPlayArea.GetVRNode(role); vrNode.transform.position = t.position; vrNode.transform.rotation = t.rotation; vrNode.SetTracked(true); }
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); } }
protected virtual void UpdateCameraRotationXR() { //On the legacy XRMode, the camera is automatically rotated with the movement of the HMD. In The XRPlugin mode, we //have to manually apply the rotation of the HMD to the camera. if (QuickSingletonManager.GetInstance <QuickVRManager>()._XRMode == QuickVRManager.XRMode.XRPlugin) { QuickVRNode vrNodeHead = QuickSingletonManager.GetInstance <QuickVRPlayArea>().GetVRNode(HumanBodyBones.Head); vrNodeHead.UpdateState(); _camera.transform.localRotation = vrNodeHead.transform.localRotation; } }
protected virtual void Awake() { foreach (QuickHumanBodyBones role in QuickVRNode.GetTypeList()) { CreateVRNode(role); } for (HumanBodyBones boneID = HumanBodyBones.LeftThumbProximal; boneID <= HumanBodyBones.RightLittleProximal; boneID++) { _fingerLength[boneID] = 0; } }
protected virtual void Start() { _skeleton = transform.GetOrCreateComponent <OVRSkeleton>(); transform.GetOrCreateComponent <OVRMesh>(); transform.GetOrCreateComponent <OVRMeshRenderer>(); _renderer = transform.GetOrCreateComponent <SkinnedMeshRenderer>(); //_renderer.material = Resources.Load<Material>("Materials/QuickDiffuseCyan"); _renderer.material = Resources.Load <Material>("Materials/QuickOVRHandMaterial"); _playArea = GetComponentInParent <QuickVRPlayArea>(); _vrNodeHand = _playArea.GetVRNode(IsLeft() ? HumanBodyBones.LeftHand : HumanBodyBones.RightHand); _ovrNodeHand = IsLeft() ? OVRPlugin.Node.HandLeft : OVRPlugin.Node.HandRight; }
protected virtual void CoUpdateTrackedNode() { QuickVRNode hipsNode = _vrPlayArea.GetVRNode(HumanBodyBones.Hips); if (hipsNode) { QuickTrackedObject tObject = hipsNode.IsTracked()? hipsNode.GetTrackedObject() : _vrPlayArea.GetVRNode(HumanBodyBones.Head).GetTrackedObject(); if (tObject != _trackedObject) { _trackedObject = tObject; Init(); } } }
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 bool IsVRNodesSwaped(QuickVRNode nodeLeft, QuickVRNode nodeRight, bool doSwaping = true) { bool result = false; QuickVRNode hmdNode = GetVRNode(HumanBodyBones.Head); if (hmdNode.IsTracked() && nodeLeft.IsTracked() && nodeRight.IsTracked()) { float dLeft = Vector3.Dot(nodeLeft.transform.position - hmdNode.transform.position, hmdNode.transform.right); float dRight = Vector3.Dot(nodeRight.transform.position - hmdNode.transform.position, hmdNode.transform.right); result = dLeft > dRight; if (result && doSwaping) { SwapQuickVRNode(nodeLeft, nodeRight); } } return(result); }
public override void Calibrate() { base.Calibrate(); transform.localScale = Vector3.one; _footprints.translationOffset = Vector3.zero; _footprints.transform.rotation = transform.rotation; _vrPlayArea.Calibrate(); float rotAngle = Vector3.SignedAngle(_vrPlayArea.GetUserForward(), transform.forward, transform.up); _vrPlayArea.transform.Rotate(transform.up, rotAngle, Space.World); //Set the offset of the TrackedObject of the head QuickVRNode node = _vrPlayArea.GetVRNode(HumanBodyBones.Head); Vector3 offset = GetIKSolver(IKBone.Head)._targetLimb.position - node.GetTrackedObject().transform.position; _vrPlayArea.transform.position += offset; }
protected virtual QuickVRNode CreateVRNode(QuickHumanBodyBones role) { Transform tNode = transform.CreateChild("VRNode" + role.ToString()); QuickVRNode n = null; if (role == QuickHumanBodyBones.Head) { n = tNode.GetOrCreateComponent <QuickVRNodeHead>(); } else if (role == QuickHumanBodyBones.LeftHand) { n = tNode.GetOrCreateComponent <QuickVRNodeHand>(); ((QuickVRNodeHand)n)._isLeft = true; } else if (role == QuickHumanBodyBones.RightHand) { n = tNode.GetOrCreateComponent <QuickVRNodeHand>(); ((QuickVRNodeHand)n)._isLeft = false; } else if (role == QuickHumanBodyBones.LeftEye) { n = tNode.GetOrCreateComponent <QuickVRNodeEye>(); ((QuickVRNodeEye)n)._isLeft = true; } else if (role == QuickHumanBodyBones.RightEye) { n = tNode.GetOrCreateComponent <QuickVRNodeEye>(); ((QuickVRNodeEye)n)._isLeft = false; } else { n = tNode.GetOrCreateComponent <QuickVRNode>(); } n.SetRole(role); _vrNodes[role] = n; return(n); }
protected virtual void UpdateIKTargetRotFromUser(QuickVRNode node, HumanBodyBones boneID) { GetIKSolver(boneID)._targetLimb.rotation = node.GetTrackedObject().transform.rotation; }
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(); }
protected virtual void OnCalibrateVRNodeRightHand(QuickVRNode node) { }
public virtual void Calibrate() { //POSSIBLE TRACKER CONFIGURATIONS //1 -> Head //3 -> Head + Hands //4 -> Head + Hands + Hips //6 -> Head + Hands + Hips + Feet //10 -> Head + Hands + Hips + Feet + Elbows + Knees _isHandsSwaped = false; List <InputDevice> bodyTrackers = GetBodyTrackers(); int numTrackers = bodyTrackers.Count; QuickVRManager.Log("NUM BODY TRACKERS = " + numTrackers); //Try to assign the default nodes for Head and Hands QuickVRNode nodeHMD = GetVRNode(HumanBodyBones.Head); QuickVRNode nodeLeftHand = GetVRNode(HumanBodyBones.LeftHand); QuickVRNode nodeRightHand = GetVRNode(HumanBodyBones.RightHand); nodeHMD._inputDevice = InputDevices.GetDeviceAtXRNode(XRNode.Head); nodeLeftHand._inputDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand); nodeRightHand._inputDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand); if (numTrackers == 1 || numTrackers == 3 || numTrackers == 4 || numTrackers == 6 || numTrackers == 10) { if (!nodeHMD._inputDevice.isValid) { //The head will always be the upper body tracker nodeHMD._inputDevice = bodyTrackers[0]; } if (numTrackers == 3) { //Head + Hands if (!nodeLeftHand._inputDevice.isValid) { nodeLeftHand._inputDevice = bodyTrackers[1]; } if (!nodeRightHand._inputDevice.isValid) { nodeRightHand._inputDevice = bodyTrackers[2]; } } //else if (numTrackers == 4) //{ // //Head + Hands + Hips // //1) Remove the head node from the list // bodyTrackers.RemoveAt(0); // //2) The hips is the node that is "in the middle", i.e., the hands are in opposite sides of the hips node. // InitHipsAndHands(bodyTrackers); //} //else if (numTrackers == 6) //{ // //Head + Hands + Hips + Feet // //1) The Feet are the trackers with the lower y // InitVRNode(HumanBodyBones.LeftFoot, bodyTrackers[5]); // InitVRNode(HumanBodyBones.RightFoot, bodyTrackers[4]); // //2) Remove the unnecessary nodes and proceed as in the previous case // bodyTrackers.RemoveAt(5); // bodyTrackers.RemoveAt(4); // bodyTrackers.RemoveAt(0); // InitHipsAndHands(bodyTrackers); //} //UpdateVRNodes(); //IsVRNodesSwaped(HumanBodyBones.LeftFoot, HumanBodyBones.RightFoot); } else { QuickVRManager.LogWarning("BAD NUMBER OF BODY TRACKERS!!!"); } UpdateVRNodes(); _isHandsSwaped = IsVRNodesSwaped(HumanBodyBones.LeftHand, HumanBodyBones.RightHand); QuickVRManager.Log("handsSwaped = " + _isHandsSwaped); foreach (HumanBodyBones t in QuickVRNode.GetTypeList()) { QuickVRNode n = GetVRNode(t); if (n) { n.Calibrate(); } } }
protected virtual void OnCalibrateVRNodeHead(QuickVRNode node) { node.GetTrackedObject().transform.localPosition = _headOffset; }