diff --git a/controllers/prototype/index.js b/controllers/prototype/index.js index 28b3f0d..ce5af91 100644 --- a/controllers/prototype/index.js +++ b/controllers/prototype/index.js @@ -171,3 +171,29 @@ module.exports.clicker = function(req, res, next) { }); }; + +module.exports.viewer = function(req, res, next) { + + var scene = req.params.scene; + + switch (scene) { + + case 'peach': res.locals.scene = "L3D.initPeach"; break; + case 'coolcoolmountain': res.locals.scene = "L3D.initMountain"; break; + case 'whomp': res.locals.scene = "L3D.initWhomp"; break; + case 'bobomb': res.locals.scene = "L3D.initBobomb"; break; + default: + // 404 + var err = new Error('Incorrect scene'); + err.status = 404; + next(err); + break; + + } + + res.setHeader('Content-Type', 'text/html'); + res.render('prototype_viewer.jade', res.locals, function(err, result) { + res.send(result); + }); + +}; diff --git a/controllers/prototype/urls.js b/controllers/prototype/urls.js index aec4ae4..253fad4 100644 --- a/controllers/prototype/urls.js +++ b/controllers/prototype/urls.js @@ -8,5 +8,6 @@ module.exports = { '/prototype/replay_info/:id': 'replay_info', '/prototype/tutorial': 'tutorial', '/prototype/sponza': 'sponza', - '/prototype/coin-creator/:scene': 'clicker' + '/prototype/coin-creator/:scene': 'clicker', + '/prototype/coin-viewer/:scene': 'viewer' }; diff --git a/controllers/prototype/views/prototype_clicker.jade b/controllers/prototype/views/prototype_clicker.jade index 1f24e73..cde4e92 100644 --- a/controllers/prototype/views/prototype_clicker.jade +++ b/controllers/prototype/views/prototype_clicker.jade @@ -7,7 +7,6 @@ block mainjs script initMainScene = #{scene}; script Recommendation = L3D.ArrowRecommendation; - script(src="/static/js/filesaver.min.js") script(src="/static/js/coincreator.min.js") block extrabutton diff --git a/controllers/prototype/views/prototype_viewer.jade b/controllers/prototype/views/prototype_viewer.jade new file mode 100644 index 0000000..0a65f56 --- /dev/null +++ b/controllers/prototype/views/prototype_viewer.jade @@ -0,0 +1,10 @@ +extends ./prototype + +block title + title #{title} - Prototype + +block mainjs + script initMainScene = #{scene}; + script Recommendation = L3D.ArrowRecommendation; + + script(src="/static/js/coinviewer.min.js") diff --git a/js/Makefile b/js/Makefile index 04c938e..c773437 100644 --- a/js/Makefile +++ b/js/Makefile @@ -6,7 +6,7 @@ else CLOSURE=../utils/simple-compiler/compiler.sh endif -all: L3D L3DP Socket Three Stats Bouncing Multisphere StreamingSimulator PrototypeReplay PrototypeInteractive Tutorial TestList CoinCreator +all: L3D L3DP Socket Three Stats Bouncing Multisphere StreamingSimulator PrototypeReplay PrototypeInteractive Tutorial TestList CoinCreator CoinViewer L3D: $(CLOSURE) $(OPT) \ @@ -90,6 +90,11 @@ CoinCreator: --js l3d/apps/prototype/coin-creator/main.js \ --js_output_file ../static/js/coincreator.min.js +CoinViewer: + $(CLOSURE) $(OPT) \ + --js l3d/apps/prototype/coin-viewer/main.js \ + --js_output_file ../static/js/coinviewer.min.js + PrototypeReplay: $(CLOSURE) $(OPT) \ --js l3d/apps/prototype/ButtonManager.js \ diff --git a/js/l3d/apps/prototype/coin-viewer/main.js b/js/l3d/apps/prototype/coin-viewer/main.js new file mode 100644 index 0000000..ae5c5f2 --- /dev/null +++ b/js/l3d/apps/prototype/coin-viewer/main.js @@ -0,0 +1,264 @@ +// Let's be sure we avoid using global variables +var onWindowResize = (function() { + +// Disable scrolling +window.onscroll = function () { window.scrollTo(0, 0); }; +document.addEventListener('contextmenu', function(e) { + e.preventDefault(); +}); +window.onload = main; + +var stats; +var renderer, scene, container; +var clickableObjects = []; +var recommendations, objectClicker; +var previewer; +var camera1; +var coins = []; +var previousTime; +var pointer; +var startCanvas; +var name; + +function sceneName() { + switch (initMainScene) { + case L3D.initPeach: + return 'L3D.initPeach'; + case L3D.initWhomp: + return 'L3D.initWhomp'; + case L3D.initBobomb: + return 'L3D.initBobomb'; + case L3D.initMountain: + return 'L3D.initMountain'; + } +} + +saveCoins = function() { + + var result = {scene: sceneName(), coins: []}; + + if (name === undefined) { + name = window.prompt('Your name please ? :D'); + } + + result.name = name; + + for (var i = 0; i < coins.length; i++) { + if (coins[i].mesh.visible) + result.coins.push(coins[i].mesh.position); + } + + L3D.DB.Private.sendData('/posts/coin-info', result, true); + +}; + +function main() { + + // Main container that holds everything + container = document.getElementById('container'); + + // Initialization + initThreeElements(); + initCanvases(); + initModels(); + initListeners(); + + appendTo(container)(stats, startCanvas, pointer, previewer, renderer); + + // Set the good size of cameras + onWindowResize(); + + // Some config + L3D.DB.disable(); + + Coin.update(); + startCanvas.render(L3D.StartCanvas.Black); + + // Bind previewer to renderer (for fixed option) + function bind() { + if (document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement) { + // Lock event + previewer.fixed = true; + } else { + // Unlock event + previewer.fixed = false; + } + } + document.addEventListener('pointerlockchange', bind); + document.addEventListener('mozpointerlockchange', bind); + document.addEventListener('webkitpointerlockchange', bind); + + // Start rendering + setInterval(render, 20); + +} + +function initThreeElements() { + + // Initialize scene + scene = new THREE.Scene(); + renderer = new THREE.WebGLRenderer({alpha:true, antialias:true}); + renderer.setClearColor(0x87ceeb); + + // Initialize pointer camera + camera1 = new L3D.PointerCamera( + 50, + container_size.width() / container_size.height(), + 0.01, 100000, renderer, container + ); + +} + +function initCanvases() { + + // Initialize previewer + previewer = new L3D.Previewer(renderer, scene); + previewer.domElement.style.position ="absolute"; + previewer.domElement.style.cssFloat = 'top-left'; + + // Initialize stats counter + stats = new Stats(); + stats.setMode(0); + stats.domElement.style.position = 'absolute'; + stats.domElement.style.cssFloat = "top-left"; + + // Initialize pointer for pointer lock + pointer = new L3D.MousePointer(camera1); + + // Init start canvas + startCanvas = new L3D.StartCanvas(camera1); + +} + +function initModels() { + + var i = 0; + + // Init recommendations + recommendations = initMainScene(camera1, scene, coins, clickableObjects, []); + + // Erase coins and recommendations + for (i =0; i < recommendations.length; i++) + recommendations[i].traverse(function(obj) {obj.visible = false;}); + recommendations = []; + +} + +function initListeners() { + + // Add listeners + window.addEventListener('resize', onWindowResize, false); + + // HTML Bootstrap buttons + buttonManager = new ButtonManager(camera1, recommendations, previewer); + + // Object clicker for hover and clicking recommendations + objectClicker = new L3D.ObjectClicker( + renderer, + camera1, + clickableObjects, + objectClickerOnHover(camera1, previewer, recommendations, container), // Create onHover function + + // onclick + function(c, x, y, event) { + + if (event.button !== 2) + return; + + if (c !== undefined) { + + if (c.object instanceof Coin) { + + c.object.mesh.visible = false; + c.object.raycastable = false; + + } else { + + var newPosition = c.point.clone(); + var direction = L3D.Tools.diff(newPosition, camera1.position); + direction.normalize(); + direction.multiplyScalar(0.2); + newPosition.sub(direction); + var coin = new Coin(newPosition.x, newPosition.y, newPosition.z, function() {}); + coin.addToScene(scene); + coins.push(coin); + clickableObjects.push(coin); + + } + + } + }, + container + ); + +} + +function render() { + + // Stats for render + stats.begin(); + + objectClicker.update(); + + // Update recommendations (set raycastable if shown) + recommendations.map(function(reco) { + if (reco instanceof Recommendation) { + reco.traverse(function(elt) { + elt.visible = elt.raycastable = buttonManager.showArrows; + }); + } + }); + + // Update coins + coins.forEach(function(coin) { coin.update(); }); + + // Update main camera + var currentTime = Date.now() - previousTime; + camera1.update(isNaN(currentTime) ? 20 : currentTime); + previousTime = Date.now(); + + // Update the recommendations + recommendations.map(function(reco) { reco.update(camera1);}); + + // Set current position of camera + camera1.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, camera1); + + // Remove borders of preview + previewer.clear(); + + // Hide arrows in recommendation + recommendations.map(function(reco) { if (reco instanceof Recommendation) hide(reco); }); + + // Update transparent elements + THREEx.Transparency.update(camera1); + + // Render preview + previewer.render(container_size.width(), container_size.height()); + + // Finish stats + stats.end(); + +} + +function onWindowResize() { + + resizeElements(renderer, container, previewer, pointer, startCanvas); + + recommendations.forEach(function(reco) { + resetCameraAspect(reco.camera, container_size.width(), container_size.height()); + }); + + render(); + +} + +// onWindowResize will be the only global function +return onWindowResize; + +})(); diff --git a/js/l3d/src/scenes/initScene.js b/js/l3d/src/scenes/initScene.js index f698faf..5560914 100644 --- a/js/l3d/src/scenes/initScene.js +++ b/js/l3d/src/scenes/initScene.js @@ -241,13 +241,17 @@ L3D.generateCoins = function(totalCoins, coin_ids) { var indices = []; var coins = []; - for (var i = 0; i < 8; i++) { + var bound = (coin_ids instanceof Array && coin_ids.length === 0) ? totalCoins.length : 8; + + for (i = 0; i < bound; i++) { coins.push(totalCoins[i].coin); totalCoins[i].coin.id = totalCoins[i].id; indices.push(totalCoins[i].id); } - if (coin_ids === undefined) + console.log(bound); + + if (coin_ids === undefined || (coin_ids instanceof Array && coin_ids.length === 0)) L3D.DB.Private.sendData('/posts/coin-id', {indices : indices}); return coins;