A hell of a lot cleaning
This commit is contained in:
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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];
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -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());
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
Reference in New Issue
Block a user