Added replay (first step)

This commit is contained in:
Thomas FORGIONE
2015-05-19 15:43:09 +02:00
parent 98ca4676d8
commit 0d73873135
5 changed files with 472 additions and 12 deletions

120
static/js/ReplayCamera.js Normal file
View File

@@ -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;
}

272
static/js/prototype/replay.js vendored Normal file
View File

@@ -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;});
}