Modif
This commit is contained in:
parent
adbd3c95f1
commit
df876748c1
|
@ -0,0 +1,71 @@
|
|||
diffTable;
|
||||
|
||||
EXP_ID = 1;
|
||||
ARROW_ID = 2;
|
||||
STARTED = 3;
|
||||
TIME = 4;
|
||||
|
||||
% Compute diff tables, and split by exps
|
||||
|
||||
hovers = {};
|
||||
map = [];
|
||||
|
||||
start = 1;
|
||||
current_exp_id = M(1,EXP_ID);
|
||||
|
||||
for i = 1:length(M),
|
||||
|
||||
if M(i, EXP_ID) ~= current_exp_id,
|
||||
|
||||
current_exp_id = M(i, EXP_ID);
|
||||
start = start + 1;
|
||||
|
||||
end
|
||||
|
||||
map(i) = start;
|
||||
|
||||
end
|
||||
|
||||
hovers = cell(max(map), 1);
|
||||
|
||||
is_hovering = false;
|
||||
current_hover = -1;
|
||||
current_time = 0;
|
||||
|
||||
for i = 1:length(M),
|
||||
|
||||
if M(i, STARTED),
|
||||
|
||||
if (current_hover ~= -1 && M(i, ARROW_ID) ~= current_hover && is_hovering),
|
||||
|
||||
% Add line for previous hovering
|
||||
hovers{map(M(i, EXP_ID))} = [hovers{map(M(i, EXP_ID))}; M(i, TIME) - current_time];
|
||||
|
||||
end
|
||||
|
||||
current_hover = M(i, ARROW_ID);
|
||||
current_time = M(i, TIME);
|
||||
|
||||
else
|
||||
|
||||
hovers{map(M(i, EXP_ID))} = [hovers{map(M(i, EXP_ID))}; M(i, TIME) - current_time];
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
% All hover time
|
||||
all_hovers = sort(vertcat(hovers{:}));
|
||||
|
||||
times = 0:0.001:0.6;
|
||||
|
||||
curve = zeros(length(times),1);
|
||||
|
||||
for i = 1 : length(times),
|
||||
|
||||
curve(i) = sum(all_hovers < times(i));
|
||||
|
||||
end
|
||||
|
||||
plot(times, curve);
|
||||
|
|
@ -24,6 +24,7 @@ let modelMap;
|
|||
let smallMap;
|
||||
let smallModel;
|
||||
let triangleMeshes = [];
|
||||
let colorToFace = [];
|
||||
|
||||
let renderer = new THREE.CanvasRenderer();
|
||||
renderer.domElement.style = renderer.domElement;
|
||||
|
@ -45,6 +46,7 @@ scene.add(mesh);
|
|||
scene.add(camera);
|
||||
|
||||
let counter = 0;
|
||||
let forceFinished = false;
|
||||
|
||||
init()
|
||||
|
||||
|
@ -78,7 +80,7 @@ function init() {
|
|||
}
|
||||
|
||||
progLoader = new L3D.ProgressiveLoader(
|
||||
buildPathBigObj(path), scene, info.camera, null, function(a,b) { /* process.stderr.write((100*a/b) + '%\n'); */ }, false, info.sort
|
||||
buildPathBigObj(path), new THREE.Object3D(), info.camera, null, function(a,b) { /* process.stderr.write((100*a/b) + '%\n'); */ }, false, info.sort
|
||||
);
|
||||
|
||||
// Init variables
|
||||
|
@ -104,6 +106,7 @@ function init() {
|
|||
|
||||
face3.materialIndex = counter;
|
||||
material.materials.push(new THREE.MeshBasicMaterial({color: counter, overdraw: true}));
|
||||
colorToFace[counter] = face3;
|
||||
|
||||
geometry.faces.push(face3);
|
||||
|
||||
|
@ -116,12 +119,12 @@ function init() {
|
|||
|
||||
}
|
||||
|
||||
process.stderr.write('Loading complete.\n');
|
||||
process.stderr.write('--> Loading complete.\n');
|
||||
|
||||
progLoader.onBeforeEmit = loop;
|
||||
|
||||
progLoader.load(function() {
|
||||
process.stderr.write("Loading complete\n");
|
||||
process.stderr.write("--> Loading complete\n");
|
||||
forceFinished = true;
|
||||
});
|
||||
|
||||
|
@ -144,19 +147,50 @@ function buildPathMap(path) { return './maps/' + path.name + '.json'; }
|
|||
|
||||
function loop() {
|
||||
|
||||
process.stderr.write(imageNumber + '\n');
|
||||
process.stderr.write('--> ' + imageNumber + '\n');
|
||||
|
||||
for (let i = 0; i < 10; i++)
|
||||
camera.update(20);
|
||||
|
||||
camera.look();
|
||||
|
||||
process.stderr.write('Rendering...\n');
|
||||
process.stderr.write('--> Rendering...\n');
|
||||
let lastTime = Date.now();
|
||||
renderer.render(scene, camera);
|
||||
process.stderr.write('Renderered in ' + (Date.now() - lastTime) + '\n');
|
||||
process.stderr.write('--> Renderered in ' + (Date.now() - lastTime) + '\n');
|
||||
|
||||
fs.writeFileSync(__dirname + '/img/' + pad(imageNumber++, 5) + '.png', renderer.domElement.toBuffer());
|
||||
fs.writeFileSync(__dirname + '/img' + (info.sort ? '1' : '') + '/' + pad(imageNumber++, 5) + '.png', renderer.domElement.toBuffer());
|
||||
|
||||
let score = 0;
|
||||
let denom = 0;
|
||||
|
||||
// Traverse image to find faces
|
||||
lastTime = Date.now();
|
||||
let pixelData = renderer.getContext()
|
||||
.getImageData(0, 0, renderer.domElement.width, renderer.domElement.height).data;
|
||||
|
||||
for (let i = 0; i < pixelData.length; i += 4) {
|
||||
|
||||
let pixelNumber = (pixelData[i] << 16) + (pixelData[i+1] << 8) + (pixelData[i+2]);
|
||||
|
||||
if (pixelNumber !== 0) {
|
||||
denom++;
|
||||
try {
|
||||
if (progLoader.hasFace(colorToFace[pixelNumber])) {
|
||||
score++;
|
||||
}
|
||||
} catch(e) {
|
||||
process.stderr.write('--> ' + pixelNumber + '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process.stderr.write('--> Computed pixels in ' + (Date.now() - lastTime) + 'ms\n');
|
||||
|
||||
score /= denom;
|
||||
|
||||
process.stderr.write('--> Score : ' + score + '\n');
|
||||
console.log(score);
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,7 +221,7 @@ function initElements(camera, sceneInfo, redCoins) {
|
|||
// camera.coins = L3D.generateCoins(L3D.createWhompCoins(), redCoins);
|
||||
return {name:'Whomps Fortress', folder:'whomp'};
|
||||
default:
|
||||
process.stderr.write('This sceneId doesn\'t exist\n');
|
||||
process.stderr.write('--> This sceneId doesn\'t exist\n');
|
||||
process.exit(-1);
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ L3D.ReplayCamera = function() {
|
|||
|
||||
this.recommendationClicked = null;
|
||||
|
||||
this.isArrow = false;
|
||||
|
||||
};
|
||||
L3D.ReplayCamera.prototype = Object.create(THREE.PerspectiveCamera.prototype);
|
||||
L3D.ReplayCamera.prototype.constructor = L3D.ReplayCamera;
|
||||
|
@ -107,6 +109,11 @@ L3D.ReplayCamera.prototype.nextEvent = function() {
|
|||
|
||||
var self = this;
|
||||
|
||||
if (self.isArrow) {
|
||||
self.isArrow = false;
|
||||
process.stderr.write('\033[31mArrowclicked finished !\033[0m\n');
|
||||
}
|
||||
|
||||
this.counter++;
|
||||
|
||||
// Finished
|
||||
|
@ -139,6 +146,8 @@ L3D.ReplayCamera.prototype.nextEvent = function() {
|
|||
// },500);
|
||||
// })(this);
|
||||
} else if (this.event.type == 'arrow') {
|
||||
self.isArrow = true;
|
||||
process.stderr.write('\033[33mArrowclicked ! ' + JSON.stringify(self.cameras[self.event.id].camera.position) + '\033[0m\n');
|
||||
if (this.shouldRecover) {
|
||||
(function(self, tmp) {
|
||||
self.event.type = 'camera';
|
||||
|
@ -252,7 +261,7 @@ L3D.ReplayCamera.prototype.moveHermite = function(recommendation) {
|
|||
|
||||
L3D.ReplayCamera.prototype.moveReco = function(recommendationId) {
|
||||
|
||||
this.recommendationClicked = this.cameras[recommendationId].camera;
|
||||
this.recommendationClicked = recommendationId;
|
||||
|
||||
this.moveHermite(this.cameras[recommendationId]);
|
||||
|
||||
|
@ -270,7 +279,7 @@ L3D.ReplayCamera.prototype.save = function() {};
|
|||
*/
|
||||
L3D.ReplayCamera.prototype.toList = function() {
|
||||
|
||||
var camera = (this.recommendationClicked === null ? this : this.recommendationClicked);
|
||||
var camera = this; // (this.recommendationClicked === null ? this : this.cameras[this.recommendationClicked].camera);
|
||||
|
||||
camera.updateMatrix();
|
||||
camera.updateMatrixWorld();
|
||||
|
@ -284,7 +293,7 @@ L3D.ReplayCamera.prototype.toList = function() {
|
|||
var ret =
|
||||
[[camera.position.x, camera.position.y, camera.position.z],
|
||||
[camera.target.x, camera.target.y, camera.target.z],
|
||||
this.recommendationClicked !== null
|
||||
this.recommendationClicked
|
||||
];
|
||||
|
||||
for (var i = 0; i < frustum.planes.length; i++) {
|
||||
|
|
|
@ -301,7 +301,7 @@ ProgressiveLoader.prototype.initIOCallbacks = function() {
|
|||
|
||||
this.socket.on('elements', function(arr) {
|
||||
|
||||
process.stderr.write('Received ' + arr.length + '\n');
|
||||
// process.stderr.write('Received ' + arr.length + '\n');
|
||||
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
|
||||
|
@ -431,16 +431,24 @@ ProgressiveLoader.prototype.initIOCallbacks = function() {
|
|||
|
||||
}
|
||||
|
||||
var param;
|
||||
if (typeof self.onBeforeEmit === 'function') {
|
||||
self.onBeforeEmit();
|
||||
|
||||
for (var m of self.meshes) {
|
||||
m.geometry.computeBoundingSphere();
|
||||
}
|
||||
param = self.onBeforeEmit();
|
||||
setTimeout(function() { self.socket.emit('next', self.getCamera(), param);}, 100);
|
||||
|
||||
} else {
|
||||
|
||||
// Ask for next elements
|
||||
if (!self.laggy) {
|
||||
self.socket.emit('next', self.getCamera());
|
||||
self.socket.emit('next', self.getCamera(), param);
|
||||
} else {
|
||||
setTimeout(function() { self.socket.emit('next', self.getCamera());}, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.socket.on('disconnect', function() {
|
||||
|
|
|
@ -25,7 +25,7 @@ L3D.initPeachCastle = function(scene, collidableObjects, recommendation, clickab
|
|||
var loader = new L3D.ProgressiveLoader(
|
||||
'/static/data/castle/princess peaches castle (outside).obj',
|
||||
scene,
|
||||
null,
|
||||
recommendation,
|
||||
function(object) {
|
||||
if (clickable !== undefined)
|
||||
clickable.push(object);
|
||||
|
@ -356,7 +356,7 @@ L3D.initWhompScene = function(scene, collidableObjects, recommendation, clickabl
|
|||
var loader = new L3D.ProgressiveLoader(
|
||||
'/static/data/whomp/Whomps Fortress.obj',
|
||||
scene,
|
||||
null,
|
||||
recommendation,
|
||||
function(object) {
|
||||
if (clickable !== undefined)
|
||||
clickable.push(object);
|
||||
|
@ -512,7 +512,7 @@ L3D.initMountainScene = function(scene, collidableObjects, recommendation, click
|
|||
var loader = new L3D.ProgressiveLoader(
|
||||
'/static/data/mountain/coocoolmountain.obj',
|
||||
scene,
|
||||
null,
|
||||
recommendation,
|
||||
function(object) {
|
||||
// object.rotation.x = -Math.PI/2;
|
||||
// object.rotation.z = Math.PI/2;
|
||||
|
|
|
@ -355,9 +355,6 @@ function pushMesh(name) {
|
|||
reco.matrixWorldInverse.getInverse( reco.matrixWorld );
|
||||
|
||||
var frustum = new THREE.Frustum();
|
||||
var projScreenMatrix = new THREE.Matrix4();
|
||||
projScreenMatrix.multiplyMatrices(reco.projectionMatrix, reco.matrixWorldInverse);
|
||||
|
||||
frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(reco.projectionMatrix, reco.matrixWorldInverse));
|
||||
|
||||
geo.availableMeshes[name].recommendations.push({
|
||||
|
|
|
@ -159,7 +159,7 @@ geo.MeshStreamer = function(path) {
|
|||
* Number of element to send by packet
|
||||
* @type {Number}
|
||||
*/
|
||||
this.chunk = 1250;
|
||||
this.chunk = 1250 / 2;
|
||||
|
||||
this.previousReco = 0;
|
||||
|
||||
|
@ -344,7 +344,7 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
|
||||
});
|
||||
|
||||
socket.on('next', function(_camera) {
|
||||
socket.on('next', function(_camera, score) {
|
||||
|
||||
var cameraFrustum = {};
|
||||
|
||||
|
@ -365,7 +365,7 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
planes: []
|
||||
};
|
||||
|
||||
var fullFrustum = _camera[2];
|
||||
var recommendationClicked = _camera[2];
|
||||
|
||||
for (i = 3; i < _camera.length; i++) {
|
||||
|
||||
|
@ -384,10 +384,25 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
|
||||
// Create config for proportions of chunks
|
||||
var config;
|
||||
var didPrefetch = false;
|
||||
|
||||
if (self.prefetch) {
|
||||
if (!self.prefetch || (recommendationClicked === null && score < 0.85)) {
|
||||
|
||||
console.log("Score not good enough, no prefetch");
|
||||
config = [{ frustum: cameraFrustum, proportion: 1}];
|
||||
|
||||
} else if (recommendationClicked !== null) {
|
||||
|
||||
console.log("Recommendation is clicking : full for " + JSON.stringify(self.mesh.recommendations[recommendationClicked].position));
|
||||
config = [{frustum: cameraFrustum, proportion:0.5}, {frustum : self.mesh.recommendations[recommendationClicked], proportion: 0.5}];
|
||||
|
||||
} else {
|
||||
|
||||
console.log("Good % (" + score + "), allow some prefetching");
|
||||
|
||||
didPrefetch = true;
|
||||
config = [{ frustum: cameraFrustum, proportion : 0.5}];
|
||||
// config = [];
|
||||
|
||||
// Find best recommendation
|
||||
var bestReco;
|
||||
|
@ -398,20 +413,20 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
|
||||
var sum = 0;
|
||||
|
||||
for (var i = 0; i < self.mesh.recommendations.length; i++) {
|
||||
for (var i = 1; i <= self.mesh.recommendations.length; i++) {
|
||||
|
||||
sum += self.predictionTable[self.previousReco][i];
|
||||
|
||||
}
|
||||
|
||||
for (var i = 0; i < self.mesh.recommendations.length; i++) {
|
||||
for (var i = 1; 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]
|
||||
frustum : self.mesh.recommendations[i-1]
|
||||
|
||||
});
|
||||
|
||||
|
@ -428,41 +443,63 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
config = [{frustum: cameraFrustum, proportion: 1}];
|
||||
|
||||
}
|
||||
|
||||
// Send next elements
|
||||
var oldTime = Date.now();
|
||||
var next = self.nextElements(config);
|
||||
|
||||
// console.log(next.configSizes);
|
||||
// console.log(
|
||||
// 'Adding ' +
|
||||
// next.size +
|
||||
// ' for newConfig : '
|
||||
// + JSON.stringify(config.map(function(o) { return o.proportion}))
|
||||
// );
|
||||
|
||||
|
||||
console.log(next.configSizes);
|
||||
|
||||
// console.log('Time to generate chunk : ' + (Date.now() - oldTime) + 'ms');
|
||||
|
||||
if (self.prefetch && next.size < self.chunk) {
|
||||
|
||||
console.log("Chunk not full : prefetch reco");
|
||||
|
||||
// Recompute config
|
||||
var newConfig = [];
|
||||
var sum = 0;
|
||||
|
||||
if (!didPrefetch) {
|
||||
|
||||
if (self.predictionTable !== undefined) {
|
||||
|
||||
var sum = 0;
|
||||
|
||||
for (var i = 1; i <= self.mesh.recommendations.length; i++) {
|
||||
|
||||
sum += self.predictionTable[self.previousReco][i];
|
||||
|
||||
}
|
||||
|
||||
for (var i = 1; i <= self.mesh.recommendations.length; i++) {
|
||||
|
||||
if (self.predictionTable[self.previousReco][i] > 0) {
|
||||
|
||||
newConfig.push({
|
||||
|
||||
proportion : self.predictionTable[self.previousReco][i] / (sum),
|
||||
frustum : self.mesh.recommendations[i-1]
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (var i = 0; i < config.length; i++) {
|
||||
|
||||
// Check if config was full
|
||||
|
@ -475,19 +512,26 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
|
||||
}
|
||||
|
||||
// Normalize config probabilities
|
||||
for (var i = 0; i < newConfig.length; i++) {
|
||||
|
||||
newConfig[i].proportion /= sum;
|
||||
|
||||
}
|
||||
|
||||
// Normalize config probabilities
|
||||
}
|
||||
|
||||
|
||||
var newData = self.nextElements(newConfig, self.chunk - next.size);
|
||||
|
||||
next.data.push.apply(next.data, newData.data);
|
||||
|
||||
// console.log('Adding ' + newData.size + ' for newConfig : ' + JSON.stringify(newConfig.map(function(o) { return o.proportion})));
|
||||
// console.log(
|
||||
// 'Adding ' +
|
||||
// newData.size +
|
||||
// ' for newConfig : '
|
||||
// + JSON.stringify(newConfig.map(function(o) { return o.proportion}))
|
||||
// );
|
||||
|
||||
next.size = next.size + newData.size;
|
||||
|
||||
|
@ -495,6 +539,8 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
|
||||
if (next.size < self.chunk) {
|
||||
|
||||
console.log("Chunk not full : fill linear");
|
||||
|
||||
// If nothing, just serve stuff
|
||||
var tmp = self.nextElements([
|
||||
// {
|
||||
|
@ -508,7 +554,7 @@ geo.MeshStreamer.prototype.start = function(socket) {
|
|||
|
||||
}
|
||||
|
||||
// console.log('Chunk of size ' + next.size);
|
||||
console.log('Chunk of size ' + next.size + ' (generated in ' + (Date.now() - oldTime) + 'ms)');
|
||||
// console.log('Time to generate chunk : ' + (Date.now() - oldTime) + 'ms');
|
||||
|
||||
if (next.data.length === 0) {
|
||||
|
@ -637,9 +683,13 @@ geo.MeshStreamer.prototype.nextElements = function(config, chunk) {
|
|||
|
||||
// Sort buffer
|
||||
if (config[configIndex].frustum !== undefined) {
|
||||
|
||||
buffers[configIndex].sort(this.faceComparator(config[configIndex].frustum));
|
||||
|
||||
} else {
|
||||
|
||||
// console.log("Did not sort");
|
||||
|
||||
}
|
||||
|
||||
// Fill chunk
|
||||
|
@ -648,9 +698,9 @@ geo.MeshStreamer.prototype.nextElements = function(config, chunk) {
|
|||
var size = this.pushFace(buffers[configIndex][i], data);
|
||||
|
||||
totalSize += size;
|
||||
configSize += size;
|
||||
configSizes[configIndex] += size;
|
||||
|
||||
if (configSize > chunk * config[configIndex].proportion) {
|
||||
if (configSizes[configIndex] > chunk * config[configIndex].proportion) {
|
||||
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue