/// <summary> Retrieve flexion angles, normalized to [0...1] or [fingers extended ... fingers flexed] </summary> /// <param name="flexions"></param> /// <param name="forceUpdate"></param> /// <returns></returns> public virtual bool GetNormalizedFlexion(out float[] flexions, bool forceUpdate = false) { if (lastHandModel == null) { lastHandModel = SGCore.Kinematics.BasicHandModel.Default(this.IsRight); } //if (lastProfile == null) { lastProfile = SGCore.HandProfile.Default(this.IsRight); } return(GetNormalizedFlexion(lastHandModel, SG_HandProfiles.GetProfile(this.IsRight), out flexions, forceUpdate)); }
// Update is called once per frame void Update() { //Keybinds if (Input.GetKeyDown(this.toggleGloveKey)) { this.GloveVisible = !GloveVisible; } if (Input.GetKeyDown(this.toggleHandKey)) { this.HandVisible = !HandVisible; } //Automated Updates if (this.glove != null && glove.IsConnected) { if (!setupComplete) { setupComplete = true; this.HandGeometry = SGCore.Kinematics.BasicHandModel.Default(this.glove.IsRight); //Debug.Log("WireFrame; " + this.HandGeometry.ToString()); this.CalibrateWrist(); SG_HandPose idleHand = SG_HandPose.Idle(glove.IsRight); this.UpdateHand(idleHand); if (this.glove.InternalGlove is SGCore.SG.SenseGlove) { // Debug.Log("Generated glove model for " + this.glove.GetInternalObject().GetDeviceID()); SGCore.SG.SG_GloveInfo gloveModel = ((SGCore.SG.SenseGlove) this.glove.InternalGlove).GetGloveModel(); GenerateGlove(gloveModel); SGCore.SG.SG_GlovePose idlePose = SGCore.SG.SG_GlovePose.IdlePose(gloveModel); this.UpdateGlove(idlePose); } } if (this.wristTransform != null && this.foreArmTransform != null) { if (Input.GetKeyDown(this.resetWristKey)) { this.CalibrateWrist(); } Quaternion imu; if (this.glove.GetIMURotation(out imu)) { this.UpdateWrist(imu); } } if (this.gloveBase.activeInHierarchy) { this.UpdateGlove(); } if (this.handBase.activeInHierarchy) { this.UpdateHand(); } } }
//---------------------------------------------------------------------------------------------- // Hand Tracking Methods /// <summary> Returns the HandPose from the Glove Hardware linked to this TrackedHand. </summary> /// <param name="hand"></param> /// <param name="pose"></param> /// <returns></returns> public virtual bool GetHandPose(out SG_HandPose pose) { if (this.gloveHardware != null && this.handModel != null) { SGCore.Kinematics.BasicHandModel HM = handModel.HandKinematics; //Debug.Log("TrackedHand: " + HM.ToString()); return(this.gloveHardware.GetHandPose(this.handModel.HandKinematics, out pose, true)); } pose = SG_HandPose.Idle(this.TracksRightHand); return(false); }
/// <summary> Retrieve flexion angles, normalized to [0...1] or [fingers extended ... fingers flexed] </summary> /// <param name="handModel"></param> /// <param name="userProfile"></param> /// <param name="flexions"></param> /// <param name="forceUpdate"></param> /// <returns></returns> public virtual bool GetNormalizedFlexion(SGCore.Kinematics.BasicHandModel handModel, SGCore.HandProfile userProfile, out float[] flexions, bool forceUpdate = false) { SG_HandPose pose; if (GetHandPose(handModel, userProfile, out pose, forceUpdate)) { flexions = pose.normalizedFlexion; return(true); } flexions = new float[5]; return(false); }
/// <summary> Returns a Hand Pose containing everything you'd want to animate a hand model in Unity. Using a custom HandProfile. </summary> /// <returns></returns> public bool GetHandPose(SGCore.Kinematics.BasicHandModel handDimensions, SGCore.HandProfile userProfile, out SG_HandPose pose, bool forceUpdate = false) { #if UNFINISHED_FEATURES if (this.CVDataAvailable(forceUpdate)) //we are able to get CV data. Yay { pose = new SG_HandPose(SGCore.HandPose.FromHandAngles(lastCVData.handAngles, lastCVData.rightHand, handDimensions)); newPoseNeeded = false; //we don't need a new pose this frame, thank you. lastHandModel = handDimensions; lastHandPose = pose; return(true); } #endif if (this.lastGlove != null) { if (forceUpdate || newPoseNeeded) //we need a new pose { lastHandModel = handDimensions; if (this.CalibrationStage == CalibrationStage.MoveFingers) { lastHandPose = SG_HandPose.Idle(this.IsRight); newPoseNeeded = false; //we don't need a new pose this frame, thank you. } else if (this.CalibrationLocked && this.currentSequence != null) { //we should gram it from the calibrationSequence instead. if (this.currentSequence.GetCalibrationPose(out lastHandPose)) { newPoseNeeded = false; } } else { SGCore.HandPose iPose; if (lastGlove.GetHandPose(handDimensions, userProfile, out iPose)) { lastHandPose = new SG_HandPose(iPose); newPoseNeeded = false; //we don't need a new pose this frame, thank you. } } } // else we already have one, and don't want to force-update. pose = lastHandPose; return(lastHandPose != null); } else if (lastHandPose == null) { lastHandPose = SG_HandPose.Idle(this.IsRight); } //only if we dont yet have a LastHandPose. //otherwise we shouldn't bother pose = lastHandPose; return(false); }
/// <summary> Generates a BasicHandModel based on the Joint Transforms of this hand. </summary> /// <returns></returns> private SGCore.Kinematics.BasicHandModel GenerateHandModel() { bool right = this.handSide != HandSide.LeftHand; float[][] handLenghts = new float[5][]; SGCore.Kinematics.Vect3D[] startPositions = new SGCore.Kinematics.Vect3D[5]; Transform[][] fingerJoints = FingerJoints; SGCore.Kinematics.BasicHandModel defaultH = SGCore.Kinematics.BasicHandModel.Default(right); for (int f = 0; f < 5; f++) { // SGCore.Kinematics.Vect3D lastPos = fingerJoints[f].Length > 0 ? SG_Util.ToPosition(fingerJoints[f][0].position, true) // : defaultH.GetJointPosition((SGCore.Finger)f); SGCore.Kinematics.Vect3D lastPos = fingerJoints[f].Length > 0 ? RelativePosition(fingerJoints[f][0], this.wristTransform) : defaultH.GetJointPosition((SGCore.Finger)f); startPositions[f] = lastPos; //the first position is the starting position. handLenghts[f] = new float[3]; float[] defaultL = handLenghts[f] = defaultH.GetFingerLengths((SGCore.Finger)f); for (int j = 1; j < 4; j++) { if (fingerJoints[f].Length > j) { SGCore.Kinematics.Vect3D currPos = RelativePosition(fingerJoints[f][j], this.wristTransform); handLenghts[f][j - 1] = (currPos.x - lastPos.x); //converts from m to mm lastPos = currPos; //update } else { handLenghts[f][j - 1] = defaultL[j - 1]; } } } SGCore.Kinematics.BasicHandModel HM = new SGCore.Kinematics.BasicHandModel(right, handLenghts, startPositions); //Debug.Log("Collected HandModelInfo: " + HM.ToString(true)); return(HM); }
/// <summary> Returns a Hand Pose containing everything you'd want to animate a hand model in Unity. Using the global HandProfile. </summary> /// <param name="handModel"></param> /// <param name="pose"></param> /// <param name="forceUpdate"></param> /// <returns></returns> public virtual bool GetHandPose(SGCore.Kinematics.BasicHandModel handModel, out SG_HandPose pose, bool forceUpdate = false) { return(GetHandPose(handModel, SG_HandProfiles.GetProfile(this.IsRight), out pose, forceUpdate)); }