Implemented orbit controls (closes #14 & #15)

0.1
Robin Hawkes 2014-02-13 19:22:43 +00:00
rodzic e603f69717
commit c415da3040
5 zmienionych plików z 156 dodań i 15 usunięć

Wyświetl plik

@ -51,6 +51,7 @@ module.exports = function(grunt) {
'src/client/data/DataOverpass.js',
'src/client/Grid.js',
'src/client/controls/Mouse.js',
'src/client/controls/Keyboard.js',
'src/client/controls/Controls.js'
],
dest: 'build/vizi.js'

Wyświetl plik

@ -9,18 +9,22 @@
_.extend(this, VIZI.Mediator);
this.mouse = undefined;
this.keyboard = undefined;
};
Controls.prototype.init = function(camera) {
this.mouse = VIZI.Mouse.getInstance(camera);
this.keyboard = VIZI.Keyboard.getInstance();
this.subscribe("update", this.onUpdate);
this.subscribe("orbitControlCap", this.orbitCapReset);
return Q.fcall(function() {});
};
Controls.prototype.onUpdate = function() {
var mouseState = this.mouse.state;
var keyboardState = this.keyboard.state;
// Zoom
if (mouseState.wheelDelta !== 0) {
@ -28,14 +32,23 @@
}
// Pan
if (mouseState.buttons.left) {
if (mouseState.buttons.left && !keyboardState.keys.leftShift) {
this.publish("panControl", mouseState.pos3dDelta);
}
// Orbit
if (mouseState.buttons.left && keyboardState.keys.leftShift) {
this.publish("orbitControl", mouseState.downPos2dDelta, mouseState.camera.startTheta, mouseState.camera.startPhi);
}
// Zero deltas
this.mouse.resetDelta();
};
Controls.prototype.orbitCapReset = function() {
this.mouse.updateCamera();
};
var instance;
// an emulation of static variables and methods

Wyświetl plik

@ -0,0 +1,83 @@
/* globals window, _, VIZI */
(function() {
"use strict";
VIZI.Keyboard = (function() {
var Keyboard = function() {
VIZI.Log("Inititialising mouse manager");
_.extend(this, VIZI.Mediator);
this.state = {
keys: {}
};
this.initDOMEvents();
};
Keyboard.prototype.initDOMEvents = function() {
var self = this;
document.addEventListener("keydown", function(event) {
self.onKeyDown(event);
}, false);
document.addEventListener("keyup", function(event) {
self.onKeyUp(event);
}, false);
};
Keyboard.prototype.onKeyDown = function(event) {
var key = this.keyCodeToString(event.keyCode);
if (!key) {
return;
}
this.state.keys[key] = true;
};
Keyboard.prototype.onKeyUp = function(event) {
var key = this.keyCodeToString(event.keyCode);
if (!key) {
return;
}
this.state.keys[key] = false;
};
Keyboard.prototype.keyCodeToString = function(keyCode) {
var key;
switch (keyCode) {
case 16:
key = "leftShift";
break;
default:
key = false;
}
return key;
};
var instance;
// an emulation of static variables and methods
var _static = {
name: "VIZI.Keyboard",
// Method for getting an instance. It returns
// a singleton instance of a singleton object
getInstance: function() {
if ( instance === undefined ) {
instance = new Keyboard();
}
return instance;
}
};
return _static;
}());
}());

Wyświetl plik

@ -20,14 +20,15 @@
},
pos2d: new THREE.Vector2(),
downPos2d: new THREE.Vector2(),
downPos2dDelta: new THREE.Vector2(),
pos3d: new THREE.Vector3(),
downPos3d: new THREE.Vector3(),
pos2dDelta: new THREE.Vector2(),
pos3dDelta: new THREE.Vector3(),
wheelDelta: 0,
camera: {
downTheta: this.camera.theta,
downPhi: this.camera.phi
startTheta: this.camera.theta,
startPhi: this.camera.phi
}
};
@ -77,6 +78,9 @@
state.downPos2d.x = event.clientX;
state.downPos2d.y = event.clientY;
state.pos2dDelta.x = 0;
state.pos2dDelta.y = 0;
var pos3d = this.mouseIn3d(state.downPos2d);
state.pos3d.x = pos3d.x;
@ -87,8 +91,12 @@
state.downPos3d.y = pos3d.y;
state.downPos3d.z = pos3d.z;
state.camera.downTheta = this.camera.theta;
state.camera.downPhi = this.camera.phi;
state.pos3dDelta.x = 0;
state.pos3dDelta.y = 0;
state.pos3dDelta.z = 0;
state.camera.startTheta = this.camera.theta;
state.camera.startPhi = this.camera.phi;
};
Mouse.prototype.onMouseMove = function(event) {
@ -104,13 +112,18 @@
var pos3d = this.mouseIn3d(state.pos2d);
state.pos3dDelta.x = state.downPos3d.x - pos3d.x;
state.pos3dDelta.y = state.downPos3d.y - pos3d.y;
state.pos3dDelta.z = state.downPos3d.z - pos3d.z;
state.pos3d.x = pos3d.x;
state.pos3d.y = pos3d.y;
state.pos3d.z = pos3d.z;
if (state.buttons.left) {
state.downPos2dDelta.x = event.clientX - state.downPos2d.x;
state.downPos2dDelta.y = event.clientY - state.downPos2d.y;
state.pos3dDelta.x = state.downPos3d.x - pos3d.x;
state.pos3dDelta.y = state.downPos3d.y - pos3d.y;
state.pos3dDelta.z = state.downPos3d.z - pos3d.z;
}
};
Mouse.prototype.onMouseUp = function(event) {
@ -130,7 +143,9 @@
state.buttons.right = false;
}
// TODO: Reset mouse down positions?
// Reset mouse down positions and deltas
state.downPos2dDelta.x = 0;
state.downPos2dDelta.y = 0;
};
Mouse.prototype.onMouseWheel = function(event) {
@ -174,6 +189,20 @@
return pos;
};
// TODO: Tidy this up
Mouse.prototype.updateCamera = function() {
var state = this.state;
state.downPos2d.x = state.pos2d.x;
state.downPos2d.y = state.pos2d.y;
state.downPos2dDelta.x = 0;
state.downPos2dDelta.y = 0;
state.camera.startTheta = this.camera.theta;
state.camera.startPhi = this.camera.phi;
};
var instance;
// an emulation of static variables and methods

