From 93549bc434f09c9aa043ed3b6f1107db4d9ff9d4 Mon Sep 17 00:00:00 2001 From: Thomas FORGIONE Date: Wed, 8 Apr 2015 11:36:15 +0200 Subject: [PATCH] Added fluid movement from camera to recommendation --- js/CameraContainer.js | 3 +- js/PointerCamera.js | 115 +++++++++++++++++++++++++++--------------- js/Tools.js | 8 +++ scene/js/main.js | 66 ++++++++++++------------ 4 files changed, 117 insertions(+), 75 deletions(-) diff --git a/js/CameraContainer.js b/js/CameraContainer.js index 5bb1600..7da76c9 100644 --- a/js/CameraContainer.js +++ b/js/CameraContainer.js @@ -39,11 +39,10 @@ CameraContainer.prototype.getById = function(id) { for (var i in this.cameras) { if (this.cameras[i].mesh !== undefined) { if (this.cameras[i].mesh.id == id) { - return i; + return this.get(i); } } } - return -1; } CameraContainer.prototype.setById = function(id) { diff --git a/js/PointerCamera.js b/js/PointerCamera.js index 023463d..cf1eb16 100644 --- a/js/PointerCamera.js +++ b/js/PointerCamera.js @@ -7,11 +7,11 @@ var PointerCamera = function() { this.phi = Math.PI; // this.keyboard = undefined; + this.moving = false; this.dragging = false; - this.mouse = {x: 0, y: 0}; - this.move = {x: 0, y: 0}; + this.mouseMove = {x: 0, y: 0}; // Stuff for rendering @@ -49,48 +49,83 @@ PointerCamera.prototype.constructor = PointerCamera; // Update function PointerCamera.prototype.update = function() { - // Update angles - if (this.increasePhi) this.phi += this.sensitivity; - if (this.decreasePhi) this.phi -= this.sensitivity; - if (this.increaseTheta) this.theta += this.sensitivity; - if (this.decreaseTheta) this.theta -= this.sensitivity; + if (this.moving) { + var position_direction = Tools.diff(this.new_position, this.position); + var target_direction = Tools.diff(this.new_target, this.target); - if (this.dragging) { - this.theta += this.move.x; - this.phi -= this.move.y; + this.position.add(Tools.mul(position_direction, 0.05)); + this.target.add(Tools.mul(target_direction, 0.05)); - this.move.x = 0; - this.move.y = 0; + if (Tools.norm2(Tools.diff(this.position, this.new_position)) < 1 && + Tools.norm2(Tools.diff(this.target, this.new_target)) < 1){ + // this.position = this.new_position.clone(); + // this.target = this.new_target.clone(); + this.moving = false; + + // Update phi and theta so that return to reality does not hurt + var forward = Tools.diff(this.new_target, this.new_position); + forward.normalize(); + + this.phi = Math.asin(forward.z); + + // Don't know why this line works... + this.theta = Math.atan(forward.y / forward.x) + Math.PI; + + } + + } else { + // Update angles + if (this.increasePhi) this.phi += this.sensitivity; + if (this.decreasePhi) this.phi -= this.sensitivity; + if (this.increaseTheta) this.theta += this.sensitivity; + if (this.decreaseTheta) this.theta -= this.sensitivity; + + if (this.dragging) { + this.theta += this.mouseMove.x; + this.phi -= this.mouseMove.y; + + this.mouseMove.x = 0; + this.mouseMove.y = 0; + } + + // Clamp phi and theta + this.phi = Math.min(Math.max(-(Math.PI/2-0.1),this.phi), Math.PI/2-0.1); + this.theta = ((this.theta - Math.PI) % (2*Math.PI)) + Math.PI; + + var delta = 0.1; + + // Update direction + this.forward.z = Math.sin(this.phi); + + var cos = Math.cos(this.phi); + this.forward.x = cos * Math.cos(this.theta); + this.forward.y = cos * Math.sin(this.theta); + this.forward.normalize(); + + // Update + var forward = this.forward.clone(); + forward.multiplyScalar(400.0 * delta); + var left = this.up.clone(); + left.cross(forward); + left.normalize(); + left.multiplyScalar(400.0 * delta); + + if (this.moveForward) this.position.add(Tools.mul(forward, this.speed)); + if (this.moveBackward) this.position.sub(Tools.mul(forward, this.speed)); + if (this.moveLeft) this.position.add(Tools.mul(left, this.speed)); + if (this.moveRight) this.position.sub(Tools.mul(left, this.speed)); + + this.target = this.position.clone(); + this.target.add(forward); } - // Clamp phi - this.phi = Math.min(Math.max(-(Math.PI/2-0.1),this.phi), Math.PI/2-0.1); - var delta = 0.1; +} - // Update direction - this.forward.z = Math.sin(this.phi); - - var cos = Math.cos(this.phi); - this.forward.x = cos * Math.cos(this.theta); - this.forward.y = cos * Math.sin(this.theta); - this.forward.normalize(); - - // Update - var forward = this.forward.clone(); - forward.multiplyScalar(400.0 * delta); - var left = this.up.clone(); - left.cross(forward); - left.normalize(); - left.multiplyScalar(400.0 * delta); - - if (this.moveForward) this.position.add(Tools.mul(forward, this.speed)); - if (this.moveBackward) this.position.sub(Tools.mul(forward, this.speed)); - if (this.moveLeft) this.position.add(Tools.mul(left, this.speed)); - if (this.moveRight) this.position.sub(Tools.mul(left, this.speed)); - - this.target = this.position.clone(); - this.target.add(forward); +PointerCamera.prototype.move = function(otherCamera) { + this.moving = true; + this.new_target = otherCamera.target.clone(); + this.new_position = otherCamera.position.clone(); } // Look function @@ -144,8 +179,8 @@ PointerCamera.prototype.onMouseMove = function(event) { this.mouse.x = ( ( event.clientX - renderer.domElement.offsetLeft ) / renderer.domElement.width ) * 2 - 1; this.mouse.y = - ( ( event.clientY - renderer.domElement.offsetTop ) / renderer.domElement.height ) * 2 + 1; - this.move.x = this.mouse.x - mouse.x; - this.move.y = this.mouse.y - mouse.y; + this.mouseMove.x = this.mouse.x - mouse.x; + this.mouseMove.y = this.mouse.y - mouse.y; } } diff --git a/js/Tools.js b/js/Tools.js index cc992c3..8fb8732 100644 --- a/js/Tools.js +++ b/js/Tools.js @@ -31,3 +31,11 @@ Tools.mul = function(v1, lambda) { Tools.equals = function(v1, v2) { return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z; } + +Tools.norm2 = function(v) { + return v.x * v.x + v.y * v.y + v.z * v.z; +} + +Tools.norm = function(v) { + return Math.sqrt(Tools.norm2(v)); +} diff --git a/scene/js/main.js b/scene/js/main.js index e0bace3..99693ee 100644 --- a/scene/js/main.js +++ b/scene/js/main.js @@ -177,47 +177,47 @@ function show(object) { } function click(event) { - if (cameras.mainCamera() == cameras.get(0)) { - var mouse = { - x: ((event.clientX - renderer.domElement.offsetLeft) / renderer.domElement.width ) * 2 - 1, - y: - ((event.clientY - renderer.domElement.offsetTop) / renderer.domElement.height) * 2 + 1 - } + var mouse = { + x: ((event.clientX - renderer.domElement.offsetLeft) / renderer.domElement.width ) * 2 - 1, + y: - ((event.clientY - renderer.domElement.offsetTop) / renderer.domElement.height) * 2 + 1 + } - var camera = cameras.mainCamera(); - var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5); - vector.unproject(camera); + var camera = cameras.mainCamera(); + var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5); + vector.unproject(camera); - raycaster.set(camera.position, vector.sub(camera.position).normalize()); + raycaster.set(camera.position, vector.sub(camera.position).normalize()); - var intersects = raycaster.intersectObjects(scene.children, true); + var intersects = raycaster.intersectObjects(scene.children, true); - if ( intersects.length > 0 ) { - var minDistance; - var bestIndex; + if ( intersects.length > 0 ) { + var minDistance; + var bestIndex; - // Looking for cameras - for (i in intersects) { - if (minDistance === undefined || intersects[i].distance < minDistance) { - // We will not consider a line as clickable - if (! (intersects[i].object instanceof THREE.Line)) { - minDistance = intersects[i].distance; - bestIndex = i; - } - } - } - if (bestIndex !== undefined) { - cameras.setById(intersects[bestIndex].object.id); - } - - // Looking for objects - for (o in objects) { - if ( intersects[bestIndex].object.id == objects[o].id) { - cameras.mainCamera(objects[o].seen_by[0]); + // Looking for cameras + for (i in intersects) { + if (minDistance === undefined || intersects[i].distance < minDistance) { + // We will not consider a line as clickable + if (! (intersects[i].object instanceof THREE.Line)) { + minDistance = intersects[i].distance; + bestIndex = i; } } } - } else { - cameras.mainCamera(0); + + if (bestIndex !== undefined) { + if (cameras.getById(intersects[bestIndex].object.id) !== undefined) { + cameras.get(0).move(cameras.getById(intersects[bestIndex].object.id)); + } + } + + // Looking for objects + for (o in objects) { + if ( intersects[bestIndex].object.id == objects[o].id) { + cameras.get(0).move(cameras.get(objects[o].seen_by[0])); + break; + } + } } // var pos = cameras.mainCamera().position;