├── example
├── simpleviewer
│ ├── views
│ │ ├── layout.ejs
│ │ ├── 404.ejs
│ │ ├── 500.ejs
│ │ ├── webgl.ejs
│ │ └── index.ejs
│ ├── package.json
│ ├── public
│ │ ├── stylesheets
│ │ │ └── style.css
│ │ └── javascripts
│ │ │ ├── postprocessing
│ │ │ ├── TexturePass.js
│ │ │ ├── ShaderPass.js
│ │ │ ├── RenderPass.js
│ │ │ ├── SavePass.js
│ │ │ ├── DotScreenPass.js
│ │ │ ├── FilmPass.js
│ │ │ ├── MaskPass.js
│ │ │ ├── BloomPass.js
│ │ │ └── EffectComposer.js
│ │ │ ├── Detector.js
│ │ │ ├── Stats.js
│ │ │ ├── kinect.js
│ │ │ ├── main.js
│ │ │ ├── webgl.js
│ │ │ ├── socket.io.js
│ │ │ └── ShaderExtras.js
│ └── server.js
└── hellokinect
│ ├── hellokinect.js
│ └── depthbuffer_sample.js
├── .gitignore
├── .npmignore
├── Makefile
├── freenect.js
├── package.json
├── wscript
├── README.md
├── LICENSE
└── src
└── node_freenect.cc
/example/simpleviewer/views/layout.ejs:
--------------------------------------------------------------------------------
1 | <%- body %>
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
3 | .lock-wscript
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .git*
2 | .DS_Store
3 | .lock-wscript
4 | example/
5 | node_modules/
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | make:
2 | node-waf configure clean build;
3 |
4 | clean:
5 | rm -rf ./build
6 |
7 |
--------------------------------------------------------------------------------
/example/simpleviewer/views/404.ejs:
--------------------------------------------------------------------------------
1 |
404 Not Found
2 | This is not a page you are looking for.
--------------------------------------------------------------------------------
/example/simpleviewer/views/500.ejs:
--------------------------------------------------------------------------------
1 | 500 Internal Server Error
2 | An unexpected error seems to have occured.
3 | Error Details
4 |
5 | <%= error %>
6 |
7 |
--------------------------------------------------------------------------------
/freenect.js:
--------------------------------------------------------------------------------
1 | // require the c++ bindings & export to javascript
2 | var binding = require(__dirname + '/build/default/freenect_binding');
3 |
4 | var LedOptions = {
5 | OFF: 0,
6 | GREEN: 1,
7 | RED: 2,
8 | YELLOW: 3,
9 | BLINK_GREEN: 5,
10 | BLINK_RED_YELLOW: 6
11 | };
12 |
13 | module.exports = {
14 | Kinect: binding.Kinect,
15 | LedOptions: LedOptions
16 | };
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "freenect",
3 | "description" : "libfreenect bindings for Node.js",
4 | "version" : "0.0.2",
5 | "author" : "Kazuyuki Honda ",
6 | "keywords": ["kinect", "libfreenect"],
7 | "repository": "git://github.com/hakobera/node-freenect",
8 | "main" : "freenect",
9 | "scripts" : {
10 | "install" : "node-waf configure build"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/example/simpleviewer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simpleviewer",
3 | "description": "A simple node-freenect viewer for kinect with Node.",
4 | "version": "0.0.1",
5 | "homepage": "https://github.com/hakobera/node-freenect",
6 | "author": "Kazuyuki Honda ",
7 | "directories": {
8 | "public": "./public"
9 | },
10 | "engine": {
11 | "node": ">=-0.4.0"
12 | },
13 | "dependencies": {
14 | "express": "2.2.2",
15 | "connect": "1.3.0",
16 | "ejs": "0.4.1",
17 | "socket.io": "0.6.17",
18 | "browserify": "0.3.1",
19 | "jsmin": "1.0.0"
20 | },
21 | "bin": {
22 | "simpleviewer": "./server.js"
23 | }
24 | }
--------------------------------------------------------------------------------
/example/hellokinect/hellokinect.js:
--------------------------------------------------------------------------------
1 | var Freenect = require('freenect');
2 |
3 | var kinect = new Freenect.Kinect(),
4 | ledOption = 0,
5 | prev = Date.now();
6 |
7 | setInterval(function() {
8 | var now = Date.now(),
9 | interval = now - prev,
10 | depth = kinect.getDepth(),
11 | len = depth.length,
12 | tiltAngle = kinect.getTiltAngle(),
13 | i;
14 |
15 | console.log('Interval: %d, Depth Size: %d, LED Option: %d, Tile Angle: %d',
16 | interval, len, ledOption, tiltAngle);
17 |
18 | // Manupulate depth pixel data like following code.
19 | for (i = 0; i < len; ++i) {
20 | depth[i] = 255 - depth[i];
21 | }
22 |
23 | // Change LED color and blink pattern.
24 | kinect.setLed(ledOption);
25 |
26 | ledOption += 1;
27 | if (ledOption > 6) {
28 | ledOption = 0
29 | }
30 |
31 | prev = now;
32 |
33 | }, 200);
34 |
--------------------------------------------------------------------------------
/example/hellokinect/depthbuffer_sample.js:
--------------------------------------------------------------------------------
1 | var Freenect = require('freenect');
2 |
3 | var kinect = new Freenect.Kinect(),
4 | ledOption = 0,
5 | prev = Date.now();
6 |
7 | setInterval(function() {
8 | var now = Date.now(),
9 | interval = now - prev,
10 | depth = kinect.getDepthBuffer(),
11 | len = depth.length,
12 | tiltAngle = kinect.getTiltAngle(),
13 | i;
14 |
15 | console.log('Interval: %d, Depth Size: %d, LED Option: %d, Tile Angle: %d',
16 | interval, len, ledOption, tiltAngle);
17 |
18 | // Manupulate depth pixel data like following code.
19 | for (i = 0; i < len; ++i) {
20 | depth[i] = 255 - depth[i];
21 | }
22 |
23 | // Change LED color and blink pattern.
24 | kinect.setLed(ledOption);
25 |
26 | ledOption += 1;
27 | if (ledOption > 6) {
28 | ledOption = 0
29 | }
30 |
31 | prev = now;
32 |
33 | }, 100);
34 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | color: #fff;
5 | background-color: #000;
6 | font: 14px "Lucida Grande, "Helvetica Nueue", Arial, sans-serif;
7 | }
8 |
9 | h1,h2,h3,h4,h5,h6
10 | p,ul,li,div,form {
11 | margin: 0;
12 | padding: 0;
13 | }
14 |
15 | a {
16 | outline: none;
17 | -moz-outline-style: none;
18 | }
19 |
20 | header {
21 | padding: 0 20px;
22 | color: #000;
23 | background-color: #eee;
24 | }
25 |
26 | #contents {
27 | padding: 10px 20px;
28 | }
29 |
30 | fieldset {
31 | margin: 10px 0;
32 | }
33 |
34 | footer {
35 | margin-top: 15px;
36 | color: #999;
37 | font-size: 12px;
38 | text-align: center;
39 | }
40 |
41 | input.number {
42 | text-align: right;
43 | }
44 |
45 | ul.horizontal {
46 | list-style:: none;
47 | }
48 |
49 | ul.horizontal li {
50 | display: inline-block;
51 | }
--------------------------------------------------------------------------------
/wscript:
--------------------------------------------------------------------------------
1 | import os
2 | import Options, Utils
3 | from os import unlink, symlink, chdir, popen
4 | from os.path import exists
5 |
6 | VERSION = '0.0.1'
7 |
8 | def set_options(opt):
9 | opt.tool_options('compiler_cxx')
10 |
11 | def configure(conf):
12 | conf.check_tool('compiler_cxx')
13 | conf.check_tool('node_addon')
14 | conf.check_cxx(lib = 'usb-1.0')
15 | conf.check_cxx(lib = 'freenect')
16 | conf.check_cxx(lib = 'freenect_sync')
17 |
18 | def build(bld):
19 | obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
20 | obj.target = 'freenect_binding'
21 | obj.source = './src/node_freenect.cc'
22 | obj.includes = [ '/usr/local/include', '/usr/local/include/libfreenect' ]
23 | obj.lib = [ 'usb-1.0', 'freenect', 'freenect_sync' ]
24 | obj.name = 'node-freenect'
25 |
26 | def shutdown():
27 | t = 'freenect_bindings.node'
28 | if exists('build/default' + t) and not exists(t):
29 | symlink('build/default/' + t, t)
30 |
31 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/TexturePass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.TexturePass = function( texture, opacity ) {
6 |
7 | var shader = THREE.ShaderExtras[ "screen" ];
8 |
9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
10 |
11 | this.uniforms[ "opacity" ].value = ( opacity !== undefined ) ? opacity : 1.0;
12 | this.uniforms[ "tDiffuse" ].texture = texture;
13 |
14 | this.material = new THREE.ShaderMaterial( {
15 |
16 | uniforms: this.uniforms,
17 | vertexShader: shader.vertexShader,
18 | fragmentShader: shader.fragmentShader
19 |
20 | } );
21 |
22 | this.enabled = true;
23 | this.needsSwap = false;
24 |
25 | };
26 |
27 | THREE.TexturePass.prototype = {
28 |
29 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
30 |
31 | THREE.EffectComposer.quad.material = this.material;
32 |
33 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer );
34 |
35 | }
36 |
37 | };
38 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/ShaderPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.ShaderPass = function( shader, textureID ) {
6 |
7 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse";
8 |
9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
10 |
11 | this.material = new THREE.ShaderMaterial( {
12 |
13 | uniforms: this.uniforms,
14 | vertexShader: shader.vertexShader,
15 | fragmentShader: shader.fragmentShader
16 |
17 | } );
18 |
19 | this.renderToScreen = false;
20 |
21 | this.enabled = true;
22 | this.needsSwap = true;
23 | this.clear = false;
24 |
25 | };
26 |
27 | THREE.ShaderPass.prototype = {
28 |
29 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
30 |
31 | if ( this.uniforms[ this.textureID ] ) {
32 |
33 | this.uniforms[ this.textureID ].texture = readBuffer;
34 |
35 | }
36 |
37 | THREE.EffectComposer.quad.material = this.material;
38 |
39 | if ( this.renderToScreen ) {
40 |
41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera );
42 |
43 | } else {
44 |
45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, this.clear );
46 |
47 | }
48 |
49 | }
50 |
51 | };
52 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/RenderPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
6 |
7 | this.scene = scene;
8 | this.camera = camera;
9 |
10 | this.overrideMaterial = overrideMaterial;
11 |
12 | this.clearColor = clearColor;
13 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;
14 |
15 | this.oldClearColor = new THREE.Color();
16 | this.oldClearAlpha = 1;
17 |
18 | this.enabled = true;
19 | this.clear = true;
20 | this.needsSwap = false;
21 |
22 | };
23 |
24 | THREE.RenderPass.prototype = {
25 |
26 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
27 |
28 | this.scene.overrideMaterial = this.overrideMaterial;
29 |
30 | if ( this.clearColor ) {
31 |
32 | this.oldClearColor.copy( renderer.getClearColor() );
33 | this.oldClearAlpha = renderer.getClearAlpha();
34 |
35 | renderer.setClearColor( this.clearColor, this.clearAlpha );
36 |
37 | }
38 |
39 | renderer.render( this.scene, this.camera, readBuffer, this.clear );
40 |
41 | if ( this.clearColor ) {
42 |
43 | renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
44 |
45 | }
46 |
47 | this.scene.overrideMaterial = null;
48 |
49 | }
50 |
51 | };
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | node-freenect
2 | =============
3 |
4 | This software is Node.js addon for control Microsoft Kinect device,
5 | bindings for [libfreenect](https://github.com/OpenKinect/libfreenect).
6 |
7 |
8 | This addon can work on Mac OS X environment, maybe linux environment could work.
9 |
10 | It cannot work on Windows environment.
11 |
12 | Requirements
13 | ------------
14 |
15 | For the addon, you'll need
16 |
17 | * Mac OS X >= 10.6
18 | * Node.js >= 0.4.0
19 | * libfreenect
20 | * libusb-freenect on Mac OS X, libusb-1.0-dev on Linux
21 | * python >= 2.6
22 |
23 | Installation
24 | ------------
25 |
26 | Just clone this repository, and using npm.
27 |
28 | npm install
29 |
30 |
31 | Licence
32 | -------
33 |
34 | Copyright 2011 Kazuyuki Honda
35 |
36 | Licensed under the Apache License, Version 2.0 (the "License");
37 | you may not use this file except in compliance with the License.
38 | You may obtain a copy of the License at
39 |
40 | http://www.apache.org/licenses/LICENSE-2.0
41 |
42 | Unless required by applicable law or agreed to in writing, software
43 | distributed under the License is distributed on an "AS IS" BASIS,
44 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45 | See the License for the specific language governing permissions and
46 | limitations under the License.
47 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/SavePass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.SavePass = function( renderTarget ) {
6 |
7 | var shader = THREE.ShaderExtras[ "screen" ];
8 |
9 | this.textureID = "tDiffuse";
10 |
11 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
12 |
13 | this.material = new THREE.ShaderMaterial( {
14 |
15 | uniforms: this.uniforms,
16 | vertexShader: shader.vertexShader,
17 | fragmentShader: shader.fragmentShader
18 |
19 | } );
20 |
21 | this.renderTarget = renderTarget;
22 |
23 | if ( this.renderTarget === undefined ) {
24 |
25 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
26 | this.renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters );
27 |
28 | }
29 |
30 | this.enabled = true;
31 | this.needsSwap = false;
32 | this.clear = false;
33 |
34 | };
35 |
36 | THREE.SavePass.prototype = {
37 |
38 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
39 |
40 | if ( this.uniforms[ this.textureID ] ) {
41 |
42 | this.uniforms[ this.textureID ].texture = readBuffer;
43 |
44 | }
45 |
46 | THREE.EffectComposer.quad.material = this.material;
47 |
48 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTarget, this.clear );
49 |
50 | }
51 |
52 | };
53 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/DotScreenPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.DotScreenPass = function( center, angle, scale ) {
6 |
7 | var shader = THREE.ShaderExtras[ "dotscreen" ];
8 |
9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
10 |
11 | if ( center !== undefined )
12 | this.uniforms[ "center" ].value.copy( center );
13 |
14 | if ( angle !== undefined ) this.uniforms[ "angle"].value = angle;
15 | if ( scale !== undefined ) this.uniforms[ "scale"].value = scale;
16 |
17 | this.material = new THREE.ShaderMaterial( {
18 |
19 | uniforms: this.uniforms,
20 | vertexShader: shader.vertexShader,
21 | fragmentShader: shader.fragmentShader
22 |
23 | } );
24 |
25 | this.enabled = true;
26 | this.renderToScreen = false;
27 | this.needsSwap = true;
28 |
29 | };
30 |
31 | THREE.DotScreenPass.prototype = {
32 |
33 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
34 |
35 | this.uniforms[ "tDiffuse" ].texture = readBuffer;
36 | this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height );
37 |
38 | THREE.EffectComposer.quad.material = this.material;
39 |
40 | if ( this.renderToScreen ) {
41 |
42 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera );
43 |
44 | } else {
45 |
46 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false );
47 |
48 | }
49 |
50 | }
51 |
52 | };
53 |
--------------------------------------------------------------------------------
/example/simpleviewer/views/webgl.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Simple Viewer - node-freenect
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/FilmPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.FilmPass = function( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) {
6 |
7 | var shader = THREE.ShaderExtras[ "film" ];
8 |
9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
10 |
11 | this.material = new THREE.ShaderMaterial( {
12 |
13 | uniforms: this.uniforms,
14 | vertexShader: shader.vertexShader,
15 | fragmentShader: shader.fragmentShader
16 |
17 | } );
18 |
19 | if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale;
20 | if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity;
21 | if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity;
22 | if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount;
23 |
24 | this.enabled = true;
25 | this.renderToScreen = false;
26 | this.needsSwap = true;
27 |
28 | };
29 |
30 | THREE.FilmPass.prototype = {
31 |
32 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
33 |
34 | this.uniforms[ "tDiffuse" ].texture = readBuffer;
35 | this.uniforms[ "time" ].value += delta;
36 |
37 | THREE.EffectComposer.quad.material = this.material;
38 |
39 | if ( this.renderToScreen ) {
40 |
41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera );
42 |
43 | } else {
44 |
45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false );
46 |
47 | }
48 |
49 | }
50 |
51 | };
52 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/MaskPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.MaskPass = function ( scene, camera ) {
6 |
7 | this.scene = scene;
8 | this.camera = camera;
9 |
10 | this.enabled = true;
11 | this.clear = true;
12 | this.needsSwap = false;
13 |
14 | this.inverse = false;
15 |
16 | };
17 |
18 | THREE.MaskPass.prototype = {
19 |
20 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
21 |
22 | var context = renderer.context;
23 |
24 | // don't update color or depth
25 |
26 | context.colorMask( false, false, false, false );
27 | context.depthMask( false );
28 |
29 | // set up stencil
30 |
31 | var writeValue, clearValue;
32 |
33 | if ( this.inverse ) {
34 |
35 | writeValue = 0;
36 | clearValue = 1;
37 |
38 | } else {
39 |
40 | writeValue = 1;
41 | clearValue = 0;
42 |
43 | }
44 |
45 | context.enable( context.STENCIL_TEST );
46 | context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );
47 | context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );
48 | context.clearStencil( clearValue );
49 |
50 | // draw into the stencil buffer
51 |
52 | renderer.render( this.scene, this.camera, readBuffer, this.clear );
53 | renderer.render( this.scene, this.camera, writeBuffer, this.clear );
54 |
55 | // re-enable update of color and depth
56 |
57 | context.colorMask( true, true, true, true );
58 | context.depthMask( true );
59 |
60 | // only render where stencil is set to 1
61 |
62 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
63 | context.stencilOp( context.KEEP, context.KEEP, context.KEEP );
64 |
65 | }
66 |
67 | };
68 |
69 |
70 | THREE.ClearMaskPass = function () {
71 |
72 | this.enabled = true;
73 |
74 | };
75 |
76 | THREE.ClearMaskPass.prototype = {
77 |
78 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
79 |
80 | var context = renderer.context;
81 |
82 | context.disable( context.STENCIL_TEST );
83 |
84 | }
85 |
86 | };
87 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/Detector.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | * @author mr.doob / http://mrdoob.com/
4 | */
5 |
6 | Detector = {
7 |
8 | canvas: !! window.CanvasRenderingContext2D,
9 | webgl: ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(),
10 | workers: !! window.Worker,
11 | fileapi: window.File && window.FileReader && window.FileList && window.Blob,
12 |
13 | getWebGLErrorMessage: function () {
14 |
15 | var element = document.createElement( 'div' );
16 | element.id = 'webgl-error-message';
17 | element.style.fontFamily = 'monospace';
18 | element.style.fontSize = '13px';
19 | element.style.fontWeight = 'normal';
20 | element.style.textAlign = 'center';
21 | element.style.background = '#fff';
22 | element.style.color = '#000';
23 | element.style.padding = '1.5em';
24 | element.style.width = '400px';
25 | element.style.margin = '5em auto 0';
26 |
27 | if ( ! this.webgl ) {
28 |
29 | element.innerHTML = window.WebGLRenderingContext ? [
30 | 'Your graphics card does not seem to support WebGL.
',
31 | 'Find out how to get it here.'
32 | ].join( '\n' ) : [
33 | 'Your browser does not seem to support WebGL.
',
34 | 'Find out how to get it here.'
35 | ].join( '\n' );
36 |
37 | }
38 |
39 | return element;
40 |
41 | },
42 |
43 | addGetWebGLMessage: function ( parameters ) {
44 |
45 | var parent, id, element;
46 |
47 | parameters = parameters || {};
48 |
49 | parent = parameters.parent !== undefined ? parameters.parent : document.body;
50 | id = parameters.id !== undefined ? parameters.id : 'oldie';
51 |
52 | element = Detector.getWebGLErrorMessage();
53 | element.id = id;
54 |
55 | parent.appendChild( element );
56 |
57 | }
58 |
59 | };
60 |
--------------------------------------------------------------------------------
/example/simpleviewer/views/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Simple Viewer - node-freenect
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/Stats.js:
--------------------------------------------------------------------------------
1 | // stats.js r8 - http://github.com/mrdoob/stats.js
2 | var Stats=function(){var h,a,n=0,o=0,i=Date.now(),u=i,p=i,l=0,q=1E3,r=0,e,j,f,b=[[16,16,48],[0,255,255]],m=0,s=1E3,t=0,d,k,g,c=[[16,48,16],[0,255,0]];h=document.createElement("div");h.style.cursor="pointer";h.style.width="80px";h.style.opacity="0.9";h.style.zIndex="10001";h.addEventListener("mousedown",function(a){a.preventDefault();n=(n+1)%2;n==0?(e.style.display="block",d.style.display="none"):(e.style.display="none",d.style.display="block")},!1);e=document.createElement("div");e.style.textAlign=
3 | "left";e.style.lineHeight="1.2em";e.style.backgroundColor="rgb("+Math.floor(b[0][0]/2)+","+Math.floor(b[0][1]/2)+","+Math.floor(b[0][2]/2)+")";e.style.padding="0 0 3px 3px";h.appendChild(e);j=document.createElement("div");j.style.fontFamily="Helvetica, Arial, sans-serif";j.style.fontSize="9px";j.style.color="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";j.style.fontWeight="bold";j.innerHTML="FPS";e.appendChild(j);f=document.createElement("div");f.style.position="relative";f.style.width="74px";f.style.height=
4 | "30px";f.style.backgroundColor="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";for(e.appendChild(f);f.children.length<74;)a=document.createElement("span"),a.style.width="1px",a.style.height="30px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+b[0][0]+","+b[0][1]+","+b[0][2]+")",f.appendChild(a);d=document.createElement("div");d.style.textAlign="left";d.style.lineHeight="1.2em";d.style.backgroundColor="rgb("+Math.floor(c[0][0]/2)+","+Math.floor(c[0][1]/2)+","+Math.floor(c[0][2]/2)+")";d.style.padding=
5 | "0 0 3px 3px";d.style.display="none";h.appendChild(d);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.fontSize="9px";k.style.color="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";k.style.fontWeight="bold";k.innerHTML="MS";d.appendChild(k);g=document.createElement("div");g.style.position="relative";g.style.width="74px";g.style.height="30px";g.style.backgroundColor="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";for(d.appendChild(g);g.children.length<74;)a=document.createElement("span"),
6 | a.style.width="1px",a.style.height=Math.random()*30+"px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+c[0][0]+","+c[0][1]+","+c[0][2]+")",g.appendChild(a);return{domElement:h,update:function(){i=Date.now();m=i-u;s=Math.min(s,m);t=Math.max(t,m);k.textContent=m+" MS ("+s+"-"+t+")";var a=Math.min(30,30-m/200*30);g.appendChild(g.firstChild).style.height=a+"px";u=i;o++;if(i>p+1E3)l=Math.round(o*1E3/(i-p)),q=Math.min(q,l),r=Math.max(r,l),j.textContent=l+" FPS ("+q+"-"+r+")",a=Math.min(30,30-l/
7 | 100*30),f.appendChild(f.firstChild).style.height=a+"px",p=i,o=0}}};
8 |
9 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/kinect.js:
--------------------------------------------------------------------------------
1 | (function(global) {
2 | var server,
3 | socket,
4 | host = 'localhost',
5 | port = 3000,
6 | connected = false,
7 | connectionCallback,
8 | commandCallbacks = {};
9 |
10 | socket = new io.Socket(host, {
11 | port: port,
12 | connectTimeout: 10000,
13 | reconnect: true
14 | });
15 |
16 | socket.on('connecting', function(transportType) {
17 | connected = false;
18 | console.log('Connecting to %s:%d using %s', host, port, transportType);
19 | });
20 |
21 | socket.on('connect', function() {
22 | connected = true;
23 | console.log('Connected to %s:%d', host, port);
24 | if (connectionCallback) {
25 | connectionCallback();
26 | }
27 | });
28 |
29 | socket.on('connect_failed', function() {
30 | connected = false;
31 | console.log('Connect failed.');
32 | });
33 |
34 | socket.on('close', function() {
35 | connected = false;
36 | console.log('Connection closed.');
37 | });
38 |
39 | socket.on('disconnect', function() {
40 | connected = false;
41 | console.log('Connection disconnected.');
42 | });
43 |
44 | socket.on('recconect', function(transportType, reconnectionAttempts) {
45 | connected = true;
46 | console.log('Reconnecting to %s:%d using %s %s', host, port, transportType, reconnectionAttempts);
47 | });
48 |
49 | socket.on('reconnect_failed', function() {
50 | connected = false;
51 | console.log('Reconnect failed.');
52 | });
53 |
54 | socket.on('message', function(command) {
55 | var cmd = JSON.parse(command);
56 | // console.log('[callback][%s]', cmd.type);
57 | if (commandCallbacks.hasOwnProperty(cmd.type)) {
58 | commandCallbacks[cmd.type].call(Kinect, cmd.result);
59 | };
60 | });
61 |
62 | Kinect = {
63 |
64 | connect: function(callback) {
65 | socket.connect();
66 | if (callback && typeof(callback) === 'function') {
67 | connectionCallback = callback
68 | }
69 | },
70 |
71 | sendCommand: function(commandType, options) {
72 | if (connected) {
73 | var cmd = options || {};
74 | cmd.type = commandType
75 | // console.log('[send][%s]', cmd.type, cmd);
76 | socket.send(JSON.stringify(cmd));
77 | }
78 | },
79 |
80 | on: function(commandType, callback) {
81 | if (callback && typeof(callback) === 'function') {
82 | commandCallbacks[commandType] = callback;
83 | }
84 | },
85 |
86 | setLed: function(ledOption) {
87 | this.sendCommand('setLed', { option: ledOption });
88 | },
89 |
90 | setTiltAngle: function(angle) {
91 | this.sendCommand('setTiltAngle', { angle: angle });
92 | },
93 |
94 | getDepth: function(callback) {
95 | this.sendCommand('getDepth');
96 | this.on('getDepth', function(ret) {
97 | if (callback) {
98 | callback.call(Kinect, ret.data);
99 | }
100 | });
101 | },
102 |
103 | getVideo: function(callback) {
104 | this.sendCommand('getVideo');
105 | this.on('getVideo', function(ret) {
106 | if (callback) {
107 | callback.call(Kinect, ret.data);
108 | }
109 | });
110 | },
111 |
112 | stop: function() {
113 | this.sendCommand('stop');
114 | }
115 |
116 | };
117 |
118 | Kinect.LED_OPTIONS = {
119 | OFF: 0,
120 | GREEN: 1,
121 | RED: 2,
122 | YELLOW: 3,
123 | BLINK_GREEN: 5,
124 | BLINK_RED_YELLOW: 6
125 | };
126 |
127 | return Kinect;
128 | })(this);
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/BloomPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.BloomPass = function( strength, kernelSize, sigma, resolution ) {
6 |
7 | strength = ( strength !== undefined ) ? strength : 1;
8 | kernelSize = ( kernelSize !== undefined ) ? kernelSize : 25;
9 | sigma = ( sigma !== undefined ) ? sigma : 4.0;
10 | resolution = ( resolution !== undefined ) ? resolution : 256;
11 |
12 | // render targets
13 |
14 | var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
15 |
16 | this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars );
17 | this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars );
18 |
19 | // screen material
20 |
21 | var screenShader = THREE.ShaderExtras[ "screen" ];
22 |
23 | this.screenUniforms = THREE.UniformsUtils.clone( screenShader.uniforms );
24 |
25 | this.screenUniforms[ "opacity" ].value = strength;
26 |
27 | this.materialScreen = new THREE.ShaderMaterial( {
28 |
29 | uniforms: this.screenUniforms,
30 | vertexShader: screenShader.vertexShader,
31 | fragmentShader: screenShader.fragmentShader,
32 | blending: THREE.AdditiveBlending,
33 | transparent: true
34 |
35 | } );
36 |
37 | // convolution material
38 |
39 | var convolutionShader = THREE.ShaderExtras[ "convolution" ];
40 |
41 | this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms );
42 |
43 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurx;
44 | this.convolutionUniforms[ "cKernel" ].value = THREE.ShaderExtras.buildKernel( sigma );
45 |
46 | this.materialConvolution = new THREE.ShaderMaterial( {
47 |
48 | uniforms: this.convolutionUniforms,
49 | vertexShader: "#define KERNEL_SIZE " + kernelSize + ".0\n" + convolutionShader.vertexShader,
50 | fragmentShader: "#define KERNEL_SIZE " + kernelSize + "\n" + convolutionShader.fragmentShader
51 |
52 | } );
53 |
54 | this.enabled = true;
55 | this.needsSwap = false;
56 | this.clear = false;
57 |
58 | };
59 |
60 | THREE.BloomPass.prototype = {
61 |
62 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
63 |
64 | if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST );
65 |
66 | // Render quad with blured scene into texture (convolution pass 1)
67 |
68 | THREE.EffectComposer.quad.material = this.materialConvolution;
69 |
70 | this.convolutionUniforms[ "tDiffuse" ].texture = readBuffer;
71 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX;
72 |
73 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetX, true );
74 |
75 |
76 | // Render quad with blured scene into texture (convolution pass 2)
77 |
78 | this.convolutionUniforms[ "tDiffuse" ].texture = this.renderTargetX;
79 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY;
80 |
81 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetY, true );
82 |
83 | // Render original scene with superimposed blur to texture
84 |
85 | THREE.EffectComposer.quad.material = this.materialScreen;
86 |
87 | this.screenUniforms[ "tDiffuse" ].texture = this.renderTargetY;
88 |
89 | if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
90 |
91 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer, this.clear );
92 |
93 | }
94 |
95 | };
96 |
97 | THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 );
98 | THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 );
99 |
100 |
101 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/main.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | var rgbButton = $('#rbgButton'),
3 | depthButton = $('#depthButton'),
4 | stopButton = $('#stopButton'),
5 | depthCanvas = document.getElementById('depthbuffer'),
6 | depthContext = depthCanvas.getContext('2d'),
7 | // screenImage = screenContext.createImageData(screenCanvas.width, screenCanvas.height),
8 | depthImage = depthContext.createImageData(80, 60),
9 | depthSize = depthCanvas.width * depthCanvas.height,
10 |
11 | screenCanvas = document.getElementById('screen'),
12 | screenContext = screenCanvas.getContext('2d'),
13 | // screenImage = screenContext.createImageData(screenCanvas.width, screenCanvas.height),
14 | screenImage = screenContext.createImageData(400, 300),
15 | screenSize = screenCanvas.width * screenCanvas.height,
16 |
17 | ledSwitch = $('input[name=led]'),
18 | tiltAngleInput = $('#tiltAngleInput'),
19 | tiltAngleButton = $('#tiltAngleButton');
20 |
21 | Kinect.connect();
22 | /*
23 | rgbButton.click(function(e) {
24 | e.preventDefault();
25 | Kinect.getVideo(function(data) {
26 | var length = data.length,
27 | pixels = screenImage.data,
28 | i, srcIndex, dstIndex;
29 |
30 | console.log(length);
31 |
32 | for (i = 0; i < screenSize; i+=4) {
33 | srcIndex = i * 3;
34 | dstIndex = i * 4;
35 | pixels[dstIndex ] = data[srcIndex ];
36 | pixels[dstIndex+1] = data[srcIndex+1];
37 | pixels[dstIndex+2] = data[srcIndex+2];
38 | pixels[dstIndex+3] = 255;
39 | }
40 |
41 | screenContext.putImageData(screenImage, 0, 0);
42 | });
43 | });
44 | */
45 |
46 |
47 | var last_frametime = 0;
48 | var last_fps = 0;
49 |
50 | var getDepthFrame = function() {
51 |
52 | Kinect.getDepth(function(data) {
53 | console.log(data);
54 |
55 | var offset = 0,
56 | length = data.length,
57 | pixels = depthImage.data,
58 | i, color;
59 |
60 | offset = 0;
61 | for (i = 0; i < length; ++i) {
62 | color = data[i] ;
63 | pixels[offset ] = color;
64 | pixels[offset+1] = color;
65 | pixels[offset+2] = color;
66 | pixels[offset+3] = 255;
67 | offset += 4;
68 | }
69 | depthContext.putImageData(depthImage, 0, 0);
70 | screenContext.drawImage(depthCanvas, 0,0,depthCanvas.width,depthCanvas.height,0,0,screenCanvas.width,screenCanvas.height);
71 |
72 | var t = (new Date()).getTime();
73 | if (last_frametime == 0)
74 | last_frametime = t;
75 |
76 | var dt = t - last_frametime;
77 | if( dt >0 ){
78 | var cfps = 1000.0 / dt;
79 |
80 | last_fps *= 0.5;
81 | last_fps += cfps*0.5;
82 | }
83 |
84 | $('#debug').text('avg. fps: '+Math.round(last_fps,3));
85 |
86 | last_frametime = t;
87 | getDepthFrame();
88 | });
89 | };
90 |
91 | setTimeout(function(){
92 | getDepthFrame();
93 | }, 500);
94 |
95 | /*
96 | depthButton.click(function(e) {
97 | e.preventDefault();
98 | Kinect.getDepth(function(data) {
99 | var offset = 0,
100 | length = data.length,
101 | pixels = screenImage.data,
102 | scale = 255 / 2047,
103 | i, color;
104 |
105 | for (i = 0; i < length; ++i) {
106 | offset = 4 * i;
107 | color = data[i] * scale | 0;
108 | pixels[offset ] = color;
109 | pixels[offset+1] = color;
110 | pixels[offset+2] = color;
111 | pixels[offset+3] = 255;
112 | }
113 |
114 | screenContext.putImageData(screenImage, 0, 0);
115 | });
116 | });
117 |
118 | stopButton.click(function(e) {
119 | e.preventDefault();
120 | Kinect.stop();
121 | });
122 | */
123 | ledSwitch.click(function(e) {
124 | Kinect.setLed($(this).val());
125 | });
126 |
127 | tiltAngleButton.click(function(e) {
128 | e.preventDefault();
129 | var v = tiltAngleInput.val(),
130 | angle = parseFloat(v);
131 | if (!isNaN(angle)) {
132 | Kinect.setTiltAngle(angle);
133 | }
134 | });
135 |
136 | });
137 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/postprocessing/EffectComposer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.EffectComposer = function( renderer, renderTarget ) {
6 |
7 | this.renderer = renderer;
8 |
9 | this.renderTarget1 = renderTarget;
10 |
11 | if ( this.renderTarget1 === undefined ) {
12 |
13 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
14 | this.renderTarget1 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters );
15 |
16 | }
17 |
18 | this.renderTarget2 = this.renderTarget1.clone();
19 |
20 | this.writeBuffer = this.renderTarget1;
21 | this.readBuffer = this.renderTarget2;
22 |
23 | this.passes = [];
24 |
25 | this.copyPass = new THREE.ShaderPass( THREE.ShaderExtras[ "screen" ] );
26 |
27 | };
28 |
29 | THREE.EffectComposer.prototype = {
30 |
31 | swapBuffers: function() {
32 |
33 | var tmp = this.readBuffer;
34 | this.readBuffer = this.writeBuffer;
35 | this.writeBuffer = tmp;
36 |
37 | },
38 |
39 | addPass: function ( pass ) {
40 |
41 | this.passes.push( pass );
42 |
43 | },
44 |
45 | render: function ( delta ) {
46 |
47 | this.writeBuffer = this.renderTarget1;
48 | this.readBuffer = this.renderTarget2;
49 |
50 | var maskActive = false;
51 |
52 | var pass, i, il = this.passes.length;
53 |
54 | for ( i = 0; i < il; i ++ ) {
55 |
56 | pass = this.passes[ i ];
57 |
58 | if ( !pass.enabled ) continue;
59 |
60 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );
61 |
62 | if ( pass.needsSwap ) {
63 |
64 | if ( maskActive ) {
65 |
66 | var context = this.renderer.context;
67 |
68 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
69 |
70 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );
71 |
72 | context.stencilFunc( context.EQUAL, 1, 0xffffffff );
73 |
74 | }
75 |
76 | this.swapBuffers();
77 |
78 | }
79 |
80 | if ( pass instanceof THREE.MaskPass ) {
81 |
82 | maskActive = true;
83 |
84 | } else if ( pass instanceof THREE.ClearMaskPass ) {
85 |
86 | maskActive = false;
87 |
88 | }
89 |
90 | }
91 |
92 | },
93 |
94 | reset: function ( renderTarget ) {
95 |
96 | this.renderTarget1 = renderTarget;
97 |
98 | if ( this.renderTarget1 === undefined ) {
99 |
100 | this.renderTarget1 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters );
101 |
102 | }
103 |
104 | this.renderTarget2 = this.renderTarget1.clone();
105 |
106 | this.writeBuffer = this.renderTarget1;
107 | this.readBuffer = this.renderTarget2;
108 |
109 | THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 );
110 |
111 | THREE.EffectComposer.camera.left = window.innerWidth / - 2;
112 | THREE.EffectComposer.camera.right = window.innerWidth / 2;
113 | THREE.EffectComposer.camera.top = window.innerHeight / 2;
114 | THREE.EffectComposer.camera.bottom = window.innerHeight / - 2;
115 |
116 | THREE.EffectComposer.camera.updateProjectionMatrix();
117 |
118 | }
119 |
120 | };
121 |
122 | // shared ortho camera
123 |
124 | THREE.EffectComposer.camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 );
125 |
126 | // shared fullscreen quad scene
127 |
128 | THREE.EffectComposer.geometry = new THREE.PlaneGeometry( 1, 1 );
129 |
130 | THREE.EffectComposer.quad = new THREE.Mesh( THREE.EffectComposer.geometry, null );
131 | THREE.EffectComposer.quad.position.z = -100;
132 | THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 );
133 |
134 | THREE.EffectComposer.scene = new THREE.Scene();
135 | THREE.EffectComposer.scene.add( THREE.EffectComposer.quad );
136 | THREE.EffectComposer.scene.add( THREE.EffectComposer.camera );
137 |
--------------------------------------------------------------------------------
/example/simpleviewer/server.js:
--------------------------------------------------------------------------------
1 | var express = require('express'),
2 | connect = require('connect'),
3 | ejs = require('ejs'),
4 | sys = require('sys'),
5 | path = require('path'),
6 | io = require('socket.io'),
7 | freenect = require('../../freenect'),
8 | kinect = new freenect.Kinect(),
9 | port = 3000,
10 | app,
11 | socket;
12 |
13 | app = express.createServer();
14 |
15 | app.configure(function() {
16 | app.set('views', __dirname + '/views');
17 | app.use(express.favicon());
18 | app.use(express.bodyParser());
19 | app.use(express.cookieParser());
20 | app.use(express.logger({ format: '\x1b[1m:method\x1b[0m \x1b[33m:url\x1b]0m :response-time ms' }));
21 | app.use(express.methodOverride());
22 | app.use(express.static(__dirname + '/public'));
23 | });
24 |
25 | app.configure('development', function() {
26 | app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
27 | });
28 |
29 | app.configure('production', function() {
30 | app.use(express.errorHandler());
31 | });
32 |
33 | function NotFound(msg) {
34 | this.name = 'NotFound';
35 | Error.call(this, msg);
36 | Error.captureStackTrace(this, arguments.callee);
37 | }
38 |
39 | sys.inherits(NotFound, Error);
40 |
41 | app.get('/404', function(req, res) {
42 | throw new NotFound();
43 | });
44 |
45 | app.get('/500', function(req, res) {
46 | throw new Error('An expected error');
47 | });
48 |
49 | app.get('/bad', function(req, res) {
50 | unknownMethod();
51 | });
52 |
53 | app.error(function(err, req, res, next) {
54 | if (err instanceof NotFound) {
55 | res.render('404.ejs', { status: 404 });
56 | } else {
57 | next(err);
58 | }
59 | });
60 |
61 | if (app.settings.env === 'production') {
62 | app.error(function(err, req, res) {
63 | res.render('500.ejs', {
64 | status: 500,
65 | locals: {
66 | error: err
67 | }
68 | });
69 | });
70 | }
71 |
72 | app.get('/', function(req, res) {
73 | res.render('index.ejs');
74 | });
75 |
76 | app.get('/webgl', function(req, res) {
77 | res.render('webgl.ejs');
78 | });
79 |
80 | var commands = {
81 | setLed: function(cmd) {
82 | var option = parseInt(cmd.option, 10);
83 | if (isNaN(option)) {
84 | color = 5; // BLINK GREEN
85 | }
86 | return kinect.setLed(option);
87 | },
88 |
89 | setTiltAngle: function(cmd) {
90 | var angle = parseFloat(cmd.angle);
91 | if (isNaN(angle)) {
92 | return false;
93 | }
94 | return kinect.setTiltAngle(angle);
95 | },
96 |
97 | stop: function(cmd) {
98 | kinect.stop();
99 | return true;
100 | },
101 |
102 | getDepth: function(cmd) {
103 | var buffer = kinect.getScaledDepthBuffer(80,60);
104 | d = Array.prototype.slice.call(buffer,0);
105 | // console.log('Buffer:', d);
106 | return {
107 | data: d
108 | };
109 | },
110 |
111 | getVideo: function(cmd) {
112 | var buffer = kinect.getVideo();
113 | return {
114 | data: buffer
115 | };
116 | }
117 |
118 | };
119 |
120 | app.listen(port);
121 | console.log('Express server listening on port %d, environment: %s', port, app.settings.env);
122 | console.log('Using connect %s, Express %s, EJS %s', connect.version, express.version, ejs.version);
123 |
124 | socket = io.listen(app);
125 |
126 | /*
127 | app.configure('production',function(){
128 | socket.set('transports', [
129 | 'websocket'
130 | //,flashsocket'
131 | //,'htmlfile'
132 | //,'xhr-polling'
133 | //,'jsonp-polling'
134 | ]);
135 | });
136 | */
137 |
138 | socket.on('connection', function(client) {
139 | console.log('Connected from');
140 | console.log(client);
141 |
142 | client.on('message', function(message) {
143 | var command = JSON.parse(message),
144 | ret = {};
145 |
146 | // console.log(command);
147 | if (commands.hasOwnProperty(command.type)) {
148 | ret.type = command.type;
149 | ret.result = commands[command.type](command);
150 | client.send(JSON.stringify(ret));
151 | } else {
152 | ret.type = command.type;
153 | ret.result = 'Invalid command.';
154 | client.send(JSON.stringify(ret));
155 | }
156 | });
157 |
158 | client.on('disconnect', function() {
159 | console.log('Disconnect %s', client);
160 | });
161 | });
162 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/webgl.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | var depthCanvas = document.getElementById('depthbuffer'),
4 | depthContext = depthCanvas.getContext('2d'),
5 | depthImage = depthContext.createImageData(80, 60),
6 | depthSize = depthCanvas.width * depthCanvas.height,
7 |
8 | screenCanvas = document.getElementById('screen'),
9 | screenContext = screenCanvas.getContext('2d'),
10 | screenImage = screenContext.createImageData(400, 300),
11 | screenSize = screenCanvas.width * screenCanvas.height;
12 |
13 | Kinect.connect();
14 |
15 | var last_frametime = 0;
16 | var last_fps = 0;
17 |
18 | var getDepthFrame = function() {
19 |
20 | Kinect.getDepth(function(data) {
21 | // console.log(data);
22 |
23 | var offset = 0,
24 | length = data.length,
25 | pixels = depthImage.data,
26 | i, color;
27 |
28 | offset = 0;
29 | for (i = 0; i < length; ++i) {
30 | color = data[i];
31 | if (color < 5) color = 255;
32 | pixels[offset ] = color;
33 | pixels[offset+1] = color;
34 | pixels[offset+2] = color;
35 | pixels[offset+3] = 255;
36 | offset += 4;
37 | }
38 | depthContext.putImageData(depthImage, 0, 0);
39 | screenContext.drawImage(depthCanvas, 0,0,depthCanvas.width,depthCanvas.height,0,0,screenCanvas.width,screenCanvas.height);
40 | updateBlockZ();
41 |
42 | var t = (new Date()).getTime();
43 | if (last_frametime == 0)
44 | last_frametime = t;
45 |
46 | var dt = t - last_frametime;
47 | if( dt >0 ){
48 | var cfps = 1000.0 / dt;
49 |
50 | last_fps *= 0.5;
51 | last_fps += cfps*0.5;
52 | }
53 |
54 | $('#debug').text('avg. fps: '+Math.round(last_fps,3));
55 |
56 | last_frametime = t;
57 |
58 | getDepthFrame();
59 | });
60 | };
61 |
62 |
63 |
64 |
65 |
66 |
67 | var container, stats;
68 | var camera, scene, projector, renderer;
69 | var objects = [], plane;
70 |
71 | var delta = 0.01;
72 |
73 |
74 | var gridwidth = 38;
75 | var gridheight = 24;
76 | var gridlength = gridwidth * gridheight;
77 |
78 | var objectspacing = 40;
79 |
80 | var mouse = new THREE.Vector2(),
81 | offset = new THREE.Vector3(),
82 | INTERSECTED,
83 | SELECTED;
84 |
85 | var halfWidth, halfHeight;
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | function init() {
101 |
102 | var halfWidth = window.innerWidth / 2;
103 | var halfHeight = window.innerHeight / 2;
104 |
105 | container = document.getElementById('webgl');
106 |
107 | scene = new THREE.Scene();
108 |
109 | camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
110 | camera.position.z = 1000;
111 | camera.position.x = 0;
112 | scene.add( camera );
113 |
114 | scene.add( new THREE.AmbientLight( 0x505050 ) );
115 |
116 | var light = new THREE.SpotLight( 0xffffff, 1 );
117 | light.position.set( -1000, 800, 2500 );
118 | light.castShadow = true;
119 | light.shadowCameraNear = 200;
120 | light.shadowCameraFar = camera.far;
121 | light.shadowCameraFov = 50;
122 | light.shadowBias = -0.00022;
123 | light.shadowDarkness = 0.8;
124 | light.shadowMapWidth = 512;
125 | light.shadowMapHeight = 512;
126 |
127 | scene.add( light );
128 |
129 | var geometry = new THREE.CubeGeometry( objectspacing*0.8, objectspacing*0.8, 800 );
130 |
131 | for ( var i = 0; i < gridlength; i ++ ) {
132 |
133 | // var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );
134 | var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0xffffff } ) );
135 |
136 | object.material.ambient = object.material.color;
137 |
138 | var row = Math.floor( i / gridwidth );
139 | var col = Math.floor( i % gridwidth );
140 |
141 | object.position.x = -objectspacing * (col - (gridwidth-1)/2);
142 | object.position.y = -objectspacing * (row - (gridheight-1)/2);
143 | object.position.z = 0;
144 |
145 | object.rotation.x = 0;// ( Math.random() * 360 ) * Math.PI / 180;
146 | object.rotation.y = 0;// ( Math.random() * 360 ) * Math.PI / 180;
147 | object.rotation.z = 0;// ( Math.random() * 360 ) * Math.PI / 180;
148 |
149 | object.castShadow = true;
150 | object.receiveShadow = true;
151 |
152 | scene.add( object );
153 |
154 | objects.push( object );
155 |
156 | }
157 |
158 | // plane = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.25, transparent: true, wireframe: true } ) );
159 | // plane.lookAt( camera.position );
160 | // plane.visible = false;
161 | // scene.add( plane );
162 |
163 | projector = new THREE.Projector();
164 |
165 | renderer = new THREE.WebGLRenderer( { antialias: false } );
166 | renderer.sortObjects = false;
167 | renderer.setSize( window.innerWidth, window.innerHeight );
168 | renderer.shadowMapEnabled = true;
169 | renderer.shadowMapSoft = false;
170 |
171 | var shaderVignette = THREE.ShaderExtras[ "vignette" ];
172 | var effectVignette = new THREE.ShaderPass( shaderVignette );
173 | effectVignette.uniforms[ "offset" ].value = 0.95;
174 | effectVignette.uniforms[ "darkness" ].value = 1.6;
175 |
176 | var effectHBlur = new THREE.ShaderPass( THREE.ShaderExtras[ "horizontalBlur" ] );
177 | var effectVBlur = new THREE.ShaderPass( THREE.ShaderExtras[ "verticalBlur" ] );
178 | effectHBlur.uniforms[ 'h' ].value = 2 / ( window.innerWidth/2 );
179 | effectVBlur.uniforms[ 'v' ].value = 2 / ( window.innerHeight/2 );
180 |
181 | var effectDotScreen = new THREE.DotScreenPass( new THREE.Vector2( 0, 0 ), 0.1, 0.8 );
182 |
183 | var rtWidth = window.innerWidth;
184 | var rtHeight = window.innerHeight;
185 | rtParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: true };
186 |
187 | var renderModel = new THREE.RenderPass( scene, camera );
188 | composer1 = new THREE.EffectComposer( renderer, new THREE.WebGLRenderTarget( rtWidth, rtHeight, rtParameters ) );
189 | composer1.addPass( renderModel );
190 | composer1.addPass( effectVignette );
191 | composer1.addPass( effectDotScreen );
192 | effectDotScreen.renderToScreen = true;
193 | // effectVignette.renderToScreen = true;
194 | // renderModel.renderToScreen = true;
195 |
196 | container.appendChild( renderer.domElement );
197 |
198 | // stats = new Stats();
199 | // stats.domElement.style.position = 'absolute';
200 | // stats.domElement.style.top = '0px';
201 | // container.appendChild( stats.domElement );
202 | }
203 |
204 | function animate() {
205 | requestAnimationFrame( animate );
206 | render();
207 | // stats.update();
208 | }
209 |
210 | function updateBlockZ() {
211 | // renderer.render( delta );
212 |
213 | var pixels = depthImage.data;
214 | for ( var i = 0; i < gridlength; i ++ ) {
215 |
216 | var row = Math.floor( i / gridwidth );
217 | var col = Math.floor( i % gridwidth );
218 |
219 | var object = objects[i];
220 |
221 | var px = Math.round(col * depthImage.width / gridwidth);
222 | var py = Math.round(row * depthImage.height / gridheight);
223 |
224 | var pixel = pixels[(py*depthImage.width+px)*4];
225 | if( pixel == 0 )
226 | pixel = 255;
227 |
228 | object.position.z = -((pixel-128)*5) - 400;
229 |
230 | // object.rotation.x += delta;
231 | // object.rotation.y += delta*(i+50)/100;
232 | // object.rotation.z += delta*i/100;
233 | }
234 | }
235 |
236 | function render() {
237 | renderer.clear();
238 | composer1.render( delta );
239 |
240 |
241 | }
242 |
243 |
244 |
245 |
246 | setTimeout(function(){
247 | getDepthFrame();
248 | init();
249 | animate();
250 | }, 500);
251 |
252 |
253 | });
254 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
--------------------------------------------------------------------------------
/src/node_freenect.cc:
--------------------------------------------------------------------------------
1 | /**
2 | * Node.js addon for libfreenect.
3 | */
4 |
5 | //-------------------------------------------------------------------------
6 | // Includes
7 | //-------------------------------------------------------------------------
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include
18 |
19 | //-------------------------------------------------------------------------
20 | // Defines
21 | //-------------------------------------------------------------------------
22 | // Taken from node-usb
23 | #define V8STR(str) v8::String::New(str)
24 | #define THROW_BAD_ARGS(FAIL_MSG) return v8::ThrowException(v8::Exception::TypeError(V8STR(FAIL_MSG)));
25 | #define THROW_ERROR(FAIL_MSG) return v8::ThrowException(v8::Exception::Error(V8STR(FAIL_MSG))));
26 | #define THROW_NOT_YET return v8::ThrowException(v8::Exception::Error(v8::String::Concat(v8::String::New(__FUNCTION__), v8::String::New("not yet supported"))));
27 |
28 | #define MAX_TILT_DEGS (31.0)
29 | #define MIN_TILT_DEGS (-31.0)
30 | #define INVALID_TILT_DEGS (-99.0)
31 |
32 | //-------------------------------------------------------------------------
33 | // libfreenect wrapper for Node.js
34 | //-------------------------------------------------------------------------
35 | class Freenect : node::ObjectWrap
36 | {
37 | public:
38 |
39 | Freenect()
40 | : deviceIndex(0), videoFormat(FREENECT_VIDEO_RGB), depthFormat(FREENECT_DEPTH_11BIT)
41 | {
42 | videoBuffer = malloc(freenect_find_video_mode(FREENECT_RESOLUTION_LOW, FREENECT_VIDEO_RGB).bytes);
43 | depthBuffer = malloc(freenect_find_depth_mode(FREENECT_RESOLUTION_LOW, FREENECT_DEPTH_11BIT).bytes);
44 | tiltState = new freenect_raw_tilt_state();
45 | tiltAngle = GetTiltAngle();
46 | }
47 |
48 | virtual ~Freenect()
49 | {
50 | free(videoBuffer);
51 | free(depthBuffer);
52 | freenect_sync_stop();
53 | }
54 |
55 | /**
56 | * Set LED option.
57 | *
58 | * @param option LED option to set.
59 | * @return True if set tilt angle success.
60 | */
61 | bool SetLed(freenect_led_options option)
62 | {
63 | int ret = freenect_sync_set_led(option, deviceIndex);
64 | if (ret < 0) {
65 | printf("Could set LED %d\n", option);
66 | return false;
67 | }
68 | ledOption = option;
69 | return true;
70 | }
71 |
72 | /**
73 | * Set tilt angle.
74 | *
75 | * @param angle Tilt angle toset. Range [-30.0..30.0]
76 | * @return True if set tilt angle success.
77 | */
78 | bool SetTiltAngle(double angle)
79 | {
80 | double deg = angle;
81 | if (deg <= MIN_TILT_DEGS) {
82 | deg = MIN_TILT_DEGS;
83 | }
84 | if (deg >= MAX_TILT_DEGS) {
85 | deg = MAX_TILT_DEGS;
86 | }
87 |
88 | int ret = freenect_sync_set_tilt_degs(deg, deviceIndex);
89 | if (ret < 0) {
90 | printf("Could set tilt degs %f\n", deg);
91 | return false;
92 | }
93 | tiltAngle = deg;
94 | return true;
95 | }
96 |
97 | /**
98 | * Get video or IR buffer from kinect.
99 | *
100 | * @return Video buffer or NULL on error.
101 | */
102 | void* GetVideo()
103 | {
104 | uint32_t timestamp;
105 | int ret = freenect_sync_get_video(&videoBuffer, ×tamp, deviceIndex, videoFormat);
106 | if (ret != 0) {
107 | printf("Could not get video\n");
108 | return NULL;
109 | }
110 | return videoBuffer;
111 | }
112 |
113 | /**
114 | * Get depth buffer from kinect.
115 | *
116 | * @return Depth buffer or NULL on error.
117 | */
118 | void* GetDepth()
119 | {
120 | uint32_t timestamp;
121 | int ret = freenect_sync_get_depth(&depthBuffer, ×tamp, deviceIndex, depthFormat);
122 | if (ret != 0) {
123 | printf("Could not get depth\n");
124 | return NULL;
125 | }
126 | return depthBuffer;
127 | }
128 |
129 | /**
130 | * Get tilt angle of kinect.
131 | *
132 | * @return Depth buffer data
133 | */
134 | double GetTiltAngle()
135 | {
136 | int ret = freenect_sync_get_tilt_state(&tiltState, deviceIndex);
137 | if (ret != 0) {
138 | printf("Could not get tilt angle\n");
139 | return INVALID_TILT_DEGS;
140 | }
141 | double angle = freenect_get_tilt_degs(tiltState);
142 | return angle;
143 | }
144 |
145 | /**
146 | * Stop conecting to kinect device.
147 | */
148 | void Stop()
149 | {
150 | freenect_sync_stop();
151 | }
152 |
153 | //------------------------------------------------------------------------
154 |
155 | //------------------------------------------------------------------------
156 | // Export functions.
157 | //------------------------------------------------------------------------
158 |
159 | /**
160 | * Constructor for Node.js.
161 | *
162 | * @param args Constructor arguments passed from Node.js
163 | * @return Freenect component for Node.js
164 | */
165 | static v8::Handle New(const v8::Arguments& args)
166 | {
167 | v8::HandleScope scope;
168 |
169 | Freenect* freenect = new Freenect();
170 | freenect->Wrap(args.This());
171 | freenect->Ref();
172 | return args.This();
173 | }
174 |
175 | /**
176 | * Set LED options.
177 | *
178 | * @param args Arguments list.
179 | * @return {Boolean} true if args is valid options.
180 | */
181 | static v8::Handle SetLed(const v8::Arguments& args)
182 | {
183 | v8::HandleScope scope;
184 |
185 | if (args.Length() != 1) {
186 | THROW_BAD_ARGS("SetLed must have 1 argument.")
187 | }
188 |
189 | v8::Local ledOption = args[0];
190 | if (!ledOption->IsInt32()) {
191 | THROW_BAD_ARGS("SetLed must have 1 int argument.")
192 | }
193 |
194 | int n = ledOption->Int32Value();
195 | if (n < LED_OFF) {
196 | n = LED_OFF;
197 | }
198 | if (n > LED_BLINK_RED_YELLOW) {
199 | n = LED_BLINK_RED_YELLOW;
200 | }
201 |
202 | Freenect* freenect = getThis(args);
203 | bool ret = freenect->SetLed(static_cast(n));
204 | return v8::Boolean::New(ret);
205 | }
206 |
207 | /**
208 | * Set tilt angle of kinect.
209 | *
210 | * @param args Arguments list.
211 | * @return {Boolean} true if args is valid options.
212 | */
213 | static v8::Handle SetTiltAngle(const v8::Arguments& args)
214 | {
215 | v8::HandleScope scope;
216 |
217 | if (args.Length() != 1) {
218 | THROW_BAD_ARGS("SetTiltAngle must have 1 argument.")
219 | }
220 |
221 | v8::Local angle = args[0];
222 | if (!angle->IsNumber()) {
223 | THROW_BAD_ARGS("SetTiltAngle must have 1 number argument.")
224 | }
225 |
226 | double a = angle->NumberValue();
227 |
228 | Freenect* freenect = getThis(args);
229 | bool ret = freenect->SetTiltAngle(a);
230 | return v8::Boolean::New(ret);
231 | }
232 |
233 | /**
234 | * Get RBG image of kinect.
235 | *
236 | * @param args Arguments list.
237 | * @return {Array.} RGB pixel data
238 | */
239 | static v8::Handle GetVideo(const v8::Arguments& args)
240 | {
241 | v8::HandleScope scope;
242 |
243 | Freenect* freenect = getThis(args);
244 | unsigned char* buf = static_cast(freenect->GetVideo());
245 | int length = freenect_find_video_mode(FREENECT_RESOLUTION_LOW, FREENECT_VIDEO_RGB).bytes;
246 | v8::Local array = v8::Array::New(length);
247 | /*
248 | for (int i = 0; i < length; i+=16) {
249 | array->Set(i , v8::Uint32::New(buf[i ]));
250 | array->Set(i+1 , v8::Uint32::New(buf[i+ 1]));
251 | array->Set(i+2 , v8::Uint32::New(buf[i+ 2]));
252 | array->Set(i+3 , v8::Uint32::New(buf[i+ 3]));
253 | array->Set(i+4 , v8::Uint32::New(buf[i+ 4]));
254 | array->Set(i+5 , v8::Uint32::New(buf[i+ 5]));
255 | array->Set(i+6 , v8::Uint32::New(buf[i+ 6]));
256 | array->Set(i+7 , v8::Uint32::New(buf[i+ 7]));
257 | array->Set(i+8 , v8::Uint32::New(buf[i+ 8]));
258 | array->Set(i+9 , v8::Uint32::New(buf[i+ 9]));
259 | array->Set(i+10, v8::Uint32::New(buf[i+10]));
260 | array->Set(i+11, v8::Uint32::New(buf[i+11]));
261 | array->Set(i+12, v8::Uint32::New(buf[i+12]));
262 | array->Set(i+13, v8::Uint32::New(buf[i+13]));
263 | array->Set(i+14, v8::Uint32::New(buf[i+14]));
264 | array->Set(i+15, v8::Uint32::New(buf[i+15]));
265 | }
266 | */
267 | return array;
268 | }
269 |
270 | /**
271 | * Get video buffer of kinect.
272 | *
273 | * @param args Arguments list.
274 | * @return {Buffer} Video buffer data (RGB)
275 | */
276 | static v8::Handle GetVideoBuffer(const v8::Arguments& args)
277 | {
278 | v8::HandleScope scope;
279 |
280 | Freenect* freenect = getThis(args);
281 | char* buf = static_cast(freenect->GetVideo());
282 | node::Buffer* retbuf = node::Buffer::New(buf, freenect_find_video_mode(FREENECT_RESOLUTION_LOW, FREENECT_VIDEO_RGB).bytes);
283 | return retbuf->handle_;
284 | }
285 |
286 | /**
287 | * Get depth buffer of kinect.
288 | *
289 | * @param args Arguments list.
290 | * @return {Array.} Depth buffer data
291 | */
292 | static v8::Handle GetDepth(const v8::Arguments& args)
293 | {
294 | v8::HandleScope scope;
295 |
296 | Freenect* freenect = getThis(args);
297 | uint16_t* buf = static_cast(freenect->GetDepth());
298 | int length = 640*480;
299 | v8::Local array = v8::Array::New(length);
300 | for (int i = 0; i < length; i+=16) {
301 | array->Set(i , v8::Uint32::New(buf[i ]));
302 | array->Set(i+1 , v8::Uint32::New(buf[i+ 1]));
303 | array->Set(i+2 , v8::Uint32::New(buf[i+ 2]));
304 | array->Set(i+3 , v8::Uint32::New(buf[i+ 3]));
305 | array->Set(i+4 , v8::Uint32::New(buf[i+ 4]));
306 | array->Set(i+5 , v8::Uint32::New(buf[i+ 5]));
307 | array->Set(i+6 , v8::Uint32::New(buf[i+ 6]));
308 | array->Set(i+7 , v8::Uint32::New(buf[i+ 7]));
309 | array->Set(i+8 , v8::Uint32::New(buf[i+ 8]));
310 | array->Set(i+9 , v8::Uint32::New(buf[i+ 9]));
311 | array->Set(i+10, v8::Uint32::New(buf[i+10]));
312 | array->Set(i+11, v8::Uint32::New(buf[i+11]));
313 | array->Set(i+12, v8::Uint32::New(buf[i+12]));
314 | array->Set(i+13, v8::Uint32::New(buf[i+13]));
315 | array->Set(i+14, v8::Uint32::New(buf[i+14]));
316 | array->Set(i+15, v8::Uint32::New(buf[i+15]));
317 | }
318 | return array;
319 | }
320 |
321 | /**
322 | * Get depth buffer of kinect.
323 | *
324 | * @param args Arguments list.
325 | * @return {Buffer} Depth buffer data
326 | */
327 | static v8::Handle GetDepthBuffer(const v8::Arguments& args)
328 | {
329 | printf("entering getdepth\n");
330 | v8::HandleScope scope;
331 | Freenect* freenect = getThis(args);
332 | uint16_t* buf = static_cast(freenect->GetDepth());
333 | freenect_frame_mode mode = freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_11BIT);
334 | int length = mode.width * mode.height;
335 | printf("valid:%d, width:%d, height:%d, length:%d\n", mode.is_valid, mode.width, mode.height, length);
336 | if(!mode.is_valid)
337 | return v8::Boolean::New(false);
338 | char *buf2 = (char *)malloc(length);//[640*480] = { 0,1,2,3,4,5 };
339 | printf("ptr buf=0x%08X, buf2=0x%08X\n", (unsigned long)buf, (unsigned long)buf2);
340 | for (int i = 0; i < length; i++) {
341 | buf2[i] = rand()&255;//buf[i] >> 2;
342 | }
343 | node::Buffer* retbuf = node::Buffer::New(buf2, length);
344 | free(buf2);
345 | printf("leaving getdepth\n");
346 | return retbuf->handle_;
347 | }
348 |
349 | /**
350 | * Get scaled depth buffer of kinect.
351 | *
352 | * @param args Arguments list.
353 | * @return {Buffer} Depth buffer data
354 | */
355 | static v8::Handle GetScaledDepthBuffer(const v8::Arguments& args)
356 | {
357 |
358 | if (args.Length() != 2) {
359 | THROW_BAD_ARGS("GetScaledDepthBuffer must have 2 arguments.")
360 | }
361 |
362 | v8::Local w_param = args[0];
363 | v8::Local h_param = args[1];
364 | if (!w_param->IsNumber() && !h_param->IsNumber()) {
365 | THROW_BAD_ARGS("SetTiltAngle must have 2 number argument.")
366 | }
367 |
368 | int outputwidth = (int)w_param->NumberValue();
369 | int outputheight = (int)h_param->NumberValue();
370 |
371 | v8::HandleScope scope;
372 | Freenect* freenect = getThis(args);
373 | uint16_t* buf = static_cast(freenect->GetDepth());
374 | freenect_frame_mode mode = freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_11BIT);
375 | int length = mode.width * mode.height;
376 | int outputlength = outputwidth * outputheight;
377 | printf("valid:%d, width:%d (%d), height:%d (%d), length:%d\n", mode.is_valid, mode.width, outputwidth, mode.height, outputheight, length);
378 | char *buf2 = (char *)malloc(length);//[640*480] = { 0,1,2,3,4,5 };
379 | char *buf3 = (char *)malloc(outputlength);//[640*480] = { 0,1,2,3,4,5 };
380 | printf("ptr buf=0x%08X, buf2=0x%08X\n", (unsigned long)buf, (unsigned long)buf2);
381 |
382 | // scale to bytes
383 | for (int i = 0; i < length; i++) {
384 | buf2[i] = buf[i] >> 2;
385 | }
386 |
387 | // ugly downscaler
388 |
389 | int oo = 0;
390 | int istride = mode.width;
391 | for(int j=0; jhandle_;
405 | }
406 |
407 | /**
408 | * Get tilt angle of kinect.
409 | *
410 | * @param args Arguments list.
411 | * @return {Number} Depth buffer data
412 | */
413 | static v8::Handle GetTiltAngle(const v8::Arguments& args)
414 | {
415 | v8::HandleScope scope;
416 |
417 | Freenect* freenect = getThis(args);
418 | double angle = freenect->GetTiltAngle();
419 | return v8::Number::New(angle);
420 | }
421 |
422 | /**
423 | * Stop connecting to kinect.
424 | *
425 | * @param args Arguments list.
426 | * @return {undefined}
427 | */
428 | static v8::Handle Stop(const v8::Arguments& args)
429 | {
430 | v8::HandleScope scope;
431 |
432 | Freenect* freenect = getThis(args);
433 | freenect->Stop();
434 | return v8::Undefined();
435 | }
436 |
437 | private:
438 | int deviceIndex;
439 | double tiltAngle;
440 |
441 | freenect_led_options ledOption;
442 | freenect_raw_tilt_state* tiltState;
443 | freenect_video_format videoFormat;
444 | freenect_depth_format depthFormat;
445 |
446 | void* videoBuffer;
447 | void* depthBuffer;
448 |
449 | /**
450 | * Get this pointer from v8::Arguments.
451 | */
452 | static Freenect* getThis(const v8::Arguments& args)
453 | {
454 | Freenect* freenect = ObjectWrap::Unwrap(args.This());
455 | return freenect;
456 | }
457 |
458 | };
459 |
460 | //-------------------------------------------------------------------------
461 | // Node.js addon interfaces
462 | //-------------------------------------------------------------------------
463 |
464 | extern "C" void init(v8::Handle target)
465 | {
466 | v8::HandleScope scope;
467 |
468 | v8::Local t = v8::FunctionTemplate::New(Freenect::New);
469 | t->InstanceTemplate()->SetInternalFieldCount(1);
470 | NODE_SET_PROTOTYPE_METHOD(t, "setLed", Freenect::SetLed);
471 | NODE_SET_PROTOTYPE_METHOD(t, "setTiltAngle", Freenect::SetTiltAngle);
472 | NODE_SET_PROTOTYPE_METHOD(t, "getTiltAngle", Freenect::GetTiltAngle);
473 | NODE_SET_PROTOTYPE_METHOD(t, "getVideo", Freenect::GetVideo);
474 | NODE_SET_PROTOTYPE_METHOD(t, "getVideoBuffer", Freenect::GetVideoBuffer);
475 | NODE_SET_PROTOTYPE_METHOD(t, "getDepth", Freenect::GetDepth);
476 | NODE_SET_PROTOTYPE_METHOD(t, "getDepthBuffer", Freenect::GetDepthBuffer);
477 | NODE_SET_PROTOTYPE_METHOD(t, "getScaledDepthBuffer", Freenect::GetScaledDepthBuffer);
478 | NODE_SET_PROTOTYPE_METHOD(t, "stop", Freenect::Stop);
479 | target->Set(v8::String::New("Kinect"), t->GetFunction());
480 | }
481 |
482 |
483 |
484 |
--------------------------------------------------------------------------------
/example/simpleviewer/public/javascripts/socket.io.js:
--------------------------------------------------------------------------------
1 | /* Socket.IO.min 0.6.2 @author Guillermo Rauch , @license The MIT license., @copyright Copyright (c) 2010 LearnBoost */
2 | var io=this.io={version:"0.6.2",setPath:function(a){window.console&&console.error&&console.error("io.setPath will be removed. Please set the variable WEB_SOCKET_SWF_LOCATION pointing to WebSocketMain.swf"),this.path=/\/$/.test(a)?a:a+"/",WEB_SOCKET_SWF_LOCATION=a+"lib/vendor/web-socket-js/WebSocketMain.swf"}};"jQuery"in this&&(jQuery.io=this.io),typeof window!="undefined"&&typeof WEB_SOCKET_SWF_LOCATION=="undefined"&&(WEB_SOCKET_SWF_LOCATION="/socket.io/lib/vendor/web-socket-js/WebSocketMain.swf"),function(){var a=this.io,b=!1;a.util={ios:!1,load:function(a){if(/loaded|complete/.test(document.readyState)||b)return a();"attachEvent"in window?window.attachEvent("onload",a):window.addEventListener("load",a,!1)},inherit:function(a,b){for(var c in b.prototype)a.prototype[c]=b.prototype[c]},indexOf:function(a,b,c){for(var d=a.length,e=c<0?Math.max(0,d+c):c||0;e