//Functions from sample project, update hand positions public override void SetSensoPose(Senso.HandData aData) { Palm.localRotation = /*(Quaternion.Inverse(wq) */ aData.PalmRotation; Palm.localPosition = aData.PalmPosition; //base.VibrateFinger(Senso.EFingerType.Thumb, 50, 1); //Fingers if (aData.AdvancedThumb) { //Quaternion thumbQ = new Quaternion(aData.ThumbQuaternion.y / 3.0f, aData.ThumbQuaternion.x, -aData.ThumbQuaternion.z, aData.ThumbQuaternion.w); Quaternion thumbQ = new Quaternion(aData.ThumbQuaternion.z, aData.ThumbQuaternion.y, -aData.ThumbQuaternion.x / 3.0f, aData.ThumbQuaternion.w); thumbBones[0].localRotation = fingerInitialRotations[0][0] * thumbQ; thumbBones[1].localRotation = fingerInitialRotations[0][1] * Quaternion.Euler(0.0f, 0.0f, -aData.ThumbQuaternion.x / 3.0f); thumbBones[2].localRotation = fingerInitialRotations[0][2] * Quaternion.Euler(0.0f, 0.0f, aData.ThumbBend * Mathf.Rad2Deg); } else // old method { setFingerBones(ref thumbBones, aData.ThumbAngles, Senso.EFingerType.Thumb); } setFingerBones(ref indexBones, aData.IndexAngles, Senso.EFingerType.Index); setFingerBones(ref middleBones, aData.MiddleAngles, Senso.EFingerType.Middle); setFingerBones(ref thirdBones, aData.ThirdAngles, Senso.EFingerType.Third); setFingerBones(ref littleBones, aData.LittleAngles, Senso.EFingerType.Little); //MIDI CC function checkCommands(aData); }
//Change MIDI CC Values by the angle of all fingers except thumbs private void changeValWHand(Senso.HandData aData) { float angMin = 0f, angMax = 70f; //Min and max finger angle values float palm = aData.PalmRotation.eulerAngles.z; //Palm angle rotation float[] fingers = new float[4]; //Finger angles //Get the current angles of fingers, thumbs are ignored fingers[0] = aData.IndexAngles.y; fingers[1] = aData.MiddleAngles.y; fingers[2] = aData.ThirdAngles.y; fingers[3] = aData.LittleAngles.y; float fingerMean = fingers.Average(); //Average the angles if (palm > 160f && palm < 230f) // Angle range of the palm { value = (int)scale(fingerMean, angMin, angMax, min, max); // Scale the angle mean to be 0-127 (MIDI CC range) //Debug.Log(value); control = true; // Toggle control variable, which SendMax will read to know that the user is controlling the MIDI CC values } else { //Debug.Log("Not in control"); if (control) { timer = true; // So that there are no changes by mistake after just leaving control hand position, we toggle the timer } control = false; //Make control variable false, so that SendMax knows that the user is no longer controlling MIDI CC values } }
private void checkCommands(Senso.HandData aData) { //Track the angles from the last x frames, if program just started, the arrays are filled with the same starting angles updateAngles(aData); if (mode == 0) { raiseVolumeWFinger(aData, 2); } /*float dev = stDev(vibrateFinger); * if ((dev >= std) /*|| ((dev >= std-5.0f) && (vibrateFinger==1) )) * { * x = 1; * vibrateFinger = rnd.Next(5); * } * else if (dev >= std - 4.0f && vibrateFinger == 1) * { * x = 1; * vibrateFinger = rnd.Next(5); * * } * else * { * x = 0; * }*/ }
//Update angles, transform finger angles to MIDICC range values to send to Max patch private void checkCommands(Senso.HandData aData) { updateAngles(aData); changeValWHand(aData); //Use hand rotation and finger angles //changeValWFinger(aData,2);//Uses angle of one finger changeSettingWHand(aData); // Swipe movement to change song }
//Updates angles array with current finger angles //Track the angles from the last x frames, if program just started, the arrays are filled with the same starting angles private void updateAngles(Senso.HandData aData) { if (start == 0)//When program just started { start = 1; //We make all values of each finger equal for (int i = 0; i < 5; i++) { float arr; switch (i) //Get the latest value { case 1: arr = aData.ThumbAngles.y; break; case 2: arr = aData.IndexAngles.y; break; case 3: arr = aData.MiddleAngles.y; break; case 4: arr = aData.ThirdAngles.y; break; default: arr = aData.LittleAngles.y; break; } for (int j = 0; j < prevFrames; ++j) //Copy it to all array spaces of the current finger { angles[i, j] = arr; } } } else { //Afterwards, we only dispose the oldest value in the array, move all value back by 1, and add the newest value at the end for (int i = 0; i < 5; i++) { float arr; switch (i) //Get the latest value { case 1: arr = aData.ThumbAngles.y; break; //angles[1] case 2: arr = aData.IndexAngles.y; break; //angles[2] case 3: arr = aData.MiddleAngles.y; break; //angles[3] case 4: arr = aData.ThirdAngles.y; break; //angles[4] default: arr = aData.LittleAngles.y; break; //angles[0] } for (int j = 0; j < (prevFrames - 1); j++) //Move values back { angles[i, j] = angles[i, (j + 1)]; } angles[i, (prevFrames - 1)] = arr; //Add newest value } } }
private void updateAngles(Senso.HandData aData) { if (start == 0) { //When program just started start = 1; for (int i = 0; i < 5; i++) { float arr; switch (i) { case 1: arr = aData.ThumbAngles.y; break; case 2: arr = aData.IndexAngles.y; break; case 3: arr = aData.MiddleAngles.y; break; case 4: arr = aData.ThirdAngles.y; break; default: arr = aData.LittleAngles.y; break; } for (int j = 0; j < prevFrames; ++j) { angles[i, j] = arr; } } } else { for (int i = 0; i < 5; i++) { float arr; switch (i) { case 1: arr = aData.ThumbAngles.y; break; case 2: arr = aData.IndexAngles.y; break; case 3: arr = aData.MiddleAngles.y; break; case 4: arr = aData.ThirdAngles.y; break; default: arr = aData.LittleAngles.y; break; } for (int j = 0; j < (prevFrames - 1); j++) { angles[i, j] = angles[i, (j + 1)]; } angles[i, (prevFrames - 1)] = arr; } } }
//Change MIDI CC Values by the angle of one finger private void changeValWFinger(Senso.HandData aData, int finger) { float fingerAngle, angMin = 50, angMax = -20; //Min and max depending on the angle of the finger switch (finger) // Get the angle value dependin on the finger chosen { case 1: fingerAngle = aData.ThumbAngles.x + 40.0f; break; case 2: fingerAngle = aData.IndexAngles.y; break; case 3: fingerAngle = aData.MiddleAngles.y; break; case 4: fingerAngle = aData.ThirdAngles.y; break; default: fingerAngle = aData.LittleAngles.y; break; } //Scale the values to be 0-127 (MIDI CC range) value = (int)scale(fingerAngle, angMin, angMax, min, max); }
private void raiseVolumeWFinger(Senso.HandData aData, int finger) { float fingerAngle; switch (finger) { case 1: fingerAngle = aData.ThumbAngles.x + 40.0f; break; case 2: fingerAngle = aData.IndexAngles.y; break; case 3: fingerAngle = aData.MiddleAngles.y; break; case 4: fingerAngle = aData.ThirdAngles.y; break; default: fingerAngle = aData.LittleAngles.y; break; } if (base.HandType == Senso.EPositionType.RightHand) { Debug.Log("Angle: " + fingerAngle); } }
//Swipe movement to change song private void changeSettingWHand(Senso.HandData aData) { float palm = aData.PalmRotation.eulerAngles.z; //Palm angle rotation float[] stdFingers = new float[4]; //Finger deviations int[] fingers = { 0, 2, 3, 4 }; //Thumbs are ignored (1) for (int i = 0; i < 4; i++) //Calculate the standard deviations from all fingers { stdFingers[i] = stDev(fingers[i]); } float fingerMean = stdFingers.Average(); //Get the mean of all standard deviations //Change song if (fingerMean > 19f && !timer && palm > 250f && palm < 310 /*&& constant(fingers)*/) // If standard deviation mean meets a threshold, the timer is off, and the palm angle is between a range { change = true; //Toggle change so that SendMax sends bang to change song timer = true; //Toggle timer //Debug.Log("Change"); } //Stop motion, currently toggling changing effects with values on/off if (fingerMean > 9f && !timer && (palm > 350f || palm < 30f) /*&& constant(fingers)*/) // If standard deviation mean meets a threshold, the timer is off, and the palm angle is between a range { stop = true; //Toggle change so that SendMax sends bang to toggle MIDI CC changing by the wave values timer = true; //Toggle timer Debug.Log("Stop"); //Switch planes mode foreach (GameObject p in planes) { p.GetComponent <PlanesController>().switchPlanes(); } } }
public override void SetSensoPose(Senso.HandData data) { base.SetSensoPose(data); Palm.localPosition = transformVector3(data.PalmPosition); Palm.localRotation = palmInitialRotation * data.PalmRotation; if (data.AdvancedThumb) { //Quaternion thumbQ = new Quaternion(aData.ThumbQuaternion.y / 3.0f, aData.ThumbQuaternion.x, -aData.ThumbQuaternion.z, aData.ThumbQuaternion.w); Quaternion thumbQ = new Quaternion(data.ThumbQuaternion.x, data.ThumbQuaternion.y, -data.ThumbQuaternion.z / 3.0f, data.ThumbQuaternion.w); thumbBones[0].localRotation = fingerInitialRotations[0][0] * thumbQ; thumbBones[1].localRotation = fingerInitialRotations[0][1] * Quaternion.Euler(0.0f, 0.0f, -data.ThumbQuaternion.x / 3.0f); thumbBones[2].localRotation = fingerInitialRotations[0][2] * Quaternion.Euler(0.0f, 0.0f, -data.ThumbBend * Mathf.Rad2Deg); } setFingerBones(ref indexBones, data.IndexAngles, ref fingerInitialRotations[1]); setFingerBones(ref middleBones, data.MiddleAngles, ref fingerInitialRotations[2]); setFingerBones(ref thirdBones, data.ThirdAngles, ref fingerInitialRotations[3]); setFingerBones(ref littleBones, data.LittleAngles, ref fingerInitialRotations[4]); //setThumbBones(ref ThumbFingerJoints, data.Fingers[0].Angles, thumbInitialRotations); }
abstract public void SetSensoPose(HandData newData);
public virtual void SetSensoPose(HandData newData) { Pose = newData; }