Added basic building functionality

0.1
Rob Hawkes 2013-11-01 01:08:53 +00:00
rodzic 1c5fe32f72
commit a723a4c0dd
13 zmienionych plików z 9491 dodań i 7 usunięć

Wyświetl plik

@ -22,9 +22,11 @@ module.exports = function(grunt) {
'src/shared/vendor/q.js',
'src/shared/vendor/three/three.js',
'src/shared/vendor/three/ColorConverter.js',
'src/shared/vendor/d3.js',
'src/client/Vizi.js',
'src/client/Log.js',
'src/client/Mediator.js',
'src/client/Geo.js',
'src/client/City.js',
'src/client/Loop.js',
'src/client/webgl/WebGL.js',
@ -34,7 +36,8 @@ module.exports = function(grunt) {
'src/client/objects/ObjectManager.js',
'src/client/objects/BuildingManager.js',
'src/client/objects/Object.js',
'src/client/objects/Floor.js'
'src/client/objects/Floor.js',
'src/client/objects/Building.js'
],
dest: 'build/vizi.js'
}

Wyświetl plik

@ -22,6 +22,7 @@
<script>
var city = new VIZI.City();
city.loadBuildings("osm-buildings.json");
</script>
</body>

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -6,6 +6,14 @@
VIZI.Log("Inititialising city");
_.extend(this, VIZI.Mediator);
// Set up geo methods
this.geo = VIZI.Geo.getInstance({
areaCoords: {
bottomLeft: [-0.090062,51.489438],
topRight: [0.012322,51.519747]
}
});
// Set up basic WebGL components (scene, camera, lights, renderer)
this.webgl = new VIZI.WebGL();
@ -24,6 +32,11 @@
VIZI.Log("Loading buildings");
var buildingManager = new VIZI.BuildingManager();
buildingManager.load(url).then(console.log, console.error).done();
buildingManager.load(url).then(function(value) {
VIZI.Log(value);
buildingManager.process(value);
}, function(error) {
console.error(error.stack);
}).done();
};
}());

47
src/client/Geo.js 100644
Wyświetl plik

@ -0,0 +1,47 @@
/* globals window, _, VIZI, d3 */
(function() {
"use strict";
VIZI.Geo = (function() {
var Geo = function(options) {
this.projection = this.setProjection(options.areaCoords);
this.pixelsPerMeter = this.setPixelsPerMeter();
};
Geo.prototype.setProjection = function(areaCoords) {
return d3.geo.mercator()
.center([
areaCoords.bottomLeft[0] + (areaCoords.topRight[0] - areaCoords.bottomLeft[0]) / 2,
areaCoords.bottomLeft[1] + (areaCoords.topRight[1] - areaCoords.bottomLeft[1]) / 2
]) // Geographic coordinates of map centre
.translate([0, 0]) // Pixel coordinates of .center()
.scale(10000000);
};
// TODO: Stop using London as a base for this
Geo.prototype.setPixelsPerMeter = function() {
var metersPerLat = 111200;
var pixelsPerLat = this.projection([0, 50])[1] - this.projection([0, 51])[1];
return pixelsPerLat / metersPerLat;
};
var instance;
// an emulation of static variables and methods
var _static = {
name: "VIZI.Geo",
// Method for getting an instance. It returns
// a singleton instance of a singleton object
getInstance: function( options ) {
if ( instance === undefined ) {
instance = new Geo( options );
}
return instance;
}
};
return _static;
}());
}());

Wyświetl plik

@ -6,7 +6,7 @@
VERSION: 1.0
};
// List any constants here, like:
// List any constants or helper functions here, like:
// https://github.com/mrdoob/three.js/blob/master/src/Three.js
// Expose VIZI to the window

Wyświetl plik

