UNPKG

3.95 kBJavaScriptView Raw
1var Pointable = require('./pointable'),
2 glMatrix = require("gl-matrix")
3 , vec3 = glMatrix.vec3
4 , mat3 = glMatrix.mat3
5 , mat4 = glMatrix.mat4
6 , _ = require('underscore');
7
8
9var Bone = module.exports = function(finger, data) {
10 this.finger = finger;
11
12 this._center = null, this._matrix = null;
13
14 /**
15 * An integer code for the name of this bone.
16 *
17 * * 0 -- metacarpal
18 * * 1 -- proximal
19 * * 2 -- medial
20 * * 3 -- distal
21 * * 4 -- arm
22 *
23 * @member type
24 * @type {number}
25 * @memberof Leap.Bone.prototype
26 */
27 this.type = data.type;
28
29 /**
30 * The position of the previous, or base joint of the bone closer to the wrist.
31 * @type {vector3}
32 */
33 this.prevJoint = data.prevJoint;
34
35 /**
36 * The position of the next joint, or the end of the bone closer to the finger tip.
37 * @type {vector3}
38 */
39 this.nextJoint = data.nextJoint;
40
41 /**
42 * The estimated width of the tool in millimeters.
43 *
44 * The reported width is the average width of the visible portion of the
45 * tool from the hand to the tip. If the width isn't known,
46 * then a value of 0 is returned.
47 *
48 * Pointable objects representing fingers do not have a width property.
49 *
50 * @member width
51 * @type {number}
52 * @memberof Leap.Pointable.prototype
53 */
54 this.width = data.width;
55
56 var displacement = new Array(3);
57 vec3.sub(displacement, data.nextJoint, data.prevJoint);
58
59 this.length = vec3.length(displacement);
60
61
62 /**
63 *
64 * These fully-specify the orientation of the bone.
65 * See examples/threejs-bones.html for more info
66 * Three vec3s:
67 * x (red): The rotation axis of the finger, pointing outwards. (In general, away from the thumb )
68 * y (green): The "up" vector, orienting the top of the finger
69 * z (blue): The roll axis of the bone.
70 *
71 * Most up vectors will be pointing the same direction, except for the thumb, which is more rightwards.
72 *
73 * The thumb has one fewer bones than the fingers, but there are the same number of joints & joint-bases provided
74 * the first two appear in the same position, but only the second (proximal) rotates.
75 *
76 * Normalized.
77 */
78 this.basis = data.basis;
79};
80
81Bone.prototype.left = function(){
82
83 if (this._left) return this._left;
84
85 this._left = mat3.determinant(this.basis[0].concat(this.basis[1]).concat(this.basis[2])) < 0;
86
87 return this._left;
88
89};
90
91
92/**
93 * The Affine transformation matrix describing the orientation of the bone, in global Leap-space.
94 * It contains a 3x3 rotation matrix (in the "top left"), and center coordinates in the fourth column.
95 *
96 * Unlike the basis, the right and left hands have the same coordinate system.
97 *
98 */
99Bone.prototype.matrix = function(){
100
101 if (this._matrix) return this._matrix;
102
103 var b = this.basis,
104 t = this._matrix = mat4.create();
105
106 // open transform mat4 from rotation mat3
107 t[0] = b[0][0], t[1] = b[0][1], t[2] = b[0][2];
108 t[4] = b[1][0], t[5] = b[1][1], t[6] = b[1][2];
109 t[8] = b[2][0], t[9] = b[2][1], t[10] = b[2][2];
110
111 t[3] = this.center()[0];
112 t[7] = this.center()[1];
113 t[11] = this.center()[2];
114
115 if ( this.left() ) {
116 // flip the basis to be right-handed
117 t[0] *= -1;
118 t[1] *= -1;
119 t[2] *= -1;
120 }
121
122 return this._matrix;
123};
124
125/**
126 * Helper method to linearly interpolate between the two ends of the bone.
127 *
128 * when t = 0, the position of prevJoint will be returned
129 * when t = 1, the position of nextJoint will be returned
130 */
131Bone.prototype.lerp = function(out, t){
132
133 vec3.lerp(out, this.prevJoint, this.nextJoint, t);
134
135};
136
137/**
138 *
139 * The center position of the bone
140 * Returns a vec3 array.
141 *
142 */
143Bone.prototype.center = function(){
144
145 if (this._center) return this._center;
146
147 var center = vec3.create();
148 this.lerp(center, 0.5);
149 this._center = center;
150 return center;
151
152};
153
154// The negative of the z-basis
155Bone.prototype.direction = function(){
156
157 return [
158 this.basis[2][0] * -1,
159 this.basis[2][1] * -1,
160 this.basis[2][2] * -1
161 ];
162
163};