Added replay (first step)
This commit is contained in:
parent
98ca4676d8
commit
0d73873135
|
@ -1,7 +1,8 @@
|
|||
var tools = require('../../my_modules/filterInt.js');
|
||||
var pg = require('pg');
|
||||
var pgc = require('../../private.js');
|
||||
|
||||
var createNewId = function(req, callback) {
|
||||
var createNewId = function(req, res, callback) {
|
||||
pg.connect(pgc.url, function(err, client, release) {
|
||||
client.query(
|
||||
"INSERT INTO users(name) VALUES('anonymous'); SELECT currval('users_id_seq');",
|
||||
|
@ -16,6 +17,42 @@ var createNewId = function(req, callback) {
|
|||
});
|
||||
}
|
||||
|
||||
var getPathFromId = function(req, res, callback, id) {
|
||||
pg.connect(pgc.url, function(err, client, release) {
|
||||
client.query(
|
||||
"SELECT ((camera).position).x AS px, " +
|
||||
"((camera).position).y AS py, " +
|
||||
"((camera).position).z AS pz, " +
|
||||
"((camera).target).x AS tx, " +
|
||||
"((camera).target).y AS ty, " +
|
||||
"((camera).target).z AS tz " +
|
||||
"FROM keyboardevent WHERE user_id = $1;",
|
||||
[id],
|
||||
function(err, result) {
|
||||
res.locals.path = [];
|
||||
for (var i in result.rows) {
|
||||
res.locals.path.push(
|
||||
{
|
||||
position : {
|
||||
x: result.rows[i].px,
|
||||
y: result.rows[i].py,
|
||||
z: result.rows[i].pz
|
||||
},
|
||||
target : {
|
||||
x: result.rows[i].tx,
|
||||
y: result.rows[i].ty,
|
||||
z: result.rows[i].tz
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
callback();
|
||||
release();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.index = function(req, res) {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
|
||||
|
@ -25,7 +62,7 @@ module.exports.index = function(req, res) {
|
|||
}
|
||||
|
||||
module.exports.arrows = function(req, res) {
|
||||
createNewId(req, function() {
|
||||
createNewId(req, res, function() {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
|
||||
res.locals.cameraStyle = 'arrows';
|
||||
|
@ -37,7 +74,7 @@ module.exports.arrows = function(req, res) {
|
|||
}
|
||||
|
||||
module.exports.viewports = function(req, res) {
|
||||
createNewId(req, function() {
|
||||
createNewId(req, res, function() {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
|
||||
res.locals.cameraStyle = 'viewports';
|
||||
|
@ -49,7 +86,7 @@ module.exports.viewports = function(req, res) {
|
|||
}
|
||||
|
||||
module.exports.reverse = function(req, res) {
|
||||
createNewId(req, function() {
|
||||
createNewId(req, res, function() {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
|
||||
res.locals.cameraStyle = 'reverse';
|
||||
|
@ -59,3 +96,24 @@ module.exports.reverse = function(req, res) {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.replay_info = function(req, res) {
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
|
||||
// Parse id
|
||||
var id = tools.filterInt(req.params.id);
|
||||
|
||||
getPathFromId(req, res, function() {
|
||||
res.send(JSON.stringify(res.locals.path));
|
||||
}, id);
|
||||
}
|
||||
|
||||
module.exports.replay = function(req, res) {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.locals.cameraStyle = "replay";
|
||||
res.locals.id = tools.filterInt(req.params.id);
|
||||
res.render('prototype.jade', res.locals, function(err, result) {
|
||||
res.send(result);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -2,5 +2,7 @@ module.exports = {
|
|||
'/prototype': 'index',
|
||||
'/prototype/arrows': 'arrows',
|
||||
'/prototype/viewports': 'viewports',
|
||||
'/prototype/reverse': 'reverse'
|
||||
'/prototype/reverse': 'reverse',
|
||||
'/prototype/replay/:id': 'replay',
|
||||
'/prototype/replay_info/:id': 'replay_info'
|
||||
}
|
||||
|
|
|
@ -14,13 +14,21 @@ block extrajs
|
|||
script(src="/static/js/prototype/ButtonManager.js")
|
||||
script(src="/static/js/prototype/Coin.js")
|
||||
script(src="/static/js/Logger.js")
|
||||
|
||||
if cameraStyle == 'replay'
|
||||
script var params = params || {}; params.get = params.get || {}; params.get.id = #{id};
|
||||
script(src="/static/js/ReplayCamera.js")
|
||||
script(src="/static/js/prototype/replay.js")
|
||||
else
|
||||
if cameraStyle == 'arrows'
|
||||
script RecommendedCamera = FixedCamera;
|
||||
else if cameraStyle == 'viewports'
|
||||
script RecommendedCamera = OldFixedCamera;
|
||||
else if cameraStyle == 'reverse'
|
||||
script RecommendedCamera = ReverseCamera
|
||||
|
||||
script(src="/static/js/prototype/main.js")
|
||||
|
||||
script document.getElementById('music').volume = 0.5;
|
||||
|
||||
block extrahead
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
// class camera extends THREE.PerspectiveCamera
|
||||
var ReplayCamera = function() {
|
||||
THREE.PerspectiveCamera.apply(this, arguments);
|
||||
|
||||
this.started = false;
|
||||
this.counter = 0;
|
||||
|
||||
this.position = new THREE.Vector3();
|
||||
this.target = new THREE.Vector3();
|
||||
this.new_position = new THREE.Vector3();
|
||||
this.new_target = new THREE.Vector3();
|
||||
|
||||
var id = params.get.id;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/prototype/replay_info/" + id, true);
|
||||
|
||||
(function(self) {
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
self.path = JSON.parse(xhr.responseText);
|
||||
self.position.x = self.path[0].position.x;
|
||||
self.position.y = self.path[0].position.y;
|
||||
self.position.z = self.path[0].position.z;
|
||||
self.target = new THREE.Vector3(
|
||||
self.path[0].target.x,
|
||||
self.path[0].target.y,
|
||||
self.path[0].target.z
|
||||
);
|
||||
self.started = true;
|
||||
self.move(self.path[++self.counter]);
|
||||
}
|
||||
}
|
||||
})(this);
|
||||
xhr.send();
|
||||
|
||||
// Set Position
|
||||
this.theta = Math.PI;
|
||||
this.phi = Math.PI;
|
||||
|
||||
|
||||
}
|
||||
ReplayCamera.prototype = Object.create(THREE.PerspectiveCamera.prototype);
|
||||
ReplayCamera.prototype.constructor = ReplayCamera;
|
||||
|
||||
ReplayCamera.prototype.look = function() {
|
||||
this.lookAt(this.target);
|
||||
}
|
||||
|
||||
// Update function
|
||||
ReplayCamera.prototype.update = function(time) {
|
||||
if (this.started)
|
||||
this.linearMotion(time);
|
||||
}
|
||||
|
||||
ReplayCamera.prototype.linearMotion = function(time) {
|
||||
var tmp = Tools.sum(Tools.mul(this.old_position, 1-this.t), Tools.mul(this.new_position, this.t));
|
||||
this.position.x = tmp.x;
|
||||
this.position.y = tmp.y;
|
||||
this.position.z = tmp.z;
|
||||
this.target = Tools.sum(Tools.mul(this.old_target, 1-this.t), Tools.mul(this.new_target, this.t));
|
||||
this.t += 0.1 * time / 20;
|
||||
|
||||
if (this.t > 1) {
|
||||
this.counter++;
|
||||
if (this.counter < this.path.length) {
|
||||
this.move(this.path[this.counter]);
|
||||
} else {
|
||||
this.started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReplayCamera.prototype.reset = function() {
|
||||
this.resetBobomb();
|
||||
this.moving = false;
|
||||
this.movingHermite = false;
|
||||
// this.position.copy(new THREE.Vector3(-8.849933489419644, 9.050627639459208, 0.6192960680432451));
|
||||
// this.target.copy(new THREE.Vector3(17.945323228767702, -15.156828589982375, -16.585740412769756));
|
||||
// this.anglesFromVectors();
|
||||
}
|
||||
|
||||
ReplayCamera.prototype.resetBobomb = function() {
|
||||
this.position.copy(new THREE.Vector3(34.51854618261728,10.038879540840306,-21.772598201888613));
|
||||
this.target.copy(new THREE.Vector3(-2.593404107644737,8.039712770013185,-6.983870133675925));
|
||||
this.anglesFromVectors();
|
||||
}
|
||||
|
||||
ReplayCamera.prototype.vectorsFromAngles = function() {
|
||||
// Update direction
|
||||
this.forward.y = Math.sin(this.phi);
|
||||
|
||||
var cos = Math.cos(this.phi);
|
||||
this.forward.z = cos * Math.cos(this.theta);
|
||||
this.forward.x = cos * Math.sin(this.theta);
|
||||
this.forward.normalize();
|
||||
|
||||
}
|
||||
|
||||
ReplayCamera.prototype.anglesFromVectors = function() {
|
||||
// Update phi and theta so that return to reality does not hurt
|
||||
var forward = Tools.diff(this.target, this.position);
|
||||
forward.normalize();
|
||||
|
||||
this.phi = Math.asin(forward.y);
|
||||
|
||||
// Don't know why this line works... But thanks Thierry-san and
|
||||
// Bastien because it seems to work...
|
||||
this.theta = Math.atan2(forward.x, forward.z);
|
||||
}
|
||||
|
||||
ReplayCamera.prototype.move = function(otherCamera) {
|
||||
this.moving = true;
|
||||
this.old_target = this.target.clone();
|
||||
this.old_position = this.position.clone();
|
||||
this.new_target = new THREE.Vector3(otherCamera.target.x, otherCamera.target.y, otherCamera.target.z);
|
||||
this.new_position = new THREE.Vector3(otherCamera.position.x, otherCamera.position.y, otherCamera.position.z);
|
||||
this.t = 0;
|
||||
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
// Disable scrolling
|
||||
window.onscroll = function () { window.scrollTo(0, 0); };
|
||||
|
||||
var mesh_number = 25;
|
||||
var renderer, scene, controls, cube, container, plane, mouse= {x:0, y:0};
|
||||
var bigmesh;
|
||||
var raycaster;
|
||||
var objects = [];
|
||||
var cameras, cameraSelecter;
|
||||
var spheres = new Array(mesh_number);
|
||||
var visible = 0;
|
||||
var stats;
|
||||
var previewer;
|
||||
|
||||
var loader;
|
||||
var coins;
|
||||
var beenFullscreen = false;
|
||||
var isFullscreen = false;
|
||||
var previousTime;
|
||||
|
||||
var main_section = document.getElementById('main-section');
|
||||
var offset = function() {
|
||||
return
|
||||
document.getElementById('nav').offsetHeight
|
||||
+ document.getElementById('main-div').offsetHeight;
|
||||
}
|
||||
|
||||
console.log(document.getElementById('main-div').offsetHeight);
|
||||
var container_size = {
|
||||
width: function() { if (!isFullscreen) return main_section.clientWidth; else return screen.width;},
|
||||
height: function() {
|
||||
if (!isFullscreen)
|
||||
return main_section.clientHeight
|
||||
- document.getElementById('nav').offsetHeight
|
||||
- document.getElementById('main-div').offsetHeight;
|
||||
else
|
||||
return screen.height;
|
||||
}
|
||||
};
|
||||
|
||||
console.log(container_size.width(), container_size.height());
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function init() {
|
||||
// Collidable objects to prevent camera from traversing objects
|
||||
var collidableObjects = new Array();
|
||||
|
||||
// Initialize renderer
|
||||
container = document.getElementById('container');
|
||||
container.style.height = container_size.height() + 'px';
|
||||
container.style.width = container_size.width() + 'px';
|
||||
renderer = new THREE.WebGLRenderer({alpha:true, antialias:true});
|
||||
renderer.setSize(container_size.width(), container_size.height());
|
||||
// renderer.setSize(container_size.width(), container_size.height());
|
||||
renderer.shadowMapEnabled = true;
|
||||
renderer.setClearColor(0x87ceeb);
|
||||
|
||||
// Initialize previewer
|
||||
previewer = new Previewer(renderer);
|
||||
previewer.domElement.style.position ="absolute";
|
||||
previewer.domElement.style.cssFloat = 'top-left';
|
||||
previewer.domElement.width = container_size.width();
|
||||
previewer.domElement.height = container_size.height();
|
||||
|
||||
// Initialize scene
|
||||
scene = new THREE.Scene();
|
||||
|
||||
// Initialize stats counter
|
||||
stats = new Stats();
|
||||
stats.setMode(0);
|
||||
stats.domElement.style.position = 'absolute';
|
||||
stats.domElement.style.cssFloat = "top-left";
|
||||
|
||||
// Add elements to page
|
||||
container.appendChild( stats.domElement );
|
||||
container.appendChild(previewer.domElement);
|
||||
container.appendChild(renderer.domElement);
|
||||
|
||||
// init light
|
||||
var directional_light = new THREE.DirectionalLight(0xdddddd);
|
||||
directional_light.position.set(1, 2.5, 1).normalize();
|
||||
directional_light.castShadow = false;
|
||||
scene.add(directional_light);
|
||||
|
||||
var ambient_light = new THREE.AmbientLight(0x555555);
|
||||
scene.add(ambient_light);
|
||||
|
||||
// Initialize pointer camera
|
||||
var camera1 = new ReplayCamera(50, container_size.width() / container_size.height(), 0.01, 100000, container);
|
||||
scene.add(camera1);
|
||||
|
||||
// Initialize recommendations
|
||||
var otherCams = createBobombCameras(container_size.width(), container_size.height());
|
||||
cameras = new CameraContainer(camera1, otherCams);
|
||||
otherCams.forEach(function(cam) { cam.addToScene(scene); });
|
||||
|
||||
// Initalize loader
|
||||
var loader = new THREE.OBJMTLLoader();
|
||||
|
||||
// Load scene
|
||||
// initPeachCastle(scene, collidableObjects, loader, static_path);
|
||||
initBobombScene(scene, collidableObjects, loader, static_path);
|
||||
coins = createBobombCoins();
|
||||
|
||||
setTimeout(function() {coins.forEach(function(coin) { coin.addToScene(scene);})}, 1000);
|
||||
|
||||
// Add listeners
|
||||
initListeners();
|
||||
}
|
||||
|
||||
function initListeners() {
|
||||
window.addEventListener('resize', onWindowResize, false);
|
||||
|
||||
// Transmit click event to camera selecter
|
||||
container.addEventListener('mousedown', function(event) {
|
||||
if (event.which == 1)
|
||||
cameraSelecter.click(event);
|
||||
}, false
|
||||
);
|
||||
|
||||
// Update camera selecter when mouse moved
|
||||
container.addEventListener('mousemove', function(event) {
|
||||
cameraSelecter.update(event);
|
||||
}, false
|
||||
);
|
||||
|
||||
// Escape key to exit fullscreen mode
|
||||
document.addEventListener('keydown', function(event) { if (event.keyCode == 27) { stopFullscreen();} }, false);
|
||||
|
||||
// HTML Bootstrap buttons
|
||||
buttonManager = new ButtonManager(cameras, previewer);
|
||||
|
||||
// Camera selecter for hover and clicking recommendations
|
||||
cameraSelecter = new CameraSelecter(renderer, cameras, buttonManager);
|
||||
}
|
||||
|
||||
function fullscreen() {
|
||||
isFullscreen = true;
|
||||
|
||||
if (!beenFullscreen) {
|
||||
beenFullscreen = true;
|
||||
alert('To quit fullscren mode, type ESC key');
|
||||
}
|
||||
|
||||
container.style.position = "absolute";
|
||||
container.style.cssFloat = "top-left";
|
||||
container.style.top = "50px";
|
||||
container.style.bottom = "0px";
|
||||
container.style.left = "0px";
|
||||
container.style.right = "0px";
|
||||
container.style.width="";
|
||||
container.style.height="";
|
||||
container.style.overflow = "hidden";
|
||||
|
||||
// canvas.style.position = "absolute";
|
||||
// canvas.style.cssFloat = "top-left";
|
||||
// canvas.style.top = "0px";
|
||||
// canvas.style.bottom = "0px";
|
||||
// canvas.style.left = "0px";
|
||||
// canvas.style.right = "0px";
|
||||
// canvas.width=window.innerWidth;
|
||||
// canvas.height=window.innerHeight;
|
||||
// canvas.style.overflow = "hidden";
|
||||
|
||||
onWindowResize();
|
||||
}
|
||||
|
||||
function stopFullscreen() {
|
||||
isFullscreen = false;
|
||||
|
||||
container.style.position = "";
|
||||
container.style.cssFloat = "";
|
||||
container.style.top = "";
|
||||
container.style.bottom = "";
|
||||
container.style.left = "";
|
||||
container.style.right = "";
|
||||
container.style.width = container_size.width() + "px";
|
||||
container.style.height = container_size.height() + "px";
|
||||
|
||||
// canvas.style.position = "";
|
||||
// canvas.style.cssFloat = "";
|
||||
// canvas.style.top = "";
|
||||
// canvas.style.bottom = "";
|
||||
// canvas.style.left = "";
|
||||
// canvas.style.right = "";
|
||||
// canvas.width = container_size.width();
|
||||
// canvas.height = container_size.height();
|
||||
// canvas.style.overflow = "";
|
||||
|
||||
onWindowResize();
|
||||
}
|
||||
|
||||
function render() {
|
||||
cameraSelecter.update();
|
||||
|
||||
// Update recommendations (set raycastable if shown)
|
||||
var transform = buttonManager.showArrows ? show : hide;
|
||||
cameras.map(function(camera) {
|
||||
if (camera instanceof RecommendedCamera) {
|
||||
transform(camera);
|
||||
|
||||
camera.traverse(function(elt) {
|
||||
elt.raycastable = buttonManager.showArrows;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Update coins
|
||||
coins.forEach(function(coin) { coin.update(); });
|
||||
|
||||
// Update main camera
|
||||
var currentTime = Date.now() - previousTime;
|
||||
cameras.updateMainCamera(isNaN(currentTime) ? 20 : currentTime);
|
||||
previousTime = Date.now();
|
||||
|
||||
// Update the recommendations
|
||||
cameras.update(cameras.mainCamera());
|
||||
|
||||
|
||||
// Set current position of camera
|
||||
cameras.look();
|
||||
|
||||
var left = 0, bottom = 0, width = container_size.width(), height = container_size.height();
|
||||
renderer.setScissor(left, bottom, width, height);
|
||||
renderer.enableScissorTest(true);
|
||||
renderer.setViewport(left, bottom, width, height);
|
||||
renderer.render(scene, cameras.mainCamera());
|
||||
|
||||
// Remove borders of preview
|
||||
previewer.clear();
|
||||
|
||||
// Hide arrows in recommendation
|
||||
cameras.map(function(camera) { if (camera instanceof RecommendedCamera) hide(camera); });
|
||||
|
||||
// Render preview
|
||||
previewer.render(cameraSelecter.prev, container_size.width(), container_size.height());
|
||||
}
|
||||
|
||||
function animate() {
|
||||
// Render each frame
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
// stats count the number of frames per second
|
||||
stats.begin();
|
||||
render();
|
||||
stats.end();
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
|
||||
container.style.width = container_size.width() + "px";
|
||||
container.style.height = container_size.height() + "px";
|
||||
|
||||
previewer.domElement.width = container_size.width();
|
||||
previewer.domElement.height = container_size.height();
|
||||
|
||||
renderer.setSize(container_size.width(), container_size.height());
|
||||
cameras.forEach(function(camera) {camera.aspect = container_size.width() / container_size.height();});
|
||||
cameras.forEach(function(camera) {camera.updateProjectionMatrix();});
|
||||
render();
|
||||
}
|
||||
|
||||
function hide(object) {
|
||||
object.traverse(function(object) {object.visible = false;});
|
||||
}
|
||||
|
||||
function show(object) {
|
||||
object.traverse(function(object) {object.visible = true;});
|
||||
}
|
||||
|
Loading…
Reference in New Issue