@ -0,0 +1,55 @@
/* globals window, _, VIZI, THREE */
(function() {
"use strict";
VIZI.Building = function(feature) {
VIZI.Log("Inititialising building object");
VIZI.Object.call(this);
this.materials = [
new THREE.MeshLambertMaterial({vertexColors: THREE.VertexColors})
];
this.object = this.createObject(feature);
};
VIZI.Building.prototype = Object.create( VIZI.Object.prototype );
// TODO: Handle multi-polygons
VIZI.Building.prototype.createObject = function(feature) {
var properties = feature.properties;
var area = properties.area;
// Skip if building area is too small
if (area < 200) {
return;
}
var colour = new THREE.Color(0xcccccc);
var coords = feature.geometry.coordinates[0];
var shape = this.createShapeFromCoords(coords);
var height = 10 * this.geo.pixelsPerMeter;
var extrudeSettings = { amount: height, bevelEnabled: false };
var geom = new THREE.ExtrudeGeometry( shape, extrudeSettings );
VIZI.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, this.materials[0]);
mesh.position.y = height;
// Flip buildings as they are up-side down
mesh.rotation.x = 90 * Math.PI / 180;
return mesh;
};
}());

Wyświetl plik

@ -3,7 +3,31 @@
"use strict";
VIZI.BuildingManager = function() {
// Extend Object class
VIZI.Log("Inititialising building manager");
VIZI.ObjectManager.call(this);
};
VIZI.BuildingManager.prototype = Object.create( VIZI.ObjectManager.prototype );
VIZI.BuildingManager.prototype.process = function(data) {
VIZI.Log("Processing buildings");
var features = data.features;
var objects = _.map(features, this.processFeature);
this.combinedObjects = this.combineObjects(objects);
this.publish("addToScene", this.combinedObjects);
};
VIZI.BuildingManager.prototype.processFeature = function(feature) {
switch (feature.type) {
case "Feature":
return new VIZI.Building(feature);
default:
VIZI.Log("Unable to process building of type: " + feature.type);
return;
}
};
}());

Wyświetl plik

@ -5,12 +5,13 @@
VIZI.Floor = function() {
VIZI.Log("Inititialising floor object");
// Extend Object class
VIZI.Object.call(this);
this.object = this.createObject();
};
VIZI.Floor.prototype = Object.create( VIZI.Object.prototype );
VIZI.Floor.prototype.createObject = function() {
var floorContainer = new THREE.Object3D();

Wyświetl plik

@ -4,7 +4,27 @@
VIZI.Object = function() {
_.extend(this, VIZI.Mediator);
this.geo = VIZI.Geo.getInstance();
};
VIZI.Object.prototype.createObject = function() {};
VIZI.Object.prototype.createShapeFromCoords = function(coords) {
var self = this;
var shape = new THREE.Shape();
_.each(coords, function(element, index) {
var projectedCoords = self.geo.projection(element);
// Move if first coordinate
if (index === 0) {
shape.moveTo( projectedCoords[0], projectedCoords[1] );
} else {
shape.lineTo( projectedCoords[0], projectedCoords[1] );
}
});
return shape;
};
}());

Wyświetl plik

@ -1,16 +1,46 @@
/* globals window, _, VIZI, THREE, Q */
/* globals window, _, VIZI, THREE, Q, d3 */
(function() {
"use strict";
VIZI.ObjectManager = function() {
_.extend(this, VIZI.Mediator);
this.objects = [];
this.combinedMaterial = new THREE.MeshLambertMaterial({vertexColors: THREE.VertexColors});
this.combinedObjects = undefined;
};
VIZI.ObjectManager.prototype.load = function(url) {
var deferred = Q.defer();
// JSON load stuffs
d3.json(url, function(error, data) {
if (error) {
deferred.reject(new Error(error));
} else {
deferred.resolve(data);
}
});
return deferred.promise;
};
VIZI.ObjectManager.prototype.process = function(objects) {};
VIZI.ObjectManager.prototype.processFeature = function(feature) {};
VIZI.ObjectManager.prototype.combineObjects = function(objects) {
var combinedGeom = new THREE.Geometry();
_.each(objects, function(object) {
if (!object.object) {
return;
}
THREE.GeometryUtils.merge(combinedGeom, object.object);
});
combinedGeom.computeFaceNormals();
return new THREE.Mesh( combinedGeom, this.combinedMaterial );
};
}());

Wyświetl plik

@ -65,4 +65,19 @@
this.lights.push(hemiLight);
this.publish("addToScene", hemiLight);
};
// Global helpers (move elsewhere?)
VIZI.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;
}
} );
};
}());

9274
src/shared/vendor/d3.js vendored 100755

Plik diff jest za duży Load Diff