[core, node] Support axonometric rendering
This commit is contained in:
@@ -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;
|
||||
|
||||
Submodule mapbox-gl-js updated: 3634d94547...cecd21c9dc
@@ -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": {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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>&);
|
||||
|
||||
|
||||
@@ -121,6 +121,9 @@ test('Map', function(t) {
|
||||
'setZoom',
|
||||
'setBearing',
|
||||
'setPitch',
|
||||
'setAxonometric',
|
||||
'setXSkew',
|
||||
'setYSkew',
|
||||
'dumpDebugLogs',
|
||||
'queryRenderedFeatures'
|
||||
]);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user