Wyświetl plik

@ -23,6 +23,7 @@
this.subscribe("resize", this.resize);
this.subscribe("zoomControl", this.zoom);
this.subscribe("panControl", this.pan);
this.subscribe("orbitControl", this.orbit);
};
VIZI.Camera.prototype.createCamera = function() {
@ -83,11 +84,6 @@
};
VIZI.Camera.prototype.pan = function(delta3d) {
// TODO: Remove if it looks like this isn't breaking anything
// this.camera.position.x += delta3d.x;
// this.camera.position.z += delta3d.z;
// this.camera.updateMatrix();
this.target.position.x += delta3d.x;
this.target.position.z += delta3d.z;
@ -106,6 +102,25 @@
this.publish("render");
};
VIZI.Camera.prototype.orbit = function(delta2d, theta, phi) {
// Round delta to next highest pixel to prevent jerkiness
this.theta = - ( delta2d.x * 0.5 ) + theta;
this.phi = ( delta2d.y * 0.5 ) + phi;
// Cap orbit to bounds
this.phi = Math.min( 175, Math.max( 65, this.phi ) );
// Let controls know that the cap has been hit
if (this.phi === 175 || this.phi === 65) {
this.publish("orbitControlCap");
}
this.updatePosition();
this.lookAtTarget();
this.publish("render");
};
VIZI.Camera.prototype.datChange = function() {
this.updatePosition();
this.lookAtTarget();