void RoutingPluginPrivate::updateDestinationInformation() { if ( m_routingModel->route().currentSegment().isValid() ) { qreal remaining = remainingDistance(); qreal distanceLeft = nextInstructionDistance(); m_audio->update( m_routingModel->route(), distanceLeft, remaining, m_routingModel->deviatedFromRoute() ); m_nearNextInstruction = distanceLeft < thresholdDistance; QString pixmapHtml = "<img src=\":/flag.png\" /><br />"; m_widget.destinationDistanceLabel->setText( pixmapHtml + richText( fuzzyDistance( remaining ) ) ); m_widget.instructionIconLabel->setEnabled( m_nearNextInstruction ); m_widget.progressBar->setMaximum( thresholdDistance ); m_widget.progressBar->setValue( qRound( distanceLeft ) ); updateButtonVisibility(); QString pixmap = MarbleDirs::path( "bitmaps/routing_step.png" ); pixmapHtml = QString( "<img src=\"%1\" />" ).arg( pixmap ); qreal planetRadius = m_marbleWidget->model()->planet()->radius(); GeoDataCoordinates const onRoute = m_routingModel->route().positionOnRoute(); GeoDataCoordinates const ego = m_routingModel->route().position(); qreal const distanceToRoute = planetRadius * distanceSphere( ego, onRoute ); if ( !m_routingModel->route().currentSegment().isValid() ) { m_widget.instructionLabel->setText( richText( QObject::tr( "Calculate a route to get directions." ) ) ); m_widget.instructionIconLabel->setText( pixmapHtml ); } else if ( distanceToRoute > 300.0 ) { m_widget.instructionLabel->setText( richText( QObject::tr( "Route left." ) ) ); m_widget.instructionIconLabel->setText( pixmapHtml ); } else if ( !m_routingModel->route().currentSegment().nextRouteSegment().isValid() ) { m_widget.instructionLabel->setText( richText( QObject::tr( "Destination ahead." ) ) ); m_widget.instructionIconLabel->setText( pixmapHtml ); } else { pixmap = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().directionPixmap(); QString const instructionText = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().instructionText(); m_widget.instructionLabel->setText( richText( "%1" ).arg( instructionText ) ); pixmapHtml = QString( "<p align=\"center\"><img src=\"%1\" /><br />%2</p>" ).arg( pixmap ); m_widget.instructionIconLabel->setText( pixmapHtml.arg( richText( fuzzyDistance( distanceLeft ) ) ) ); if( remaining > 50 ) { m_routeCompleted = false; } else { if ( !m_routeCompleted ) { QString content = QObject::tr( "Arrived at destination. <a href=\"#reverse\">Calculate the way back.</a>" ); m_widget.instructionLabel->setText( richText( "%1" ).arg( content ) ); } m_routeCompleted = true; } } forceRepaint(); } }
/* Calculate direction vector from current position of renderable at time of attach. */ void dtn::ProcessMoveRenderable::onAttach() { sf::Vector2f renderablePos = m_renderable->getSprite().getPosition(); float distX = m_destination.x - renderablePos.x; float distY = m_destination.y - renderablePos.y; float magnitude = std::sqrt(std::pow(distX, 2) + std::pow(distY, 2)); float uVecX = distX / magnitude; float uVecY = distY / magnitude; m_direction = sf::Vector2f(uVecX, uVecY); std::cout << "MOVE STARTED: \n"; std::cout << m_renderable->getEntityID() << ' ' << m_renderable->getSprite().getPosition().x << ' ' << m_renderable->getSprite().getPosition().y << ' ' << m_destination.x << ' ' << m_destination.y << "\n\n"; // accelerate to max speed at 50 % of distance traveled m_distanceEstimate = remainingDistance(); float time = 2*(m_distanceEstimate / m_speed); m_acceleration = (m_speed / (time / 2)); }
/* Called each ProcessManager update. */ bool dtn::ProcessMoveRenderable::update(float dt) { // deal with easing float remDist = remainingDistance(); if (remDist < 0.45*m_distanceEstimate) { m_curSpeed -= m_acceleration*dt; if (m_curSpeed < m_minimumSpeed) m_curSpeed = m_minimumSpeed; } else if (remDist > 0.55*m_distanceEstimate) { if (m_curSpeed < m_speed) m_curSpeed += m_acceleration*dt; if (m_curSpeed > m_speed) m_curSpeed = m_speed; } sf::Vector2f newPosition = m_renderable->getSprite().getPosition(); // if renderable outside of window (strange floating point bug) // snap to position if (newPosition.x < 0 || newPosition.x > dtn::Utilities::WINDOW_WIDTH) { std::cout << "OUT OF RANGE MOVEMENT X" << '\n'; newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } else if (newPosition.y < 0 || newPosition.y > dtn::Utilities::WINDOW_HEIGHT) { std::cout << "OUT OF RANGE MOVEMENT Y" << '\n'; newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } // if delta time is huge, snap to position (to avoid tunneling) else if (dt >= 0.2) { std::cout << "DELTA TIME TOO GREAT IN MOVE RENDERABLE: \n"; std::cout << m_renderable->getEntityID() << '\n'; std::cout << dt << "\n\n"; newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } // if moving right and higher than x pos snap to pos else if (m_direction.x > 0 && newPosition.x > m_destination.x) { std::cout << "MOVED PAST IN POSITIVE X DIRECTION IN MOVE RENDERABLE: " << '\n'; newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } // if moving left and lower than x pos snap to pos else if (m_direction.x < 0 && newPosition.x < m_destination.x) { std::cout << "MOVED PAST IN NEGATIVE X DIRECTION IN MOVE RENDERABLE: " << '\n'; newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } // if moving down and higher than y pos snap to pos else if (m_direction.y > 0 && newPosition.y > m_destination.y) { std::cout << "MOVED PAST IN POSITIVE Y DIRECTION IN MOVE RENDERABLE: " << '\n'; newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } // if moving up and lower than y pos snap to pos else if (m_direction.y < 0 && newPosition.y < m_destination.y) { std::cout << "MOVED PAST IN NEGATIVE Y DIRECTION IN MOVE RENDERABLE: " << '\n'; newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } // if within tolerance snap to position else if (std::abs(newPosition.x - m_destination.x) <= 3.f && std::abs(newPosition.y - m_destination.y) <= 3.f) { newPosition.x = static_cast<float>(m_destination.x); newPosition.y = static_cast<float>(m_destination.y); m_dead = true; } // else move closer to position else { newPosition.x += m_curSpeed * m_direction.x*dt; newPosition.y += m_curSpeed * m_direction.y*dt; } m_renderable->getSprite().setPosition(newPosition); return m_dead; }
float dtn::ProcessMoveRenderable::remainingTime() { float dist = remainingDistance(); return dist / m_speed; }