/**
* Class that represents a generator that streams the current recommendation clicked if any, or the frustum, and tries to preload recommendations that might be clicked
* @constructor
* @augments geo.V_PP_Generator
* @param streamer {geo.MeshStreamer} the parent mesh streamer
*/
geo.V_PP_PD_Generator = function() {
geo.V_PP_Generator.apply(this, arguments);
};
geo.V_PP_PD_Generator.prototype = Object.create(geo.V_PP_Generator);
geo.V_PP_PD_Generator.prototype.constructor = geo.V_PP_PD_Generator;
/**
* Generates a config that streams partly the frustum, and splits the rest of the chunk among the recommendations that are likely to be clicked
* @param cameraFrustum {Object} the frustum of the camera (with its position, target, and planes)
* @param recommendationClicked {Number|null} id of the recommendation (can be null if no recommendations are clicked)
* @returns {Object[]} an array with one element corresponding the current recommendation or the camera frustum, and others for eventual recommendations to preload
*/
geo.V_PP_PD_Generator.prototype.generateMainConfig = function(cameraFrustum, recommendationClicked) {
var config;
if (recommendationClicked != null) {
if (this.streamer.beginning === true) {
this.streamer.beginning = false;
}
// Case full reco
console.log("Going to " + recommendationClicked);
console.log("Recommendation is clicking : full for " + JSON.stringify(this.streamer.mesh.recommendations[recommendationClicked].position));
config = [{recommendationId : recommendationClicked + 1, proportion: 1, smart:true}];
} else if (this.streamer.beginning === true) {
console.log('Begining : full init');
config = [{recommendationId : 0, proportion:1, smart: true}];
} else {
// Case full prefetch
console.log("Allow some prefetching");
config = [{ frustum: cameraFrustum, proportion : this.streamer.frustumPercentage}];
// Find best recommendation
var bestReco;
var bestScore = -Infinity;
var bestIndex = null;
if (this.streamer.predictionTable !== undefined) {
var sum = 0;
for (var i = 1; i <= this.streamer.mesh.recommendations.length; i++) {
sum += this.streamer.predictionTable[this.streamer.previousReco][i];
}
for (var i = 1; i <= this.streamer.mesh.recommendations.length; i++) {
if (this.streamer.predictionTable[this.streamer.previousReco][i] > 0) {
config.push({
proportion : this.streamer.predictionTable[this.streamer.previousReco][i] * this.streamer.prefetchPercentage / sum,
recommendationId : i,
smart: true
});
}
}
} else {
process.stderr.write('ERROR : PREDICTION TABLE IF UNDEFINED');
}
}
return config;
};
/**
* Generates a config that depends on the previous configuration and that tries to fill the recommendations that were not already filled.
* @param previousConfig {Object} the previous configuration list (that was launched on generateMainConfig
* @param previousData {Object} the data that were given by the nextElements
method on {@link geo.MeshStreamer}
* @param cameraFrustum {Object} the frustum of the camera, containing its position, target and planes
* @returns {Object[]} a configuration that tries to fill what was not filled before
*/
geo.V_PP_PD_Generator.prototype.generateFillingConfig = function(previousConfig, previousData, cameraFrustum) {
var sum = 0;
var newConfig = [];
for (var i = 0; i < previousConfig.length; i++) {
// Check if previousConfig was full
if (previousResult.configSizes[i] >= this.streamer.chunk * previousConfig[i].proportion) {
newConfig.push(previousConfig[i]);
sum += previousConfig[i].proportion;
}
}
// Normalize previousConfig probabilities
for (var i = 0; i < newConfig.length; i++) {
newConfig[i].proportion /= sum;
}
return newConfig;
};