#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { class UnwrappedTileID; class TileCoordinate; struct TransformStateProperties { TransformStateProperties& withX(const optional& val) { x = val; return *this; } TransformStateProperties& withY(const optional& val) { y = val; return *this; } TransformStateProperties& withScale(const optional& val) { scale = val; return *this; } TransformStateProperties& withBearing(const optional& val) { bearing = val; return *this; } TransformStateProperties& withPitch(const optional& val) { pitch = val; return *this; } TransformStateProperties& withXSkew(const optional& val) { xSkew = val; return *this; } TransformStateProperties& withYSkew(const optional& val) { ySkew = val; return *this; } TransformStateProperties& withAxonometric(const optional& val) { axonometric = val; return *this; } TransformStateProperties& withPanningInProgress(const optional& val) { panning = val; return *this; } TransformStateProperties& withScalingInProgress(const optional& val) { scaling = val; return *this; } TransformStateProperties& withRotatingInProgress(const optional& val) { rotating = val; return *this; } TransformStateProperties& withEdgeInsets(const optional& val) { edgeInsets = val; return *this; } TransformStateProperties& withSize(const optional& val) { size = val; return *this; } TransformStateProperties& withConstrainMode(const optional& val) { constrain = val; return *this; } TransformStateProperties& withNorthOrientation(const optional& val) { northOrientation = val; return *this; } TransformStateProperties& withViewportMode(const optional& val) { viewPortMode = val; return *this; } optional x; optional y; optional bearing; optional scale; optional pitch; optional xSkew; optional ySkew; optional axonometric; optional panning; optional scaling; optional rotating; optional edgeInsets; optional size; optional constrain; optional northOrientation; optional viewPortMode; }; class TransformState { public: TransformState(ConstrainMode = ConstrainMode::HeightOnly, ViewportMode = ViewportMode::Default); void setProperties(const TransformStateProperties& properties); // Matrix void matrixFor(mat4&, const UnwrappedTileID&) const; void getProjMatrix(mat4& matrix, uint16_t nearZ = 1, bool aligned = false) const; // Dimensions Size getSize() const; void setSize(const Size& size_); // North Orientation NorthOrientation getNorthOrientation() const; double getNorthOrientationAngle() const; void setNorthOrientation(NorthOrientation); // Constrain mode ConstrainMode getConstrainMode() const; void setConstrainMode(ConstrainMode); // Viewport mode ViewportMode getViewportMode() const; void setViewportMode(ViewportMode val); CameraOptions getCameraOptions(const optional&) const; // EdgeInsects EdgeInsets getEdgeInsets() const { return edgeInsets; } void setEdgeInsets(const EdgeInsets&); // Position LatLng getLatLng(LatLng::WrapMode = LatLng::Unwrapped) const; double pixel_x() const; double pixel_y() const; // Zoom double getZoom() const; uint8_t getIntegerZoom() const; double getZoomFraction() const; // Scale double getScale() const; void setScale(double); // Positions double getX() const; void setX(double); double getY() const; void setY(double); // Bounds void setLatLngBounds(LatLngBounds); LatLngBounds getLatLngBounds() const; void setMinZoom(double); double getMinZoom() const; void setMaxZoom(double); double getMaxZoom() const; void setMinPitch(double); double getMinPitch() const; void setMaxPitch(double); double getMaxPitch() const; // Rotation double getBearing() const; void setBearing(double); float getFieldOfView() const; float getCameraToCenterDistance() const; double getPitch() const; void setPitch(double); double getXSkew() const; void setXSkew(double); double getYSkew() const; void setYSkew(double); bool getAxonometric() const; void setAxonometric(bool); // State bool isChanging() const; bool isRotating() const; void setRotatingInProgress(bool val) { rotating = val; } bool isScaling() const; void setScalingInProgress(bool val) { scaling = val; } bool isPanning() const; void setPanningInProgress(bool val) { panning = val; } bool isGestureInProgress() const; void setGestureInProgress(bool val) { gestureInProgress = val; } // Conversion ScreenCoordinate latLngToScreenCoordinate(const LatLng&) const; ScreenCoordinate latLngToScreenCoordinate(const LatLng&, vec4&) const; LatLng screenCoordinateToLatLng(const ScreenCoordinate&, LatLng::WrapMode = LatLng::Unwrapped) const; // Implements mapbox-gl-js pointCoordinate() : MercatorCoordinate. TileCoordinate screenCoordinateToTileCoordinate(const ScreenCoordinate&, uint8_t atZoom) const; double zoomScale(double zoom) const; double scaleZoom(double scale) const; bool valid() const { return !size.isEmpty() && (scale >= min_scale && scale <= max_scale); } float getCameraToTileDistance(const UnwrappedTileID&) const; float maxPitchScaleFactor() const; /** Recenter the map so that the given coordinate is located at the given point on screen. */ void moveLatLng(const LatLng&, const ScreenCoordinate&); void setLatLngZoom(const LatLng& latLng, double zoom); void constrain(double& scale, double& x, double& y) const; const mat4& getProjectionMatrix() const; const mat4& getInvProjectionMatrix() const; FreeCameraOptions getFreeCameraOptions() const; void setFreeCameraOptions(const FreeCameraOptions& options); private: bool rotatedNorth() const; // Viewport center offset, from [size.width / 2, size.height / 2], defined // by |edgeInsets| in screen coordinates, with top left origin. ScreenCoordinate getCenterOffset() const; LatLngBounds bounds; // Limit the amount of zooming possible on the map. double min_scale = std::pow(2, 0); double max_scale = std::pow(2, util::DEFAULT_MAX_ZOOM); // Limit the amount of pitch double minPitch = util::PITCH_MIN; double maxPitch = util::PITCH_MAX; NorthOrientation orientation = NorthOrientation::Upwards; // logical dimensions Size size; mat4 coordinatePointMatrix(const mat4& projMatrix) const; mat4 getPixelMatrix() const; void setScalePoint(double scale, const ScreenCoordinate& point); void updateMatricesIfNeeded() const; bool needsMatricesUpdate() const { return requestMatricesUpdate; } bool setCameraPosition(const vec3& position); bool setCameraOrientation(const Quaternion& orientation); void updateCameraState() const; void updateStateFromCamera(); const mat4& getCoordMatrix() const; const mat4& getInvertedMatrix() const; private: ConstrainMode constrainMode; ViewportMode viewportMode; // animation state bool rotating = false; bool scaling = false; bool panning = false; bool gestureInProgress = false; // map position double x = 0, y = 0; double bearing = 0; double scale = 1; // This fov value is somewhat arbitrary. The altitude of the camera used // to be defined as 1.5 screen heights above the ground, which was an // arbitrary choice. This is the fov equivalent to that value calculated with: // `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; EdgeInsets edgeInsets; mutable util::Camera camera; // cache values for spherical mercator math double Bc = Projection::worldSize(scale) / util::DEGREES_MAX; double Cc = Projection::worldSize(scale) / util::M2PI; mutable bool requestMatricesUpdate{true}; mutable mat4 projectionMatrix; mutable mat4 invProjectionMatrix; mutable mat4 coordMatrix; mutable mat4 invertedMatrix; }; } // namespace mbgl