LeapConnector.prototype.getBasis = function (frame) {

  var handLast = frame.hands[0];
  var dir = handLast.direction;
  var nor = handLast.palmNormal;
  var dxn = Leap.vec3.create();
  Leap.vec3.cross(dxn, dir, nor);
  var basisLast = [].concat(dir).concat(nor);
  basisLast[6] = dxn[0];
  basisLast[7] = dxn[1];
  basisLast[8] = dxn[2];
  
  return basisLast;
}
Ejemplo n.º 2
0
controller.on( 'frame' , function( frame ){

    var gestures = frame.gestures,
        circle,
        pointable,
        direction,
        normal;
// Check if is there any gesture going on
    if(gestures.length > 0) {
        // In this example we will focus only on the first gesture, for the sake of simplicity
        if(gestures[0].type == 'circle') {
            circle = gestures[0];
            // Get Pointable object
            circle.pointable = frame.pointable(circle.pointableIds[0]);
            // Reset circle gesture variables as nedded, not really necessary in this case
            if(circle.state == 'start') {
                clockwise = true;
            } else if (circle.state == 'update') {
                direction = circle.pointable.direction;
                // Check if pointable exists
                if(direction) {
                    normal = circle.normal;
                    // Check if product of vectors is going forwards or backwards
                    // Since Leap uses a right hand rule system
                    // forward is into the screen, while backwards is out of it
                    clockwise = Leap.vec3.dot(direction, normal) > 0;
                    if(clockwise) {
                        //Do clockwose stuff

                        if(isDoingWork){
                            return;
                        }
                        isDoingWork = true;
                        OSX.volume.set("clockwise", function(vol){
                            isDoingWork = false;
                        })
                    } else {
                        //Do counterclockwise stuff

                        if(isDoingWork){
                            return;
                        }
                        isDoingWork = true;
                        OSX.volume.set("counter-clockwise", function(vol){
                            isDoingWork = false;
                        })

                    }
                }
            }
        }
    }


});
LeapConnector.prototype.axisAngle = function(rotation) {
    //NOTE: Index = 3*row + col when basis vector 
  var axis = [
    rotation[5] - rotation[7],
    rotation[6] - rotation[2],
    rotation[1] - rotation[3]
  ];
  var sin = Leap.vec3.len(axis);
  var cos = ((rotation[0] + rotation[4] + rotation[8]) - 1.0)*0.5;
  var angle = Math.atan2(sin,cos);

    if (-1e-6 < sin && sin < 1e-6) {
        axis = [0, 0, 0];
        angle = 0;
        return [axis, angle];
    }
    
    Leap.vec3.scale(axis, axis, 1 / sin);
  return [axis,angle];
}
Ejemplo n.º 4
0
      if(hand.type=="right" && hand.confidence > .7) hand.fingers.forEach(function(finger) {
        if(finger.type== 0 ) { //THUMB
          var bottomBone = finger.proximal;
          var middlePartBone = finger.medial;
          var topPartBone = finger.distal;

          var topVec= getVec(topPartBone);
          var middlePartVec= getVec(middlePartBone);
          var bottomPartVec= getVec(bottomBone);

          var bottomVec = leapjs.vec3.create();
          leapjs.vec3.add(bottomVec,bottomPartVec,middlePartVec);


          var handDirection = hand.direction;
          var handVec = leapjs.vec3.fromValues(handDirection[0],handDirection[1],handDirection[2]);

          var bottomDeg=getDegBetween(bottomVec,handVec);
          var topDeg=getDegBetween(bottomVec,topVec);

          result["1_T"]=topDeg;
          result["1_B"]=bottomDeg;
          result["hasData"]=true;
        } else if(finger.type==1) { // INDEX
          var distalVec= getVec(finger.distal);
          var medialVec= getVec(finger.medial);
          var proximalVec = getVec(finger.proximal);
          var metaVec = getVec(finger.metacarpal);

          var topVec = leapjs.vec3.create();
          leapjs.vec3.add(topVec,medialVec,distalVec);

          var topDeg=getDegBetween(proximalVec,topVec);
          var bottomDeg=getDegBetween(metaVec,proximalVec);

          result["2_T"]=topDeg;
          result["2_B"]=bottomDeg;
          result["hasData"]=true;
        } else if(finger.type==3) { // INDEX
          var medialVec= getVec(finger.medial);
          var distalVec= getVec(finger.distal);
          var metaVec = getVec(finger.metacarpal);
          var proximalVec = getVec(finger.proximal);

          var topVec = leapjs.vec3.create();
          leapjs.vec3.add(topVec,medialVec,distalVec);

          var bottomDeg=getDegBetween(metaVec,proximalVec);
          var topDeg=getDegBetween(proximalVec,topVec);

          result["3_T"]=topDeg;
          result["3_B"]=bottomDeg;
          result["hasData"]=true;
        }
      });
