port perspective projection matrix from -js
This commit is contained in:
@@ -10,19 +10,11 @@ using namespace mbgl;
|
||||
|
||||
void TransformState::matrixFor(mat4& matrix, const TileID& id, const int8_t z) const {
|
||||
const double tile_scale = std::pow(2, z);
|
||||
const double tile_size = scale * util::tileSize / tile_scale;
|
||||
double s = util::tileSize * scale / tile_scale;
|
||||
|
||||
matrix::identity(matrix);
|
||||
|
||||
matrix::translate(matrix, matrix, 0.5f * (float)width, 0.5f * (float)height, 0);
|
||||
matrix::rotate_z(matrix, matrix, angle);
|
||||
matrix::translate(matrix, matrix, -0.5f * (float)width, -0.5f * (float)height, 0);
|
||||
|
||||
matrix::translate(matrix, matrix, pixel_x() + id.x * tile_size, pixel_y() + id.y * tile_size, 0);
|
||||
|
||||
// TODO: Get rid of the 8 (scaling from 4096 to tile size);
|
||||
float factor = scale / tile_scale / (4096.0f / util::tileSize);
|
||||
matrix::scale(matrix, matrix, factor, factor, 1);
|
||||
matrix::translate(matrix, matrix, id.x * s, id.y * s, 0);
|
||||
matrix::scale(matrix, matrix, s / 4096.0f, s / 4096.0f, 1);
|
||||
}
|
||||
|
||||
box TransformState::cornersToBox(uint32_t z) const {
|
||||
@@ -154,6 +146,13 @@ float TransformState::getAngle() const {
|
||||
return angle;
|
||||
}
|
||||
|
||||
float TransformState::getAltitude() const {
|
||||
return altitude;
|
||||
}
|
||||
|
||||
float TransformState::getPitch() const {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
#pragma mark - Projection
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ public:
|
||||
// Rotation
|
||||
float getAngle() const;
|
||||
|
||||
float getAltitude() const;
|
||||
float getPitch() const;
|
||||
|
||||
// Projection
|
||||
const vec2<double> pixelForLatLng(const LatLng latLng) const;
|
||||
const LatLng latLngForPixel(const vec2<double> pixel) const;
|
||||
@@ -56,6 +59,9 @@ public:
|
||||
// Changing
|
||||
bool isChanging() const;
|
||||
|
||||
double pixel_x() const;
|
||||
double pixel_y() const;
|
||||
|
||||
private:
|
||||
void constrain(double& scale, double& y) const;
|
||||
|
||||
@@ -63,9 +69,6 @@ private:
|
||||
double min_scale = std::pow(2, 0);
|
||||
double max_scale = std::pow(2, 18);
|
||||
|
||||
double pixel_x() const;
|
||||
double pixel_y() const;
|
||||
|
||||
// logical dimensions
|
||||
uint16_t width = 0, height = 0;
|
||||
|
||||
@@ -80,6 +83,8 @@ private:
|
||||
double x = 0, y = 0;
|
||||
double angle = 0;
|
||||
double scale = 1;
|
||||
double altitude = 1.5;
|
||||
double pitch = 0;
|
||||
|
||||
// cache values for spherical mercator math
|
||||
double Bc = (scale * util::tileSize) / 360;
|
||||
|
||||
@@ -117,6 +117,7 @@ struct DepthTest {
|
||||
static const Type Default;
|
||||
inline static void Set(const Type& value) {
|
||||
MBGL_CHECK_ERROR(value ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST));
|
||||
MBGL_CHECK_ERROR(glDisable(GL_DEPTH_TEST));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -132,8 +132,27 @@ void Painter::lineWidth(float line_width) {
|
||||
}
|
||||
|
||||
void Painter::changeMatrix() {
|
||||
// Initialize projection matrix
|
||||
matrix::ortho(projMatrix, 0, state.getWidth(), state.getHeight(), 0, -1, 1);
|
||||
|
||||
double halfFov = std::atan(0.5 / state.getAltitude());
|
||||
double topHalfSurfaceDistance = std::sin(halfFov) * state.getAltitude() /
|
||||
std::sin(M_PI / 2.0f - state.getPitch() - halfFov);
|
||||
// Calculate z value of the farthest fragment that should be rendered.
|
||||
double farZ = std::cos(M_PI / 2.0f - state.getPitch()) * topHalfSurfaceDistance + state.getAltitude();
|
||||
|
||||
matrix::perspective(projMatrix, 2.0f * std::atan((state.getHeight() / 2.0f) / state.getAltitude()),
|
||||
double(state.getWidth()) / state.getHeight(), 0.1, farZ);
|
||||
|
||||
matrix::translate(projMatrix, projMatrix, 0, 0, -state.getAltitude());
|
||||
|
||||
// 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 / state.getHeight());
|
||||
|
||||
matrix::rotate_x(projMatrix, projMatrix, state.getPitch());
|
||||
matrix::rotate_z(projMatrix, projMatrix, state.getAngle());
|
||||
|
||||
matrix::translate(projMatrix, projMatrix, state.pixel_x() - state.getWidth() / 2.0f,
|
||||
state.pixel_y() - state.getWidth() / 2.0f, 0);
|
||||
|
||||
// The extrusion matrix.
|
||||
matrix::identity(extrudeMatrix);
|
||||
|
||||
Reference in New Issue
Block a user