#include #include #include #include #include #include #include #include #include #include #include namespace mbgl { using namespace style; RenderCircleLayer::RenderCircleLayer(Immutable _impl) : RenderLayer(style::LayerType::Circle, _impl), unevaluated(impl().paint.untransitioned()) { } const style::CircleLayer::Impl& RenderCircleLayer::impl() const { return static_cast(*baseImpl); } std::unique_ptr RenderCircleLayer::createBucket(const BucketParameters& parameters, const std::vector& layers) const { return std::make_unique(parameters, layers); } void RenderCircleLayer::transition(const TransitionParameters& parameters) { unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); } void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); passes = ((evaluated.get().constantOr(1) > 0 || evaluated.get().constantOr(1) > 0) && (evaluated.get().constantOr(Color::black()).a > 0 || evaluated.get().constantOr(Color::black()).a > 0) && (evaluated.get().constantOr(1) > 0 || evaluated.get().constantOr(1) > 0)) ? RenderPass::Translucent : RenderPass::None; } bool RenderCircleLayer::hasTransition() const { return unevaluated.hasTransition(); } void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; } const bool scaleWithMap = evaluated.get() == CirclePitchScaleType::Map; const bool pitchWithMap = evaluated.get() == AlignmentType::Map; for (const RenderTile& tile : renderTiles) { assert(dynamic_cast(tile.tile.getBucket(*baseImpl))); CircleBucket& bucket = *reinterpret_cast(tile.tile.getBucket(*baseImpl)); parameters.programs.circle.get(evaluated).draw( parameters.context, gl::Triangles(), parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), parameters.mapMode == MapMode::Still ? parameters.stencilModeForClipping(tile.clip) : gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), CircleProgram::UniformValues { uniforms::u_matrix::Value{ tile.translatedMatrix(evaluated.get(), evaluated.get(), parameters.state) }, uniforms::u_scale_with_map::Value{ scaleWithMap }, uniforms::u_extrude_scale::Value{ pitchWithMap ? std::array {{ tile.id.pixelsToTileUnits(1, parameters.state.getZoom()), tile.id.pixelsToTileUnits(1, parameters.state.getZoom()) }} : parameters.pixelsToGLUnits }, uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() }, uniforms::u_pitch_with_map::Value{ pitchWithMap } }, *bucket.vertexBuffer, *bucket.indexBuffer, bucket.segments, bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(), getID() ); } } bool RenderCircleLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, const float zoom, const float bearing, const float pixelsToTileUnits) const { // Translate query geometry auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, evaluated.get(), evaluated.get(), bearing, pixelsToTileUnits); // Evaluate function auto circleRadius = evaluated.get() .evaluate(feature, zoom, style::CircleRadius::defaultValue()) * pixelsToTileUnits; // Test intersection return util::polygonIntersectsBufferedMultiPoint(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries(), circleRadius); } } // namespace mbgl