| 460 | } |
| 461 | |
| 462 | std::pair<glsl::mat4, glsl::mat4> Arrow3d::CalculateTransform(ScreenBase const & screen, float dz, float scaleFactor, |
| 463 | dp::ApiVersion apiVersion) const |
| 464 | { |
| 465 | double arrowScale = VisualParams::Instance().GetVisualScale() * arrow3d::kArrowSize * scaleFactor; |
| 466 | if (screen.isPerspective()) |
| 467 | { |
| 468 | double const t = GetNormalizedZoomLevel(screen.GetScale(), arrow3d::kArrow3dMinZoom); |
| 469 | arrowScale *= (arrow3d::kArrow3dScaleMin * (1.0 - t) + arrow3d::kArrow3dScaleMax * t); |
| 470 | } |
| 471 | |
| 472 | glm::quat const qx = glm::angleAxis(m_meshEulerAngles.x, glm::vec3{1.0f, 0.0f, 0.0f}); |
| 473 | glm::quat const qy = glm::angleAxis(m_meshEulerAngles.y, glm::vec3{0.0f, 1.0f, 0.0f}); |
| 474 | glm::quat qz = glm::angleAxis(static_cast<float>(m_azimuth + screen.GetAngle() + m_meshEulerAngles.z), |
| 475 | glm::vec3{0.0f, 0.0f, -1.0f}); |
| 476 | auto const rotationMatrix = glm::mat4_cast(qz * qy * qx); |
| 477 | |
| 478 | qz = glm::angleAxis(static_cast<float>(m_meshEulerAngles.z), glm::vec3{0.0f, 0.0f, -1.0f}); |
| 479 | auto const normalMatrix = glm::mat4_cast(qz * qy * qx); |
| 480 | |
| 481 | auto const scaleMatrix = glm::scale( |
| 482 | glm::mat4(1.0f), glm::vec3{arrowScale, arrowScale, screen.isPerspective() ? arrowScale : 1.0} * m_meshScale); |
| 483 | |
| 484 | auto const translationMatrix = glm::translate(glm::mat4(1.0f), m_meshOffset); |
| 485 | |
| 486 | auto postProjectionScale = glm::vec3{2.0f / screen.PixelRect().SizeX(), 2.0f / screen.PixelRect().SizeY(), 1.0f}; |
| 487 | postProjectionScale.z = |
| 488 | screen.isPerspective() ? std::min(postProjectionScale.x, postProjectionScale.y) * screen.GetScale3d() : 0.1f; |
| 489 | auto const postProjectionScaleMatrix = glm::scale(glm::mat4(1.0f), postProjectionScale); |
| 490 | |
| 491 | m2::PointD const pos = screen.GtoP(m_position); |
| 492 | auto const dX = static_cast<float>(2.0 * pos.x / screen.PixelRect().SizeX() - 1.0); |
| 493 | auto const dY = static_cast<float>(2.0 * pos.y / screen.PixelRect().SizeY() - 1.0); |
| 494 | auto const postProjectionTranslationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3{dX, -dY, dz}); |
| 495 | |
| 496 | auto modelTransform = |
| 497 | postProjectionTranslationMatrix * postProjectionScaleMatrix * scaleMatrix * translationMatrix * rotationMatrix; |
| 498 | |
| 499 | if (screen.isPerspective()) |
| 500 | { |
| 501 | glm::mat4 pTo3dView = glm::make_mat4x4(screen.Pto3dMatrix().m_data); |
| 502 | auto postProjectionPerspective = pTo3dView * modelTransform; |
| 503 | return std::make_pair(postProjectionPerspective, normalMatrix); |
| 504 | } |
| 505 | |
| 506 | if (apiVersion == dp::ApiVersion::Metal) |
| 507 | { |
| 508 | modelTransform[3][2] = modelTransform[3][2] + 0.5f; |
| 509 | modelTransform[2][2] = modelTransform[2][2] * 0.5f; |
| 510 | } |
| 511 | |
| 512 | return std::make_pair(modelTransform, normalMatrix); |
| 513 | } |
| 514 | } // namespace df |
nothing calls this directly
no test coverage detected