// Update is called once per frame. void Update() { // Access the ThalmicMyo component attached to the Myo object. ThalmicMyo thalmicMyo = myo.GetComponent <ThalmicMyo> (); // Update references when the pose becomes fingers spread or the q key is pressed. bool updateReference = false; if (thalmicMyo.pose != _lastPose) { _lastPose = thalmicMyo.pose; if (thalmicMyo.pose == Pose.FingersSpread) { updateReference = true; ExtendUnlockAndNotifyUserAction(thalmicMyo); } } if (Input.GetKeyDown("r")) { updateReference = true; } // Update references. This anchors the joint on-screen such that it faces forward away // from the viewer when the Myo armband is oriented the way it is when these references are taken. if (updateReference) { // _antiYaw represents a rotation of the Myo armband about the Y axis (up) which aligns the forward // vector of the rotation with Z = 1 when the wearer's arm is pointing in the reference direction. _antiYaw = Quaternion.FromToRotation( new Vector3(myo.transform.forward.x, 0, myo.transform.forward.z), new Vector3(0, 0, 1) ); // _referenceRoll represents how many degrees the Myo armband is rotated clockwise // about its forward axis (when looking down the wearer's arm towards their hand) from the reference zero // roll direction. This direction is calculated and explained below. When this reference is // taken, the joint will be rotated about its forward axis such that it faces upwards when // the roll value matches the reference. Vector3 referenceZeroRoll = computeZeroRollVector(myo.transform.forward); _referenceRoll = rollFromZero(referenceZeroRoll, myo.transform.forward, myo.transform.up); } // Current zero roll vector and roll value. Vector3 zeroRoll = computeZeroRollVector(myo.transform.forward); float roll = rollFromZero(zeroRoll, myo.transform.forward, myo.transform.up); // The relative roll is simply how much the current roll has changed relative to the reference roll. // adjustAngle simply keeps the resultant value within -180 to 180 degrees. float relativeRoll = normalizeAngle(roll - _referenceRoll); // antiRoll represents a rotation about the myo Armband's forward axis adjusting for reference roll. Quaternion antiRoll = Quaternion.AngleAxis(relativeRoll, myo.transform.forward); // Here the anti-roll and yaw rotations are applied to the myo Armband's forward direction to yield // the orientation of the joint. transform.rotation = _antiYaw * antiRoll * Quaternion.LookRotation(myo.transform.forward); // The above calculations were done assuming the Myo armbands's +x direction, in its own coordinate system, // was facing toward the wearer's elbow. If the Myo armband is worn with its +x direction facing the other way, // the rotation needs to be updated to compensate. if (thalmicMyo.xDirection == Thalmic.Myo.XDirection.TowardWrist) { // Mirror the rotation around the XZ plane in Unity's coordinate system (XY plane in Myo's coordinate // system). This makes the rotation reflect the arm's orientation, rather than that of the Myo armband. transform.rotation = new Quaternion(transform.localRotation.x, -transform.localRotation.y, transform.localRotation.z, -transform.localRotation.w); } }