A hell of a lot cleaning

This commit is contained in:
Thomas FORGIONE
2015-07-01 15:03:11 +02:00
parent bb938e5342
commit 86f2094af6
45 changed files with 56 additions and 193 deletions
+169
View File
@@ -0,0 +1,169 @@
var CameraSelecter = function(renderer, scene, cameras, coins, buttonManager) {
this.raycaster = new THREE.Raycaster();
this.renderer = renderer;
this.mouse = {};
this.cameras = cameras;
this.prev = {};
this.buttonManager = buttonManager;
this.scene = scene;
this.coins = coins;
};
CameraSelecter.prototype.pointedCamera = function() {
var returnCamera;
var x = ( this.mouse.x / this.renderer.domElement.width ) * 2 - 1;
var y = - (this.mouse.y / this.renderer.domElement.height) * 2 + 1;
var camera = this.cameras.mainCamera();
if (camera.pointerLocked) {
this.mouse.x = this.renderer.domElement.width/2 ;
this.mouse.y = this.renderer.domElement.height/2 ;
x = 0;
y = 0;
}
var vector = new THREE.Vector3(x, y, 0.5);
vector.unproject(camera);
this.raycaster.set(camera.position, vector.sub(camera.position).normalize());
var intersects = this.raycaster.intersectObjects(this.scene.children, true);
if ( intersects.length > 0 ) {
var minDistance;
var bestIndex;
// Looking for cameras
for (var i in intersects) {
if (intersects[i].object.raycastable && !(intersects[i].object instanceof THREE.Line)) {
if ((intersects[i].distance > 0.5 && minDistance === undefined) || (intersects[i].distance < minDistance )) {
if (!(intersects[i].object instanceof THREE.Mesh && intersects[i].object.material.opacity < 0.1)) {
minDistance = intersects[i].distance;
bestIndex = i;
}
}
}
}
if (bestIndex !== undefined) {
// if (this.cameras.getById(intersects[bestIndex].object.parent.id) !== undefined) {
var obj = intersects[bestIndex].object;
for (var coin in this.coins) {
if (obj === this.coins[coin].mesh) {
return this.coins[coin];
}
}
this.currentPointedCamera = this.cameras.getByObject(intersects[bestIndex].object);
return this.currentPointedCamera;
// }
}
}
this.currentPointedCamera = null;
};
CameraSelecter.prototype.update = function(event, y) {
var e;
if (event !== undefined) {
this.mouse.x = event.offsetX === undefined ? event.layerX : event.offsetX;
this.mouse.y = event.offsetY === undefined ? event.layerY : event.offsetY;
}
if (y !== undefined) {
this.mouse.x = this.renderer.domElement.width/2;
this.mouse.y = this.renderer.domElement.height/2;
}
var previousCamera = this.currentPointedCamera;
var hovered = this.pointedCamera();
if (hovered !== undefined && !(hovered instanceof Coin)) {
if (hovered !== previousCamera) {
// log it
e = new BD.Event.Hovered();
e.start = true;
e.arrow_id = this.cameras.cameras.indexOf(this.currentPointedCamera);
e.send();
this.prev.x = this.mouse.x;
this.prev.y = this.mouse.y;
}
this.prev.camera = hovered;
this.prev.go = true;
} else {
if (this.prev.go) {
// Log if previous was not null
e = new BD.Event.Hovered();
e.start = false;
e.arrow_id = null;
e.send();
}
this.prev.go = false;
}
document.getElementById('container').style.cursor = hovered ? "pointer" : "auto";
if (this.cameras.mainCamera().pointerLocked)
this.cameras.mainCamera().mousePointer.render(hovered ? MousePointer.RED : MousePointer.BLACK);
};
CameraSelecter.prototype.click = function(event) {
var e;
var newCamera = this.pointedCamera();
if (newCamera !== undefined && !(newCamera instanceof Coin)) {
e = new BD.Event.ArrowClicked();
e.arrow_id = this.cameras.cameras.indexOf(newCamera);
e.send();
newCamera.check();
this.cameras.mainCamera().moveHermite(newCamera);
buttonManager.updateElements();
} else if (newCamera instanceof Coin) {
// Coin found, notify server
e = new BD.Event.CoinClicked();
e.coin_id = this.coins.indexOf(newCamera);
e.send();
newCamera.get();
}
};
CameraSelecter.prototype.clickPointer = function(event) {
var e;
if (this.cameras.mainCamera().pointerLocked) {
var newCamera = this.pointedCamera();
if (newCamera !== undefined && !(newCamera instanceof Coin)) {
e = new BD.Event.ArrowClicked();
e.arrow_id = this.cameras.cameras.indexOf(newCamera);
e.send();
newCamera.check();
this.cameras.mainCamera().moveHermite(newCamera);
buttonManager.updateElements();
} else if (newCamera instanceof Coin) {
// Coin found, notify server
e = new BD.Event.CoinClicked();
e.coin_id = this.coins.indexOf(newCamera);
e.send();
newCamera.get();
}
}
};
+77
View File
@@ -0,0 +1,77 @@
/**
* Represents the history of an object
* @constructor
*/
var History = function() {
/**
* Stores the different states of the object
* @type {Object[]}
*/
this.states = [];
/**
* Represents the position in the history we're at
* @type {Number}
*/
this.index = -1;
/**
* Represents the number of elements in the history
* @type {Number}
*/
this.size = 0;
};
/**
* Appends a new state at the end of the history
* @param {Object} state the state to append
*/
History.prototype.addState = function(state) {
++this.index;
this.size = this.index + 1;
this.states[this.size-1] = state;
};
/**
* Returns the previous state and change the index to the previous state (so you can redo)
*/
History.prototype.undo = function() {
if (this.undoable()) {
this.index--;
return this.currentState();
}
};
/**
* Returns the next state and change the index to the next state (so you can re-undo)
*/
History.prototype.redo = function() {
if (this.redoable()) {
this.index++;
return this.currentState();
}
};
/**
* Checks if there is a undo possibility
* @returns {Boolean} true if undo is possible, false otherwise
*/
History.prototype.undoable = function() {
return this.index > 0;
};
/**
* Checks if there is a redo possibility
* @returns {Boolean} true if redo is possible, false otherwise
*/
History.prototype.redoable = function() {
return this.index < this.size - 1;
};
/**
* Returns the current state in the history
* @returns {Object} the current state in the history
*/
History.prototype.currentState = function() {
return this.states[this.index];
};
+242
View File
@@ -0,0 +1,242 @@
var utils = (function() {
var utils = {};
// Defines a double linked-list class
utils.List = function() {
this._size = 0;
this._begin = null;
this._end = null;
};
// Returns the number of element of a list
utils.List.prototype.size = function() {
return this._size;
};
// Pushes an element to the end of a class
utils.List.prototype.push = function(element) {
if (this._size === 0) {
this._begin = { data : element, next: null, prev: null };
this._end = this._begin;
this._size = 1;
} else {
var newObject = { data: element, next: null, prev: this._end };
this._end.next = newObject;
this._end = newObject;
this._size++;
}
};
// Sort the list
utils.List.prototype.sort = function(comparator) {
if (comparator === undefined) {
comparator = priv.defaultComparator;
}
var array = [];
this.forEach(function(elt) {
array.push(elt);
});
array.sort(function(a, b) {
return comparator(a, b);
});
var size = this.size();
this.clear();
for (var i = 0; i < size; i++) {
this.push(array[i]);
}
};
// Remove last element and returns it
utils.List.prototype.pop = function() {
var tmp = this._end;
this._end = null;
return tmp.data;
};
// Apply a function to each element of the list
utils.List.prototype.forEach = function(callback) {
var chain = this._begin;
while (chain !== null) {
callback(chain.data);
chain = chain.next;
}
};
// Apply a function to each element of the list (starting from the end)
utils.List.prototype.forEachInverse = function(callback) {
var chain = this._end;
while (chain !== null) {
callback(chain.data);
chain = chain.prev;
}
};
// Get ith element of the list
utils.List.prototype.at = function(ith) {
if (ith < 0 || ith >= this.size()) {
return null;
}
var chain = this._begin;
for (var i = 0; i < ith; i++) {
chain = chain.next;
}
return chain.data;
};
// Clear the list
utils.List.prototype.clear = function() {
this._begin = null;
this._end = null;
this._size = 0;
};
// Insert an element at the right place in the list
// Precondition : list must be sorted
utils.List.prototype.insertSorted = function(elt, comparator) {
var newElement;
if (comparator === undefined) {
comparator = priv.defaultComparator;
}
if (this._begin === null) {
// Inserted in front (empty list)
this.push(elt);
} else if (comparator(this._begin.data, elt) > 0) {
// Inserted in front (smallest element)
newElement = {prev: null, next: this._begin, data: elt};
this._begin.prev = newElement;
this._begin = newElement;
this._size ++;
} else if (comparator(this._end.data, elt) < 0) {
// Inserted in end
this.push(elt);
} else {
// Inserted in the middle
var chain = this._begin;
while (chain.next !== null) {
// If chain < elt < chain.next
if (comparator(chain.next.data, elt) > 0) {
newElement = {data: elt, next: chain.next, prev: chain};
if (chain.next) {
chain.next.prev = newElement;
}
chain.next = newElement;
this._size ++;
return;
}
// Next step
chain = chain.next;
}
}
};
// Check if a list is sorted of not
utils.List.prototype.isSorted = function(comparator) {
var chain = this._begin;
if (comparator === undefined) {
comparator = priv.defaultComparator;
}
while (chain.next !== null) {
if (comparator(chain.data, chain.next.data) > 0) {
return false;
}
chain = chain.next;
}
return true;
};
// Gives an iterator to the begin of the list
utils.List.prototype.begin = function() {
return new utils.List.Iterator(this._begin, 0);
};
// Gives an iterator to the end of the list
utils.List.prototype.end = function() {
return new utils.List.Iterator(this._end, this.size() - 1);
};
// Class iterator
utils.List.Iterator = function(chain, counter) {
this._chain = chain;
this._counter = counter;
};
// Go to the next element
utils.List.Iterator.prototype.next = function() {
this._chain = this._chain.next;
this._counter ++;
};
// Go to the previous element
utils.List.Iterator.prototype.prev = function() {
this._chain = this._chain.prev;
this._counter --;
};
// Return the current element
utils.List.Iterator.prototype.get = function() {
return this._chain.data;
};
// Check if there is another element next
utils.List.Iterator.prototype.hasNext = function() {
return this._chain.next !== null;
};
// Check if there is another element before
utils.List.Iterator.prototype.hasPrev = function() {
return this._chain.prev !== null;
};
// Compares to another iterator of the same list
utils.List.Iterator.prototype.lowerThan = function(it2) {
return utils.distance(this, it2) > 0;
};
// Compares to another iterator of the same list
utils.List.Iterator.prototype.greaterThan = function(it2) {
return utils.distance(this, it2) < 0;
};
// Returns the distance between two iterators of the same list
utils.distance = function(it1, it2) {
return it2._counter - it1._counter;
};
priv = {};
priv.defaultComparator = function(a,b) {
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
};
// Support for NodeJs
if (typeof module !== 'undefined' && module.exports) {
module.exports = utils;
} else {
return utils;
}
})();
+17
View File
@@ -0,0 +1,17 @@
var list = new utils.List();
var size = 100;
for (var i = 0; i < size; i++) {
list.push(Math.random());
}
// For with C++-style iterator
// for (var it = list.begin(); it.lowerThan(list.end()); it.next()) {
// console.log(it.get());
// }
console.log(false === list.isSorted());
list.sort();
console.log(list.isSorted());
console.log(size === list.size());
+116
View File
@@ -0,0 +1,116 @@
var BD = {};
BD.Private = {};
BD.Private.sendData = function(url, data) {
if (BD.Private.enabled) {
// Append time to data
data.time = Date.now() / 1000;
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/json;charset=UTF-8");
// xhr.onreadystatechange = function() {
// if(xhr.readyState == 4 && xhr.status == 200) {
// console.log("Done : " + xhr.responseText);
// }
// }
xhr.send(JSON.stringify(data));
}
};
BD.Private.enabled = true;
BD.enable = function() {
BD.Private.enabled = true;
};
BD.disable = function() {
BD.Private.enabled = false;
};
BD.Private.compactCamera = function(camera) {
return {
position: {
x: camera.position.x,
y: camera.position.y,
z: camera.position.z
},
target: {
x: camera.target.x,
y: camera.target.y,
z: camera.target.z
}
};
};
BD.Event = {};
BD.Event.ArrowClicked = function() {};
BD.Event.ArrowClicked.prototype.send = function() {
var url = "/arrow-clicked";
var data = {arrow_id: this.arrow_id};
BD.Private.sendData(url, data);
};
BD.Event.CoinClicked = function() {};
BD.Event.CoinClicked.prototype.send = function() {
var url = "/coin-clicked";
var data = {coin_id: this.coin_id};
BD.Private.sendData(url, data);
};
BD.Event.KeyboardEvent = function() {};
BD.Event.KeyboardEvent.prototype.send = function() {
var url = "/keyboard-event";
var data = {
camera: BD.Private.compactCamera(this.camera)
};
BD.Private.sendData(url, data);
};
BD.Event.ResetClicked = function() {};
BD.Event.ResetClicked.prototype.send = function() {
var url = "/reset-clicked";
var data = {};
BD.Private.sendData(url, data);
};
BD.Event.PreviousNextClicked = function() {};
BD.Event.PreviousNextClicked.prototype.send = function() {
var url = "/previous-next-clicked";
var data = {
// casts previous to boolean
previous: this.previous,
camera: BD.Private.compactCamera(this.camera)
};
BD.Private.sendData(url, data);
};
BD.Event.Hovered = function() {};
BD.Event.Hovered.prototype.send = function() {
var url = "/hovered";
var data = {
start: this.start,
arrow_id: this.arrow_id
};
BD.Private.sendData(url, data);
};
BD.Event.Fps = function() {};
BD.Event.Fps.prototype.send = function() {
var url = "/fps";
var data = {
fps: this.fps
};
BD.Private.sendData(url, data);
};
+49
View File
@@ -0,0 +1,49 @@
var Displayable = function() {
// Nothing to do here
};
Displayable.prototype.addToScene = function(scene) {
scene.add(this.mesh);
};
Displayable.prototype.translate = function(x,y,z) {
this.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(x,y,z));
};
// class Cube extends Displayable
var Cube = function(size, style) {
// Super constructor call
Displayable.call(this);
if (size === undefined) size = 100;
if (style === undefined) style = {};
this.geometry = new THREE.BoxGeometry(size, size, size);
this.material = new THREE.MeshLambertMaterial(style);
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.mesh.castShadow = false;
};
Cube.prototype = Object.create(Displayable.prototype);
Cube.prototype.constructor = Cube;
// class Plane extends Displayable
var Plane = function(size1, size2, style) {
Displayable.call(this);
if (style === undefined) style = {};
this.geometry = new THREE.PlaneBufferGeometry(size1, size2);
this.material = new THREE.MeshLambertMaterial(style);
this.material.side = THREE.DoubleSide;
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.mesh.receiveShadow = true;
};
Plane.prototype = Object.create(Displayable.prototype);
Plane.prototype.constructor = Plane;
Plane.prototype.addToScene = function(scene) {
scene.add(this.mesh);
};