Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fill-extrude-height and fill-extrude-base properties. #3223

Merged
merged 79 commits into from Oct 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
c8eadf6
first pass at recreating the building branch
May 25, 2016
ebed8ec
Rm large json, rm building stroke
May 25, 2016
300e373
Rm shaders
May 25, 2016
455ca3a
Incorporate building levels data in demo
May 25, 2016
3436411
Building shadow colors
May 25, 2016
42b141e
building -> extrusion
May 26, 2016
197534c
Implement extrusion-opacity
May 26, 2016
0c23500
Have interior rings working (commit before refactoring)
May 27, 2016
3944d49
factor out extra for loop
May 27, 2016
b2a5e46
Building -> Extrusion
May 27, 2016
a48fd60
spec names
May 27, 2016
b9c7417
Make extrusions at least render patterns as if flat
May 28, 2016
a75a2f5
WIP COMMIT: moving pattern extrusions
May 28, 2016
0939cc7
WIP: no longer growing patternbldgs
May 28, 2016
e48e829
WIP: move extrusion pattern to its own shader
May 28, 2016
e7cfe8d
extrusion-pattern
May 31, 2016
828c8b9
WIP: antialiasing
Jun 1, 2016
c808b0d
Nothing is rendering to the secondary texture, which _is_ successfull…
Jun 3, 2016
3cf0395
clean up a bit
Jun 4, 2016
75e87d5
wip: working ish, except depth
Jun 6, 2016
b365ec9
wip: it works! add depth renderbuffer
Jun 7, 2016
4e79339
tweaks
Jun 7, 2016
9b87a8c
fix depth rendering with labels
Jun 7, 2016
5186335
don't apply opacity to building tiles on renderbuffer draw
Jun 7, 2016
3f5b222
wip towards DDS
Jun 10, 2016
4f1a83d
Property fns for extrusion-height and extrusion-min-height
Jun 13, 2016
34f4db1
Enable dds with patterns
Jun 13, 2016
f7bc6f3
lighting-anchor as root, dds color + opacity
Jun 14, 2016
6ffffd8
(dds style)
Jun 27, 2016
ba3f8c4
* Eliminate isUpper attribute (utilize a_normal.x mod trick)
Aug 3, 2016
5a5da62
DDS extrusion-outline-color
Aug 11, 2016
ff663da
Make extrusion-outline-color default to extrusion-color
Aug 11, 2016
ecddb80
Implement extrusion-translate
Aug 11, 2016
5481382
extrusion-outline-color is defined but is a property fn
Aug 12, 2016
e33d169
* Remove DDS outline_color, but make outline_color default to color i…
Aug 17, 2016
948ce9a
Cleanups in draw_extrusion. Also, return to lighting array .xzy forma…
Aug 17, 2016
484f813
eslint, attach light properties to painter [ci skip
Aug 17, 2016
04c2716
Resolve rebase differences; make texture save/get two-dimensional
Aug 18, 2016
2aaf00e
Ignore local debug styles [ci skip]
Aug 18, 2016
26da60a
Move setVertexAttribPointers back to buffer, change style function to…
Aug 19, 2016
9ec56fe
(wip) Setup individual lighting APIs (not yet cascading)
Aug 22, 2016
5757fc1
Fix extrusion pattern side scaling [ci skip]
Aug 23, 2016
0b10737
:no_good: to non-1 alpha values
Aug 24, 2016
ec4f1a4
Fix bad read of 0 extrusion-layer-opacity; bail early in 0 opacity ca…
Aug 24, 2016
09ac0c0
Changes from spec discussion:
Aug 25, 2016
583ae2b
Fix 0 light-intensity
Aug 25, 2016
e6eaae2
Fix light defaults
Aug 25, 2016
440d015
Fix combination of `map` light options and default light options
Aug 26, 2016
e071272
:no_good: const keyword [ci skip]
Aug 29, 2016
eda0885
Rename PrerenderedExtrusionLayer -> ExtrusionTexture
Aug 30, 2016
c6b09b6
Un-namespace all the light object subproperties; implement set and ge…
Aug 30, 2016
c4fafb0
Cleanups and hardening
Aug 31, 2016
bf8576f
extrusion-min-heigt -> extrusion-base-height
Sep 1, 2016
b029cd3
Set alpha to 1 in js rather than in the shader
Sep 1, 2016
6eae2f3
:no_good: extrusion type; switch to '-extrude-' properties on existin…
Sep 2, 2016
2e1ff69
Fix zoom-and-property-fn bug in fill_style_layer [ci skip]
Sep 6, 2016
adb2446
Fix boundary edge checking, include for both walls and outlines
Sep 6, 2016
461a08f
Better checking for boundary edges [ci skip]
Sep 7, 2016
35f2fd9
Fix extrusion patterns [ci skip]
Sep 8, 2016
f3e7e19
[wip] intermediate commit
Sep 8, 2016
44dc32c
Lighting APIs:
Sep 9, 2016
ca480ae
eslint, tests
Sep 13, 2016
9c8548b
Lighting docs [ci skip]
Sep 13, 2016
8ab1080
Fix for missing walls in straight cross-tile features
Sep 15, 2016
1cbd0ef
Use computed paint properties in draw
Sep 16, 2016
2a76e2f
Revert debug page changes, light vs lighting naming conventions
Sep 19, 2016
ae99aa0
Address PR comments (tests not ready) [ci skip]
Oct 5, 2016
c9adf20
Separate FillBucket and FillExtrusionBucket, update light tests
Oct 6, 2016
f98cf81
Only save 1 viewport-sized texture for reuse; delete if window is res…
Oct 6, 2016
4c574ae
Update shas to see what CI thinks :pray:
Oct 6, 2016
bf64408
Remove unnecessary GL stencil calls, flip depth mask back off after d…
Oct 6, 2016
b3c2d7b
Disable fill-outline-color for extruded fills
Oct 7, 2016
0441831
Fix bad depth mask flip, rm unnecessary depth sublayer call, update r…
Oct 7, 2016
d39013a
Round edge distance, update render test sha
Oct 7, 2016
59a3bcb
Rebase, rationalize extrusion shader names, update rebased SHAs
Oct 7, 2016
5cc4b0e
Update test SHA
Oct 7, 2016
386b3b4
Update shas
Oct 7, 2016
5224fa6
Rename light direction to position
Oct 7, 2016
6add46a
Update shas MERGETOWN
Oct 7, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion debug/index.html
Expand Up @@ -3,7 +3,7 @@
<head>
<title>Mapbox GL JS debug page</title>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<link rel='stylesheet' href='/dist/mapbox-gl.css' />
<style>
Expand Down
11 changes: 10 additions & 1 deletion js/data/bucket.js
Expand Up @@ -17,11 +17,20 @@ module.exports = Bucket;
Bucket.create = function(options) {
var Classes = {
fill: require('./bucket/fill_bucket'),
fillextrusion: require('./bucket/fill_extrusion_bucket'),
line: require('./bucket/line_bucket'),
circle: require('./bucket/circle_bucket'),
symbol: require('./bucket/symbol_bucket')
};
return new Classes[options.layer.type](options);

var type = options.layer.type;
if (type === 'fill' && (!options.layer.isPaintValueFeatureConstant('fill-extrude-height') ||
!options.layer.isPaintValueZoomConstant('fill-extrude-height') ||
options.layer.getPaintValue('fill-extrude-height') !== 0)) {
type = 'fillextrusion';
}

return new Classes[type](options);
};


Expand Down
25 changes: 20 additions & 5 deletions js/data/bucket/fill_bucket.js
Expand Up @@ -5,6 +5,7 @@ var util = require('../../util/util');
var loadGeometry = require('../load_geometry');
var earcut = require('earcut');
var classifyRings = require('../../util/classify_rings');
var Point = require('point-geometry');
var EARCUT_MAX_RINGS = 500;

module.exports = FillBucket;
Expand Down Expand Up @@ -56,9 +57,15 @@ FillBucket.prototype.programInterfaces = {
}
};

