Exemple #1
0
        /// <summary>
        /// Adds keyframe data into these VectorHandCurves at the specified time using the
        /// provided hand data.
        /// </summary>
        public void AddKeyframes(float time, Hand hand)
        {
            bool isTracked = hand != null;

            isTrackedCurve.AddBooleanKey(time, isTracked);

            if (isTracked)
            {
                VectorHand vectorHand = Pool <VectorHand> .Spawn();

                try {
                    vectorHand.Encode(hand);

                    palmPosCurves.AddKeyframes(time, vectorHand.palmPos);
                    palmRotCurves.AddKeyframes(time, vectorHand.palmRot);

                    for (int i = 0; i < VectorHand.NUM_JOINT_POSITIONS; i++)
                    {
                        jointPositionCurves[i].AddKeyframes(time, vectorHand.jointPositions[i]);
                    }
                }
                finally {
                    Pool <VectorHand> .Recycle(vectorHand);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Encodes a Leap hand into a VectorHand representation.
        /// </summary>
        public static void Encode(Hand hand, ref VectorHand toVectorHand)
        {
            toVectorHand.isLeft  = hand.IsLeft;
            toVectorHand.palmPos = hand.PalmPosition.ToVector3();
            toVectorHand.palmRot = hand.Rotation.ToQuaternion();
            if (toVectorHand.jointPositions == null || toVectorHand.jointPositions.Length != NUM_JOINT_POSITIONS)
            {
                toVectorHand.jointPositions = new Vector3[NUM_JOINT_POSITIONS];
            }

            int boneIdx = 0;

            for (int i = 0; i < 5; i++)
            {
                Vector3 baseMetacarpal = ToLocal(hand.Fingers[i].bones[0].PrevJoint.ToVector3(),
                                                 toVectorHand.palmPos, toVectorHand.palmRot);
                toVectorHand.jointPositions[boneIdx++] = baseMetacarpal;
                for (int j = 0; j < 4; j++)
                {
                    Vector3 joint = ToLocal(hand.Fingers[i].bones[j].NextJoint.ToVector3(),
                                            toVectorHand.palmPos, toVectorHand.palmRot);
                    toVectorHand.jointPositions[boneIdx++] = joint;
                }
            }
        }
        /// <summary>
        /// Samples hand curve data into the provided hand object at the specified time.
        ///
        /// If the hand is not tracked at the specified time, the function returns false,
        /// although hand data is still copied (via interpolation).
        /// </summary>
        public bool Sample(float time, Hand intoHand, bool isLeft)
        {
            bool isTracked = isTrackedCurve.Evaluate(time) > 0.5f;

            VectorHand vectorHand = Pool <VectorHand> .Spawn();

            try
            {
                vectorHand.isLeft  = isLeft;
                vectorHand.palmPos = palmPosCurves.Evaluate(time);
                vectorHand.palmRot = palmRotCurves.Evaluate(time);

                for (int i = 0; i < VectorHand.NUM_JOINT_POSITIONS; i++)
                {
                    vectorHand.jointPositions[i] = jointPositionCurves[i].Evaluate(time);
                }

                vectorHand.Decode(intoHand);

                // Fill temporal data if we have a hand from the previous sampling.
                if (_lastHand != null)
                {
                    intoHand.FillTemporalData(_lastHand, Time.deltaTime);

                    _lastHand.CopyFrom(intoHand);
                }
                else
                {
                    _lastHand = new Hand();
                }
            }
            finally
            {
                Pool <VectorHand> .Recycle(vectorHand);
            }

            return(isTracked);
        }
Exemple #4
0
        /// <summary>
        /// Decodes a VectorHand representation into a Leap hand.
        /// </summary>
        public static void Decode(ref VectorHand vectorHand, Hand toHand)
        {
            int        boneIdx   = 0;
            Vector3    prevJoint = Vector3.zero;
            Vector3    nextJoint = Vector3.zero;
            Quaternion boneRot   = Quaternion.identity;

            var isLeft         = vectorHand.isLeft;
            var palmPos        = vectorHand.palmPos;
            var palmRot        = vectorHand.palmRot;
            var jointPositions = vectorHand.jointPositions;

            // Fill fingers.
            for (int fingerIdx = 0; fingerIdx < 5; fingerIdx++)
            {
                for (int jointIdx = 0; jointIdx < 4; jointIdx++)
                {
                    boneIdx   = fingerIdx * 4 + jointIdx;
                    prevJoint = jointPositions[fingerIdx * 5 + jointIdx];
                    nextJoint = jointPositions[fingerIdx * 5 + jointIdx + 1];

                    if ((nextJoint - prevJoint).normalized == Vector3.zero)
                    {
                        // Thumb "metacarpal" slot is an identity bone.
                        boneRot = Quaternion.identity;
                    }
                    else
                    {
                        boneRot = Quaternion.LookRotation((nextJoint - prevJoint).normalized,
                                                          Vector3.Cross((nextJoint - prevJoint).normalized,
                                                                        (fingerIdx == 0 ?
                                                                         (isLeft ? -Vector3.up : Vector3.up)
                                                 : Vector3.right)));
                    }

                    // Convert to world space from palm space.
                    nextJoint = ToWorld(nextJoint, palmPos, palmRot);
                    prevJoint = ToWorld(prevJoint, palmPos, palmRot);
                    boneRot   = palmRot * boneRot;

                    toHand.GetBone(boneIdx).Fill(prevJoint: prevJoint.ToVector(),
                                                 nextJoint: nextJoint.ToVector(),
                                                 center:    ((nextJoint + prevJoint) / 2f).ToVector(),
                                                 direction: (palmRot * Vector3.forward).ToVector(),
                                                 length:    (prevJoint - nextJoint).magnitude,
                                                 width:     0.01f,
                                                 type:      (Bone.BoneType)jointIdx,
                                                 rotation:  boneRot.ToLeapQuaternion());
                }
                toHand.Fingers[fingerIdx].Fill(frameId:                -1,
                                               handId:                 (isLeft ? 0 : 1),
                                               fingerId:               fingerIdx,
                                               timeVisible:            Time.time,
                                               tipPosition:            nextJoint.ToVector(),
                                               tipVelocity:            Vector.Zero,
                                               direction:              (boneRot * Vector3.forward).ToVector(),
                                               stabilizedTipPosition:  nextJoint.ToVector(),
                                               width:                  1f,
                                               length:                 1f,
                                               isExtended:             true,
                                               type:                   (Finger.FingerType)fingerIdx);
            }

            // Fill arm data.
            toHand.Arm.Fill(ToWorld(new Vector3(0f, 0f, -0.3f), palmPos, palmRot).ToVector(),
                            ToWorld(new Vector3(0f, 0f, -0.055f), palmPos, palmRot).ToVector(),
                            ToWorld(new Vector3(0f, 0f, -0.125f), palmPos, palmRot).ToVector(),
                            Vector.Zero,
                            0.3f,
                            0.05f,
                            (palmRot).ToLeapQuaternion());

            // Finally, fill hand data.
            toHand.Fill(frameID:                -1,
                        id:                     (isLeft ? 0 : 1),
                        confidence:             1f,
                        grabStrength:           0.5f,
                        grabAngle:              100f,
                        pinchStrength:          0.5f,
                        pinchDistance:          50f,
                        palmWidth:              0.085f,
                        isLeft:                 isLeft,
                        timeVisible:            1f,
                        fingers:                null /* already uploaded finger data */,
                        palmPosition:           palmPos.ToVector(),
                        stabilizedPalmPosition: palmPos.ToVector(),
                        palmVelocity:           Vector3.zero.ToVector(),
                        palmNormal:             (palmRot * Vector3.down).ToVector(),
                        rotation:               (palmRot.ToLeapQuaternion()),
                        direction:              (palmRot * Vector3.forward).ToVector(),
                        wristPosition:          ToWorld(new Vector3(0f, 0f, -0.055f), palmPos, palmRot).ToVector());
        }