Ejemplo n.º 5
0
// Utility function to calculate the angle between two vectors
function getDegBetween(vec1,vec2) {
  var bottomCos=leapjs.vec3.dot(vec1,vec2) / leapjs.vec3.len(vec1) / leapjs.vec3.len(vec2);
  return radToDeg(mathjs.acos(bottomCos));
}
Ejemplo n.º 6
0
// Retrieve the vector of a bone
function getVec(bone) {
  var dir = bone.direction();
  var vec = leapjs.vec3.fromValues(dir[0],dir[1],dir[2]);
  return vec;
}
LeapConnector.prototype.onFrame = function(frame) {
  var that = this;
  if (frame.hands.length == 1) {
    if (frame.fingers.length > 3) {
      var lastFrame = this.controller.frame(1);
      if (lastFrame && lastFrame.hands.length > 0) {
        
        // rotate
        that.lastY = -1;
        that.lastX = -1;
  
        var hand = frame.hands[0];
        var translation = hand.translation(lastFrame);
        // comment out for the moment until JS Leap Motion rotation bugs are fixed.
        that.gestureDispatcher.triggerPan(translation[0], -translation[1]);
        that.gestureDispatcher.triggerZoom(-translation[2]);
        
        var basis = that.getBasis(frame); 
        var basisLast = that.getBasis(lastFrame); 
        
        Leap.mat3.transpose(basisLast, basisLast);
        var rotation = Leap.mat3.create();
        Leap.mat3.multiply(rotation, basis, basisLast) 

        //Get axis-angle representation
        var axisAngle = that.axisAngle(rotation);
                      
        Leap.vec3.scale(axisAngle[0], axisAngle[0], axisAngle[1]);
        
        
        
        // yaw pitch roll are slightly better, but there still seems to be an issue.
//        var xRotation = this.limitRotation(hand.pitch() - lastFrame.hands[0].pitch());
//        var yRotation = this.limitRotation(hand.yaw() - lastFrame.hands[0].yaw());
//        var zRotation = this.limitRotation(hand.roll() - lastFrame.hands[0].roll());
        
        // these rotations have an issue where changes aren't updated properly.
        // see https://github.com/leapmotion/leapjs/issues/188
//        var xRotation = this.limitRotation(hand.rotationAngle(lastFrame, [ 1, 0, 0 ]));
//        var yRotation = this.limitRotation(hand.rotationAngle(lastFrame, [ 0, 1, 0 ]));
//        var zRotation = this.limitRotation(hand.rotationAngle(lastFrame, [ 0, 0, 1 ]));
        // console.log('lastframe1: ' + that.lastFrame);
        if (Math.abs(axisAngle[0][0]) > MIN_ROTATION || 
            Math.abs(axisAngle[0][1]) > MIN_ROTATION || 
            Math.abs(axisAngle[0][2]) > MIN_ROTATION) {
          that.gestureDispatcher.triggerRotate(this.limitRotation(axisAngle[0][0]),
              this.limitRotation(axisAngle[0][1]), this.limitRotation(axisAngle[0][2]));
        }
      }
    } else if (frame.fingers.length > 0) {

      try {
        var finger = frame.fingers[0];
        var hit = Pointer(finger);
        // Vector hit =
        // controller.locatedScreens().closestScreenHit(finger).intersect(finger,true);
        var zVel = finger.tipVelocity.getZ[2];
        var absZVel = Math.abs(zVel);
        var y = hit.getY();
        var x = hit.getX();

        if (absZVel > 50 && that.lastY != -1) {
          var scale = 2500 / (absZVel * absZVel);
          x = (hit.x - that.lastX) * scale + that.lastX;
          y = (hit.y - that.lastY) * scale + that.lastY;
        }
        that.lastY = y;
        that.lastX = x;
        if (!isNaN(x) && !isNaN(y)) {
          // that.gestureDispatcher.point(x, y);
        }
      } catch (e) {
        console.log('error occurred when pointing: ' + e);
      }
    } else {
      that.lastY = -1;
      that.lastX = -1;

    }
    var i;
    if (frame.gestures) {

      frame.gestures.forEach(function(gesture) {
        switch (gesture.type) {
        case 'swipe':
          that.gestureDispatcher.reset();
          break;
        case 'screenTap':

          that.gestureDispatcher.selectMouseCursor();
          // add a delay so the app can process the mouse clicks.
          setTimeout(that.gestureDispatcher.zoomToSelection, 100);
          break;
        case 'keyTap':
          that.gestureDispatcher.zoomToSelection();
          break;
        default:
          console.log("Unknown gesture type: " + gesture.type);
          break;
        }
      });
    }
  }
  // console.log('lastframe2: ' + that.lastFrame);
}