Should work but seems slow
This commit is contained in:
		
							parent
							
								
									5e0a6c3121
								
							
						
					
					
						commit
						844982e552
					
				| @ -7,7 +7,6 @@ let height = Math.floor(768 /10); | |||||||
| let XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; | let XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; | ||||||
| let THREE = require('three'); | let THREE = require('three'); | ||||||
| let L3D = require('../../static/js/l3d.min.js'); | let L3D = require('../../static/js/l3d.min.js'); | ||||||
| let math = require('mathjs'); |  | ||||||
| let fs = require('fs'); | let fs = require('fs'); | ||||||
| 
 | 
 | ||||||
| let scene = new THREE.Scene(); | let scene = new THREE.Scene(); | ||||||
|  | |||||||
| @ -22,6 +22,10 @@ L3D.ReplayCamera = function() { | |||||||
|     this.theta = Math.PI; |     this.theta = Math.PI; | ||||||
|     this.phi = Math.PI; |     this.phi = Math.PI; | ||||||
| 
 | 
 | ||||||
|  |     this.shouldRecover = false; | ||||||
|  | 
 | ||||||
|  |     this.recommendationClicked = null; | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| L3D.ReplayCamera.prototype = Object.create(THREE.PerspectiveCamera.prototype); | L3D.ReplayCamera.prototype = Object.create(THREE.PerspectiveCamera.prototype); | ||||||
| L3D.ReplayCamera.prototype.constructor = L3D.ReplayCamera; | L3D.ReplayCamera.prototype.constructor = L3D.ReplayCamera; | ||||||
| @ -71,10 +75,17 @@ L3D.ReplayCamera.prototype.cameraMotion = function(time) { | |||||||
|     var tmp = L3D.Tools.sum(L3D.Tools.mul(this.oldPosition, 1-this.t), L3D.Tools.mul(this.newPosition, this.t)); |     var tmp = L3D.Tools.sum(L3D.Tools.mul(this.oldPosition, 1-this.t), L3D.Tools.mul(this.newPosition, this.t)); | ||||||
|     this.position.copy(tmp); |     this.position.copy(tmp); | ||||||
|     this.target = L3D.Tools.sum(L3D.Tools.mul(this.oldTarget, 1-this.t), L3D.Tools.mul(this.newTarget, this.t)); |     this.target = L3D.Tools.sum(L3D.Tools.mul(this.oldTarget, 1-this.t), L3D.Tools.mul(this.newTarget, this.t)); | ||||||
|     this.t += 1 / (((new Date(this.path[this.counter].time)).getTime() - (new Date(this.path[this.counter-1].time)).getTime()) / 20); |     this.t += this.recovering ? 0.01 : 1 / (((new Date(this.path[this.counter].time)).getTime() - (new Date(this.path[this.counter-1].time)).getTime()) / 20); | ||||||
| 
 | 
 | ||||||
|     if (this.t > 1) { |     if (this.t > 1) { | ||||||
|         this.nextEvent(); |         this.recommendationClicked = null; | ||||||
|  |         if (typeof this.recoverCallback === 'function') { | ||||||
|  |             this.recoverCallback(); | ||||||
|  |             this.recoverCallback = null; | ||||||
|  |         } else { | ||||||
|  |             this.nextEvent(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -87,11 +98,15 @@ L3D.ReplayCamera.prototype.hermiteMotion = function(time) { | |||||||
|     this.t += 0.01 * time / 20; |     this.t += 0.01 * time / 20; | ||||||
| 
 | 
 | ||||||
|     if (this.t > 1) { |     if (this.t > 1) { | ||||||
|  |         this.recommendationClicked = null; | ||||||
|         this.nextEvent(); |         this.nextEvent(); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| L3D.ReplayCamera.prototype.nextEvent = function() { | L3D.ReplayCamera.prototype.nextEvent = function() { | ||||||
|  | 
 | ||||||
|  |     var self = this; | ||||||
|  | 
 | ||||||
|     this.counter++; |     this.counter++; | ||||||
| 
 | 
 | ||||||
|     // Finished
 |     // Finished
 | ||||||
| @ -124,7 +139,22 @@ L3D.ReplayCamera.prototype.nextEvent = function() { | |||||||
|         //     },500);
 |         //     },500);
 | ||||||
|         // })(this);
 |         // })(this);
 | ||||||
|     } else if (this.event.type == 'arrow') { |     } else if (this.event.type == 'arrow') { | ||||||
|         this.moveHermite(this.cameras[this.event.id]); |         if (this.shouldRecover) { | ||||||
|  |             (function(self, tmp) { | ||||||
|  |                 self.event.type = 'camera'; | ||||||
|  |                 self.recovering = true; | ||||||
|  |                 self.move({ | ||||||
|  |                     position: self.position.clone(), | ||||||
|  |                     target: self.cameras[self.event.id].camera.position.clone() | ||||||
|  |                 }, function() { | ||||||
|  |                     self.recovering = false; | ||||||
|  |                     self.event.type = 'arrow'; | ||||||
|  |                     self.moveReco(tmp); | ||||||
|  |                 }); | ||||||
|  |             })(this, this.event.id); | ||||||
|  |         } else { | ||||||
|  |             this.moveReco(this.event.id); | ||||||
|  |         } | ||||||
|     } else if (this.event.type == 'reset') { |     } else if (this.event.type == 'reset') { | ||||||
|         this.reset(); |         this.reset(); | ||||||
|         this.nextEvent(); |         this.nextEvent(); | ||||||
| @ -176,7 +206,13 @@ L3D.ReplayCamera.prototype.anglesFromVectors = function() { | |||||||
|     this.theta = Math.atan2(forward.x, forward.z); |     this.theta = Math.atan2(forward.x, forward.z); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| L3D.ReplayCamera.prototype.move = function(recommendation) { | L3D.ReplayCamera.prototype.move = function(recommendation, callback) { | ||||||
|  | 
 | ||||||
|  |     if (typeof callback === 'function') { | ||||||
|  | 
 | ||||||
|  |         this.recoverCallback = callback; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     var otherCamera = recommendation.camera || recommendation; |     var otherCamera = recommendation.camera || recommendation; | ||||||
| 
 | 
 | ||||||
| @ -185,12 +221,17 @@ L3D.ReplayCamera.prototype.move = function(recommendation) { | |||||||
|     this.oldPosition = this.position.clone(); |     this.oldPosition = this.position.clone(); | ||||||
|     this.newTarget =   new THREE.Vector3(otherCamera.target.x, otherCamera.target.y, otherCamera.target.z); |     this.newTarget =   new THREE.Vector3(otherCamera.target.x, otherCamera.target.y, otherCamera.target.z); | ||||||
|     this.newPosition = new THREE.Vector3(otherCamera.position.x, otherCamera.position.y, otherCamera.position.z); |     this.newPosition = new THREE.Vector3(otherCamera.position.x, otherCamera.position.y, otherCamera.position.z); | ||||||
|  | 
 | ||||||
|     this.t = 0; |     this.t = 0; | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| L3D.ReplayCamera.prototype.moveHermite = function(recommendation) { | L3D.ReplayCamera.prototype.moveHermite = function(recommendation) { | ||||||
| 
 | 
 | ||||||
|  |     if (this.shouldRecover === false) { | ||||||
|  |         this.shouldRecover = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     var otherCamera = recommendation.camera || recommendation; |     var otherCamera = recommendation.camera || recommendation; | ||||||
| 
 | 
 | ||||||
|     this.movingHermite = true; |     this.movingHermite = true; | ||||||
| @ -209,6 +250,14 @@ L3D.ReplayCamera.prototype.moveHermite = function(recommendation) { | |||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | L3D.ReplayCamera.prototype.moveReco = function(recommendationId) { | ||||||
|  | 
 | ||||||
|  |     this.recommendationClicked = this.cameras[recommendationId].camera; | ||||||
|  | 
 | ||||||
|  |     this.moveHermite(this.cameras[recommendationId]); | ||||||
|  | 
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| L3D.ReplayCamera.prototype.save = function() {}; | L3D.ReplayCamera.prototype.save = function() {}; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -220,18 +269,23 @@ L3D.ReplayCamera.prototype.save = function() {}; | |||||||
|  * </ol> |  * </ol> | ||||||
|  */ |  */ | ||||||
| L3D.ReplayCamera.prototype.toList = function() { | L3D.ReplayCamera.prototype.toList = function() { | ||||||
|     this.updateMatrix(); | 
 | ||||||
|     this.updateMatrixWorld(); |     var camera = (this.recommendationClicked === null ? this : this.recommendationClicked); | ||||||
|  | 
 | ||||||
|  |     camera.updateMatrix(); | ||||||
|  |     camera.updateMatrixWorld(); | ||||||
| 
 | 
 | ||||||
|     var frustum = new THREE.Frustum(); |     var frustum = new THREE.Frustum(); | ||||||
|     var projScreenMatrix = new THREE.Matrix4(); |     var projScreenMatrix = new THREE.Matrix4(); | ||||||
|     projScreenMatrix.multiplyMatrices(this.projectionMatrix, this.matrixWorldInverse); |     projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); | ||||||
| 
 | 
 | ||||||
|     frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(this.projectionMatrix, this.matrixWorldInverse)); |     frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)); | ||||||
| 
 | 
 | ||||||
|     var ret = |     var ret = | ||||||
|         [[this.position.x, this.position.y, this.position.z], |         [[camera.position.x, camera.position.y, camera.position.z], | ||||||
|          [this.target.x,   this.target.y,   this.target.z]]; |          [camera.target.x,   camera.target.y,   camera.target.z], | ||||||
|  |          this.recommendationClicked !== null | ||||||
|  |         ]; | ||||||
| 
 | 
 | ||||||
|     for (var i = 0; i < frustum.planes.length; i++) { |     for (var i = 0; i < frustum.planes.length; i++) { | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -90,6 +90,8 @@ var _parseList = function(arr) { | |||||||
|  */ |  */ | ||||||
| var ProgressiveLoader = function(path, scene, camera, callback, log, laggy) { | var ProgressiveLoader = function(path, scene, camera, callback, log, laggy) { | ||||||
| 
 | 
 | ||||||
|  |     var self = this; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Path to the .obj file |      * Path to the .obj file | ||||||
|      * @type {string} |      * @type {string} | ||||||
| @ -184,6 +186,12 @@ var ProgressiveLoader = function(path, scene, camera, callback, log, laggy) { | |||||||
|      */ |      */ | ||||||
|     this.camera = camera; |     this.camera = camera; | ||||||
| 
 | 
 | ||||||
|  |     this.camera._moveReco = this.camera.moveReco; | ||||||
|  | 
 | ||||||
|  |     this.camera.moveReco = function(param) { | ||||||
|  |         self.socket.emit('reco', param); | ||||||
|  |         self.camera._moveReco.apply(self.camera, arguments); | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Number of total elements for loading |      * Number of total elements for loading | ||||||
| @ -210,6 +218,14 @@ var ProgressiveLoader = function(path, scene, camera, callback, log, laggy) { | |||||||
|      */ |      */ | ||||||
|     this.log = log; |     this.log = log; | ||||||
| 
 | 
 | ||||||
|  |     this.mapFace = {}; | ||||||
|  | 
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | ProgressiveLoader.prototype.hasFace = function(face) { | ||||||
|  | 
 | ||||||
|  |     return this.mapFace[(face.a) + '-' + (face.b) + '-' + (face.c)] === true; | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -376,6 +392,8 @@ ProgressiveLoader.prototype.initIOCallbacks = function() { | |||||||
| 
 | 
 | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 self.mapFace[elt.a + '-' + elt.b + '-' + elt.c] = true; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|             } else if (elt.type === 'global') { |             } else if (elt.type === 'global') { | ||||||
| 
 | 
 | ||||||
| @ -386,6 +404,10 @@ ProgressiveLoader.prototype.initIOCallbacks = function() { | |||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (typeof self.onBeforeEmit === 'function') { | ||||||
|  |             self.onBeforeEmit(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // Ask for next elements
 |         // Ask for next elements
 | ||||||
|         if (!self.laggy) { |         if (!self.laggy) { | ||||||
|             self.socket.emit('next', self.getCamera()); |             self.socket.emit('next', self.getCamera()); | ||||||
| @ -396,7 +418,7 @@ ProgressiveLoader.prototype.initIOCallbacks = function() { | |||||||
| 
 | 
 | ||||||
|     this.socket.on('disconnect', function() { |     this.socket.on('disconnect', function() { | ||||||
|         if (typeof self.log === 'function') |         if (typeof self.log === 'function') | ||||||
|             self.log(self.numberOfFacesReceived, self.numberOfFaces); |             self.log(self.numberOfFaces, self.numberOfFaces); | ||||||
|         self.finished = true; |         self.finished = true; | ||||||
| 
 | 
 | ||||||
|         if (typeof L3D.ProgressiveLoader.onFinished === 'function') { |         if (typeof L3D.ProgressiveLoader.onFinished === 'function') { | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|  */ |  */ | ||||||
| L3D.ArrowRecommendation = function(arg1, arg2, arg3, arg4, position, target) { | L3D.ArrowRecommendation = function(arg1, arg2, arg3, arg4, position, target) { | ||||||
| 
 | 
 | ||||||
|     L3D.BaseRecommendation.apply(this); |     L3D.BaseRecommendation.apply(this, arguments); | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @type {L3D.FixedCamera} |      * @type {L3D.FixedCamera} | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|  */ |  */ | ||||||
| L3D.BaseRecommendation = function() { | L3D.BaseRecommendation = function() { | ||||||
| 
 | 
 | ||||||
|     THREE.Object3D.apply(this); |     THREE.Object3D.apply(this, arguments); | ||||||
| 
 | 
 | ||||||
|     this.camera = new THREE.PerspectiveCamera(); |     this.camera = new THREE.PerspectiveCamera(); | ||||||
|     this.camera.position.copy(arguments[4]); |     this.camera.position.copy(arguments[4]); | ||||||
|  | |||||||
| @ -712,11 +712,27 @@ L3D.initSponzaScene = function(scene, collidableObjects, recommendation, clickab | |||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| L3D.createSponzaCoins = function() { | L3D.createSponzaRecommendations = function(width, height) { | ||||||
|     return []; |    var createRecommendation = function(position, target) { | ||||||
|  |         return new Recommendation( | ||||||
|  |             50, | ||||||
|  |             width / height, | ||||||
|  |             1, | ||||||
|  |             100000, | ||||||
|  |             position, | ||||||
|  |             target | ||||||
|  |         ); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return [ | ||||||
|  |         createRecommendation( | ||||||
|  |                 new THREE.Vector3(97.36225946503932,10.925697484337014,12.852363038244272), | ||||||
|  |                 new THREE.Vector3(133.315101552449,18.576354168001703,-2.9229530646577633) | ||||||
|  |             ) | ||||||
|  |     ]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| L3D.createSponzaRecommendations = function() { | L3D.createSponzaCoins = function() { | ||||||
|     return []; |     return []; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -316,7 +316,8 @@ var availableMeshNames = { | |||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     '/static/data/sponza/sponza.obj': { |     '/static/data/sponza/sponza.obj': { | ||||||
|         done: false |         done: false, | ||||||
|  |         recommendations : L3D.createSponzaRecommendations(1134,768) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| @ -361,7 +362,8 @@ function pushMesh(name) { | |||||||
| 
 | 
 | ||||||
|                     geo.availableMeshes[name].recommendations.push({ |                     geo.availableMeshes[name].recommendations.push({ | ||||||
|                         position: reco.position, |                         position: reco.position, | ||||||
|                         frustum: frustum.planes |                         target: reco.target, | ||||||
|  |                         planes: frustum.planes | ||||||
|                     }); |                     }); | ||||||
| 
 | 
 | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -1,6 +1,19 @@ | |||||||
|  | var fs = require('fs'); | ||||||
| var THREE = require('three'); | var THREE = require('three'); | ||||||
| var L3D = require('../../static/js/l3d.min.js'); | var L3D = require('../../static/js/l3d.min.js'); | ||||||
| 
 | 
 | ||||||
|  | try | ||||||
|  | { | ||||||
|  |     var predictionTables = [ | ||||||
|  |         JSON.parse(fs.readFileSync('./mat1.json')), | ||||||
|  |         JSON.parse(fs.readFileSync('./mat2.json')), | ||||||
|  |         JSON.parse(fs.readFileSync('./mat3.json')) | ||||||
|  |     ]; | ||||||
|  | } catch (e) { | ||||||
|  |     process.stderr.write('No prefetching will be done !'); | ||||||
|  |     predictionTables = []; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function isInFrustum(element, planes) { | function isInFrustum(element, planes) { | ||||||
| 
 | 
 | ||||||
|     if (element instanceof Array) { |     if (element instanceof Array) { | ||||||
| @ -143,7 +156,9 @@ geo.MeshStreamer = function(path) { | |||||||
|      * Number of element to send by packet |      * Number of element to send by packet | ||||||
|      * @type {Number} |      * @type {Number} | ||||||
|      */ |      */ | ||||||
|     this.chunk = 1000; |     this.chunk = 500; | ||||||
|  | 
 | ||||||
|  |     this.previousReco = 0; | ||||||
| 
 | 
 | ||||||
|     if (path !== undefined) { |     if (path !== undefined) { | ||||||
| 
 | 
 | ||||||
| @ -155,7 +170,18 @@ geo.MeshStreamer = function(path) { | |||||||
| 
 | 
 | ||||||
| geo.MeshStreamer.prototype.isBackFace = function(camera, face) { | geo.MeshStreamer.prototype.isBackFace = function(camera, face) { | ||||||
| 
 | 
 | ||||||
|     var directionCamera = L3D.Tools.diff(camera.target, camera.position); |     var directionCamera = L3D.Tools.diff( | ||||||
|  |         L3D.Tools.mul( | ||||||
|  |             L3D.Tools.sum( | ||||||
|  |                 L3D.Tools.sum( | ||||||
|  |                     this.mesh.vertices[face.a], | ||||||
|  |                     this.mesh.vertices[face.b] | ||||||
|  |                 ), | ||||||
|  |                 this.mesh.vertices[face.c] | ||||||
|  |             ), | ||||||
|  |         1/3), | ||||||
|  |         camera.position | ||||||
|  |     ); | ||||||
| 
 | 
 | ||||||
|     var v1 = L3D.Tools.diff(this.mesh.vertices[face.b], this.mesh.vertices[face.a]); |     var v1 = L3D.Tools.diff(this.mesh.vertices[face.b], this.mesh.vertices[face.a]); | ||||||
|     var v2 = L3D.Tools.diff(this.mesh.vertices[face.c], this.mesh.vertices[face.a]); |     var v2 = L3D.Tools.diff(this.mesh.vertices[face.c], this.mesh.vertices[face.a]); | ||||||
| @ -260,6 +286,21 @@ geo.MeshStreamer.prototype.start = function(socket) { | |||||||
| 
 | 
 | ||||||
|         self.mesh = geo.availableMeshes[path]; |         self.mesh = geo.availableMeshes[path]; | ||||||
| 
 | 
 | ||||||
|  |         switch (path) { | ||||||
|  |             case '/static/data/bobomb/bobomb battlefeild.obj': | ||||||
|  |             case '/static/data/bobomb/bobomb battlefeild_sub.obj': | ||||||
|  |                 self.predictionTable = predictionTables[0]; | ||||||
|  |                 break; | ||||||
|  |             case '/static/data/mountain/coocoolmountain.obj': | ||||||
|  |             case '/static/data/mountain/coocoolmountain_sub.obj': | ||||||
|  |                 self.predictionTable = predictionTables[1]; | ||||||
|  |                 break; | ||||||
|  |             case '/static/data/whomp/Whomps Fortress.obj': | ||||||
|  |             case '/static/data/whomp/Whomps Fortress_sub.obj': | ||||||
|  |                 self.predictionTable = predictionTables[2]; | ||||||
|  |                 break; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|         if (self.mesh === undefined) { |         if (self.mesh === undefined) { | ||||||
|             process.stderr.write('Wrong path for model : ' + path); |             process.stderr.write('Wrong path for model : ' + path); | ||||||
|             socket.emit('refused'); |             socket.emit('refused'); | ||||||
| @ -290,16 +331,102 @@ geo.MeshStreamer.prototype.start = function(socket) { | |||||||
| 
 | 
 | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     socket.on('next', function(camera) { |     socket.on('reco', function(recoId) { | ||||||
| 
 | 
 | ||||||
|  |         self.previousReco = recoId + 1; | ||||||
|  | 
 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     socket.on('next', function(_camera) { | ||||||
|  | 
 | ||||||
|  |         var cameraFrustum = {}; | ||||||
|  | 
 | ||||||
|  |         // Clean camera attribute
 | ||||||
|  |         if (_camera !== null) { | ||||||
|  | 
 | ||||||
|  |             cameraFrustum = { | ||||||
|  |                 position: { | ||||||
|  |                     x: _camera[0][0], | ||||||
|  |                     y: _camera[0][1], | ||||||
|  |                     z: _camera[0][2] | ||||||
|  |                 }, | ||||||
|  |                 target: { | ||||||
|  |                     x: _camera[1][0], | ||||||
|  |                     y: _camera[1][1], | ||||||
|  |                     z: _camera[1][2] | ||||||
|  |                 }, | ||||||
|  |                 planes: [] | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             var shouldPrefetch = _camera[2]; | ||||||
|  | 
 | ||||||
|  |             for (i = 3; i < _camera.length; i++) { | ||||||
|  | 
 | ||||||
|  |                 cameraFrustum.planes.push({ | ||||||
|  |                     normal: { | ||||||
|  |                         x: _camera[i][0], | ||||||
|  |                         y: _camera[i][1], | ||||||
|  |                         z: _camera[i][2] | ||||||
|  |                     }, | ||||||
|  |                     constant: _camera[i][3] | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Find best recommendation
 | ||||||
|  |         var bestReco; | ||||||
|  |         var bestScore = -Infinity; | ||||||
|  |         var bestIndex = null; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         if (self.predictionTable !== undefined) { | ||||||
|  | 
 | ||||||
|  |             for (var i = 0; i < self.mesh.recommendations.length; i++) { | ||||||
|  | 
 | ||||||
|  |                 if (self.predictionTable[self.previousReco][i+1] > bestScore) { | ||||||
|  | 
 | ||||||
|  |                     bestReco = self.mesh.recommendations[i]; | ||||||
|  |                     bestScore = self.predictionTable[self.previousReco][i+1]; | ||||||
|  |                     bestIndex = i; | ||||||
|  | 
 | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } else { | ||||||
|  | 
 | ||||||
|  |             // For sponza
 | ||||||
|  |             bestReco = self.mesh.recommendations[0]; | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Create config for proportions of chunks
 | ||||||
|  |         var config = []; | ||||||
|  | 
 | ||||||
|  |         if (shouldPrefetch) { | ||||||
|  | 
 | ||||||
|  |             // Camera cull
 | ||||||
|  |             config.push({ | ||||||
|  |                 proportion: 0.5, | ||||||
|  |                 frustum: cameraFrustum | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             config.push({ | ||||||
|  |                 proportion: 0.5, | ||||||
|  |                 frustum: bestReco | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         // Send next elements
 |         // Send next elements
 | ||||||
|         var next = self.nextElements(camera); |         var next = self.nextElements(config); | ||||||
| 
 | 
 | ||||||
|         if (next.data.length === 0) { |         if (next.data.length === 0) { | ||||||
| 
 | 
 | ||||||
|             // If nothing, just serve stuff
 |             // If nothing, just serve stuff
 | ||||||
|             var tmp = self.nextElements(camera, true); |             var tmp = self.nextElements(); | ||||||
|             next.data = tmp.data; |             next.data = tmp.data; | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| @ -352,59 +479,10 @@ geo.MeshStreamer.prototype.nextMaterials = function() { | |||||||
|  * only interesting parts according to the camera |  * only interesting parts according to the camera | ||||||
|  * @returns {array} an array of elements ready to send |  * @returns {array} an array of elements ready to send | ||||||
|  */ |  */ | ||||||
| geo.MeshStreamer.prototype.nextElements = function(_camera, force) { | geo.MeshStreamer.prototype.nextElements = function(config) { | ||||||
| 
 | 
 | ||||||
|     var i; |     var i; | ||||||
| 
 | 
 | ||||||
|     if (force === undefined) { |  | ||||||
| 
 |  | ||||||
|         force = false; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Prepare camera (and scale to model)
 |  | ||||||
|     var camera = null; |  | ||||||
|     var planes = []; |  | ||||||
|     var direction; |  | ||||||
| 
 |  | ||||||
|     if (_camera !== null) { |  | ||||||
| 
 |  | ||||||
|         camera = { |  | ||||||
|             position: { |  | ||||||
|                 x: _camera[0][0], |  | ||||||
|                 y: _camera[0][1], |  | ||||||
|                 z: _camera[0][2] |  | ||||||
|             }, |  | ||||||
|             target: { |  | ||||||
|                 x: _camera[1][0], |  | ||||||
|                 y: _camera[1][1], |  | ||||||
|                 z: _camera[1][2] |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         for (i = 2; i < _camera.length; i++) { |  | ||||||
| 
 |  | ||||||
|             planes.push({ |  | ||||||
|                 normal: { |  | ||||||
|                     x: _camera[i][0], |  | ||||||
|                     y: _camera[i][1], |  | ||||||
|                     z: _camera[i][2] |  | ||||||
|                 }, |  | ||||||
|                 constant: _camera[i][3] |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Compute camera direction
 |  | ||||||
|         direction = { |  | ||||||
|             x: camera.target.x - camera.position.x, |  | ||||||
|             y: camera.target.y - camera.position.y, |  | ||||||
|             z: camera.target.z - camera.position.z |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     var sent = 0; |  | ||||||
|     var data = []; |     var data = []; | ||||||
| 
 | 
 | ||||||
|     var mightBeCompletetlyFinished = true; |     var mightBeCompletetlyFinished = true; | ||||||
| @ -413,133 +491,160 @@ geo.MeshStreamer.prototype.nextElements = function(_camera, force) { | |||||||
|     // if (camera != null)
 |     // if (camera != null)
 | ||||||
|     //     this.mesh.faces.sort(this.faceComparator(camera));
 |     //     this.mesh.faces.sort(this.faceComparator(camera));
 | ||||||
| 
 | 
 | ||||||
|     for (var faceIndex = 0; faceIndex < this.mesh.faces.length; faceIndex++) { |     if (config === undefined) { config = [] } | ||||||
| 
 | 
 | ||||||
|         var currentFace = this.mesh.faces[faceIndex]; |     configloop: | ||||||
|  |     for (var configIndex = 0; configIndex < config.length + 1; configIndex++) { | ||||||
| 
 | 
 | ||||||
|         if (this.faces[currentFace.index] === true) { |         var sent = 0; | ||||||
| 
 |  | ||||||
|             continue; |  | ||||||
| 
 | 
 | ||||||
|  |         // config[0] should always be cameraFrustum, with eventually 0 proportion
 | ||||||
|  |         var currentConfig = configIndex !== config.length ? config[configIndex] : config[0]; | ||||||
|  |         if (currentConfig === undefined) { | ||||||
|  |             currentConfig = { | ||||||
|  |                 proportion : Infinity, | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         mightBeCompletetlyFinished = false; |         for (var faceIndex = 0; faceIndex < this.mesh.faces.length; faceIndex++) { | ||||||
| 
 | 
 | ||||||
|         var vertex1 = this.mesh.vertices[currentFace.a]; |             var currentFace = this.mesh.faces[faceIndex]; | ||||||
|         var vertex2 = this.mesh.vertices[currentFace.b]; |  | ||||||
|         var vertex3 = this.mesh.vertices[currentFace.c]; |  | ||||||
| 
 | 
 | ||||||
|         if (!force && camera !== null) { |             if (this.faces[currentFace.index] === true) { | ||||||
| 
 | 
 | ||||||
|             var display = false; |  | ||||||
|             var exitToContinue = false; |  | ||||||
|             threeVertices = [vertex1, vertex2, vertex3]; |  | ||||||
| 
 |  | ||||||
|             // Frustum culling
 |  | ||||||
|             if (!isInFrustum(threeVertices, planes)) { |  | ||||||
|                 continue; |                 continue; | ||||||
|  | 
 | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Backface culling
 |             mightBeCompletetlyFinished = false; | ||||||
|             if (this.isBackFace(camera, currentFace)) { | 
 | ||||||
|                 continue; |             var vertex1 = this.mesh.vertices[currentFace.a]; | ||||||
|  |             var vertex2 = this.mesh.vertices[currentFace.b]; | ||||||
|  |             var vertex3 = this.mesh.vertices[currentFace.c]; | ||||||
|  | 
 | ||||||
|  |             if (currentConfig.frustum !== undefined) { | ||||||
|  | 
 | ||||||
|  |                 var display = false; | ||||||
|  |                 var exitToContinue = false; | ||||||
|  |                 threeVertices = [vertex1, vertex2, vertex3]; | ||||||
|  | 
 | ||||||
|  |                 // Frustum culling
 | ||||||
|  |                 if (!isInFrustum(threeVertices, currentConfig.frustum.planes)) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // Backface culling
 | ||||||
|  |                 if (this.isBackFace(currentConfig.frustum, currentFace)) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!this.vertices[currentFace.a]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(vertex1.toList()); | ||||||
|  |                 this.vertices[currentFace.a] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!this.vertices[currentFace.b]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(vertex2.toList()); | ||||||
|  |                 this.vertices[currentFace.b] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!this.vertices[currentFace.c]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(vertex3.toList()); | ||||||
|  |                 this.vertices[currentFace.c] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var normal1 = this.mesh.normals[currentFace.aNormal]; | ||||||
|  |             var normal2 = this.mesh.normals[currentFace.bNormal]; | ||||||
|  |             var normal3 = this.mesh.normals[currentFace.cNormal]; | ||||||
|  | 
 | ||||||
|  |             if (normal1 !== undefined && !this.normals[currentFace.aNormal]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(normal1.toList()); | ||||||
|  |                 this.normals[currentFace.aNormal] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (normal2 !== undefined && !this.normals[currentFace.bNormal]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(normal2.toList()); | ||||||
|  |                 this.normals[currentFace.bNormal] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (normal3 !== undefined && !this.normals[currentFace.cNormal]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(normal3.toList()); | ||||||
|  |                 this.normals[currentFace.cNormal] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var tex1 = this.mesh.texCoords[currentFace.aTexture]; | ||||||
|  |             var tex2 = this.mesh.texCoords[currentFace.bTexture]; | ||||||
|  |             var tex3 = this.mesh.texCoords[currentFace.cTexture]; | ||||||
|  | 
 | ||||||
|  |             if (tex1 !== undefined && !this.texCoords[currentFace.aTexture]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(tex1.toList()); | ||||||
|  |                 this.texCoords[currentFace.aTexture] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (tex2 !== undefined && !this.texCoords[currentFace.bTexture]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(tex2.toList()); | ||||||
|  |                 this.texCoords[currentFace.bTexture] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (tex3 !== undefined && !this.texCoords[currentFace.cTexture]) { | ||||||
|  | 
 | ||||||
|  |                 data.push(tex3.toList()); | ||||||
|  |                 this.texCoords[currentFace.cTexture] = true; | ||||||
|  |                 sent++; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             data.push(currentFace.toList()); | ||||||
|  |             // this.meshFaces[meshIndex] = this.meshFaces[meshIndex] || [];
 | ||||||
|  |             this.faces[currentFace.index] = true; | ||||||
|  |             // this.meshFaces[meshIndex].counter++;
 | ||||||
|  |             // currentMesh.faceIndex++;
 | ||||||
|  | 
 | ||||||
|  |             sent++; | ||||||
|  | 
 | ||||||
|  |             if (data.length > this.chunk) { | ||||||
|  | 
 | ||||||
|  |                 // console.log(configIndex, sent/(this.chunk * currentConfig.proportion));
 | ||||||
|  |                 return {data: data, finsihed:false}; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (sent > this.chunk * currentConfig.proportion) { | ||||||
|  | 
 | ||||||
|  |                 // console.log(configIndex, sent/(this.chunk * currentConfig.proportion));
 | ||||||
|  |                 continue configloop; | ||||||
|  | 
 | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!this.vertices[currentFace.a]) { |         return {data: data, finished: mightBeCompletetlyFinished}; | ||||||
| 
 |  | ||||||
|             data.push(vertex1.toList()); |  | ||||||
|             this.vertices[currentFace.a] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.vertices[currentFace.b]) { |  | ||||||
| 
 |  | ||||||
|             data.push(vertex2.toList()); |  | ||||||
|             this.vertices[currentFace.b] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.vertices[currentFace.c]) { |  | ||||||
| 
 |  | ||||||
|             data.push(vertex3.toList()); |  | ||||||
|             this.vertices[currentFace.c] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         var normal1 = this.mesh.normals[currentFace.aNormal]; |  | ||||||
|         var normal2 = this.mesh.normals[currentFace.bNormal]; |  | ||||||
|         var normal3 = this.mesh.normals[currentFace.cNormal]; |  | ||||||
| 
 |  | ||||||
|         if (normal1 !== undefined && !this.normals[currentFace.aNormal]) { |  | ||||||
| 
 |  | ||||||
|             data.push(normal1.toList()); |  | ||||||
|             this.normals[currentFace.aNormal] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (normal2 !== undefined && !this.normals[currentFace.bNormal]) { |  | ||||||
| 
 |  | ||||||
|             data.push(normal2.toList()); |  | ||||||
|             this.normals[currentFace.bNormal] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (normal3 !== undefined && !this.normals[currentFace.cNormal]) { |  | ||||||
| 
 |  | ||||||
|             data.push(normal3.toList()); |  | ||||||
|             this.normals[currentFace.cNormal] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         var tex1 = this.mesh.texCoords[currentFace.aTexture]; |  | ||||||
|         var tex2 = this.mesh.texCoords[currentFace.bTexture]; |  | ||||||
|         var tex3 = this.mesh.texCoords[currentFace.cTexture]; |  | ||||||
| 
 |  | ||||||
|         if (tex1 !== undefined && !this.texCoords[currentFace.aTexture]) { |  | ||||||
| 
 |  | ||||||
|             data.push(tex1.toList()); |  | ||||||
|             this.texCoords[currentFace.aTexture] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (tex2 !== undefined && !this.texCoords[currentFace.bTexture]) { |  | ||||||
| 
 |  | ||||||
|             data.push(tex2.toList()); |  | ||||||
|             this.texCoords[currentFace.bTexture] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (tex3 !== undefined && !this.texCoords[currentFace.cTexture]) { |  | ||||||
| 
 |  | ||||||
|             data.push(tex3.toList()); |  | ||||||
|             this.texCoords[currentFace.cTexture] = true; |  | ||||||
|             sent++; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         data.push(currentFace.toList()); |  | ||||||
|         // this.meshFaces[meshIndex] = this.meshFaces[meshIndex] || [];
 |  | ||||||
|         this.faces[currentFace.index] = true; |  | ||||||
|         // this.meshFaces[meshIndex].counter++;
 |  | ||||||
|         // currentMesh.faceIndex++;
 |  | ||||||
| 
 |  | ||||||
|         sent++; |  | ||||||
| 
 |  | ||||||
|         if (sent > this.chunk) { |  | ||||||
| 
 |  | ||||||
|             return {data: data, finished: false}; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return {data: data, finished: mightBeCompletetlyFinished}; |     return {data: data, finished: mightBeCompletetlyFinished}; | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| let fs = require('fs'); | let fs = require('fs'); | ||||||
| let THREE = require('three'); | let THREE = require('three'); | ||||||
| let L3D = require('../static/js/l3d.min.js'); | let L3D = require('../../static/js/l3d.min.js'); | ||||||
| 
 | 
 | ||||||
| function serialize(object) { | function serialize(object) { | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user