Tanoda
FrameValidator.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System.Linq;
10using NUnit.Framework;
11
12namespace Leap.Unity.Tests {
13
14 public abstract class FrameValidator {
15 protected const float TOLERANCE = 0.0001f;
16 protected static Finger.FingerType[] _fingers = {
17 Finger.FingerType.TYPE_INDEX,
18 Finger.FingerType.TYPE_MIDDLE,
19 Finger.FingerType.TYPE_PINKY,
20 Finger.FingerType.TYPE_RING,
21 Finger.FingerType.TYPE_THUMB
22 };
23
24 protected static Bone.BoneType[] _bones = {
25 Bone.BoneType.TYPE_DISTAL,
26 Bone.BoneType.TYPE_INTERMEDIATE,
27 Bone.BoneType.TYPE_METACARPAL,
28 Bone.BoneType.TYPE_PROXIMAL
29 };
30
31 protected Frame _frame;
32
33 [SetUp]
34 public virtual void Setup() {
36 }
37
38 [TearDown]
39 public virtual void Teardown() {
40 _frame = null;
41 }
42
43 protected abstract Frame createFrame();
44
45 [Test]
46 public void HandsAreUnique() {
47 bool existDuplicates = _frame.Hands.GroupBy(h => h.Id).Any(g => g.Count() > 1);
48 Assert.That(existDuplicates, Is.False);
49 }
50
51 [Test]
52 public void HandsHaveFiveFingers() {
53 foreach (Hand hand in _frame.Hands) {
54 Assert.That(hand.Fingers.Count, Is.EqualTo(5));
55 }
56 }
57
58 [Test]
59 public void FingersHaveFourBones([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType,
60 [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType) {
61 foreach (Hand hand in _frame.Hands) {
62 Bone bone = getBone(hand, fingerType, boneType);
63 Assert.That(bone, Is.Not.Null);
64 }
65 }
66
67 [Test]
68 public void BoneLength([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType,
69 [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType) {
70 foreach (Hand hand in _frame.Hands) {
71 Bone bone = getBone(hand, fingerType, boneType);
72 float apparentLength = bone.NextJoint.DistanceTo(bone.PrevJoint);
73 float actualLength = bone.Length;
74 Assert.That(actualLength, Is.EqualTo(apparentLength).Within(TOLERANCE));
75 }
76 }
77
78 [Test]
79 public void JointsMatch([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType,
80 [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType) {
81 foreach (Hand hand in _frame.Hands) {
82 Bone prevBone = getBone(hand, fingerType, boneType - 1);
83 Bone bone = getBone(hand, fingerType, boneType);
84 Bone nextBone = getBone(hand, fingerType, boneType + 1);
85
86 if (prevBone != null) {
88 }
89
90 if (nextBone != null) {
92 }
93 }
94 }
95
96 [Test]
97 public void CenterIsBetweenJoints([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType,
98 [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType) {
99 foreach (Hand hand in _frame.Hands) {
100 Bone bone = getBone(hand, fingerType, boneType);
101
102 Vector jointAverage = (bone.NextJoint + bone.PrevJoint) * 0.5f;
103 assertVectorsEqual(jointAverage, bone.Center);
104 }
105 }
106
107 [Test]
108 public void DirectionMatchesJoints([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType,
109 [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType) {
110 foreach (Hand hand in _frame.Hands) {
111 Bone bone = getBone(hand, fingerType, boneType);
112
113 //If the joints are at the same position this test is meaningless
114 if (bone.NextJoint.DistanceTo(bone.PrevJoint) < TOLERANCE) {
115 continue;
116 }
117
118 Vector jointDirection = (bone.NextJoint - bone.PrevJoint).Normalized;
119 assertVectorsEqual(jointDirection, bone.Direction);
120 }
121 }
122
123 [Test]
124 public void RotationIsValid() {
125 foreach (Hand hand in _frame.Hands) {
126 Assert.That(hand.Rotation.IsValid());
127 }
128 }
129
130 protected Bone getBone(Hand hand, Finger.FingerType fingerType, Bone.BoneType boneType) {
131 if (boneType < 0 || (int)boneType >= 4) {
132 return null;
133 }
134
135 foreach (Finger finger in hand.Fingers) {
136 if (finger.Type != fingerType) {
137 continue;
138 }
139
140 return finger.Bone(boneType);
141 }
142 return null;
143 }
144
145 protected void assertVectorsEqual(Vector a, Vector b, string vectorName = "Vector") {
146 Assert.That(a.x, Is.EqualTo(b.x).Within(TOLERANCE), vectorName + ".x");
147 Assert.That(a.y, Is.EqualTo(b.y).Within(TOLERANCE), vectorName + ".y");
148 Assert.That(a.z, Is.EqualTo(b.z).Within(TOLERANCE), vectorName + ".z");
149 }
150 }
151}
The Bone class represents a tracked bone.
Definition: Bone.cs:26
Vector Direction
The normalized direction of the bone from base to tip.
Definition: Bone.cs:102
BoneType
Enumerates the type of bones.
Definition: Bone.cs:168
Vector Center
The midpoint of the bone.
Definition: Bone.cs:96
Vector PrevJoint
The base of the bone, closest to the wrist. In anatomical terms, this is the proximal end of the bone...
Definition: Bone.cs:83
float Length
The estimated length of the bone.
Definition: Bone.cs:108
Vector NextJoint
The end of the bone, closest to the finger tip. In anatomical terms, this is the distal end of the bo...
Definition: Bone.cs:90
The Finger class represents a tracked finger.
Definition: Finger.cs:20
Bone Bone(Bone.BoneType boneIx)
The bone at a given bone index on this finger.
Definition: Finger.cs:79
Finger.FingerType Type
The type of this finger.
Definition: Finger.cs:95
FingerType
Enumerates the names of the fingers.
Definition: Finger.cs:167
The Frame class represents a set of hand and finger tracking data detected in a single frame.
Definition: Frame.cs:24
List< Hand > Hands
The list of Hand objects detected in this frame, given in arbitrary order. The list can be empty if n...
Definition: Frame.cs:156
The Hand class reports the physical characteristics of a detected hand.
Definition: Hand.cs:26
List< Finger > Fingers
The list of Finger objects detected in this frame that are attached to this hand, given in order from...
Definition: Hand.cs:159
LeapQuaternion Rotation
The rotation of the hand as a quaternion.
Definition: Hand.cs:211
void CenterIsBetweenJoints([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType, [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType)
void BoneLength([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType, [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType)
Bone getBone(Hand hand, Finger.FingerType fingerType, Bone.BoneType boneType)
static Bone.BoneType[] _bones
void FingersHaveFourBones([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType, [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType)
static Finger.FingerType[] _fingers
void DirectionMatchesJoints([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType, [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType)
void assertVectorsEqual(Vector a, Vector b, string vectorName="Vector")
void JointsMatch([ValueSource(typeof(FrameValidator), "_fingers")] Finger.FingerType fingerType, [ValueSource(typeof(FrameValidator), "_bones")] Bone.BoneType boneType)
bool IsValid()
Returns true if all of the quaternion's components are finite. If any component is NaN or infinite,...
The Vector struct represents a three-component mathematical vector or point such as a direction or po...
Definition: Vector.cs:36
float y
Definition: Vector.cs:219
float DistanceTo(Vector other)
The distance between the point represented by this Vector object and a point represented by the speci...
Definition: Vector.cs:102
float x
Definition: Vector.cs:218
float z
Definition: Vector.cs:220