drape_ptr<MapLinearAnimation> GetRectAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen) { auto anim = make_unique_dp<MapLinearAnimation>(); anim->SetRotate(startScreen.GetAngle(), endScreen.GetAngle()); anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(), startScreen.PixelRectIn3d(), (startScreen.GetScale() + endScreen.GetScale()) / 2.0); anim->SetScale(startScreen.GetScale(), endScreen.GetScale()); anim->SetMaxScaleDuration(kMaxAnimationTimeSec); return anim; }
drape_ptr<MapFollowAnimation> GetFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, double targetScale, double targetAngle, m2::PointD const & endPixelPos, bool isAutoZoom) { auto anim = make_unique_dp<MapFollowAnimation>(startScreen, userPos, endPixelPos, startScreen.GetScale(), targetScale, startScreen.GetAngle(), targetAngle, isAutoZoom); anim->SetMaxDuration(kMaxAnimationTimeSec); return anim; }
math::Matrix<float, 4, 4> Arrow3d::CalculateTransform(ScreenBase const & screen, float dz) const { double arrowScale = VisualParams::Instance().GetVisualScale() * kArrowSize; if (screen.isPerspective()) { static double const kLog2 = log(2.0); double const kMaxZoom = scales::UPPER_STYLE_SCALE + 1.0; double const zoomLevel = my::clamp(fabs(log(screen.GetScale()) / kLog2), kArrow3dMinZoom, kMaxZoom); double const t = (zoomLevel - kArrow3dMinZoom) / (kMaxZoom - kArrow3dMinZoom); arrowScale *= (kArrow3dScaleMin * (1.0 - t) + kArrow3dScaleMax * t); } double const scaleX = arrowScale * 2.0 / screen.PixelRect().SizeX(); double const scaleY = arrowScale * 2.0 / screen.PixelRect().SizeY(); double const scaleZ = screen.isPerspective() ? (0.002 * screen.GetDepth3d()) : 1.0; m2::PointD const pos = screen.GtoP(m_position); double const dX = 2.0 * pos.x / screen.PixelRect().SizeX() - 1.0; double const dY = 2.0 * pos.y / screen.PixelRect().SizeY() - 1.0; math::Matrix<float, 4, 4> scaleM = math::Identity<float, 4>(); scaleM(0, 0) = scaleX; scaleM(1, 1) = scaleY; scaleM(2, 2) = scaleZ; math::Matrix<float, 4, 4> rotateM = math::Identity<float, 4>(); rotateM(0, 0) = cos(m_azimuth + screen.GetAngle()); rotateM(0, 1) = -sin(m_azimuth + screen.GetAngle()); rotateM(1, 0) = -rotateM(0, 1); rotateM(1, 1) = rotateM(0, 0); math::Matrix<float, 4, 4> translateM = math::Identity<float, 4>(); translateM(3, 0) = dX; translateM(3, 1) = -dY; translateM(3, 2) = dz; math::Matrix<float, 4, 4> modelTransform = rotateM * scaleM * translateM; if (screen.isPerspective()) return modelTransform * math::Matrix<float, 4, 4>(screen.Pto3dMatrix()); return modelTransform; }
int GetTileScaleBase(ScreenBase const & s, uint32_t tileSize) { ScreenBase tmpS = s; tmpS.Rotate(-tmpS.GetAngle()); // slightly smaller than original to produce "antialiasing" effect using bilinear filtration. int const halfSize = static_cast<int>(tileSize / 1.05 / 2.0); m2::RectD glbRect; m2::PointD const pxCenter = tmpS.PixelRect().Center(); tmpS.PtoG(m2::RectD(pxCenter - m2::PointD(halfSize, halfSize), pxCenter + m2::PointD(halfSize, halfSize)), glbRect); return GetTileScaleBase(glbRect); }
drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, double targetScale, double targetAngle, m2::PointD const & endPixelPos) { auto sequenceAnim = make_unique_dp<SequenceAnimation>(); sequenceAnim->SetCustomType(kPrettyFollowAnim); m2::RectD const viewportRect = startScreen.PixelRectIn3d(); ScreenBase tmp = startScreen; tmp.SetAngle(targetAngle); tmp.MatchGandP3d(userPos, viewportRect.Center()); double const moveDuration = PositionInterpolator::GetMoveDuration(startScreen.GetOrg(), tmp.GetOrg(), startScreen); ASSERT_GREATER(moveDuration, 0.0, ()); double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0; tmp = startScreen; if (moveDuration > 0.0) { tmp.SetScale(startScreen.GetScale() * scaleFactor); auto zoomOutAnim = make_unique_dp<MapLinearAnimation>(); zoomOutAnim->SetScale(startScreen.GetScale(), tmp.GetScale()); zoomOutAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5); sequenceAnim->AddAnimation(move(zoomOutAnim)); tmp.MatchGandP3d(userPos, viewportRect.Center()); auto moveAnim = make_unique_dp<MapLinearAnimation>(); moveAnim->SetMove(startScreen.GetOrg(), tmp.GetOrg(), viewportRect, tmp.GetScale()); moveAnim->SetMaxDuration(kMaxAnimationTimeSec); sequenceAnim->AddAnimation(move(moveAnim)); } auto followAnim = make_unique_dp<MapFollowAnimation>(tmp, userPos, endPixelPos, tmp.GetScale(), targetScale, tmp.GetAngle(), targetAngle, false /* isAutoZoom */); followAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5); sequenceAnim->AddAnimation(move(followAnim)); return sequenceAnim; }
void MyPosition::RenderMyPosition(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms) { if (screen.isPerspective() && m_isRoutingMode && m_showAzimuth) { m_arrow3d.SetPosition(m_position); m_arrow3d.SetAzimuth(m_azimuth); m_arrow3d.Render(screen, mng); } else { dp::UniformValuesStorage uniforms = commonUniforms; uniforms.SetFloatValue("u_position", m_position.x, m_position.y, dp::depth::MY_POSITION_MARK); uniforms.SetFloatValue("u_azimut", -(m_azimuth + screen.GetAngle())); uniforms.SetFloatValue("u_opacity", 1.0); RenderPart(mng, uniforms, (m_showAzimuth == true) ? (m_obsoletePosition ? MY_POSITION_ARROW_GRAY : MY_POSITION_ARROW) : MY_POSITION_POINT); } }
// static void Animation::GetCurrentScreen(TPropertyCache const & properties, ScreenBase const & screen, ScreenBase & currentScreen) { currentScreen = screen; if (!properties.empty()) { double scale = currentScreen.GetScale(); double angle = currentScreen.GetAngle(); m2::PointD pos = currentScreen.GlobalRect().GlobalZero(); PropertyValue value; if (GetCachedProperty(properties, Object::MapPlane, ObjectProperty::Scale, value)) scale = value.m_valueD; if (GetCachedProperty(properties, Object::MapPlane, ObjectProperty::Angle, value)) angle = value.m_valueD; if (GetCachedProperty(properties, Object::MapPlane, ObjectProperty::Position, value)) pos = value.m_valuePointD; currentScreen.SetFromParams(pos, angle, scale); } }
bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, m2::PointD const & oldPt1, m2::PointD const & oldPt2, bool skipMinScaleAndBordersCheck, bool doRotateScreen) { math::Matrix<double, 3, 3> newM = m_Screen.GtoPMatrix() * ScreenBase::CalcTransform(oldPt1, oldPt2, newPt1, newPt2); double oldAngle = m_Screen.GetAngle(); ScreenBase tmp = m_Screen; tmp.SetGtoPMatrix(newM); if (!doRotateScreen) tmp.Rotate(-(tmp.GetAngle() - oldAngle)); if (!skipMinScaleAndBordersCheck && !CheckMinScale(tmp)) return false; m2::RectD const & worldR = m_scales.GetWorldRect(); if (!skipMinScaleAndBordersCheck && !CheckBorders(tmp)) { if (CanShrinkInto(tmp, worldR)) tmp = ShrinkInto(tmp, worldR); else return false; } if (!CheckMaxScale(tmp)) return false; // re-checking the borders, as we might violate them a bit (don't know why). if (!CheckBorders(tmp)) tmp = ScaleInto(tmp, worldR); m_Screen = tmp; return true; }
void MyPosition::RenderMyPosition(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & commonUniforms) { if (m_showAzimuth) { m_arrow3d.SetPosition(m_position); m_arrow3d.SetAzimuth(m_azimuth); m_arrow3d.Render(screen, zoomLevel, mng); } else { dp::UniformValuesStorage uniforms = commonUniforms; TileKey const key = GetTileKeyByPoint(m_position, ClipTileZoomByMaxDataZoom(zoomLevel)); math::Matrix<float, 4, 4> mv = key.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); m2::PointD const pos = MapShape::ConvertToLocal(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); uniforms.SetFloatValue("u_position", pos.x, pos.y, dp::depth::MY_POSITION_MARK); uniforms.SetFloatValue("u_azimut", -(m_azimuth + screen.GetAngle())); uniforms.SetFloatValue("u_opacity", 1.0); RenderPart(mng, uniforms, MY_POSITION_POINT); } }
void Arrow3d::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng) { // Unbind current VAO, because glVertexAttributePointer and glEnableVertexAttribute can affect it. GLFunctions::glBindVertexArray(0); ref_ptr<dp::GpuProgram> prg = mng->GetProgram(gpu::ARROW_3D_PROGRAM); prg->Bind(); if (!m_isInitialized) { Build(prg); m_isInitialized = true; } dp::ApplyState(m_state, prg); static double const kLog2 = log(2.0); double const kMaxZoom = scales::UPPER_STYLE_SCALE + 1.0; double const zoomLevel = my::clamp(fabs(log(screen.GetScale()) / kLog2), kArrow3dMinZoom, kMaxZoom); double const t = (zoomLevel - kArrow3dMinZoom) / (kMaxZoom - kArrow3dMinZoom); double const arrowScale = kArrow3dScaleMin * (1.0 - t) + kArrow3dScaleMax * t; double const scaleX = m_pixelWidth * arrowScale * 2.0 / screen.PixelRect().SizeX() / kArrowSizeX; double const scaleY = m_pixelHeight * arrowScale * 2.0 / screen.PixelRect().SizeY() / kArrowSizeY; double const scaleZ = scaleX; m2::PointD const pos = screen.GtoP(m_position); double const dX = 2.0 * pos.x / screen.PixelRect().SizeX() - 1.0; double const dY = 2.0 * pos.y / screen.PixelRect().SizeY() - 1.0; math::Matrix<float, 4, 4> scaleM = math::Identity<float, 4>(); scaleM(0, 0) = scaleX; scaleM(1, 1) = scaleY; scaleM(2, 2) = scaleZ; math::Matrix<float, 4, 4> rotateM = math::Identity<float, 4>(); rotateM(0, 0) = cos(m_azimuth + screen.GetAngle()); rotateM(0, 1) = -sin(m_azimuth + screen.GetAngle()); rotateM(1, 0) = -rotateM(0, 1); rotateM(1, 1) = rotateM(0, 0); math::Matrix<float, 4, 4> translateM = math::Identity<float, 4>(); translateM(3, 0) = dX; translateM(3, 1) = -dY; math::Matrix<float, 4, 4> modelTransform = rotateM * scaleM * translateM; modelTransform = modelTransform * math::Matrix<float, 4, 4>(screen.Pto3dMatrix()); dp::UniformValuesStorage uniforms; uniforms.SetMatrix4x4Value("m_transform", modelTransform.m_data); dp::ApplyUniforms(uniforms, prg); GLFunctions::glBindBuffer(m_bufferId, gl_const::GLArrayBuffer); GLFunctions::glEnableVertexAttribute(m_attributePosition); GLFunctions::glVertexAttributePointer(m_attributePosition, 3, gl_const::GLFloatType, false, 0, 0); GLFunctions::glBindBuffer(m_bufferNormalsId, gl_const::GLArrayBuffer); GLFunctions::glEnableVertexAttribute(m_attributeNormal); GLFunctions::glVertexAttributePointer(m_attributeNormal, 3, gl_const::GLFloatType, false, 0, 0); GLFunctions::glDrawArrays(gl_const::GLTriangles, 0, m_vertices.size() / 3); prg->Unbind(); GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); }