UNPKG

node-red-contrib-leap-motion

Version:

Node-Red nodes for leap motion

164 lines (129 loc) 3.95 kB
var Pointable = require('./pointable'), glMatrix = require("gl-matrix") , vec3 = glMatrix.vec3 , mat3 = glMatrix.mat3 , mat4 = glMatrix.mat4 , _ = require('underscore'); var Bone = module.exports = function(finger, data) { this.finger = finger; this._center = null, this._matrix = null; /** * An integer code for the name of this bone. * * * 0 -- metacarpal * * 1 -- proximal * * 2 -- medial * * 3 -- distal * * 4 -- arm * * @member type * @type {number} * @memberof Leap.Bone.prototype */ this.type = data.type; /** * The position of the previous, or base joint of the bone closer to the wrist. * @type {vector3} */ this.prevJoint = data.prevJoint; /** * The position of the next joint, or the end of the bone closer to the finger tip. * @type {vector3} */ this.nextJoint = data.nextJoint; /** * The estimated width of the tool in millimeters. * * The reported width is the average width of the visible portion of the * tool from the hand to the tip. If the width isn't known, * then a value of 0 is returned. * * Pointable objects representing fingers do not have a width property. * * @member width * @type {number} * @memberof Leap.Pointable.prototype */ this.width = data.width; var displacement = new Array(3); vec3.sub(displacement, data.nextJoint, data.prevJoint); this.length = vec3.length(displacement); /** * * These fully-specify the orientation of the bone. * See examples/threejs-bones.html for more info * Three vec3s: * x (red): The rotation axis of the finger, pointing outwards. (In general, away from the thumb ) * y (green): The "up" vector, orienting the top of the finger * z (blue): The roll axis of the bone. * * Most up vectors will be pointing the same direction, except for the thumb, which is more rightwards. * * The thumb has one fewer bones than the fingers, but there are the same number of joints & joint-bases provided * the first two appear in the same position, but only the second (proximal) rotates. * * Normalized. */ this.basis = data.basis; }; Bone.prototype.left = function(){ if (this._left) return this._left; this._left = mat3.determinant(this.basis[0].concat(this.basis[1]).concat(this.basis[2])) < 0; return this._left; }; /** * The Affine transformation matrix describing the orientation of the bone, in global Leap-space. * It contains a 3x3 rotation matrix (in the "top left"), and center coordinates in the fourth column. * * Unlike the basis, the right and left hands have the same coordinate system. * */ Bone.prototype.matrix = function(){ if (this._matrix) return this._matrix; var b = this.basis, t = this._matrix = mat4.create(); // open transform mat4 from rotation mat3 t[0] = b[0][0], t[1] = b[0][1], t[2] = b[0][2]; t[4] = b[1][0], t[5] = b[1][1], t[6] = b[1][2]; t[8] = b[2][0], t[9] = b[2][1], t[10] = b[2][2]; t[3] = this.center()[0]; t[7] = this.center()[1]; t[11] = this.center()[2]; if ( this.left() ) { // flip the basis to be right-handed t[0] *= -1; t[1] *= -1; t[2] *= -1; } return this._matrix; }; /** * Helper method to linearly interpolate between the two ends of the bone. * * when t = 0, the position of prevJoint will be returned * when t = 1, the position of nextJoint will be returned */ Bone.prototype.lerp = function(out, t){ vec3.lerp(out, this.prevJoint, this.nextJoint, t); }; /** * * The center position of the bone * Returns a vec3 array. * */ Bone.prototype.center = function(){ if (this._center) return this._center; var center = vec3.create(); this.lerp(center, 0.5); this._center = center; return center; }; // The negative of the z-basis Bone.prototype.direction = function(){ return [ this.basis[2][0] * -1, this.basis[2][1] * -1, this.basis[2][2] * -1 ]; };