kopia lustrzana https://github.com/robhawkes/vizicities
Refining Web Worker object loading
rodzic
1b47f42c48
commit
6931ba390c
|
@ -42,8 +42,8 @@
|
|||
var buildingManager = new VIZI.BuildingManager();
|
||||
buildingManager.load(url).then(function(value) {
|
||||
VIZI.Log(value);
|
||||
// buildingManager.processFeatures(value.features);
|
||||
buildingManager.processFeaturesWorker(value.features);
|
||||
buildingManager.processFeatures(value.features);
|
||||
// buildingManager.processFeaturesWorker2(value.features);
|
||||
}, function(error) {
|
||||
console.error(error.stack);
|
||||
}).done();
|
||||
|
|
|
@ -7,6 +7,14 @@
|
|||
|
||||
VIZI.Object.call(this);
|
||||
|
||||
this.debugTimes = {
|
||||
"createObject": 0,
|
||||
"createShape": 0,
|
||||
"extrude": 0,
|
||||
"applyVertexColors": 0,
|
||||
"createMesh": 0
|
||||
};
|
||||
|
||||
this.materials = [
|
||||
new THREE.MeshLambertMaterial({vertexColors: THREE.VertexColors})
|
||||
];
|
||||
|
@ -18,6 +26,8 @@
|
|||
|
||||
// TODO: Handle multi-polygons
|
||||
VIZI.Building.prototype.createObject = function(feature) {
|
||||
var createObjectTime = Date.now();
|
||||
|
||||
var properties = feature.properties;
|
||||
|
||||
var area = properties.area;
|
||||
|
@ -30,26 +40,39 @@
|
|||
var colour = new THREE.Color(0xcccccc);
|
||||
|
||||
var coords = feature.geometry.coordinates[0];
|
||||
|
||||
var createShapeTime = Date.now();
|
||||
var shape = this.createShapeFromCoords(coords);
|
||||
this.debugTimes.createShape = Date.now() - createShapeTime;
|
||||
|
||||
var height = 10 * this.geo.pixelsPerMeter;
|
||||
|
||||
var extrudeSettings = { amount: height, bevelEnabled: false };
|
||||
var geom = new THREE.ExtrudeGeometry( shape, extrudeSettings );
|
||||
|
||||
var extrudeTime = Date.now();
|
||||
var geom = new THREE.ExtrudeGeometry( shape, extrudeSettings );
|
||||
this.debugTimes.extrude = Date.now() - extrudeTime;
|
||||
|
||||
var applyVertexColorsTime = Date.now();
|
||||
VIZI.applyVertexColors( geom, colour );
|
||||
this.debugTimes.applyVertexColors = Date.now() - applyVertexColorsTime;
|
||||
|
||||
// Move geom to 0,0 and return offset
|
||||
// var offset = THREE.GeometryUtils.center( geom );
|
||||
|
||||
geom.computeFaceNormals();
|
||||
|
||||
var createMeshTime = Date.now();
|
||||
var mesh = new THREE.Mesh(geom, this.materials[0]);
|
||||
this.debugTimes.createMesh = Date.now() - createMeshTime;
|
||||
|
||||
mesh.position.y = height;
|
||||
|
||||
// Flip buildings as they are up-side down
|
||||
mesh.rotation.x = 90 * Math.PI / 180;
|
||||
|
||||
this.debugTimes.createObject = Date.now() - createObjectTime;
|
||||
|
||||
return mesh;
|
||||
};
|
||||
}());
|
|
@ -19,4 +19,30 @@
|
|||
return;
|
||||
}
|
||||
};
|
||||
|
||||
VIZI.BuildingManager.prototype.debugTimes = function() {
|
||||
var self = this;
|
||||
|
||||
var totals = {};
|
||||
_.each(self.objects, function(object) {
|
||||
_.each(object.debugTimes, function(time, key) {
|
||||
if (!totals[key]) {
|
||||
totals[key] = 0;
|
||||
}
|
||||
|
||||
totals[key] += time;
|
||||
// _.each(item, function(time) {
|
||||
// total += time;
|
||||
// });
|
||||
// VIZI.Log(key + ": " + total/_.size(item));
|
||||
});
|
||||
});
|
||||
|
||||
var averages = {};
|
||||
_.each(totals, function(total, key) {
|
||||
averages[key] = total / _.size(self.objects);
|
||||
});
|
||||
|
||||
VIZI.Log({totals: totals, averages: averages});
|
||||
};
|
||||
}());
|
|
@ -26,8 +26,14 @@
|
|||
};
|
||||
|
||||
VIZI.ObjectManager.prototype.processFeatures = function(features) {
|
||||
var startTime = Date.now();
|
||||
|
||||
var objects = _.map(features, this.processFeature);
|
||||
|
||||
VIZI.Log(Date.now() - startTime);
|
||||
|
||||
this.objects = objects;
|
||||
|
||||
this.combinedObjects = this.combineObjects(objects);
|
||||
|
||||
this.publish("addToScene", this.combinedObjects);
|
||||
|
@ -60,6 +66,8 @@
|
|||
process: function(features) {
|
||||
importScripts("worker/three.min.js", "worker/underscore.min.js");
|
||||
|
||||
var startTime = Date.now();
|
||||
|
||||
var applyVertexColors = function( g, c ) {
|
||||
g.faces.forEach( function( f ) {
|
||||
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
|
||||
|
@ -80,9 +88,9 @@
|
|||
var area = properties.area;
|
||||
|
||||
// Skip if building area is too small
|
||||
// if (area < 200) {
|
||||
// return;
|
||||
// }
|
||||
if (area < 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
var coords = feature.geometry.coordinatesConverted[0];
|
||||
// // var shape = this.createShapeFromCoords(coords);
|
||||
|
@ -118,13 +126,18 @@
|
|||
meshes.push(mesh);
|
||||
});
|
||||
|
||||
// return Date.now() - startTime;
|
||||
|
||||
return meshes;
|
||||
}
|
||||
}, 4);
|
||||
|
||||
var startTime = Date.now();
|
||||
|
||||
// TODO: Work out why this still locks up the browser
|
||||
// TODO: Work out why this still locks up the browser (amount of data being transferred back from the worker? Is it quicker to create objects in the browser?)
|
||||
// TODO: See if simply batching objects and creating them in the browser is less sluggish for the browser
|
||||
// TODO: Work out why not every feature is being returned in the promises (about 10–20 less than expected)
|
||||
|
||||
// Batch features
|
||||
var batches = 20;
|
||||
var featuresPerBatch = Math.ceil(features.length / batches);
|
||||
|
@ -167,95 +180,158 @@
|
|||
});
|
||||
|
||||
VIZI.Log(count);
|
||||
VIZI.Log(Date.now() - startTime);
|
||||
}).done();
|
||||
};
|
||||
|
||||
// worker.batch.process(features).then(function(data) {
|
||||
// VIZI.Log(Date.now() - startTime);
|
||||
// VIZI.Log(data);
|
||||
// });
|
||||
VIZI.ObjectManager.prototype.processFeaturesWorker2 = function(features) {
|
||||
VIZI.Log("Processing features using worker");
|
||||
|
||||
// worker.batch(function(feature) {
|
||||
// return feature;
|
||||
// // VIZI.Log(feature);
|
||||
// // worker.close();
|
||||
// }).process(features).then(function(data) {
|
||||
// VIZI.Log(Date.now() - startTime);
|
||||
// VIZI.Log(data);
|
||||
// });
|
||||
var geo = VIZI.Geo.getInstance();
|
||||
|
||||
// worker.data(features).then(function(data) {
|
||||
// VIZI.Log(Date.now() - startTime);
|
||||
// VIZI.Log(data);
|
||||
// worker.close();
|
||||
// });
|
||||
// Convert coordinates
|
||||
_.each(features, function(feature) {
|
||||
var coords = feature.geometry.coordinates[0];
|
||||
feature.geometry.coordinatesConverted = [[]];
|
||||
_.each(coords, function(coord) {
|
||||
feature.geometry.coordinatesConverted[0].push(geo.projection(coord));
|
||||
});
|
||||
});
|
||||
|
||||
// var worker = new Parallel(features, { evalPath: "worker/eval.js" });
|
||||
// worker.require("three.min.js");
|
||||
// worker.require("underscore.min.js");
|
||||
// worker.require({fn: VIZI.applyVertexColors, name: "applyVertexColors"});
|
||||
VIZI.Log(features);
|
||||
|
||||
// var startTime = Date.now();
|
||||
// worker.spawn(function(features) {
|
||||
// var meshes = [];
|
||||
// var material = new THREE.MeshLambertMaterial({vertexColors: THREE.VertexColors});
|
||||
var worker = cw({
|
||||
process: function(feature) {
|
||||
importScripts("worker/three.min.js", "worker/underscore.min.js");
|
||||
|
||||
// _.each(features, function(feature) {
|
||||
// var properties = feature.properties;
|
||||
var startTime = Date.now();
|
||||
|
||||
// var area = properties.area;
|
||||
var applyVertexColors = function( g, c ) {
|
||||
g.faces.forEach( function( f ) {
|
||||
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
|
||||
for( var j = 0; j < n; j ++ ) {
|
||||
f.vertexColors[ j ] = c;
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
// // Skip if building area is too small
|
||||
// if (area < 200) {
|
||||
// return;
|
||||
// }
|
||||
var material = new THREE.MeshLambertMaterial({vertexColors: THREE.VertexColors});
|
||||
var material2 = new THREE.MeshLambertMaterial({color: 0xcccccc});
|
||||
var colour = new THREE.Color(0xcccccc);
|
||||
|
||||
// var colour = new THREE.Color(0xcccccc);
|
||||
|
||||
// var coords = feature.geometry.coordinatesConverted[0];
|
||||
// // // var shape = this.createShapeFromCoords(coords);
|
||||
// var shape = new THREE.Shape();
|
||||
// _.each(coords, function(coord, index) {
|
||||
// // Move if first coordinate
|
||||
// if (index === 0) {
|
||||
// shape.moveTo( coord[0], coord[1] );
|
||||
// } else {
|
||||
// shape.lineTo( coord[0], coord[1] );
|
||||
// }
|
||||
// _.each(features, function(feature) {
|
||||
var properties = feature.properties;
|
||||
|
||||
var area = properties.area;
|
||||
|
||||
// Skip if building area is too small
|
||||
if (area < 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
var coords = feature.geometry.coordinatesConverted[0];
|
||||
// // var shape = this.createShapeFromCoords(coords);
|
||||
var shape = new THREE.Shape();
|
||||
_.each(coords, function(coord, index) {
|
||||
// Move if first coordinate
|
||||
if (index === 0) {
|
||||
shape.moveTo( coord[0], coord[1] );
|
||||
} else {
|
||||
shape.lineTo( coord[0], coord[1] );
|
||||
}
|
||||
});
|
||||
|
||||
// var height = 10 * this.geo.pixelsPerMeter;
|
||||
var height = 10;
|
||||
|
||||
var extrudeSettings = { amount: height, bevelEnabled: false };
|
||||
// var geom = new THREE.ExtrudeGeometry( shape, extrudeSettings );
|
||||
var geom = new THREE.CubeGeometry(10, 10, 10);
|
||||
|
||||
// applyVertexColors( geom, colour );
|
||||
|
||||
// Move geom to 0,0 and return offset
|
||||
// var offset = THREE.GeometryUtils.center( geom );
|
||||
|
||||
geom.computeFaceNormals();
|
||||
var mesh = new THREE.Mesh(geom, material2);
|
||||
|
||||
// mesh.position.y = height;
|
||||
|
||||
// Flip buildings as they are up-side down
|
||||
// mesh.rotation.x = 90 * Math.PI / 180;
|
||||
|
||||
// meshes.push(mesh);
|
||||
// });
|
||||
|
||||
// // var height = 10 * this.geo.pixelsPerMeter;
|
||||
// var height = 10;
|
||||
// return Date.now() - startTime;
|
||||
|
||||
// var extrudeSettings = { amount: height, bevelEnabled: false };
|
||||
// var geom = new THREE.ExtrudeGeometry( shape, extrudeSettings );
|
||||
return mesh;
|
||||
}
|
||||
}, 4);
|
||||
|
||||
// applyVertexColors( geom, colour );
|
||||
|
||||
// // Move geom to 0,0 and return offset
|
||||
// // var offset = THREE.GeometryUtils.center( geom );
|
||||
var startTime = Date.now();
|
||||
|
||||
// geom.computeFaceNormals();
|
||||
// var mesh = new THREE.Mesh(geom, material);
|
||||
// TODO: Work out why this still locks up the browser (amount of data being transferred back from the worker? Is it quicker to create objects in the browser?)
|
||||
// TODO: See if simply batching objects and creating them in the browser is less sluggish for the browser
|
||||
// TODO: Work out why not every feature is being returned in the promises (about 10–20 less than expected)
|
||||
|
||||
// mesh.position.y = height;
|
||||
// Batch features
|
||||
// var batches = 20;
|
||||
// var featuresPerBatch = Math.ceil(features.length / batches);
|
||||
// var batchedMeshes = [];
|
||||
// var batchPromises = [];
|
||||
|
||||
// // Flip buildings as they are up-side down
|
||||
// mesh.rotation.x = 90 * Math.PI / 180;
|
||||
// var i = batches;
|
||||
// while (i--) {
|
||||
// var startIndex = i * featuresPerBatch;
|
||||
// startIndex = (startIndex < 0) ? 0 : startIndex;
|
||||
|
||||
// meshes.push(mesh);
|
||||
// // VIZI.Log("Start index: " + startIndex);
|
||||
// // VIZI.Log("End index: " + (startIndex+(featuresPerBatch-1)));
|
||||
|
||||
// // var endIndex = i * featuresPerBatch;
|
||||
// // endIndex = (endIndex > features.length-1) ? features.length-1 : endIndex;
|
||||
|
||||
// var featuresBatch = features.splice(startIndex, featuresPerBatch-1);
|
||||
|
||||
// batchPromises.push(this.workerPromise(worker, featuresBatch));
|
||||
|
||||
// // worker.process(featuresBatch).then(function(data) {
|
||||
// // VIZI.Log(Date.now() - startTime);
|
||||
// // // VIZI.Log(data);
|
||||
// // batchedMeshes.concat(data);
|
||||
// // // worker.close();
|
||||
// // });
|
||||
// }
|
||||
|
||||
// // Handle promises
|
||||
// Q.allSettled(batchPromises).then(function (promises) {
|
||||
// var count = 0;
|
||||
|
||||
// _.each(promises, function (promise) {
|
||||
// if (promise.state === "fulfilled") {
|
||||
// var value = promise.value;
|
||||
// count += value.length;
|
||||
// // VIZI.Log(value);
|
||||
// }
|
||||
// });
|
||||
|
||||
// return meshes;
|
||||
// }).then(function(meshes) {
|
||||
// VIZI.Log(count);
|
||||
// VIZI.Log(Date.now() - startTime);
|
||||
// VIZI.Log(meshes);
|
||||
// });
|
||||
|
||||
// var objects = _.map(features, this.processFeature);
|
||||
|
||||
// this.combinedObjects = this.combineObjects(objects);
|
||||
|
||||
// this.publish("addToScene", this.combinedObjects);
|
||||
// }).done();
|
||||
|
||||
var self = this;
|
||||
worker.batch(function(feature) {
|
||||
feature.__proto__.constructor = THREE.Object3D;
|
||||
self.publish("addToScene", feature);
|
||||
// return feature;
|
||||
// VIZI.Log(feature);
|
||||
// worker.close();
|
||||
}).process(features).then(function(data) {
|
||||
VIZI.Log(Date.now() - startTime);
|
||||
VIZI.Log(data);
|
||||
});
|
||||
};
|
||||
|
||||
VIZI.ObjectManager.prototype.processFeature = function(feature) {};
|
||||
|
|
Ładowanie…
Reference in New Issue