diff options
-rw-r--r-- | include/mbgl/map/map.hpp | 8 | ||||
m--------- | mapbox-gl-js | 0 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | platform/glfw/settings_json.hpp | 3 | ||||
-rw-r--r-- | platform/node/src/node_map.cpp | 82 | ||||
-rw-r--r-- | platform/node/src/node_map.hpp | 3 | ||||
-rw-r--r-- | platform/node/test/js/map.test.js | 3 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 29 | ||||
-rw-r--r-- | src/mbgl/map/transform.cpp | 26 | ||||
-rw-r--r-- | src/mbgl/map/transform.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.hpp | 3 |
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; |