summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2015-11-16 16:32:09 +0100
committerKonstantin Käfer <mail@kkaefer.com>2015-12-15 11:41:58 -0800
commit4fc8226838a23154ca8acc5e5fcb6144de0794cb (patch)
treeac2354fda5e9bca147d7eb3f5bdddbaa291dc319
parent62412af6ab746dd8fb5b8984c75b3ff6e6b223e5 (diff)
downloadqtlocation-mapboxgl-4fc8226838a23154ca8acc5e5fcb6144de0794cb.tar.gz
[core] allow changing the orientation
You can now change the orientation of north to be to the right, bottom, left in addition to the default of top
-rw-r--r--include/mbgl/map/map.hpp4
-rw-r--r--include/mbgl/platform/default/glfw_view.hpp2
-rw-r--r--include/mbgl/util/geo.hpp8
-rw-r--r--include/mbgl/util/mat4.hpp1
-rw-r--r--platform/default/glfw_view.cpp14
-rw-r--r--src/mbgl/map/map.cpp12
-rw-r--r--src/mbgl/map/transform.cpp11
-rw-r--r--src/mbgl/map/transform.hpp4
-rw-r--r--src/mbgl/map/transform_state.cpp44
-rw-r--r--src/mbgl/map/transform_state.hpp7
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp2
-rw-r--r--src/mbgl/util/mat4.cpp34
12 files changed, 136 insertions, 7 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index df7597ced4..f8c3f4a172 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -133,6 +133,10 @@ public:
void setPitch(double pitch, const Duration& = Duration::zero());
double getPitch() const;
+ // North Orientation
+ void setNorthOrientation(NorthOrientation);
+ NorthOrientation getNorthOrientation() const;
+
// Size
uint16_t getWidth() const;
uint16_t getHeight() const;
diff --git a/include/mbgl/platform/default/glfw_view.hpp b/include/mbgl/platform/default/glfw_view.hpp
index a434b71bb1..0e46f7d87e 100644
--- a/include/mbgl/platform/default/glfw_view.hpp
+++ b/include/mbgl/platform/default/glfw_view.hpp
@@ -50,6 +50,8 @@ private:
static std::shared_ptr<const mbgl::SpriteImage>
makeSpriteImage(int width, int height, float pixelRatio);
+ void nextOrientation();
+
void addRandomPointAnnotations(int count);
void addRandomShapeAnnotations(int count);
void addRandomCustomPointAnnotations(int count);
diff --git a/include/mbgl/util/geo.hpp b/include/mbgl/util/geo.hpp
index 2f0e4f6fdc..e815456f22 100644
--- a/include/mbgl/util/geo.hpp
+++ b/include/mbgl/util/geo.hpp
@@ -100,6 +100,14 @@ struct MetersBounds {
}
};
+// Determines the orientation of the map.
+enum class NorthOrientation : uint8_t {
+ Upwards, // Default
+ Rightwards,
+ Downwards,
+ Leftwards,
+};
+
} // namespace mbgl
#endif
diff --git a/include/mbgl/util/mat4.hpp b/include/mbgl/util/mat4.hpp
index e5b508e547..59f6e3ee00 100644
--- a/include/mbgl/util/mat4.hpp
+++ b/include/mbgl/util/mat4.hpp
@@ -38,6 +38,7 @@ void perspective(mat4& out, double fovy, double aspect, double near, double far)
void copy(mat4& out, const mat4& a);
void translate(mat4& out, const mat4& a, double x, double y, double z);
void rotate_x(mat4& out, const mat4& a, double rad);
+void rotate_y(mat4& out, const mat4& a, double rad);
void rotate_z(mat4& out, const mat4& a, double rad);
void scale(mat4& out, const mat4& a, double x, double y, double z);
void multiply(mat4& out, const mat4& a, const mat4& b);
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp
index 418f427c74..c83e6c324b 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/default/glfw_view.cpp
@@ -92,6 +92,7 @@ GLFWView::GLFWView(bool fullscreen_, bool benchmark_)
printf("- Press `X` to reset the transform\n");
printf("- Press `N` to reset north\n");
printf("- Press `R` to toggle any available `night` style class\n");
+ printf("- Press `Z` to cycle through north orientations\n");
printf("\n");
printf("- Press `1` through `6` to add increasing numbers of point annotations for testing\n");
printf("- Press `7` through `0` to add increasing numbers of shape annotations for testing\n");
@@ -153,6 +154,9 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
if (!mods)
view->map->resetNorth();
break;
+ case GLFW_KEY_Z:
+ view->nextOrientation();
+ break;
case GLFW_KEY_Q:
view->clearAnnotations();
break;
@@ -218,6 +222,16 @@ GLFWView::makeSpriteImage(int width, int height, float pixelRatio) {
return std::make_shared<mbgl::SpriteImage>(width, height, pixelRatio, std::move(pixels));
}
+void GLFWView::nextOrientation() {
+ using NO = mbgl::NorthOrientation;
+ switch (map->getNorthOrientation()) {
+ case NO::Upwards: map->setNorthOrientation(NO::Rightwards); break;
+ case NO::Rightwards: map->setNorthOrientation(NO::Downwards); break;
+ case NO::Downwards: map->setNorthOrientation(NO::Leftwards); break;
+ default: map->setNorthOrientation(NO::Upwards); break;
+ }
+}
+
void GLFWView::addRandomCustomPointAnnotations(int count) {
std::vector<mbgl::PointAnnotation> points;
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 4336c2556d..3c585a8ae2 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -343,6 +343,18 @@ double Map::getPitch() const {
}
+#pragma mark - North Orientation
+
+void Map::setNorthOrientation(NorthOrientation orientation) {
+ transform->setNorthOrientation(orientation);
+ update(Update::Repaint);
+}
+
+NorthOrientation Map::getNorthOrientation() const {
+ return transform->getNorthOrientation();
+}
+
+
#pragma mark - Projection
MetersBounds Map::getWorldBoundsMeters() const {
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 5ba3b7493d..4604fbb287 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -498,6 +498,17 @@ double Transform::getPitch() const {
return state.pitch;
}
+#pragma mark - North Orientation
+
+void Transform::setNorthOrientation(NorthOrientation orientation) {
+ state.orientation = orientation;
+ state.constrain(state.scale, state.x, state.y);
+}
+
+NorthOrientation Transform::getNorthOrientation() const {
+ return state.getNorthOrientation();
+}
+
#pragma mark - Transition
void Transform::startTransition(std::function<double(double)> easing,
diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp
index 391b8c8d65..0bb6bb851e 100644
--- a/src/mbgl/map/transform.hpp
+++ b/src/mbgl/map/transform.hpp
@@ -52,6 +52,10 @@ public:
void setPitch(double pitch, const Duration& = Duration::zero());
double getPitch() const;
+ // North Orientation
+ void setNorthOrientation(NorthOrientation);
+ NorthOrientation getNorthOrientation() const;
+
// Transitions
bool inTransition() const;
Update updateTransitions(const TimePoint& now);
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 44a4c29402..7153c2524b 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -37,10 +37,17 @@ void TransformState::getProjMatrix(mat4& projMatrix) const {
// After the rotateX, z values are in pixel units. Convert them to
// altitude unites. 1 altitude unit = the screen height.
- matrix::scale(projMatrix, projMatrix, 1, -1, 1.0f / getHeight());
+ matrix::scale(projMatrix, projMatrix, 1, -1, 1.0f / (rotatedNorth() ? getWidth() : getHeight()));
+
+ using NO = NorthOrientation;
+ switch (getNorthOrientation()) {
+ case NO::Rightwards: matrix::rotate_y(projMatrix, projMatrix, getPitch()); break;
+ case NO::Downwards: matrix::rotate_x(projMatrix, projMatrix, -getPitch()); break;
+ case NO::Leftwards: matrix::rotate_y(projMatrix, projMatrix, -getPitch()); break;
+ default: matrix::rotate_x(projMatrix, projMatrix, getPitch()); break;
+ }
- matrix::rotate_x(projMatrix, projMatrix, getPitch());
- matrix::rotate_z(projMatrix, projMatrix, getAngle());
+ matrix::rotate_z(projMatrix, projMatrix, getAngle() + getNorthOrientationAngle());
matrix::translate(projMatrix, projMatrix, pixel_x() - getWidth() / 2.0f,
pixel_y() - getHeight() / 2.0f, 0);
@@ -72,6 +79,24 @@ uint16_t TransformState::getHeight() const {
return height;
}
+#pragma mark - North Orientation
+
+NorthOrientation TransformState::getNorthOrientation() const {
+ return orientation;
+}
+
+double TransformState::getNorthOrientationAngle() const {
+ double angleOrientation = 0;
+ if (orientation == NorthOrientation::Rightwards) {
+ angleOrientation += M_PI / 2.0f;
+ } else if (orientation == NorthOrientation::Downwards) {
+ angleOrientation += M_PI;
+ } else if (orientation == NorthOrientation::Leftwards) {
+ angleOrientation -= M_PI / 2.0f;
+ }
+ return angleOrientation;
+}
+
#pragma mark - Position
LatLng TransformState::getLatLng() const {
@@ -318,21 +343,26 @@ mat4 TransformState::getPixelMatrix() const {
#pragma mark - (private helper functions)
+bool TransformState::rotatedNorth() const {
+ using NO = NorthOrientation;
+ return (orientation == NO::Leftwards || orientation == NO::Rightwards);
+}
+
void TransformState::constrain(double& scale_, double& x_, double& y_) const {
// Constrain minimum scale to avoid zooming out far enough to show off-world areas.
if (constrainMode == ConstrainMode::WidthAndHeight) {
- scale_ = std::max(scale_, static_cast<double>(width / util::tileSize));
+ scale_ = std::max(scale_, static_cast<double>((rotatedNorth() ? height : width) / util::tileSize));
}
- scale_ = std::max(scale_, static_cast<double>(height / util::tileSize));
+ scale_ = std::max(scale_, static_cast<double>((rotatedNorth() ? width : height) / util::tileSize));
// Constrain min/max pan to avoid showing off-world areas.
if (constrainMode == ConstrainMode::WidthAndHeight) {
- double max_x = (scale_ * util::tileSize - width) / 2;
+ double max_x = (scale_ * util::tileSize - (rotatedNorth() ? height : width)) / 2;
x_ = std::max(-max_x, std::min(x_, max_x));
}
- double max_y = (scale_ * util::tileSize - height) / 2;
+ double max_y = (scale_ * util::tileSize - (rotatedNorth() ? width : height)) / 2;
y_ = std::max(-max_y, std::min(y_, max_y));
}
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 37ea7fa0f4..fd9a556eb9 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -34,6 +34,10 @@ public:
uint16_t getWidth() const;
uint16_t getHeight() const;
+ // North Orientation
+ NorthOrientation getNorthOrientation() const;
+ double getNorthOrientationAngle() const;
+
std::array<float, 2> locationCoordinate(float lon, float lat) const;
void getLonLat(double &lon, double &lat) const;
@@ -74,12 +78,15 @@ public:
TileCoordinate pointToCoordinate(const PrecisionPoint&) const;
private:
+ bool rotatedNorth() const;
void constrain(double& scale, double& x, double& y) const;
// Limit the amount of zooming possible on the map.
double min_scale = std::pow(2, 0);
double max_scale = std::pow(2, 18);
+ NorthOrientation orientation = NorthOrientation::Upwards;
+
// logical dimensions
uint16_t width = 0, height = 0;
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index 4a00d941db..0cb73b9f27 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -40,6 +40,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
exMatrix = extrudeMatrix;
s = state.getAltitude();
gammaScale = 1.0f;
+ matrix::rotate_z(exMatrix, exMatrix, state.getNorthOrientationAngle());
}
matrix::scale(exMatrix, exMatrix, s, s, 1);
@@ -218,6 +219,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
s = 4096.0f / util::tileSize / id.overscaling / std::pow(2, state.getZoom() - id.z);
} else {
exMatrix = extrudeMatrix;
+ matrix::rotate_z(exMatrix, exMatrix, state.getNorthOrientationAngle());
s = state.getAltitude();
}
matrix::scale(exMatrix, exMatrix, s, s, 1);
diff --git a/src/mbgl/util/mat4.cpp b/src/mbgl/util/mat4.cpp
index 0934cd081e..5f6f9d1b4c 100644
--- a/src/mbgl/util/mat4.cpp
+++ b/src/mbgl/util/mat4.cpp
@@ -214,6 +214,40 @@ void matrix::rotate_x(mat4& out, const mat4& a, double rad) {
out[11] = a23 * c - a13 * s;
}
+void matrix::rotate_y(mat4& out, const mat4& a, double rad) {
+ double s = std::sin(rad),
+ c = std::cos(rad),
+ a00 = a[0],
+ a01 = a[1],
+ a02 = a[2],
+ a03 = a[3],
+ a20 = a[8],
+ a21 = a[9],
+ a22 = a[10],
+ a23 = a[11];
+
+ if (&a != &out) { // If the source and destination differ, copy the unchanged rows
+ out[4] = a[4];
+ out[5] = a[5];
+ out[6] = a[6];
+ out[7] = a[7];
+ out[12] = a[12];
+ out[13] = a[13];
+ out[14] = a[14];
+ out[15] = a[15];
+ }
+
+ // Perform axis-specific matrix multiplication
+ out[0] = a00 * c - a20 * s;
+ out[1] = a01 * c - a21 * s;
+ out[2] = a02 * c - a22 * s;
+ out[3] = a03 * c - a23 * s;
+ out[8] = a00 * s + a20 * c;
+ out[9] = a01 * s + a21 * c;
+ out[10] = a02 * s + a22 * c;
+ out[11] = a03 * s + a23 * c;
+}
+
void matrix::rotate_z(mat4& out, const mat4& a, double rad) {
double s = std::sin(rad),
c = std::cos(rad),