Skip to content

Commit

Permalink
Fix issue #4860: apply map rotation to unpitched point labels.
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisLoer committed Jun 21, 2017
1 parent 09bec65 commit 78bb9dc
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 6 deletions.
11 changes: 9 additions & 2 deletions src/render/draw_symbol.js
Expand Up @@ -68,6 +68,10 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
const rotateWithMap = rotationAlignment === 'map';
const pitchWithMap = pitchAlignment === 'map';
const alongLine = rotateWithMap && layer.layout['symbol-placement'] === 'line';
// Line label rotation happens in `updateLineLabels`
// Pitched point labels are automatically rotated by the labelPlaneMatrix projection
// Unpitched point labels need to have their rotation applied after projection
const rotateInShader = rotateWithMap && !pitchWithMap && !alongLine;

const depthOn = pitchWithMap;

Expand Down Expand Up @@ -96,7 +100,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
program = painter.useProgram(isSDF ? 'symbolSDF' : 'symbolIcon', programConfiguration);
programConfiguration.setUniforms(gl, program, layer, {zoom: painter.transform.zoom});

setSymbolDrawState(program, painter, layer, coord.z, isText, isSDF, rotateWithMap, pitchWithMap, bucket.fontstack, bucket.iconsNeedLinear, sizeData);
setSymbolDrawState(program, painter, layer, coord.z, isText, isSDF, rotateInShader, pitchWithMap, bucket.fontstack, bucket.iconsNeedLinear, sizeData);
}

painter.enableTileClippingMask(coord);
Expand Down Expand Up @@ -125,7 +129,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
if (!depthOn) gl.enable(gl.DEPTH_TEST);
}

function setSymbolDrawState(program, painter, layer, tileZoom, isText, isSDF, rotateWithMap, pitchWithMap, fontstack, iconsNeedLinear, sizeData) {
function setSymbolDrawState(program, painter, layer, tileZoom, isText, isSDF, rotateInShader, pitchWithMap, fontstack, iconsNeedLinear, sizeData) {

const gl = painter.gl;
const tr = painter.transform;
Expand Down Expand Up @@ -170,6 +174,9 @@ function setSymbolDrawState(program, painter, layer, tileZoom, isText, isSDF, ro
const size = symbolSize.evaluateSizeForZoom(sizeData, tr, layer, isText);
if (size.uSizeT !== undefined) gl.uniform1f(program.u_size_t, size.uSizeT);
if (size.uSize !== undefined) gl.uniform1f(program.u_size, size.uSize);

gl.uniform1f(program.u_aspect_ratio, tr.width / tr.height);
gl.uniform1i(program.u_rotate_symbol, rotateInShader);
}

function drawTileSymbols(program, programConfiguration, painter, layer, tile, buffers, isText, isSDF, pitchWithMap) {
Expand Down
17 changes: 15 additions & 2 deletions src/shaders/symbol_icon.vertex.glsl
Expand Up @@ -10,6 +10,8 @@ uniform highp float u_size_t; // used to interpolate between zoom stops when siz
uniform highp float u_size; // used when size is both zoom and feature constant
uniform highp float u_camera_to_center_distance;
uniform highp float u_pitch;
uniform bool u_rotate_symbol;
uniform highp float u_aspect_ratio;
uniform highp float u_collision_y_stretch;

#pragma mapbox: define lowp float opacity
Expand Down Expand Up @@ -62,8 +64,19 @@ void main() {

float fontScale = u_is_text ? size / 24.0 : size;

highp float angle_sin = sin(segment_angle);
highp float angle_cos = cos(segment_angle);
highp float symbol_rotation = 0.0;
if (u_rotate_symbol) {
// See comments in symbol_sdf.vertex
vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1);

vec2 a = projectedPoint.xy / projectedPoint.w;
vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w;

symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);
}

highp float angle_sin = sin(segment_angle + symbol_rotation);
highp float angle_cos = cos(segment_angle + symbol_rotation);
mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);

vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0);
Expand Down
19 changes: 17 additions & 2 deletions src/shaders/symbol_sdf.vertex.glsl
Expand Up @@ -29,6 +29,8 @@ uniform mat4 u_gl_coord_matrix;
uniform bool u_is_text;
uniform bool u_pitch_with_map;
uniform highp float u_pitch;
uniform bool u_rotate_symbol;
uniform highp float u_aspect_ratio;
uniform highp float u_camera_to_center_distance;
uniform highp float u_collision_y_stretch;

Expand Down Expand Up @@ -82,8 +84,21 @@ void main() {

float fontScale = u_is_text ? size / 24.0 : size;

highp float angle_sin = sin(segment_angle);
highp float angle_cos = cos(segment_angle);
highp float symbol_rotation = 0.0;
if (u_rotate_symbol) {
// Point labels with 'rotation-alignment: map' are horizontal with respect to tile units
// To figure out that angle in projected space, we draw a short horizontal line in tile
// space, project it, and measure its angle in projected space.
vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1);

vec2 a = projectedPoint.xy / projectedPoint.w;
vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w;

symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);
}

highp float angle_sin = sin(segment_angle + symbol_rotation);
highp float angle_cos = cos(segment_angle + symbol_rotation);
mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);

vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0);
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,41 @@
{
"version": 8,
"metadata": {
"test": {
"width": 256,
"height": 256
}
},
"bearing": 45,
"pitch": 45,
"sources": {
"geojson": {
"type": "geojson",
"data": {
"type": "Point",
"coordinates": [
0,
0
]
}
}
},
"glyphs": "local://glyphs/{fontstack}/{range}.pbf",
"layers": [
{
"id": "text",
"type": "symbol",
"source": "geojson",
"layout": {
"symbol-placement": "point",
"text-rotation-alignment": "map",
"text-pitch-alignment": "viewport",
"text-field": "Test Text",
"text-font": [
"Open Sans Semibold",
"Arial Unicode MS Bold"
]
}
}
]
}

0 comments on commit 78bb9dc

Please sign in to comment.