Exemple #1
0
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;
}