Skip to content

Commit

Permalink
Initial commit. Waiting for leap motion bug to be fixed.
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethsabir committed Oct 16, 2014
1 parent 6217466 commit 5ea5add
Show file tree
Hide file tree
Showing 6 changed files with 401 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>molecular-control-toolkit-js</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,49 @@ molecular-control-toolkit-js
============================

A javascript adapter to the molecular control toolkit.

see https://github.com/Traksewt/molecular-control-toolkit

This toolkit can be used to transfer Leap Motion events in the browser direct to an applet.

in the browser JS:
<code>
var leapToolkit = new molecularControlToolkitJS.leap(gestures());

var gestures = function () {
var functions = ['triggerPan', 'triggerRotate', 'triggerZoom', 'point', 'reset', 'zoomToSelection', 'selectMouseCursor'];
var ret = {};
functions.forEach(function (funcName) {
ret[funcName] = function () {
var newArgs = [funcName];
newArgs.push(Array.prototype.slice.call(arguments));
if (document.applets[0]) {
document.applets[0].molecularControlToolkit.apply(document.applets[0], newArgs);
}
}
})
return ret;
}

leapToolkit.start()
</code>

in the applet:
<code>
TunnellingConnector connector = null;

public void initialise() {
MolecularControlToolkit molecularControlToolkit = new MolecularControlToolkit();
this.connector = (TunnellingConnector) molecularControlToolkit.addConnector(ConnectorType.LeapMotionJS);
MyDispatcher dispatcher = new MyDispatcher();
molecularControlToolkit.setListeners(dispatcher);
}

/** The entry point for the browser events */
public void molecularControlToolkit(String methodName, float[] arguments) {
System.out.println("Method: " + methodName + ", args: " + Arrays.asList(arguments).toString());
if (this.connector != null) {
this.connector.tunnel(methodName, arguments);
}
}
</code>
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var leapConnector = require('./src/leapConnector');


module.exports.leap = leapConnector;
24 changes: 24 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "molecular-control-toolkit-js",
"version": "0.0.2",
"description": "A javascript adapter to the molecular control toolkit",
"main": "index.js",
"repository": {
"type": "git",
"url": "git://github.com/Traksewt/molecular-control-toolkit-js.git"
},
"keywords": [
"LeapMotion",
"Gesture",
"Device",
"MolecularControlToolkit"
],
"author": "Kenny Sabir",
"license": "BSD",
"bugs": {
"url": "https://github.com/Traksewt/molecular-control-toolkit-js/issues"
},
"dependencies": {
"leapjs": "*"
}
}
144 changes: 144 additions & 0 deletions src/leapConnector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
var Leap = require('leapjs');
var Pointer = require('./pointer')

/** constant for scaling pointing in the x axis */
var X_SCALE = 150;

/** constant for scaling pointing in the y axis */
var Y_SCALE = -400;

/** constant for offsetting pointing in the y axis */
var Y_OFFSET = 400;

var ROTATION_SCALE = 500;

var MAX_ROTATION = 30;

var MIN_ROTATION = 3;

var LeapConnector = function(gestureDispatcher) {
this.gestureDispatcher = gestureDispatcher;


/** Store the lastX for custom pointing algorithm */
this.lastX = -1;

/** Store the lastY for custom pointing algorithm */
this.lastY = -1;

};

LeapConnector.prototype.start = function() {
var that = this;
this.controller = Leap.loop({
// frameEventName: 'deviceFrame',
enableGestures : false
}, function(frame) {
return that.onFrame(frame);
});
return that;
}

LeapConnector.prototype.limitRotation = function(r) {
r *= ROTATION_SCALE;
r = Math.max(-MAX_ROTATION, r);
r = Math.min(MAX_ROTATION, r);
if (Math.abs(r) < MIN_ROTATION) {
r = 0;
}
return r;
}

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 == 1) {

// 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]);

// 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(xRotation) > MIN_ROTATION ||
Math.abs(yRotation) > MIN_ROTATION ||
Math.abs(zRotation) > MIN_ROTATION) {
that.gestureDispatcher.triggerRotate((xRotation),
-(yRotation), (zRotation));
}
}
} 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);
}

module.exports = LeapConnector;
Loading

0 comments on commit 5ea5add

Please sign in to comment.