UNPKG

node-red-contrib-leap-motion

Version:

Node-Red nodes for leap motion

87 lines (78 loc) 2.57 kB
var EventEmitter = require('events').EventEmitter , _ = require('underscore') var Region = module.exports = function(start, end) { this.start = new Vector(start) this.end = new Vector(end) this.enteredFrame = null } Region.prototype.hasPointables = function(frame) { for (var i = 0; i != frame.pointables.length; i++) { var position = frame.pointables[i].tipPosition if (position.x >= this.start.x && position.x <= this.end.x && position.y >= this.start.y && position.y <= this.end.y && position.z >= this.start.z && position.z <= this.end.z) { return true } } return false } Region.prototype.listener = function(opts) { var region = this if (opts && opts.nearThreshold) this.setupNearRegion(opts.nearThreshold) return function(frame) { return region.updatePosition(frame) } } Region.prototype.clipper = function() { var region = this return function(frame) { region.updatePosition(frame) return region.enteredFrame ? frame : null } } Region.prototype.setupNearRegion = function(distance) { var nearRegion = this.nearRegion = new Region( [this.start.x - distance, this.start.y - distance, this.start.z - distance], [this.end.x + distance, this.end.y + distance, this.end.z + distance] ) var region = this nearRegion.on("enter", function(frame) { region.emit("near", frame) }) nearRegion.on("exit", function(frame) { region.emit("far", frame) }) region.on('exit', function(frame) { region.emit("near", frame) }) } Region.prototype.updatePosition = function(frame) { if (this.nearRegion) this.nearRegion.updatePosition(frame) if (this.hasPointables(frame) && this.enteredFrame == null) { this.enteredFrame = frame this.emit("enter", this.enteredFrame) } else if (!this.hasPointables(frame) && this.enteredFrame != null) { this.enteredFrame = null this.emit("exit", this.enteredFrame) } return frame } Region.prototype.normalize = function(position) { return new Vector([ (position.x - this.start.x) / (this.end.x - this.start.x), (position.y - this.start.y) / (this.end.y - this.start.y), (position.z - this.start.z) / (this.end.z - this.start.z) ]) } Region.prototype.mapToXY = function(position, width, height) { var normalized = this.normalize(position) var x = normalized.x, y = normalized.y if (x > 1) x = 1 else if (x < -1) x = -1 if (y > 1) y = 1 else if (y < -1) y = -1 return [ (x + 1) / 2 * width, (1 - y) / 2 * height, normalized.z ] } _.extend(Region.prototype, EventEmitter.prototype)