FillBucket.prototype.addVertex = function(vertexArray, x, y) {
return vertexArray.emplaceBack(x, y);
};

FillBucket.prototype.addFeature = function(feature) {
var lines = loadGeometry(feature);
var polygons = classifyRings(lines, EARCUT_MAX_RINGS);
var polygons = convertCoords(classifyRings(lines, EARCUT_MAX_RINGS));

this.factor = Math.pow(2, 13);

var startGroup = this.prepareArrayGroup('fill', 0);
var startIndex = startGroup.layoutVertexArray.length;
Expand All @@ -81,23 +88,26 @@ FillBucket.prototype.addPolygon = function(polygon) {
var holeIndices = [];
var startIndex = group.layoutVertexArray.length;

var indices = [];

for (var r = 0; r < polygon.length; r++) {
var ring = polygon[r];

if (r > 0) holeIndices.push(flattened.length / 2);

for (var v = 0; v < ring.length; v++) {
var vertex = ring[v];
var v1 = ring[v];

var index = group.layoutVertexArray.emplaceBack(vertex.x, vertex.y);
var index = this.addVertex(group.layoutVertexArray, v1[0], v1[1], 0, 0, 1, 1, 0);
indices.push(index);

if (v >= 1) {
group.elementArray2.emplaceBack(index - 1, index);
}

// convert to format used by earcut
flattened.push(vertex.x);
flattened.push(vertex.y);
flattened.push(v1[0]);
flattened.push(v1[1]);
}
}

Expand All @@ -107,3 +117,8 @@ FillBucket.prototype.addPolygon = function(polygon) {
group.elementArray.emplaceBack(triangleIndices[i] + startIndex);
}
};

function convertCoords(rings) {
if (rings instanceof Point) return [rings.x, rings.y];
return rings.map(convertCoords);
}
173 changes: 173 additions & 0 deletions js/data/bucket/fill_extrusion_bucket.js
@@ -0,0 +1,173 @@
'use strict';

var Bucket = require('../bucket');
var util = require('../../util/util');
var loadGeometry = require('../load_geometry');
var earcut = require('earcut');
var classifyRings = require('../../util/classify_rings');
var Point = require('point-geometry');
var EARCUT_MAX_RINGS = 500;

module.exports = FillExtrusionBucket;

function FillExtrusionBucket() {
Bucket.apply(this, arguments);
}

FillExtrusionBucket.prototype = util.inherit(Bucket, {});

FillExtrusionBucket.prototype.programInterfaces = {
fillextrusion: {
layoutVertexArrayType: new Bucket.VertexArrayType([{
name: 'a_pos',
components: 2,
type: 'Int16'
}, {
name: 'a_normal',
components: 3,
type: 'Int16'
}, {
name: 'a_edgedistance',
components: 1,
type: 'Int16'
}]),
elementArrayType: new Bucket.ElementArrayType(3),

paintAttributes: [{
name: 'a_minH',
components: 1,
type: 'Uint16',
getValue: function(layer, globalProperties, featureProperties) {
return [layer.getPaintValue("fill-extrude-base", globalProperties, featureProperties)];
},
multiplier: 1,
paintProperty: 'fill-extrude-base'
}, {
name: 'a_maxH',
components: 1,
type: 'Uint16',
getValue: function(layer, globalProperties, featureProperties) {
return [layer.getPaintValue("fill-extrude-height", globalProperties, featureProperties)];
},
multiplier: 1,
paintProperty: 'fill-extrude-height'
}, {
name: 'a_color',
components: 4,
type: 'Uint8',
getValue: function(layer, globalProperties, featureProperties) {
var color = layer.getPaintValue("fill-color", globalProperties, featureProperties);
color[3] = 1.0;
return color;
},
multiplier: 255,
paintProperty: 'fill-color'
}]
}
};

FillExtrusionBucket.prototype.addVertex = function(vertexArray, x, y, nx, ny, nz, t, e) {
return vertexArray.emplaceBack(
// a_pos
x,
y,
// a_normal
Math.floor(nx * this.factor) * 2 + t,
ny * this.factor * 2,
nz * this.factor * 2,

// a_edgedistance
Math.round(e)
);
};

FillExtrusionBucket.prototype.addFeature = function(feature) {
var lines = loadGeometry(feature);
var polygons = convertCoords(classifyRings(lines, EARCUT_MAX_RINGS));

this.factor = Math.pow(2, 13);

var startGroup = this.prepareArrayGroup('fillextrusion', 0);
var startIndex = startGroup.layoutVertexArray.length;

for (var i = 0; i < polygons.length; i++) {
this.addPolygon(polygons[i]);
}

this.populatePaintArrays('fillextrusion', {zoom: this.zoom}, feature.properties, startGroup, startIndex);
};

FillExtrusionBucket.prototype.addPolygon = function(polygon) {
var numVertices = 0;
for (var k = 0; k < polygon.length; k++) {
numVertices += polygon[k].length;
}
numVertices *= 5;

var group = this.prepareArrayGroup('fillextrusion', numVertices);
var flattened = [];
var holeIndices = [];

var indices = [];

for (var r = 0; r < polygon.length; r++) {
var ring = polygon[r];

if (r > 0) holeIndices.push(flattened.length / 2);

var edgeDistance = 0;

for (var v = 0; v < ring.length; v++) {
var v1 = ring[v];

var index = this.addVertex(group.layoutVertexArray, v1[0], v1[1], 0, 0, 1, 1, 0);
indices.push(index);

if (v >= 1) {
var v2 = ring[v - 1];

if (!isBoundaryEdge(v1, v2)) {
var perp = Point.convert(v1)._sub(Point.convert(v2))._perp()._unit();

var bottomRight = this.addVertex(group.layoutVertexArray, v1[0], v1[1], perp.x, perp.y, 0, 0, edgeDistance);
this.addVertex(group.layoutVertexArray, v1[0], v1[1], perp.x, perp.y, 0, 1, edgeDistance);

edgeDistance += Point.convert(v2).dist(Point.convert(v1));

this.addVertex(group.layoutVertexArray, v2[0], v2[1], perp.x, perp.y, 0, 0, edgeDistance);
this.addVertex(group.layoutVertexArray, v2[0], v2[1], perp.x, perp.y, 0, 1, edgeDistance);

group.elementArray.emplaceBack(bottomRight, bottomRight + 1, bottomRight + 2);
group.elementArray.emplaceBack(bottomRight + 1, bottomRight + 2, bottomRight + 3);
}
}

// convert to format used by earcut
flattened.push(v1[0]);
flattened.push(v1[1]);
}
}

var triangleIndices = earcut(flattened, holeIndices);

for (var j = 0; j < triangleIndices.length - 2; j += 3) {
group.elementArray.emplaceBack(indices[triangleIndices[j]],
indices[triangleIndices[j + 1]],
indices[triangleIndices[j + 2]]);
}
};

function convertCoords(rings) {
if (rings instanceof Point) return [rings.x, rings.y];
return rings.map(convertCoords);
}

function isBoundaryEdge(v1, v2) {
return v1.some(function(a, i) {
return isOutside(v2[i]) && v2[i] === a;
});
}

function isOutside(coord) {
return coord < 0 || coord > Bucket.EXTENT;
}