summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauren Budorick <lauren@mapbox.com>2017-10-14 03:15:34 +0200
committerGitHub <noreply@github.com>2017-10-14 03:15:34 +0200
commite43e2aa3d700cb086e8de0e1c07a6623a192bfe0 (patch)
tree11949cef17e85e66f329444a88982196794db960
parent98bb8613c341bc9e07692f6172c661e8f700272d (diff)
downloadqtlocation-mapboxgl-e43e2aa3d700cb086e8de0e1c07a6623a192bfe0.tar.gz
[core, node] Support axonometric rendering
-rw-r--r--include/mbgl/map/map.hpp8
m---------mapbox-gl-js0
-rw-r--r--package.json2
-rw-r--r--platform/glfw/settings_json.hpp3
-rw-r--r--platform/node/src/node_map.cpp82
-rw-r--r--platform/node/src/node_map.hpp3
-rw-r--r--platform/node/test/js/map.test.js3
-rw-r--r--src/mbgl/map/map.cpp29
-rw-r--r--src/mbgl/map/transform.cpp26
-rw-r--r--src/mbgl/map/transform.hpp8
-rw-r--r--src/mbgl/map/transform_state.cpp9
-rw-r--r--src/mbgl/map/transform_state.hpp3
12 files changed, 175 insertions, 1 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index c5f90d99e1..5ba23a76dd 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -127,6 +127,14 @@ public:
void setViewportMode(ViewportMode);
ViewportMode getViewportMode() const;
+ // Projection mode
+ void setAxonometric(bool);
+ bool getAxonometric() const;
+ void setXSkew(double ySkew);
+ double getXSkew() const;
+ void setYSkew(double ySkew);
+ double getYSkew() const;
+
// Size
void setSize(Size);
Size getSize() const;
diff --git a/mapbox-gl-js b/mapbox-gl-js
-Subproject 3634d945477cb7dbbf1e0bebf4cf51542821895
+Subproject cecd21c9dcf87e4b1a5282b3a071f409c164398
diff --git a/package.json b/package.json
index e398121d18..5c91322978 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
"license": "BSD-2-Clause",
"dependencies": {
"nan": "^2.4.0",
- "node-pre-gyp": "^0.6.36",
+ "node-pre-gyp": "^0.6.37",
"npm-run-all": "^4.0.2"
},
"devDependencies": {
diff --git a/platform/glfw/settings_json.hpp b/platform/glfw/settings_json.hpp
index 49ea00e3e1..c89accb8af 100644
--- a/platform/glfw/settings_json.hpp
+++ b/platform/glfw/settings_json.hpp
@@ -17,6 +17,9 @@ public:
double zoom = 0;
double bearing = 0;
double pitch = 0;
+ bool axonometric = false;
+ double xSkew = 0.0;
+ double ySkew = 1.0;
EnumType debug = 0;
bool online = true;
diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp
index 9a7ebce445..da359f251c 100644
--- a/platform/node/src/node_map.cpp
+++ b/platform/node/src/node_map.cpp
@@ -26,6 +26,9 @@ struct NodeMap::RenderOptions {
double latitude = 0;
double longitude = 0;
mbgl::Size size = { 512, 512 };
+ bool axonometric = false;
+ double xSkew = 0;
+ double ySkew = 1;
std::vector<std::string> classes;
mbgl::MapDebugOptions debugOptions = mbgl::MapDebugOptions::NoDebug;
};
@@ -65,6 +68,9 @@ void NodeMap::Init(v8::Local<v8::Object> target) {
Nan::SetPrototypeMethod(tpl, "setZoom", SetZoom);
Nan::SetPrototypeMethod(tpl, "setBearing", SetBearing);
Nan::SetPrototypeMethod(tpl, "setPitch", SetPitch);
+ Nan::SetPrototypeMethod(tpl, "setAxonometric", SetAxonometric);
+ Nan::SetPrototypeMethod(tpl, "setXSkew", SetXSkew);
+ Nan::SetPrototypeMethod(tpl, "setYSkew", SetYSkew);
Nan::SetPrototypeMethod(tpl, "dumpDebugLogs", DumpDebugLogs);
Nan::SetPrototypeMethod(tpl, "queryRenderedFeatures", QueryRenderedFeatures);
@@ -251,6 +257,19 @@ NodeMap::RenderOptions NodeMap::ParseOptions(v8::Local<v8::Object> obj) {
options.pitch = Nan::Get(obj, Nan::New("pitch").ToLocalChecked()).ToLocalChecked()->NumberValue();
}
+ if (Nan::Has(obj, Nan::New("axonometric").ToLocalChecked()).FromJust()) {
+ options.axonometric = Nan::Get(obj, Nan::New("axonometric").ToLocalChecked()).ToLocalChecked()->BooleanValue();
+ }
+
+ if (Nan::Has(obj, Nan::New("skew").ToLocalChecked()).FromJust()) {
+ auto skewObj = Nan::Get(obj, Nan::New("skew").ToLocalChecked()).ToLocalChecked();
+ if (skewObj->IsArray()) {
+ auto skew = skewObj.As<v8::Array>();
+ if (skew->Length() > 0) { options.xSkew = Nan::Get(skew, 0).ToLocalChecked()->NumberValue(); }
+ if (skew->Length() > 1) { options.ySkew = Nan::Get(skew, 1).ToLocalChecked()->NumberValue(); }
+ }
+ }
+
if (Nan::Has(obj, Nan::New("center").ToLocalChecked()).FromJust()) {
auto centerObj = Nan::Get(obj, Nan::New("center").ToLocalChecked()).ToLocalChecked();
if (centerObj->IsArray()) {
@@ -370,6 +389,18 @@ void NodeMap::startRender(NodeMap::RenderOptions options) {
camera.angle = -options.bearing * mbgl::util::DEG2RAD;
camera.pitch = options.pitch * mbgl::util::DEG2RAD;
+ if (map->getAxonometric() != options.axonometric) {
+ map->setAxonometric(options.axonometric);
+ }
+
+ if (map->getXSkew() != options.xSkew) {
+ map->setXSkew(options.xSkew);
+ }
+
+ if (map->getYSkew() != options.ySkew) {
+ map->setYSkew(options.ySkew);
+ }
+
map->renderStill(camera, options.debugOptions, [this](const std::exception_ptr eptr) {
if (eptr) {
error = std::move(eptr);
@@ -879,6 +910,57 @@ void NodeMap::SetPitch(const Nan::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().SetUndefined();
}
+void NodeMap::SetAxonometric(const Nan::FunctionCallbackInfo<v8::Value>& info) {
+ auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
+ if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
+
+ if (info.Length() <= 0 || !info[0]->IsBoolean()) {
+ return Nan::ThrowTypeError("First argument must be a boolean");
+ }
+
+ try {
+ nodeMap->map->setAxonometric(info[0]->BooleanValue());
+ } catch (const std::exception &ex) {
+ return Nan::ThrowError(ex.what());
+ }
+
+ info.GetReturnValue().SetUndefined();
+}
+
+void NodeMap::SetXSkew(const Nan::FunctionCallbackInfo<v8::Value>& info) {
+ auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
+ if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
+
+ if (info.Length() <= 0 || !info[0]->IsNumber()) {
+ return Nan::ThrowTypeError("First argument must be a number");
+ }
+
+ try {
+ nodeMap->map->setXSkew(info[0]->NumberValue());
+ } catch (const std::exception &ex) {
+ return Nan::ThrowError(ex.what());
+ }
+
+ info.GetReturnValue().SetUndefined();
+}
+
+void NodeMap::SetYSkew(const Nan::FunctionCallbackInfo<v8::Value>& info) {
+ auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
+ if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
+
+ if (info.Length() <= 0 || !info[0]->IsNumber()) {
+ return Nan::ThrowTypeError("First argument must be a number");
+ }
+
+ try {
+ nodeMap->map->setYSkew(info[0]->NumberValue());
+ } catch (const std::exception &ex) {
+ return Nan::ThrowError(ex.what());
+ }
+
+ info.GetReturnValue().SetUndefined();
+}
+
void NodeMap::DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>& info) {
auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp
index c8e33bb347..8e7f0a3e58 100644
--- a/platform/node/src/node_map.hpp
+++ b/platform/node/src/node_map.hpp
@@ -57,6 +57,9 @@ public:
static void SetZoom(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetBearing(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetPitch(const Nan::FunctionCallbackInfo<v8::Value>&);
+ static void SetAxonometric(const Nan::FunctionCallbackInfo<v8::Value>&);
+ static void SetXSkew(const Nan::FunctionCallbackInfo<v8::Value>&);
+ static void SetYSkew(const Nan::FunctionCallbackInfo<v8::Value>&);
static void DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>&);
static void QueryRenderedFeatures(const Nan::FunctionCallbackInfo<v8::Value>&);
diff --git a/platform/node/test/js/map.test.js b/platform/node/test/js/map.test.js
index 39665e41ef..e3c8031908 100644
--- a/platform/node/test/js/map.test.js
+++ b/platform/node/test/js/map.test.js
@@ -121,6 +121,9 @@ test('Map', function(t) {
'setZoom',
'setBearing',
'setPitch',
+ 'setAxonometric',
+ 'setXSkew',
+ 'setYSkew',
'dumpDebugLogs',
'queryRenderedFeatures'
]);
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 6eb555ad1e..378bd40ab7 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -617,6 +617,35 @@ ViewportMode Map::getViewportMode() const {
return impl->transform.getViewportMode();
}
+#pragma mark - Projection mode
+
+void Map::setAxonometric(bool axonometric) {
+ impl->transform.setAxonometric(axonometric);
+ impl->onUpdate();
+}
+
+bool Map::getAxonometric() const {
+ return impl->transform.getAxonometric();
+}
+
+void Map::setXSkew(double xSkew) {
+ impl->transform.setXSkew(xSkew);
+ impl->onUpdate();
+}
+
+double Map::getXSkew() const {
+ return impl->transform.getXSkew();
+}
+
+void Map::setYSkew(double ySkew) {
+ impl->transform.setYSkew(ySkew);
+ impl->onUpdate();
+}
+
+double Map::getYSkew() const {
+ return impl->transform.getYSkew();
+}
+
#pragma mark - Projection
ScreenCoordinate Map::pixelForLatLng(const LatLng& latLng) const {
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 2bb25af28f..105adf0400 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -527,6 +527,32 @@ ViewportMode Transform::getViewportMode() const {
return state.getViewportMode();
}
+#pragma mark - Projection mode
+
+void Transform::setAxonometric(bool axonometric) {
+ state.axonometric = axonometric;
+}
+
+bool Transform::getAxonometric() const {
+ return state.axonometric;
+}
+
+void Transform::setXSkew(double xSkew) {
+ state.xSkew = xSkew;
+}
+
+double Transform::getXSkew() const {
+ return state.xSkew;
+}
+
+void Transform::setYSkew(double ySkew) {
+ state.ySkew = ySkew;
+}
+
+double Transform::getYSkew() const {
+ return state.ySkew;
+}
+
#pragma mark - Transition
void Transform::startTransition(const CameraOptions& camera,
diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp
index 749228bdf5..d429c57661 100644
--- a/src/mbgl/map/transform.hpp
+++ b/src/mbgl/map/transform.hpp
@@ -125,6 +125,14 @@ public:
void setViewportMode(ViewportMode);
ViewportMode getViewportMode() const;
+ // Projection mode
+ void setAxonometric(bool);
+ bool getAxonometric() const;
+ void setXSkew(double xSkew);
+ double getXSkew() const;
+ void setYSkew(double ySkew);
+ double getYSkew() const;
+
// Transitions
bool inTransition() const;
void updateTransitions(const TimePoint& now);
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index d1a320beae..d79a65c61e 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -66,6 +66,15 @@ void TransformState::getProjMatrix(mat4& projMatrix, uint16_t nearZ) const {
matrix::translate(projMatrix, projMatrix, pixel_x() - size.width / 2.0f,
pixel_y() - size.height / 2.0f, 0);
+ if (axonometric) {
+ // mat[11] controls perspective
+ projMatrix[11] = 0;
+
+ // mat[8], mat[9] control x-skew, y-skew
+ projMatrix[8] = xSkew;
+ projMatrix[9] = ySkew;
+ }
+
matrix::scale(projMatrix, projMatrix, 1, 1,
1.0 / Projection::getMetersPerPixelAtLatitude(getLatLng(LatLng::Unwrapped).latitude(), getZoom()));
}
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 59522d89fd..0dd6d5a15e 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -134,6 +134,9 @@ private:
// `fov = 2 * arctan((height / 2) / (height * 1.5))`
double fov = 0.6435011087932844;
double pitch = 0.0;
+ double xSkew = 0.0;
+ double ySkew = 1.0;
+ bool axonometric = false;
// cache values for spherical mercator math
double Bc = Projection::worldSize(scale) / util::DEGREES_MAX;