Prefetching working now
This commit is contained in:
parent
844982e552
commit
f4e06c9c28
|
@ -1,105 +0,0 @@
|
||||||
#!/usr/bin/node
|
|
||||||
var lib = require('./lib.js');
|
|
||||||
var r = require('./initScene.js');
|
|
||||||
|
|
||||||
var reco = [
|
|
||||||
r.createPeachRecommendations(),
|
|
||||||
r.createBobombRecommendations(),
|
|
||||||
r.createMountainRecommendations(),
|
|
||||||
r.createWhompRecommendations()
|
|
||||||
];
|
|
||||||
|
|
||||||
function distanceBetweenPoints(pt1, pt2) {
|
|
||||||
return (
|
|
||||||
Math.sqrt(
|
|
||||||
(pt2.x - pt1.x) * (pt2.x - pt1.x) +
|
|
||||||
(pt2.y - pt1.y) * (pt2.y - pt1.y) +
|
|
||||||
(pt2.z - pt1.z) * (pt2.z - pt1.z)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function main(path) {
|
|
||||||
|
|
||||||
var db = lib.loadFromFile(path);
|
|
||||||
var groups = lib.makeGroups(db);
|
|
||||||
|
|
||||||
// Erase groups that are not usable
|
|
||||||
var invalid = 0;
|
|
||||||
groups = groups.filter(function(elt) {
|
|
||||||
|
|
||||||
// An elt is valid if it contains at least 2 exp, BaseRecommendation included
|
|
||||||
if (elt.length > 1 && elt.find(function(e) { return e.recommendation_style[4] === 'B'; }) !== undefined) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
invalid++;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
var percentSum = 0;
|
|
||||||
var eltNum = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < db.experiments.length; i++) {
|
|
||||||
|
|
||||||
var exp = db.experiments[i];
|
|
||||||
|
|
||||||
if (exp.coinCombination.scene_id === 1 || exp.recommendation_style[4] === 'B' || !exp.finished || lib.coinsGot(exp) < 6) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eltNum++;
|
|
||||||
|
|
||||||
var distance = 0;
|
|
||||||
var distanceWithReco = 0;
|
|
||||||
|
|
||||||
|
|
||||||
var j = 0;
|
|
||||||
|
|
||||||
while (exp.elements.events[j].position === undefined) { j++; };
|
|
||||||
|
|
||||||
var startPosition = exp.elements.events[j].position;
|
|
||||||
j++;
|
|
||||||
|
|
||||||
while (j < exp.elements.events.length) {
|
|
||||||
|
|
||||||
var nextPosition, evt = exp.elements.events[j];
|
|
||||||
|
|
||||||
if (evt.position === undefined && evt.type !== 'arrow') { j++; continue; }
|
|
||||||
|
|
||||||
if (evt.type === 'arrow') {
|
|
||||||
nextPosition = reco[exp.coinCombination.scene_id - 1][evt.id].position;
|
|
||||||
} else {
|
|
||||||
nextPosition = evt.position;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp = distanceBetweenPoints(startPosition, nextPosition);
|
|
||||||
|
|
||||||
if (evt.type === 'arrow') {
|
|
||||||
distanceWithReco += tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
distance += tmp;
|
|
||||||
|
|
||||||
startPosition = nextPosition;
|
|
||||||
|
|
||||||
j++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
percentSum += 100 * distanceWithReco / distance;
|
|
||||||
console.log(exp.id + ' -> ' + Math.floor(100 * distanceWithReco / distance) + '%');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Mean : ' + percentSum / eltNum);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.argv.length !== 3) {
|
|
||||||
process.stderr.write('Error : please give me a JSON file to work on\n');
|
|
||||||
process.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
main(process.argv[2])
|
|
|
@ -181,6 +181,8 @@ L3D.PointerCamera = function() {
|
||||||
* @param {Object}
|
* @param {Object}
|
||||||
*/
|
*/
|
||||||
this.resetElements = {position: new THREE.Vector3(0,1,1), target: new THREE.Vector3()};
|
this.resetElements = {position: new THREE.Vector3(0,1,1), target: new THREE.Vector3()};
|
||||||
|
|
||||||
|
this.recommendationClicked = null;
|
||||||
};
|
};
|
||||||
L3D.PointerCamera.prototype = Object.create(THREE.PerspectiveCamera.prototype);
|
L3D.PointerCamera.prototype = Object.create(THREE.PerspectiveCamera.prototype);
|
||||||
L3D.PointerCamera.prototype.constructor = L3D.PointerCamera;
|
L3D.PointerCamera.prototype.constructor = L3D.PointerCamera;
|
||||||
|
@ -323,6 +325,7 @@ L3D.PointerCamera.prototype.hermiteMotion = function(time) {
|
||||||
|
|
||||||
if (this.t > 1) {
|
if (this.t > 1) {
|
||||||
this.movingHermite = false;
|
this.movingHermite = false;
|
||||||
|
this.recommendationClicked = null;
|
||||||
this.anglesFromVectors();
|
this.anglesFromVectors();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -491,6 +494,8 @@ L3D.PointerCamera.prototype.moveHermite = function(recommendation, toSave) {
|
||||||
|
|
||||||
var otherCamera = recommendation.camera || recommendation;
|
var otherCamera = recommendation.camera || recommendation;
|
||||||
|
|
||||||
|
this.recommendationClicked = otherCamera;
|
||||||
|
|
||||||
this.moving = false;
|
this.moving = false;
|
||||||
this.movingHermite = true;
|
this.movingHermite = true;
|
||||||
this.t = 0;
|
this.t = 0;
|
||||||
|
@ -762,7 +767,9 @@ L3D.PointerCamera.prototype.toList = function() {
|
||||||
|
|
||||||
var ret =
|
var ret =
|
||||||
[[this.position.x, this.position.y, this.position.z],
|
[[this.position.x, this.position.y, this.position.z],
|
||||||
[this.target.x, this.target.y, this.target.z]];
|
[this.target.x, this.target.y, this.target.z],
|
||||||
|
this.recommendationClicked !== null
|
||||||
|
];
|
||||||
|
|
||||||
for (var i = 0; i < frustum.planes.length; i++) {
|
for (var i = 0; i < frustum.planes.length; i++) {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
L3D.ProgressiveLoader = (function() {
|
L3D.ProgressiveLoader = (function() {
|
||||||
|
|
||||||
|
if (typeof process === 'undefined') {
|
||||||
|
process = {
|
||||||
|
stderr : {
|
||||||
|
write: function(str) {
|
||||||
|
console.log(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a list as it is sent by the server and gives a slightly more comprehensible result
|
* Parse a list as it is sent by the server and gives a slightly more comprehensible result
|
||||||
* @param Array array corresponding to the line of the mesh file
|
* @param Array array corresponding to the line of the mesh file
|
||||||
|
@ -88,7 +98,7 @@ var _parseList = function(arr) {
|
||||||
* @constructor
|
* @constructor
|
||||||
* @memberOf L3D
|
* @memberOf L3D
|
||||||
*/
|
*/
|
||||||
var ProgressiveLoader = function(path, scene, camera, callback, log, laggy) {
|
var ProgressiveLoader = function(path, scene, camera, callback, log, laggy, prefetch) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -186,12 +196,24 @@ var ProgressiveLoader = function(path, scene, camera, callback, log, laggy) {
|
||||||
*/
|
*/
|
||||||
this.camera = camera;
|
this.camera = camera;
|
||||||
|
|
||||||
this.camera._moveReco = this.camera.moveReco;
|
if (this.camera instanceof L3D.ReplayCamera) {
|
||||||
|
this.camera._moveReco = this.camera.moveReco;
|
||||||
|
|
||||||
this.camera.moveReco = function(param) {
|
this.camera.moveReco = function(param) {
|
||||||
self.socket.emit('reco', param);
|
self.socket.emit('reco', param);
|
||||||
self.camera._moveReco.apply(self.camera, arguments);
|
self.camera._moveReco.apply(self.camera, arguments);
|
||||||
};
|
};
|
||||||
|
} else if (this.camera instanceof L3D.PointerCamera) {
|
||||||
|
// Only good for sponza model
|
||||||
|
this.camera._moveHermite = this.camera.moveHermite;
|
||||||
|
|
||||||
|
this.camera.moveHermite = function(param) {
|
||||||
|
var toSend = param.position.x > 0 ? 0 : 1;
|
||||||
|
self.socket.emit('reco', toSend);
|
||||||
|
self.camera._moveHermite.apply(self.camera, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of total elements for loading
|
* Number of total elements for loading
|
||||||
|
@ -220,6 +242,9 @@ var ProgressiveLoader = function(path, scene, camera, callback, log, laggy) {
|
||||||
|
|
||||||
this.mapFace = {};
|
this.mapFace = {};
|
||||||
|
|
||||||
|
this.prefetch = prefetch === undefined ? true : (!!prefetch);
|
||||||
|
console.log(this.prefetch);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ProgressiveLoader.prototype.hasFace = function(face) {
|
ProgressiveLoader.prototype.hasFace = function(face) {
|
||||||
|
@ -277,6 +302,8 @@ ProgressiveLoader.prototype.initIOCallbacks = function() {
|
||||||
|
|
||||||
this.socket.on('elements', function(arr) {
|
this.socket.on('elements', function(arr) {
|
||||||
|
|
||||||
|
process.stderr.write('Received ' + arr.length + '\n');
|
||||||
|
|
||||||
for (var i = 0; i < arr.length; i++) {
|
for (var i = 0; i < arr.length; i++) {
|
||||||
|
|
||||||
if (typeof self.log === 'function' && self.numberOfFacesReceived % self.modulus === 0) {
|
if (typeof self.log === 'function' && self.numberOfFacesReceived % self.modulus === 0) {
|
||||||
|
@ -360,6 +387,8 @@ ProgressiveLoader.prototype.initIOCallbacks = function() {
|
||||||
|
|
||||||
self.numberOfFacesReceived++;
|
self.numberOfFacesReceived++;
|
||||||
|
|
||||||
|
self.mapFace[elt.a + '-' + elt.b + '-' + elt.c] = true;
|
||||||
|
|
||||||
if (!self.meshes[elt.mesh].added) {
|
if (!self.meshes[elt.mesh].added) {
|
||||||
|
|
||||||
self.meshes[elt.mesh].added = true;
|
self.meshes[elt.mesh].added = true;
|
||||||
|
@ -392,7 +421,6 @@ ProgressiveLoader.prototype.initIOCallbacks = function() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mapFace[elt.a + '-' + elt.b + '-' + elt.c] = true;
|
|
||||||
|
|
||||||
|
|
||||||
} else if (elt.type === 'global') {
|
} else if (elt.type === 'global') {
|
||||||
|
@ -436,7 +464,7 @@ ProgressiveLoader.prototype.initIOCallbacks = function() {
|
||||||
* Starts the communication with the server
|
* Starts the communication with the server
|
||||||
*/
|
*/
|
||||||
ProgressiveLoader.prototype.start = function() {
|
ProgressiveLoader.prototype.start = function() {
|
||||||
this.socket.emit('request', this.objPath, this.laggy);
|
this.socket.emit('request', this.objPath, this.laggy, this.prefetch);
|
||||||
};
|
};
|
||||||
|
|
||||||
return ProgressiveLoader;
|
return ProgressiveLoader;
|
||||||
|
|
|
@ -726,9 +726,13 @@ L3D.createSponzaRecommendations = function(width, height) {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
createRecommendation(
|
createRecommendation(
|
||||||
new THREE.Vector3(97.36225946503932,10.925697484337014,12.852363038244272),
|
new THREE.Vector3(97.36225946503932,10.925697484337014,12.852363038244272),
|
||||||
new THREE.Vector3(133.315101552449,18.576354168001703,-2.9229530646577633)
|
new THREE.Vector3(133.315101552449,18.576354168001703,-2.9229530646577633)
|
||||||
)
|
),
|
||||||
|
createRecommendation(
|
||||||
|
new THREE.Vector3(-110.4869853758238,17.692671522169423,14.022902297589127),
|
||||||
|
new THREE.Vector3(-147.9067343700736,16.890814116754584,-0.08806541935797796)
|
||||||
|
)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,12 @@ var L3D = require('../../static/js/l3d.min.js');
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var predictionTables = [
|
var predictionTables = [
|
||||||
JSON.parse(fs.readFileSync('./mat1.json')),
|
JSON.parse(fs.readFileSync('./geo/mat1.json')),
|
||||||
JSON.parse(fs.readFileSync('./mat2.json')),
|
JSON.parse(fs.readFileSync('./geo/mat2.json')),
|
||||||
JSON.parse(fs.readFileSync('./mat3.json'))
|
JSON.parse(fs.readFileSync('./geo/mat3.json')),
|
||||||
|
[[1,1,0],
|
||||||
|
[1,2,0],
|
||||||
|
[2,1,0]]
|
||||||
];
|
];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
process.stderr.write('No prefetching will be done !');
|
process.stderr.write('No prefetching will be done !');
|
||||||
|
@ -25,7 +28,7 @@ function isInFrustum(element, planes) {
|
||||||
var vertex = element[i];
|
var vertex = element[i];
|
||||||
var currentOutcode = "";
|
var currentOutcode = "";
|
||||||
|
|
||||||
for (var j = 0; j < planes.length; j++) {
|
for (var j = 0; j < planes.length; j++) {
|
||||||
|
|
||||||
var plane = planes[j];
|
var plane = planes[j];
|
||||||
|
|
||||||
|
@ -156,7 +159,7 @@ geo.MeshStreamer = function(path) {
|
||||||
* Number of element to send by packet
|
* Number of element to send by packet
|
||||||
* @type {Number}
|
* @type {Number}
|
||||||
*/
|
*/
|
||||||
this.chunk = 500;
|
this.chunk = 5000;
|
||||||
|
|
||||||
this.previousReco = 0;
|
this.previousReco = 0;
|
||||||
|
|
||||||
|
@ -278,12 +281,14 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
socket.on('request', function(path, laggy) {
|
socket.on('request', function(path, laggy, prefetch) {
|
||||||
|
|
||||||
if (laggy === true) {
|
if (laggy === true) {
|
||||||
self.chunk = 1;
|
self.chunk = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.prefetch = prefetch;
|
||||||
|
|
||||||
self.mesh = geo.availableMeshes[path];
|
self.mesh = geo.availableMeshes[path];
|
||||||
|
|
||||||
switch (path) {
|
switch (path) {
|
||||||
|
@ -299,6 +304,8 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
||||||
case '/static/data/whomp/Whomps Fortress_sub.obj':
|
case '/static/data/whomp/Whomps Fortress_sub.obj':
|
||||||
self.predictionTable = predictionTables[2];
|
self.predictionTable = predictionTables[2];
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
self.predictionTable = predictionTables[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (self.mesh === undefined) {
|
if (self.mesh === undefined) {
|
||||||
|
@ -358,7 +365,7 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
||||||
planes: []
|
planes: []
|
||||||
};
|
};
|
||||||
|
|
||||||
var shouldPrefetch = _camera[2];
|
var fullFrustum = _camera[2];
|
||||||
|
|
||||||
for (i = 3; i < _camera.length; i++) {
|
for (i = 3; i < _camera.length; i++) {
|
||||||
|
|
||||||
|
@ -375,60 +382,122 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find best recommendation
|
// Create config for proportions of chunks
|
||||||
var bestReco;
|
var config;
|
||||||
var bestScore = -Infinity;
|
|
||||||
var bestIndex = null;
|
|
||||||
|
|
||||||
|
if (self.prefetch) {
|
||||||
|
|
||||||
if (self.predictionTable !== undefined) {
|
config = [{ frustum: cameraFrustum, proportion : 0.5}];
|
||||||
|
|
||||||
for (var i = 0; i < self.mesh.recommendations.length; i++) {
|
// Find best recommendation
|
||||||
|
var bestReco;
|
||||||
|
var bestScore = -Infinity;
|
||||||
|
var bestIndex = null;
|
||||||
|
|
||||||
if (self.predictionTable[self.previousReco][i+1] > bestScore) {
|
if (self.predictionTable !== undefined) {
|
||||||
|
|
||||||
bestReco = self.mesh.recommendations[i];
|
var sum = 0;
|
||||||
bestScore = self.predictionTable[self.previousReco][i+1];
|
|
||||||
bestIndex = i;
|
for (var i = 0; i < self.mesh.recommendations.length; i++) {
|
||||||
|
|
||||||
|
sum += self.predictionTable[self.previousReco][i];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < self.mesh.recommendations.length; i++) {
|
||||||
|
|
||||||
|
if (self.predictionTable[self.previousReco][i] > 0) {
|
||||||
|
|
||||||
|
config.push({
|
||||||
|
|
||||||
|
proportion : self.predictionTable[self.previousReco][i] / (2 * sum),
|
||||||
|
frustum : self.mesh.recommendations[i]
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(config.map(function(o) { return o.proportion; }));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// For sponza
|
||||||
|
bestReco = self.mesh.recommendations[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fullFrustum) {
|
||||||
|
|
||||||
|
// console.log('Frustum and prefetch : ' + (cameraFrustum !== undefined) + ' ' + (bestReco !== undefined));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// console.log('Full frustum fetching (reco clicked)');
|
||||||
|
|
||||||
|
config = [{
|
||||||
|
proportion: 1,
|
||||||
|
frustum: cameraFrustum
|
||||||
|
}];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// For sponza
|
config = [{frustum: cameraFrustum, proportion: 1}];
|
||||||
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 oldTime = Date.now();
|
||||||
var next = self.nextElements(config);
|
var next = self.nextElements(config);
|
||||||
|
|
||||||
|
// console.log(next.configSizes);
|
||||||
|
|
||||||
|
// console.log('Time to generate chunk : ' + (Date.now() - oldTime) + 'ms');
|
||||||
|
|
||||||
if (next.data.length === 0) {
|
if (next.data.length === 0) {
|
||||||
|
|
||||||
// If nothing, just serve stuff
|
// If nothing, just serve stuff
|
||||||
var tmp = self.nextElements();
|
var tmp = self.nextElements([
|
||||||
|
// {
|
||||||
|
// proportion: 1,
|
||||||
|
// frustum: cameraFrustum
|
||||||
|
// }
|
||||||
|
]);
|
||||||
next.data = tmp.data;
|
next.data = tmp.data;
|
||||||
|
|
||||||
|
} else if (!self.prefetch && next.size < this.chunk) {
|
||||||
|
|
||||||
|
// Recompute config
|
||||||
|
var newConfig = [];
|
||||||
|
var sum = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < config.length; i++) {
|
||||||
|
|
||||||
|
// Check if config was full
|
||||||
|
if (next.configSizes[i] < this.chunk * config[i].proportion) {
|
||||||
|
|
||||||
|
newConfig.push(config[i]);
|
||||||
|
sum += config[i].proportion;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < newConfig.length; i++) {
|
||||||
|
|
||||||
|
newConfig[i].proportion /= sum;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize config probabilities
|
||||||
|
|
||||||
|
var newData = self.nextElements(newConfig, this.chunk - next.size);
|
||||||
|
|
||||||
|
next.data = next.data.push.apply(next.data, newData.data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.emit('elements', next.data);
|
socket.emit('elements', next.data);
|
||||||
|
@ -479,175 +548,186 @@ 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(config) {
|
geo.MeshStreamer.prototype.nextElements = function(config, chunk) {
|
||||||
|
|
||||||
|
if (chunk === undefined)
|
||||||
|
chunk = this.chunk;
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
var data = [];
|
var data = [];
|
||||||
|
|
||||||
|
var configSizes = [];
|
||||||
|
|
||||||
var mightBeCompletetlyFinished = true;
|
var mightBeCompletetlyFinished = true;
|
||||||
|
|
||||||
// BOOM
|
// BOOM
|
||||||
// if (camera != null)
|
// if (camera != null)
|
||||||
// this.mesh.faces.sort(this.faceComparator(camera));
|
// this.mesh.faces.sort(this.faceComparator(camera));
|
||||||
|
|
||||||
if (config === undefined) { config = [] }
|
if (config.length === 0) {
|
||||||
|
config.push({
|
||||||
|
proportion: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
configloop:
|
totalSize = 0;
|
||||||
for (var configIndex = 0; configIndex < config.length + 1; configIndex++) {
|
for (var configIndex = 0; configIndex < config.length; configIndex++) {
|
||||||
|
|
||||||
var sent = 0;
|
configSizes[configIndex] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
faceloop:
|
||||||
|
for (var faceIndex = 0; faceIndex < this.mesh.faces.length; faceIndex++) {
|
||||||
|
|
||||||
|
var currentFace = this.mesh.faces[faceIndex];
|
||||||
|
|
||||||
|
if (this.faces[currentFace.index] === true) {
|
||||||
|
|
||||||
|
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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var faceIndex = 0; faceIndex < this.mesh.faces.length; faceIndex++) {
|
mightBeCompletetlyFinished = false;
|
||||||
|
|
||||||
var currentFace = this.mesh.faces[faceIndex];
|
var vertex1 = this.mesh.vertices[currentFace.a];
|
||||||
|
var vertex2 = this.mesh.vertices[currentFace.b];
|
||||||
|
var vertex3 = this.mesh.vertices[currentFace.c];
|
||||||
|
|
||||||
if (this.faces[currentFace.index] === true) {
|
for (var configIndex = 0; configIndex < config.length; configIndex++) {
|
||||||
|
|
||||||
continue;
|
var currentConfig = config[configIndex];
|
||||||
|
|
||||||
}
|
if ( configSizes[configIndex] < chunk * currentConfig.proportion) {
|
||||||
|
|
||||||
mightBeCompletetlyFinished = false;
|
|
||||||
|
|
||||||
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 display = false;
|
||||||
var exitToContinue = false;
|
var exitToContinue = false;
|
||||||
threeVertices = [vertex1, vertex2, vertex3];
|
var threeVertices = [vertex1, vertex2, vertex3];
|
||||||
|
|
||||||
// Frustum culling
|
// Frustum culling
|
||||||
if (!isInFrustum(threeVertices, currentConfig.frustum.planes)) {
|
if (currentConfig.frustum === undefined || (isInFrustum(threeVertices, currentConfig.frustum.planes) && !this.isBackFace(currentConfig.frustum, currentFace))) {
|
||||||
continue;
|
|
||||||
|
// Send face
|
||||||
|
if (!this.vertices[currentFace.a]) {
|
||||||
|
|
||||||
|
data.push(vertex1.toList());
|
||||||
|
this.vertices[currentFace.a] = true;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.vertices[currentFace.b]) {
|
||||||
|
|
||||||
|
data.push(vertex2.toList());
|
||||||
|
this.vertices[currentFace.b] = true;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.vertices[currentFace.c]) {
|
||||||
|
|
||||||
|
data.push(vertex3.toList());
|
||||||
|
this.vertices[currentFace.c] = true;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
totalSize++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normal2 !== undefined && !this.normals[currentFace.bNormal]) {
|
||||||
|
|
||||||
|
data.push(normal2.toList());
|
||||||
|
this.normals[currentFace.bNormal] = true;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
totalSize++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normal3 !== undefined && !this.normals[currentFace.cNormal]) {
|
||||||
|
|
||||||
|
data.push(normal3.toList());
|
||||||
|
this.normals[currentFace.cNormal] = true;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
totalSize++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
totalSize++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex2 !== undefined && !this.texCoords[currentFace.bTexture]) {
|
||||||
|
|
||||||
|
data.push(tex2.toList());
|
||||||
|
this.texCoords[currentFace.bTexture] = true;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
totalSize++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex3 !== undefined && !this.texCoords[currentFace.cTexture]) {
|
||||||
|
|
||||||
|
data.push(tex3.toList());
|
||||||
|
this.texCoords[currentFace.cTexture] = true;
|
||||||
|
configSizes[configIndex]++;
|
||||||
|
totalSize++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data.push(currentFace.toList());
|
||||||
|
// this.meshFaces[meshIndex] = this.meshFaces[meshIndex] || [];
|
||||||
|
this.faces[currentFace.index] = true;
|
||||||
|
configSizes[configIndex]+=3;
|
||||||
|
totalSize+=3;
|
||||||
|
// this.meshFaces[meshIndex].counter++;
|
||||||
|
// currentMesh.faceIndex++;
|
||||||
|
|
||||||
|
// if (totalSize > chunk) {
|
||||||
|
|
||||||
|
// // console.log(configIndex, sent/(chunk * currentConfig.proportion));
|
||||||
|
// return {data: data, finsihed:false, configSizes: configSizes, size: totalSize};
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Loop on next face
|
||||||
|
continue faceloop;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backface culling
|
|
||||||
if (this.isBackFace(currentConfig.frustum, currentFace)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.vertices[currentFace.a]) {
|
if (totalSize > chunk) {
|
||||||
|
|
||||||
data.push(vertex1.toList());
|
// console.log(configIndex, sent/(chunk * currentConfig.proportion));
|
||||||
this.vertices[currentFace.a] = true;
|
return {data: data, finsihed:false, configSizes: configSizes, size: totalSize};
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {data: data, finished: mightBeCompletetlyFinished};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {data: data, finished: mightBeCompletetlyFinished};
|
return {data: data, finished: mightBeCompletetlyFinished, configSizes: configSizes};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue