diff --git a/bower.json b/bower.json index 5c10c69..ce6893c 100755 --- a/bower.json +++ b/bower.json @@ -23,7 +23,6 @@ "tests" ], "dependencies": { - "underscore-min": "http://underscorejs.org/underscore-min.js", "jquery-2.1.4.min": "http://code.jquery.com/jquery-2.1.4.min.js", "leap-0.6.4.min": "http://js.leapmotion.com/leap-0.6.4.min.js", "leap-plugins-0.1.10.min": "http://js.leapmotion.com/leap-plugins-0.1.10.min.js", diff --git a/gulpfile.js b/gulpfile.js index a6f8c9f..ac415df 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -17,7 +17,6 @@ gulp.task('vendor', function() { gulp.task('main', function() { gulp.src([ 'js/leap-extras.js', - 'js/threejs-position.js', 'js/marionette-drawer.js', 'js/app.js' ]) @@ -27,14 +26,10 @@ gulp.task('main', function() { .pipe(gulp.dest('dist/js')); }); -gulp.task('model', function() { - gulp.src(['models/*.json']) - .pipe(gulp.dest('dist/models')); -}); - -gulp.task('img', function() { - gulp.src(['images/*.png']) - .pipe(gulp.dest('dist/images')); +gulp.task('cp', function() { + gulp.src(['models/*.json']).pipe(gulp.dest('dist/models')); + gulp.src(['images/*.png']).pipe(gulp.dest('dist/images')); + gulp.src(['sounds/*.mp3']).pipe(gulp.dest('dist/sounds')); }); gulp.task('css', function() { @@ -56,4 +51,4 @@ gulp.task('replace', function() { gulp.task('js', ['vendor', 'main']); -gulp.task('default', ['js', 'css', 'replace', 'model', 'img']); \ No newline at end of file +gulp.task('default', ['js', 'css', 'replace', 'cp']); \ No newline at end of file diff --git a/index.html b/index.html index 9e95f31..ee18a52 100755 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - + Marionette Wireless @@ -24,7 +24,6 @@ - diff --git a/js/app.js b/js/app.js index ab6e52c..2e15623 100755 --- a/js/app.js +++ b/js/app.js @@ -1,29 +1,48 @@ var drawer; +function rotateRadian(radian){ + if (radian < 0) { + return radian - Math.PI; + } else { + return radian + Math.PI; + } +} + function moveObject(hand) { - if (hand && (hand.timeVisible > .25) && (hand.confidence > .7)) { - var pitch = hand.pitchDegree(), - roll = hand.rollDegree(), - yaw = hand.yawDegree(), - p = hand.get3JsScreenPosition(); + if (hand && (hand.timeVisible > 0.25) && (hand.confidence > 0.7)) { + var pitch = hand.pitch(), + roll = hand.roll() * -1, + yaw = hand.yaw() * -1, + p = { + x: hand.stabilizedPalmPosition[0], + y: hand.stabilizedPalmPosition[1], + z: hand.stabilizedPalmPosition[2] + }; drawer.moveObject(hand.type, p.x, p.y, p.z); - drawer.rotateObject(hand.type, pitch * -1, yaw, roll); + drawer.rotateObject(hand.type, pitch, rotateRadian(yaw), roll); } } $(document).ready(function () { drawer = new MarionetteDrawer(); - drawer.init(document.getElementById('container')); - drawer.addScenario(); + drawer.setup(); + drawer.setupStats(); + drawer.setBackground(); drawer.animate(); var controller = new Leap.Controller(); - controller.use('screenPosition') + controller.use('screenPosition', { + scale: 0.25 + }) .use('handEntry') - .use('threejsPosition') - .use('leapExtras'); + .use('leapExtras') + .use('boneHand', { + scene: drawer.scene, + targetEl: document.body, + arm: false + }); controller.on('frame', function (frame) { moveObject(frame.getLeftHand()); @@ -31,15 +50,14 @@ $(document).ready(function () { }); controller.on('handFound', function (hand) { + var p = hand.screenPosition(); if (hand.type === 'left') { - drawer.addHorse(hand.type); + drawer.addHorse(hand.type, p.x, p.y, p.z); } else if (hand.type == 'right') { - drawer.addFlamingo(hand.type); + drawer.addFlamingo(hand.type, p.x, p.y, p.z); } else { drawer.addCube(hand.type); } - - drawer.moveObject(hand.type); }); controller.on('handLost', function (hand) { diff --git a/js/leap-extras.js b/js/leap-extras.js index d6442d4..7a67baa 100644 --- a/js/leap-extras.js +++ b/js/leap-extras.js @@ -1,52 +1,14 @@ Leap.Controller.plugin('leapExtras', function() { - function radians2degrees(radians) { - return radians * (180 / Math.PI); - } - return { frame: { - getHandsCount: function () { - return this.hands.length; - }, - - getFingersCount: function () { - return _.reduce(this.hands, function (memo, hand) { - return memo + hand.fingers.length; - }, 0); - }, - - getExtendedFingersCount: function () { - return _.reduce(this.hands, function (memo, hand) { - return memo + _.filter(hand.fingers, function (finger) { return finger.extended }).length; - }, 0); - }, - getLeftHand: function () { - return _.findWhere(this.hands, { type: 'left' }); + return $.grep(this.hands, function (hand){ return hand.type === 'left'; })[0]; }, getRightHand: function () { - return _.findWhere(this.hands, { type: 'right' }); + return $.grep(this.hands, function (hand){ return hand.type === 'right' })[0]; }, - - getFrameRate: function () { - return this.currentFrameRate; - } - }, - - hand: { - pitchDegree: function () { - return radians2degrees(this.pitch()); - }, - - rollDegree: function () { - return radians2degrees(this.roll()); - }, - - yawDegree: function () { - return radians2degrees(this.yaw()); - } } }; }); diff --git a/js/marionette-drawer.js b/js/marionette-drawer.js index 5e20390..3da286f 100755 --- a/js/marionette-drawer.js +++ b/js/marionette-drawer.js @@ -1,89 +1,147 @@ function MarionetteDrawer() { - this.init = init; - this.addCube = addCube; - this.animate = animate; - this.moveObject = moveObject; - this.rotateObject = rotateObject; - this.addHorse = addHorse; - this.stop = stop; - this.play = play; - this.addFlamingo = addFlamingo; - this.addScenario = addScenario; - this.removeObject = removeObject; - - var container, scene, camera, renderer, stats, objects, animations; - var SCREEN_WIDTH; - var SCREEN_HEIGHT; - var clock = new THREE.Clock(); - var prevTime = Date.now(); - var stopped = false; - - function init(containerElement) { - - container = containerElement; - objects = {}; - animations = {}; - - /* CENA */ - scene = new THREE.Scene(); - - /* CAMERA */ - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - // atributos da câmera - var VIEW_ANGLE = 75, - ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, - NEAR = 0.1, - FAR = 1000; - - // setup camera - camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); - - // adiciona a camera à cena + var objects = {}, + animations = {}, + stopped = false, + prevTime = Date.now(), + clock = new THREE.Clock() + _self = this; + + function morphColorsToFaceColors(geometry) { + if (geometry.morphColors && geometry.morphColors.length) { + var colorMap = geometry.morphColors[0]; + + for (var i = 0; i < colorMap.colors.length; i++) { + geometry.faces[i].color = colorMap.colors[i]; + geometry.faces[i].color.offsetHSL(0, 0.3, 0); + } + } + } + + function render() { + if (animations) { + if (!stopped) { + var time = Date.now(); + + for (var obj in animations) { + if (animations[obj].update) { + animations[obj].update(time - prevTime); + } else { + animations[obj].updateAnimation(time - prevTime); + } + } + + prevTime = time; + } + } + + _self.renderer.autoClear = false; + _self.renderer.clear(); + + _self.renderer.setViewport(0, 0, window.innerWidth, window.innerHeight); + _self.renderer.render(_self.backgroundScene, _self.backgroundCamera); + _self.renderer.render(_self.scene, _self.camera); + } + + this.setup = function () { + var scene = new THREE.Scene(), + renderer = new THREE.WebGLRenderer({ + alpha: true, + antialias: true + }); + + renderer.setClearColor(0x000000, 0); + renderer.setSize(window.innerWidth, window.innerHeight); + + renderer.domElement.style.position = 'fixed'; + renderer.domElement.style.top = 0; + renderer.domElement.style.left = 0; + renderer.domElement.style.width = '100%'; + renderer.domElement.style.height = '100%'; + + document.body.appendChild(renderer.domElement); + + var directionalLight = new THREE.DirectionalLight(0xffffff, 1); + directionalLight.position.set(0, 0.5, 1); + scene.add(directionalLight); + + var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); + + /*camera.position.fromArray([0, 100, 500]); + camera.lookAt(new THREE.Vector3(0, 160, 0));*/ + + camera.position.set(0, 300, 500); + camera.lookAt(new THREE.Vector3(0, 160, 0)); + + listener = new THREE.AudioListener(); + camera.add(listener); + + window.addEventListener('resize', function() { + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.render(scene, camera); + }, false); + scene.add(camera); - camera.position.y = 0; - camera.position.x = 0; - camera.position.z = 400; - camera.target = new THREE.Vector3(0, 150, 0); - camera.lookAt(scene.position); + /*var light1 = new THREE.DirectionalLight(0xefefff, 2); + light1.position.set(1, 1, 1).normalize(); + scene.add(light1); + + var light2 = new THREE.DirectionalLight(0xffefef, 2); + light2.position.set(-1, -1, -1).normalize(); + scene.add(light2);*/ - /* RENDERIZADOR */ + this.scene = scene; + this.renderer = renderer; + this.camera = camera; + }; + + this.setBackground = function (img) { + if (typeof img === 'undefined') { + img = 'images/country.png'; + } - // cria e inicializa o renderizador. - renderer = new THREE.WebGLRenderer({ - antialias: true + var material = new THREE.MeshLambertMaterial({ + map: THREE.ImageUtils.loadTexture(img) }); - renderer.setClearColor(0xf0f0f0); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); + var geometry = new THREE.PlaneBufferGeometry(window.innerWidth, window.innerHeight); + var backgroundMesh = new THREE.Mesh(geometry, material); - container.appendChild(renderer.domElement); + backgroundMesh.material.depthTest = false; + backgroundMesh.material.depthWrite = false; - /* LUZ */ - var light = new THREE.DirectionalLight(0xefefff, 2); - light.position.set(1, 1, 1).normalize(); - scene.add(light); + var backgroundScene = new THREE.Scene(); + //backgroundCamera = new THREE.Camera(); - var light = new THREE.DirectionalLight(0xffefef, 2); - light.position.set(-1, -1, -1).normalize(); - scene.add(light); + /*var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 ); + directionalLight.position.set( 0, 0.5, 1 ); + backgroundScene.add(directionalLight);*/ - initStats(); + var light1 = new THREE.DirectionalLight(0xefefff, 2); + light1.position.set(1, 1, 1).normalize(); + backgroundScene.add(light1); - window.addEventListener('resize', onWindowResize, false); - } + var light2 = new THREE.DirectionalLight(0xffefef, 2); + light2.position.set(-1, -1, -1).normalize(); + backgroundScene.add(light2); - function removeObject(id) { - if (id in objects) { - var obj = objects[id]; - scene.remove(obj); - } - } + var backgroundCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500); + backgroundCamera.position.set(0, 300, 300); + backgroundCamera.lookAt(new THREE.Vector3(0, 160, 0)); + // var backgroundCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); + // backgroundCamera.position.set(0, 300, 500); + // backgroundCamera.lookAt(new THREE.Vector3(0, 160, 0)); + + backgroundScene.add(backgroundCamera); + backgroundScene.add(backgroundMesh); - function addCube(id) { + this.backgroundCamera = backgroundCamera; + this.backgroundScene = backgroundScene; + }; + + this.addCube = function (id) { // Create an array of materials to be used in a cube, one for each side var cubeMaterialArray = []; // order to add materials: x+,x-,y+,y-,z+,z- @@ -105,34 +163,20 @@ function MarionetteDrawer() { cubeMaterialArray.push(new THREE.MeshBasicMaterial({ color: 0x8833ff })); + var cubeMaterials = new THREE.MeshFaceMaterial(cubeMaterialArray); var cubeGeometry = new THREE.CubeGeometry(100, 100, 100, 1, 1, 1); + cube = new THREE.Mesh(cubeGeometry, cubeMaterials); cube.position.set(0, 0, 0); - scene.add(cube); + _self.scene.add(cube); objects[id] = cube; - } - - function addScenario() { - var texture = new THREE.ImageUtils.loadTexture('images/country.png'); - var material = new THREE.MeshBasicMaterial({ - map: texture, - side: THREE.DoubleSide - }); + }; - //var material = new THREE.MeshBasicMaterial( { color: 0x99D9EA, side: THREE.DoubleSide } ); - - var geometry = new THREE.PlaneGeometry(SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2, 10, 10); - var scenario = new THREE.Mesh(geometry, material); - - scenario.position.z = -400; - scene.add(scenario); - } - - function addHorse(id) { + this.addHorse = function (id, x, y, z) { var loader = new THREE.JSONLoader(true); - loader.load("models//horse.json", function(geometry) { + loader.load("models/horse.json", function(geometry) { var horse = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: 0x606060, @@ -140,7 +184,26 @@ function MarionetteDrawer() { })); horse.scale.set(0.8, 0.8, 0.8); - scene.add(horse); + + if (x) { + horse.position.setX(x); + } + + if (y) { + horse.position.setY(y); + } + + if (z) { + horse.position.setZ(z); + } + + var sound = new THREE.Audio(listener); + sound.load('sounds/horse.mp3'); + sound.setRefDistance(20); + sound.autoplay = true; + + horse.add(sound); + _self.scene.add(horse); objects[id] = horse; @@ -148,12 +211,11 @@ function MarionetteDrawer() { animation.play(); animations[id] = animation; }); - } - + }; - function addFlamingo(id) { + this.addFlamingo = function (id, x, y, z) { var loader = new THREE.JSONLoader(); - loader.load("models/flamingo.json", function(geometry) { + loader.load("models/flamingo.json ", function(geometry) { morphColorsToFaceColors(geometry); geometry.computeMorphNormals(); @@ -166,114 +228,77 @@ function MarionetteDrawer() { shading: THREE.FlatShading }); - var meshAnim = new THREE.MorphAnimMesh(geometry, material); + var flamingo = new THREE.MorphAnimMesh(geometry, material); - meshAnim.duration = 5000; - meshAnim.scale.set(1.0, 1.0, 1.0); - meshAnim.position.y = 200; + flamingo.duration = 5000; + flamingo.scale.set(1.0, 1.0, 1.0); - scene.add(meshAnim); - objects[id] = meshAnim; - animations[id] = meshAnim; - - meshAnim.position.setY(240); - }); - } + if (x) { + flamingo.position.setX(x); + } - function morphColorsToFaceColors(geometry) { - if (geometry.morphColors && geometry.morphColors.length) { - var colorMap = geometry.morphColors[0]; + if (y) { + flamingo.position.setY(y); + } - for (var i = 0; i < colorMap.colors.length; i++) { - geometry.faces[i].color = colorMap.colors[i]; - geometry.faces[i].color.offsetHSL(0, 0.3, 0); + if (z) { + flamingo.position.setZ(z); } - } - } + var sound = new THREE.Audio(listener); + sound.load('sounds/flamingo.mp3'); + sound.setRefDistance(20); + sound.autoplay = true; - function moveObject(id, x, y, z) { - if (id in objects) { - var obj = objects[id]; + flamingo.add(sound); - obj.position.setX(x); - obj.position.setY(y); - obj.position.setZ(z); - } - } + _self.scene.add(flamingo); - function moveLeftHand(id, x, y, z) { - if (id in objects) { - var obj = objects[id]; - //TODO - } - } + objects[id] = flamingo; - function moveRightHand(id, x, y, z) { - if (id in objects) { - var obj = objects[id]; - //TODO - } + animations[id] = flamingo; + }); } - function moveLeftLeg(id, x, y, z) { + this.removeObject = function (id) { if (id in objects) { var obj = objects[id]; - //TODO + _self.scene.remove(obj); } - } + }; - function moveRightLeg(id, x, y, z) { + this.moveObject = function (id, x, y, z) { if (id in objects) { var obj = objects[id]; - //TODO + obj.position.setX(x); + obj.position.setY(y - obj.geometry.boundingSphere.radius); + obj.position.setZ(z); } - } + }; - function rotateObject(id, angleX, angleY, angleZ) { + this.rotateObject = function (id, angleX, angleY, angleZ) { if (id in objects) { var obj = objects[id]; - obj.rotation.x = toRadian(angleX); - obj.rotation.y = toRadian(angleY); - obj.rotation.z = toRadian(angleZ); + obj.rotation.x = angleX; + obj.rotation.y = angleY; + obj.rotation.z = angleZ; } - } - - function toRadian(angle) { - return angle * Math.PI / 180; - } + }; - function animate() { - requestAnimationFrame(animate); + this.animate = function () { + requestAnimationFrame(_self.animate); render(); - stats.update(); - } - - function render() { - if (animations) { - if (!stopped) { - var time = Date.now(); - for (obj in animations) { - if (animations[obj].update) { - animations[obj].update(time - prevTime); - } else { - animations[obj].updateAnimation(time - prevTime); - } - }; - - prevTime = time; - } + if (_self.stats) { + _self.stats.update(); } + }; - renderer.clear(); + this.setupStats = function () { + var stats = new Stats(); - renderer.setViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.render(scene, camera); - } + this.stats = stats; - function initStats() { - stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left @@ -281,26 +306,15 @@ function MarionetteDrawer() { stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; - container.appendChild(stats.domElement); + //container.appendChild(stats.domElement); + document.body.appendChild(stats.domElement); + }; - return stats; - } - - function onWindowResize(event) { - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - - camera.aspect = 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT; - camera.updateProjectionMatrix(); - } - - function stop() { + this.stop = function () { stopped = true; - } + }; - function play() { + this.play = function () { stopped = false; - } -} \ No newline at end of file + }; +} diff --git a/js/threejs-position.js b/js/threejs-position.js deleted file mode 100644 index 5c18b79..0000000 --- a/js/threejs-position.js +++ /dev/null @@ -1,66 +0,0 @@ -Leap.Controller.plugin('threejsPosition', function() { - var convert, handPosition; - - /* - Convert LeapJS space to ThreeJS space. - - @param value: x or y axis. - @param base: screen width (x) or height (y) size. - @param d: scale factor to increase leap motion area (default: 2). - - @return the new space position. - */ - convert = function(value, base, d) { - var oldMax = base, - oldMin = 0, - newMax = base / (d || 2), - newMin = base / -(d || 2); - - var oldRange = (oldMax - oldMin), - newRange = (newMax - newMin); - - return (((value - oldMin) * newRange) / oldRange) + newMin; - }; - - convertDegree = function(value) { - var oldMax = 180, - oldMin = -80, - newMax = 360, - newMin = 0; - - var oldRange = (oldMax - oldMin), - newRange = (newMax - newMin); - - return (((value - oldMin) * newRange) / oldRange) + newMin; - }; - - handPosition = function(x, y, z) { - this.x = x; // X axis. - this.y = y; // Y axis. - this.z = z; // Z axis. - }; - - return { - hand: { - get3JsScreenPosition: function () { - var p = this.screenPosition(), - w = window.innerWidth, - h = window.innerHeight; - - var x = convert(p[0], w, 5), - y = convert(p[1] * -1, h), - z = p[2]; - - return new handPosition(x, y, z); - }, - - get3JsPitchDegree: function () { - return convertDegree(this.pitchDegree()); - }, - - get3JsRollDegree: function () { - return convertDegree(this.rollDegree()); - } - } - }; -}); diff --git a/sounds/flamingo.mp3 b/sounds/flamingo.mp3 new file mode 100644 index 0000000..492dc05 Binary files /dev/null and b/sounds/flamingo.mp3 differ diff --git a/sounds/horse.mp3 b/sounds/horse.mp3 new file mode 100644 index 0000000..919aedd Binary files /dev/null and b/sounds/horse.mp3 differ