Exemplo n.º 1
0
void Transport::MoveToNextWaypoint()
{
    // Clear events flagging
    _triggeredArrivalEvent = false;
    _triggeredDepartureEvent = false;

    // Set frames
    _currentFrame = _nextFrame++;
    if (_nextFrame == GetKeyFrames().end())
        _nextFrame = GetKeyFrames().begin();
}
Exemplo n.º 2
0
void CIFPAnimations::DeleteAnimations(void)
{
    CAnimManager* pAnimManager = g_pGame->GetAnimManager();
    for (auto& Animation : vecAnimations)
    {
        for (unsigned short SequenceIndex = 0; SequenceIndex < Animation.pHierarchy->GetNumSequences(); SequenceIndex++)
        {
            pAnimManager->RemoveFromUncompressedCache(Animation.pHierarchy->GetInterface());
            auto  pAnimationSequence = pAnimManager->GetCustomAnimBlendSequence(Animation.pHierarchy->GetSequence(SequenceIndex));
            void* pKeyFrames = pAnimationSequence->GetKeyFrames();
            if (!pAnimationSequence->IsBigChunkForAllSequences())
            {
                pAnimManager->FreeKeyFramesMemory(pKeyFrames);
            }
            else
            {
                if (SequenceIndex == 0)
                {
                    // All frames of all sequences are allocated on one memory block, so free that one
                    // and break the loop
                    pAnimManager->FreeKeyFramesMemory(pKeyFrames);
                    break;
                }
            }
        }
        delete Animation.pSequencesMemory;
        pAnimManager->DeleteCustomAnimHierarchyInterface(Animation.pHierarchy->GetInterface());
    }
}
Exemplo n.º 3
0
void Transport::DelayedUpdate(uint32 /*diff*/)
{
    if (GetKeyFrames().size() <= 1)
        return;

    DelayedTeleportTransport();
}
Exemplo n.º 4
0
bool ViewerIBA::OnMouseDraging(const CVD::ImageRef &from, const CVD::ImageRef &to,
                                  const int button) {
  if ((m_keyDrawViewType == DRAW_VIEW_PROFILE || m_keyDrawTlnType != DRAW_TLN_NONE) &&
      DragActiveFrame(from, to)) {
    return true;
  } else if (m_keyDrawViewType == DRAW_VIEW_2D) {
    if (m_iFrmActive >= GetKeyFrames() && m_iLFActive == m_iLF && m_iFtrActive.Valid() &&
        SearchActiveFeature(to)) {
      return true;
    } else {
      return false;
    }
  } else if (m_keyDrawViewType == DRAW_VIEW_3D) {
    if (button == VW_MOUSE_BUTTON_LEFT) {
      Point3D whereMouseDown3D;
      UnProjectWindowPoint(to, whereMouseDown3D);
      m_arcball.ComputeRotation(whereMouseDown3D);
    } else if (button == VW_MOUSE_BUTTON_RIGHT) {
      Point3D whereMouseDown3D;
      UnProjectWindowPoint(to, whereMouseDown3D, m_arcball.GetCenterZ());
      const Rotation3D &R = m_arcball.GetRotation();
      m_translation.xyzr() = R.r_00_01_02_x() * (whereMouseDown3D.x() - m_whereMouseDown3DStart.x()) +
                             R.r_10_11_12_x() * (whereMouseDown3D.y() - m_whereMouseDown3DStart.y()) +
                             m_translationStart.xyzr();
    }
    Update3DViewPoint();
    return true;
  }
  return false;
}
Exemplo n.º 5
0
void ViewerIBA::OnMouseDown(const CVD::ImageRef &where, const int button) {
  if (m_keyDrawViewType == DRAW_VIEW_2D) {
    if (m_iFrmActive >= GetKeyFrames() && m_iLFActive == m_iLF && m_iFtrActive.Valid()) {
      SearchActiveFeatureReset();
      m_dragingActiveFtr = true;
      m_ixSearchStart = m_iFtrActive.m_ix;
    }
  } else if (m_keyDrawViewType == DRAW_VIEW_3D) {
    if (button == VW_MOUSE_BUTTON_LEFT) {
      UnProjectWindowPoint(where, m_whereMouseDown3DStart);
      m_arcball.StartRotation(m_whereMouseDown3DStart);
    } else if (button == VW_MOUSE_BUTTON_RIGHT) {
      m_translationStart = m_translation;
      UnProjectWindowPoint(where, m_whereMouseDown3DStart, m_arcball.GetCenterZ());
    }
  }
}
Exemplo n.º 6
0
void Transport::Update(uint32 diff)
{
    uint32 const positionUpdateDelay = 200;

    if (AI())
        AI()->UpdateAI(diff);
    else if (!AIM_Initialize())
        TC_LOG_ERROR("entities.transport", "Could not initialize GameObjectAI for Transport");

    if (GetKeyFrames().size() <= 1)
        return;

    m_goValue.Transport.PathProgress += diff;

    uint32 timer = m_goValue.Transport.PathProgress % GetPeriod();

    // Set current waypoint
    // Desired outcome: _currentFrame->DepartureTime < timer < _nextFrame->ArriveTime
    // ... arrive | ... delay ... | departure
    //      event /         event /
    for (;;)
    {
        if (timer >= _currentFrame->ArriveTime)
        {
            if (!_triggeredArrivalEvent)
            {
                DoEventIfAny(*_currentFrame, false);
                _triggeredArrivalEvent = true;
            }

            if (timer < _currentFrame->DepartureTime)
            {
                SetMoving(false);
                if (_pendingStop)
                    SetGoState(GO_STATE_READY);
                break;  // its a stop frame and we are waiting
            }
        }

        if (_pendingStop && timer >= _currentFrame->DepartureTime && GetGoState() == GO_STATE_READY)
        {
            m_goValue.Transport.PathProgress = (m_goValue.Transport.PathProgress / GetPeriod());
            m_goValue.Transport.PathProgress *= GetPeriod();
            m_goValue.Transport.PathProgress += _currentFrame->ArriveTime;
            break;
        }

        if (timer >= _currentFrame->DepartureTime && !_triggeredDepartureEvent)
        {
            DoEventIfAny(*_currentFrame, true); // departure event
            _triggeredDepartureEvent = true;
        }

        if (timer >= _currentFrame->DepartureTime && timer < _currentFrame->NextArriveTime)
            break;  // found current waypoint

        MoveToNextWaypoint();

        // not waiting anymore
        SetMoving(true);

        // Enable movement
        if (GetGOInfo()->moTransport.canBeStopped)
            SetGoState(GO_STATE_ACTIVE);

        sScriptMgr->OnRelocate(this, _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        TC_LOG_DEBUG("entities.transport", "Transport %u (%s) moved to node %u %u %f %f %f", GetEntry(), GetName().c_str(), _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        // Departure event
        if (_currentFrame->IsTeleportFrame())
            if (TeleportTransport(_nextFrame->Node->mapid, _nextFrame->Node->x, _nextFrame->Node->y, _nextFrame->Node->z))
                return; // Update more in new map thread
    }

	// Add model to map after we are fully done with moving maps
    if (_delayedAddModel)
    {
        _delayedAddModel = false;
        if (m_model)
            GetMap()->InsertGameObjectModel(*m_model);
    }

    // Set position
    _positionChangeTimer.Update(diff);
    if (_positionChangeTimer.Passed())
    {
        _positionChangeTimer.Reset(positionUpdateDelay);
        if (IsMoving())
        {
            float t = CalculateSegmentPos(float(timer) * 0.001f);
            G3D::Vector3 pos, dir;
            _currentFrame->Spline->evaluate_percent(_currentFrame->Index, t, pos);
            _currentFrame->Spline->evaluate_derivative(_currentFrame->Index, t, dir);
            UpdatePosition(pos.x, pos.y, pos.z, atan2(dir.x, dir.y));
        }
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
Exemplo n.º 7
0
void Transport::Update(uint32 diff)
{
    uint32 const positionUpdateDelay = 200;

    if (AI())
        AI()->UpdateAI(diff);
    else if (!AIM_Initialize())
        TC_LOG_ERROR("entities.transport", "Could not initialize GameObjectAI for Transport");

    if (GetKeyFrames().size() <= 1)
        return;

    if (IsMoving() || !_pendingStop)
        m_goValue.Transport.PathProgress += diff;

    uint32 timer = m_goValue.Transport.PathProgress % GetTransportPeriod();
    bool justStopped = false;

    // Set current waypoint
    // Desired outcome: _currentFrame->DepartureTime < timer < _nextFrame->ArriveTime
    // ... arrive | ... delay ... | departure
    //      event /         event /
    for (;;)
    {
        if (timer >= _currentFrame->ArriveTime)
        {
            if (!_triggeredArrivalEvent)
            {
                DoEventIfAny(*_currentFrame, false);
                _triggeredArrivalEvent = true;
            }

            if (timer < _currentFrame->DepartureTime)
            {
                SetMoving(false);
                justStopped = true;
                if (_pendingStop && GetGoState() != GO_STATE_READY)
                {
                    SetGoState(GO_STATE_READY);
                    m_goValue.Transport.PathProgress = (m_goValue.Transport.PathProgress / GetTransportPeriod());
                    m_goValue.Transport.PathProgress *= GetTransportPeriod();
                    m_goValue.Transport.PathProgress += _currentFrame->ArriveTime;
                }
                break;  // its a stop frame and we are waiting
            }
        }

        if (timer >= _currentFrame->DepartureTime && !_triggeredDepartureEvent)
        {
            DoEventIfAny(*_currentFrame, true); // departure event
            _triggeredDepartureEvent = true;
        }

        // not waiting anymore
        SetMoving(true);

        // Enable movement
        if (GetGOInfo()->moTransport.allowstopping)
            SetGoState(GO_STATE_ACTIVE);

        if (timer >= _currentFrame->DepartureTime && timer < _currentFrame->NextArriveTime)
            break;  // found current waypoint

        MoveToNextWaypoint();

        sScriptMgr->OnRelocate(this, _currentFrame->Node->NodeIndex, _currentFrame->Node->ContinentID, _currentFrame->Node->Loc.X, _currentFrame->Node->Loc.Y, _currentFrame->Node->Loc.Z);

        TC_LOG_DEBUG("entities.transport", "Transport %u (%s) moved to node %u %u %f %f %f", GetEntry(), GetName().c_str(), _currentFrame->Node->NodeIndex, _currentFrame->Node->ContinentID, _currentFrame->Node->Loc.X, _currentFrame->Node->Loc.Y, _currentFrame->Node->Loc.Z);

        // Departure event
        if (_currentFrame->IsTeleportFrame())
            if (TeleportTransport(_nextFrame->Node->ContinentID, _nextFrame->Node->Loc.X, _nextFrame->Node->Loc.Y, _nextFrame->Node->Loc.Z, _nextFrame->InitialOrientation))
                return; // Update more in new map thread
    }

    // Add model to map after we are fully done with moving maps
    if (_delayedAddModel)
    {
        _delayedAddModel = false;
        if (m_model)
            GetMap()->InsertGameObjectModel(*m_model);
    }

    // Set position
    _positionChangeTimer.Update(diff);
    if (_positionChangeTimer.Passed())
    {
        _positionChangeTimer.Reset(positionUpdateDelay);
        if (IsMoving())
        {
            float t = !justStopped ? CalculateSegmentPos(float(timer) * 0.001f) : 1.0f;
            G3D::Vector3 pos, dir;
            _currentFrame->Spline->evaluate_percent(_currentFrame->Index, t, pos);
            _currentFrame->Spline->evaluate_derivative(_currentFrame->Index, t, dir);
            UpdatePosition(pos.x, pos.y, pos.z, std::atan2(dir.y, dir.x) + float(M_PI));
        }
        else if (justStopped)
            UpdatePosition(_currentFrame->Node->Loc.X, _currentFrame->Node->Loc.Y, _currentFrame->Node->Loc.Z, _currentFrame->InitialOrientation);
        else
        {
            /* There are four possible scenarios that trigger loading/unloading passengers:
              1. transport moves from inactive to active grid
              2. the grid that transport is currently in becomes active
              3. transport moves from active to inactive grid
              4. the grid that transport is currently in unloads
            */
            bool gridActive = GetMap()->IsGridLoaded(GetPositionX(), GetPositionY());

            if (_staticPassengers.empty() && gridActive) // 2.
                LoadStaticPassengers();
            else if (!_staticPassengers.empty() && !gridActive)
                // 4. - if transports stopped on grid edge, some passengers can remain in active grids
                //      unload all static passengers otherwise passengers won't load correctly when the grid that transport is currently in becomes active
                UnloadStaticPassengers();
        }
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
Exemplo n.º 8
0
void Transport::Update(uint32 diff)
{
    uint32 const positionUpdateDelay = 200;

    if (AI())
        AI()->UpdateAI(diff);
    else if (!AIM_Initialize())
        TC_LOG_ERROR("entities.transport", "Could not initialize GameObjectAI for Transport");

    if (GetKeyFrames().size() <= 1)
        return;

    if (IsMoving() || !_pendingStop)
        m_goValue.Transport.PathProgress += diff;

    uint32 timer = m_goValue.Transport.PathProgress % GetPeriod();

    // Set current waypoint
    // Desired outcome: _currentFrame->DepartureTime < timer < _nextFrame->ArriveTime
    // ... arrive | ... delay ... | departure
    //      event /         event /
    for (;;)
    {
        if (timer >= _currentFrame->ArriveTime)
        {
            if (!_triggeredArrivalEvent)
            {
                DoEventIfAny(*_currentFrame, false);
                _triggeredArrivalEvent = true;
            }

            if (timer < _currentFrame->DepartureTime)
            {
                SetMoving(false);
                if (_pendingStop && GetGoState() != GO_STATE_READY)
                {
                    SetGoState(GO_STATE_READY);
                    m_goValue.Transport.PathProgress = (m_goValue.Transport.PathProgress / GetPeriod());
                    m_goValue.Transport.PathProgress *= GetPeriod();
                    m_goValue.Transport.PathProgress += _currentFrame->ArriveTime;
                }
                break;  // its a stop frame and we are waiting
            }
        }

        if (timer >= _currentFrame->DepartureTime && !_triggeredDepartureEvent)
        {
            DoEventIfAny(*_currentFrame, true); // departure event
            _triggeredDepartureEvent = true;
        }

        // not waiting anymore
        SetMoving(true);

        // Enable movement
        if (GetGOInfo()->moTransport.canBeStopped)
            SetGoState(GO_STATE_ACTIVE);

        if (timer >= _currentFrame->DepartureTime && timer < _currentFrame->NextArriveTime)
            break;  // found current waypoint

        MoveToNextWaypoint();

        sScriptMgr->OnRelocate(this, _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        TC_LOG_DEBUG("entities.transport", "Transport %u (%s) moved to node %u %u %f %f %f", GetEntry(), GetName().c_str(), _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        // Departure event
        if (_currentFrame->IsTeleportFrame())
            if (TeleportTransport(_nextFrame->Node->mapid, _nextFrame->Node->x, _nextFrame->Node->y, _nextFrame->Node->z, _nextFrame->InitialOrientation))
                return; // Update more in new map thread
    }

    // Set position
    _positionChangeTimer.Update(diff);
    if (_positionChangeTimer.Passed())
    {
        _positionChangeTimer.Reset(positionUpdateDelay);
        if (IsMoving())
        {
            float t = CalculateSegmentPos(float(timer) * 0.001f);
            G3D::Vector3 pos, dir;
            _currentFrame->Spline->evaluate_percent(_currentFrame->Index, t, pos);
            _currentFrame->Spline->evaluate_derivative(_currentFrame->Index, t, dir);
            UpdatePosition(pos.x, pos.y, pos.z, atan2(dir.y, dir.x) + M_PI);
        }
        else
        {
            /* There are four possible scenarios that trigger loading/unloading passengers:
              1. transport moves from inactive to active grid
              2. the grid that transport is currently in becomes active
              3. transport moves from active to inactive grid
              4. the grid that transport is currently in unloads
            */
            if (_staticPassengers.empty() && GetMap()->IsGridLoaded(GetPositionX(), GetPositionY())) // 2.
                LoadStaticPassengers();
        }
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
Exemplo n.º 9
0
void VideoContext::SaveKeyframes(wxString filename) {
	agi::keyframe::Save(STD_STR(filename), GetKeyFrames());
	config::mru->Add("Keyframes", STD_STR(filename));
}
Exemplo n.º 10
0
void Transport::Update(uint32 diff)
{
    if (!AI())
    {
        if (!AIM_Initialize())
            sLog->outError("Could not initialize GameObjectAI for Transport");
    }
    else
        AI()->UpdateAI(diff);

    if (_isStopped)
        return;

    if (GetKeyFrames().size() <= 1)
        return;

    //_moveTimer = getMSTime() % _transportInfo->pathTime;
    _moveTimer += diff;
    _moveTimer %= _transportInfo->pathTime;
    // need restart path from beginning
    /* if (m_timer < m_curr->pathTime)
    {
        m_curr = keyFrames.begin();
        m_next = m_curr + 1;
    } */
    while (_moveTimer > _nextFrame->pathTime || _moveTimer < _currentFrame->departureTime)
    {
        // arrived at next stop point
        if (_transportInfo->pathTime > _nextFrame->pathTime && _moveTimer < _nextFrame->departureTime)
        {
            if (IsMoving())
            {
                SetMoving(false);
                DoEventIfAny(*_currentFrame, false);
            }
            break;
        }

        MoveToNextWayPoint();

        SetMoving(true);

        DoEventIfAny(*_currentFrame, true);

        // first check help in case client-server transport coordinates de-synchronization
        if (_currentFrame->IsTeleportFrame())
            TeleportTransport(_nextFrame->node->mapid, _nextFrame->node->x, _nextFrame->node->y, _nextFrame->node->z);

        ASSERT(_nextFrame != GetKeyFrames().begin());

        sScriptMgr->OnRelocate(this, _currentFrame->node->index, _currentFrame->node->mapid, _currentFrame->node->x, _currentFrame->node->y, _currentFrame->node->z);

        sLog->outDebug(LOG_FILTER_TRANSPORTS, "%s moved to %f %f %f %d", GetName(), GetPositionX(), GetPositionY(), GetPositionZ(), _currentFrame->node->mapid);
    }

    if (IsMoving())
    {
        if (_moveTimer < _currentFrame->departureTime || _moveTimer > _nextFrame->pathTime)
            sLog->outError("strange times, c.dep:%u, n.pt:%u (%s, %u)", _currentFrame->departureTime, _nextFrame->pathTime, GetName(), m_goInfo->moTransport.mapID);
        float t = CalculateSegmentPos((float)_moveTimer/(float)IN_MILLISECONDS);
        //if (t < -0.01f || t > 1.01f)
        //    sLog.outError("strange t=%f (%s, %u)", t, GetName(), m_goInfo->moTransport.mapID);
        //G3D::Vector3 pos;
        //m_spline->Evaluate(m_curr->node->index - 1, t, pos);
        //G3D::Vector3 dir;
        //m_spline->EvaluateDerivative(m_curr->node->index - 1, t, dir);
        //dir.z = 0.0f;
        //dir = -dir.direction();
        //Relocate(pos.x, pos.y, pos.z);
        float x = _currentFrame->node->x * (1.0f - t) + _nextFrame->node->x * t;
        float y = _currentFrame->node->y * (1.0f - t) + _nextFrame->node->y * t;
        float z = _currentFrame->node->z * (1.0f - t) + _nextFrame->node->z * t;
        float o = GetAngle(_nextFrame->node->x, _nextFrame->node->y) + float(M_PI);
        Relocate(x, y, z, o);
        UpdatePassengerPositions();
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
Exemplo n.º 11
0
void Transport::MoveToNextWayPoint()
{
    _currentFrame = _nextFrame++;
    if (_nextFrame == GetKeyFrames().end())
        _nextFrame = GetKeyFrames().begin();
}
Exemplo n.º 12
0
bool ViewerIBA::OnKeyDown(int key) {
#ifdef __linux__
  if (key == VW_KEY_CTRL_KEY_VALUE) {
    m_ctrlDown = true;
    return true;
  }
  if (m_ctrlDown) {
    key = key - 'a' + 1;
  }
#endif
  if (Viewer::OnKeyDown(key)) {
    return true;
  }
//#ifdef CFG_DEBUG
#if 0
//#if 1
  UT::Print("%d\n", key);
#endif
//#ifdef CFG_DEBUG
#if 0
  if (key == '+' || key == '-') {
    Camera &C = m_LBA->m_CsLF[m_iLFActive];
    if (key == '+') {
      C.m_p.y() += 0.1f;
    } else {
      C.m_p.y() -= 0.1f;
    }
    C.m_T.SetPosition(C.m_p);
    return true;
  }
#endif
#ifdef CFG_STEREO
  if (key == '1' || key == '2') {
     ActivateCamera(key == '2');
    return true;
  }
#endif
  const int nKFs = GetKeyFrames();
  const bool activeKF = m_iFrmActive < nKFs;
  switch (key) {
  case VW_KEY_XD_DRAW_VIEW_TYPE:
    if (m_keyDrawViewType == DRAW_VIEW_PROFILE) {
      m_keyDrawViewType = m_keyDrawViewTypeBkp;
    } else {
      m_keyDrawViewType.Press();
    }
    return true;
  case VW_KEY_XD_PAUSE:   m_keyPause.Press();   return true;
  case VW_KEY_XD_STEP:    m_keyStep.Press();    return true;
  case VW_KEY_XD_SAVE:
    if (m_fileNameSave == "") {
      m_fileNameSave = UT::Input<std::string>("save_file");
    }
    m_iFrmSave = GetLocalFrame(m_iLF)->m_T.m_iFrm;
    m_keyStep.Press();
    //m_handler.Quit();
    return true;
  case VW_KEY_XD_SCREEN:
    if (m_fileNameScreen == "") {
      m_fileNameScreen = UT::Input<std::string>("screen_file");
    }
    if (m_fileNameScreen != "" && UT::FileNameExtractSuffix<int>(m_fileNameScreen) == -1) {
      bool resize = m_pWnd->size().x != m_K.m_K.w() || m_pWnd->size().y != m_K.m_K.h();
      if (resize) {
        const char inp = UT::Input<char>("resize (y/n)");
        if (inp != 'y' && inp != 'Y') {
          resize = false;
        }
      }
      SaveScreen(UT::FileNameAppendSuffix(m_fileNameScreen), resize);
    }
    return true;
  //case VW_KEY_XD_ACTIVATE_NEXT_FRAME:   ActivateFrame(m_iFrmActive + 1);  return true;
  //case VW_KEY_XD_ACTIVATE_LAST_FRAME:   ActivateFrame(m_iFrmActive - 1);  return true;
  case VW_KEY_XD_ACTIVATE_NEXT_FRAME:
  case VW_KEY_XD_ACTIVATE_LAST_FRAME: {
    const bool next = key == VW_KEY_XD_ACTIVATE_NEXT_FRAME;
    int iFrm = next ? m_iFrmActive + 1 : m_iFrmActive - 1;
    if (m_iFtrActive.Valid()) {
      const int nLFs = GetLocalFrames(), nFrms = nKFs + nLFs;
      const int iKF = m_iFtrActive.m_ix.m_iKF, ix = m_iFtrActive.m_ix.m_ix;
      while (iFrm >= 0 && iFrm < nFrms && iFrm != iKF) {
        const FRM::Frame &F = *(iFrm < nKFs ? GetKeyFrame(iFrm) :
                                              GetLocalFrame((iFrm - nKFs + m_iLF + 1) % nLFs));
        const int iz = F.SearchFeatureMeasurement(iKF, ix);
        if (iz != -1
#ifdef CFG_STEREO
        && (!m_rightActive && F.m_zs[iz].m_z.Valid() || m_rightActive && F.m_zs[iz].m_zr.Valid())
#endif
        ) {
          break;
        }
        iFrm = next ? iFrm + 1 : iFrm - 1;
      }
    }
    ActivateFrame(iFrm);
    return true;
  }
  case VW_KEY_XD_ACTIVATE_KEY_FRAME:
    if (m_iFtrActive.m_ix.Valid()) {
      ActivateFrame(m_iFtrActive.m_ix.m_iKF);
    } else {
      ActivateFrame(m_iKFActive);
    }
    return true;
  case VW_KEY_XD_ACTIVATE_LOCAL_FRAME:
    if (m_iFtrActive.m_iz.Valid() && m_iFtrActive.m_iz.m_iLF != -1) {
      ActivateLocalFrame(m_iFtrActive.m_iz.m_iLF);
    } else if (activeKF) {
      ActivateLocalFrame(m_iLFActive);
    } else {
      ActivateLocalFrame(m_iLFActiveLast);
    }
    return true;
  case VW_KEY_XD_ACTIVATE_CURRENT_FRAME:
    ActivateLocalFrame(m_iLF);
    return true;
  case VW_KEY_XD_DRAW_CAMERA_TYPE_NEXT:
  case VW_KEY_XD_DRAW_CAMERA_TYPE_LAST:
    if (activeKF) {
      m_keyDrawCamTypeKF.Press(key == VW_KEY_XD_DRAW_CAMERA_TYPE_NEXT, false);
      switch (m_keyDrawCamTypeKF) {
      case DRAW_CAM_KF_LBA:
        m_keyDrawCamTypeLF = DRAW_CAM_LF_LBA;
        m_keyDrawDepType = DRAW_DEP_LBA;
        break;
      case DRAW_CAM_KF_GBA:
        m_keyDrawDepType = DRAW_DEP_GBA;
        break;
#ifdef CFG_GROUND_TRUTH
      case DRAW_CAM_KF_GT:
        m_keyDrawCamTypeLF = DRAW_CAM_LF_GT;
        if (!m_solver->m_internal->m_DsGT.empty()) {
          m_keyDrawDepType = DRAW_DEP_GT;
        }
        break;
#endif
      }
    } else {
      m_keyDrawCamTypeLF.Press(key == VW_KEY_XD_DRAW_CAMERA_TYPE_NEXT, false);
      switch (m_keyDrawCamTypeLF) {
      case DRAW_CAM_LF_LBA:
        m_keyDrawCamTypeKF = DRAW_CAM_KF_LBA;
        m_keyDrawDepType = DRAW_DEP_LBA;
        break;
#ifdef CFG_GROUND_TRUTH
      case DRAW_CAM_LF_GT:
        m_keyDrawCamTypeKF = DRAW_CAM_KF_GT;
        if (!m_solver->m_internal->m_DsGT.empty()) {
          m_keyDrawDepType = DRAW_DEP_GT;
        }
        break;
#endif
      }
    }
    ActivateFrame(m_iFrmActive);
    return true;
#ifdef CFG_GROUND_TRUTH
  case VW_KEY_XD_DRAW_CAMERA_TYPE_GROUND_TRUTH:
    if (activeKF && m_keyDrawCamTypeKF == DRAW_CAM_KF_GT) {
      m_keyDrawCamTypeKF.Set(DRAW_CAM_KF_GBA);
      m_keyDrawDepType = DRAW_DEP_GBA;
    } else if (!activeKF && m_keyDrawCamTypeLF == DRAW_CAM_LF_GT) {
      m_keyDrawCamTypeKF.Set(DRAW_CAM_KF_LBA);
      m_keyDrawCamTypeLF = DRAW_CAM_LF_LBA;
      m_keyDrawDepType = DRAW_DEP_LBA;
    } else if (activeKF && GetCameraKF(m_iKFActive, DRAW_CAM_KF_GT).Valid() ||
              !activeKF && GetCameraLF(m_iLFActive, DRAW_CAM_LF_GT).Valid()) {
      m_keyDrawCamTypeKF.Set(DRAW_CAM_KF_GT);
      m_keyDrawCamTypeLF = DRAW_CAM_LF_GT;
      if (!m_solver->m_internal->m_DsGT.empty()) {
        m_keyDrawDepType = DRAW_DEP_GT;
      }
    }
    ActivateFrame(m_iFrmActive);
    return true;
#endif
  case VW_KEY_XD_DRAW_DEPTH_TYPE_NEXT:
  case VW_KEY_XD_DRAW_DEPTH_TYPE_LAST:
    m_keyDrawDepType.Press(key == VW_KEY_XD_DRAW_DEPTH_TYPE_NEXT, false);
    return true;
  case VW_KEY_XD_DRAW_STRING:     m_keyDrawString.Press();  return true;
  case VW_KEY_XD_DRAW_TIME_LINE:  m_keyDrawTlnType.Press(); return true;
  case VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_INCREASE_1:
  case VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_DECREASE_1:
  case VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_INCREASE_2:
  case VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_DECREASE_2:
    if (m_keyDrawTlnType == DRAW_TLN_FEATURE_MATCH) {
      m_keyDrawTlnMaxFtrMatches.Press(key == VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_DECREASE_1 ||
                                      key == VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_DECREASE_2);
    } else if (key == VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_INCREASE_1 ||
               key == VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_DECREASE_1) {
      m_keyDrawTlnPriorVarPos.Press(key == VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_INCREASE_1);
    } else {
      m_keyDrawTlnPriorVarRot.Press(key == VW_KEY_XD_DRAW_TIME_LINE_BRIGHTNESS_INCREASE_2);
    }
    return true;
  }
  if (m_keyDrawViewType == DRAW_VIEW_2D || m_keyDrawViewType == DRAW_VIEW_3D) {
    switch (key) {
    case VW_KEY_XD_DRAW_AXIS:
      m_keyDrawAxis.Press();
      return true;
    case VW_KEY_XD_DRAW_AXIS_LENGTH_INCREASE:
    case VW_KEY_XD_DRAW_AXIS_LENGTH_DECREASE:
      if (m_keyDrawAxis != DRAW_AXIS_NONE) {
        m_keyDrawAxisLen.Press(key == VW_KEY_XD_DRAW_AXIS_LENGTH_INCREASE);
        m_frustrum.SetAxisLength(m_keyDrawAxisLen);
        m_frustrumActive.SetAxisLength(m_keyDrawAxisLen);
        return true;
      }
      break;
    case VW_KEY_XD_DRAW_DEPTH_PLANE:
      m_keyDrawDepPlane.Press();
      return true;
    case VW_KEY_XD_DRAW_DEPTH_VARIANCE_INCREASE:
    case VW_KEY_XD_DRAW_DEPTH_VARIANCE_DECREASE:
      m_keyDrawDepVar.Press(key == VW_KEY_XD_DRAW_DEPTH_VARIANCE_INCREASE);
      return true;
    case VW_KEY_XD_DRAW_COVARIANCE_PROBABILITY_INCREASE:
    case VW_KEY_XD_DRAW_COVARIANCE_PROBABILITY_DECREASE:
      if (m_keyDrawTlnType != DRAW_TLN_NONE ||
         (m_keyDrawViewType == DRAW_VIEW_2D && (m_keyDrawErrType2D == DRAW_ERR_ALL ||
                                                m_keyDrawErrType2D == DRAW_ERR_COVARIANCE)) ||
         (m_keyDrawViewType == DRAW_VIEW_3D && (m_keyDrawErrType3D == DRAW_ERR_ALL ||
                                                m_keyDrawErrType3D == DRAW_ERR_COVARIANCE))) {
        m_keyDrawCovProb.Press(key == VW_KEY_XD_DRAW_COVARIANCE_PROBABILITY_INCREASE);
        return true;
      }
      break;
    case VW_KEY_XD_DRAW_COVARIANCE_SCALE_INCREASE:
    case VW_KEY_XD_DRAW_COVARIANCE_SCALE_DECREASE:
      if (m_keyDrawTlnType != DRAW_TLN_NONE ||
         (m_keyDrawViewType == DRAW_VIEW_2D && (m_keyDrawErrType2D == DRAW_ERR_ALL ||
                                                m_keyDrawErrType2D == DRAW_ERR_COVARIANCE)
       || m_keyDrawViewType == DRAW_VIEW_3D && (m_keyDrawErrType3D == DRAW_ERR_ALL ||
                                                m_keyDrawErrType3D == DRAW_ERR_COVARIANCE))) {
        m_keyDrawCovScale.Press(key == VW_KEY_XD_DRAW_COVARIANCE_SCALE_INCREASE);
        return true;
      }
      break;
    case VW_KEY_XD_INPUT_ACTIVE_FEATURE: {
      const int iFrm = UT::Input<int>(" Frame");
      const std::vector<KeyFrame>::const_iterator iKF = std::lower_bound(m_GBA->m_KFs.begin(),
                                                                         m_GBA->m_KFs.end(), iFrm);
      if (iKF != m_GBA->m_KFs.end() && *iKF == iFrm) {
        const int ix = UT::Input<int>("Source");
        if (ix < 0 || ix >= static_cast<int>(iKF->m_xs.size())) {
          return false;
        }
        const int _iKF = static_cast<int>(iKF - m_GBA->m_KFs.begin());
        const FRM::Frame &F = *(activeKF ? GetKeyFrame(m_iKFActive) : GetLocalFrame(m_iLFActive));
        const int iz = F.SearchFeatureMeasurement(_iKF, ix);
        ActivateFeature(FeatureIndex::Source(_iKF, ix), iz);
      }
      return false;
    }
    case VW_KEY_PROFILE_ACTIVATE:
      if (m_keyDrawViewType != DRAW_VIEW_PROFILE) {
        m_keyDrawViewTypeBkp = m_keyDrawViewType;
        m_keyDrawViewType = DRAW_VIEW_PROFILE;
      }
      return true;
    }
  } else if (m_keyDrawViewType == DRAW_VIEW_PROFILE) {
    switch (key) {
    case VW_KEY_PROFILE_ACTIVATE:
      m_keyDrawViewType = m_keyDrawViewTypeBkp;
      return true;
    case VM_KEY_PROFILE_LEVEL_1_NEXT:
    case VM_KEY_PROFILE_LEVEL_1_LAST: {
      const int types[] = {DRAW_PRF_ACCELERATION, DRAW_PRF_IMU_DELTA_ROTATION_STATE,
                           DRAW_PRF_CAMERA_PRIOR_ROTATION_STATE, DRAW_PRF_REPROJECTION_ERROR,
                           DRAW_PRF_STATE_ROTATION_ABSOLUTE,
                           DRAW_PRF_TYPES};
      const int N = sizeof(types) / sizeof(int);
      DrawProfileTypeStep(types, N, key == VM_KEY_PROFILE_LEVEL_1_NEXT);
      return true; }
    case VM_KEY_PROFILE_LEVEL_2_NEXT:
    case VM_KEY_PROFILE_LEVEL_2_LAST: {
      const int types[] = {DRAW_PRF_ACCELERATION, DRAW_PRF_GYROSCOPE,
                           DRAW_PRF_IMU_DELTA_ROTATION_STATE,
                           DRAW_PRF_IMU_DELTA_POSITION_STATE,
                           DRAW_PRF_IMU_DELTA_VELOCITY_STATE,
                           DRAW_PRF_IMU_DELTA_BIAS_ACCELERATION_STATE,
                           DRAW_PRF_IMU_DELTA_BIAS_GYROSCOPE_STATE,
                           DRAW_PRF_CAMERA_PRIOR_ROTATION_STATE,
                           DRAW_PRF_CAMERA_PRIOR_POSITION_STATE,
                           DRAW_PRF_CAMERA_PRIOR_VELOCITY_STATE,
                           DRAW_PRF_CAMERA_PRIOR_BIAS_ACCELERATION_STATE,
                           DRAW_PRF_CAMERA_PRIOR_BIAS_GYROSCOPE_STATE,
                           DRAW_PRF_REPROJECTION_ERROR,
                           DRAW_PRF_STATE_ROTATION_ABSOLUTE,
                           DRAW_PRF_STATE_POSITION_ABSOLUTE,
                           DRAW_PRF_STATE_VELOCITY,
                           DRAW_PRF_STATE_BIAS_ACCELERATION,
                           DRAW_PRF_STATE_BIAS_GYROSCOPE,
                           DRAW_PRF_TYPES};
      const int N = sizeof(types) / sizeof(int);
      DrawProfileTypeStep(types, N, key == VM_KEY_PROFILE_LEVEL_2_NEXT);
      return true; }
    case VM_KEY_PROFILE_LEVEL_3_NEXT:
    case VM_KEY_PROFILE_LEVEL_3_LAST: {
      const int typeBkp = m_keyDrawPrfType;
      while (m_keyDrawPrfType.Press(key == VM_KEY_PROFILE_LEVEL_3_NEXT, false) &&
             !DrawProfileTypeValid()) {}
      if (!DrawProfileTypeValid()) {
        m_keyDrawPrfType = typeBkp;
      }
      return true; }
    }
  }
  if (m_keyDrawViewType == DRAW_VIEW_2D) {
    switch (key) {
    case VW_KEY_2D_DRAW_FEATURE_TYPE:     m_keyDrawFtrType.Press();   return true;
    case VW_KEY_2D_DRAW_PROJECTION_TYPE:  m_keyDrawPrjType.Press();   return true;
    case VW_KEY_2D_DRAW_ERROR_TYPE:       m_keyDrawErrType2D.Press(); return true;
    }
  } else if (m_keyDrawViewType == DRAW_VIEW_3D) {
    switch (key) {
    case VW_KEY_3D_DRAW_MOTION_TYPE:
      if (activeKF) {
        m_keyDrawMotTypeKF.Press();
      } else {
        m_keyDrawMotTypeLF.Press();
      }
      return true;
    case VW_KEY_3D_DRAW_STRUCTURE_TYPE:
      m_keyDrawStrType.Press();
      return true;
    case VW_KEY_3D_DRAW_DEPTH_COMPARE_TYPE:
      if (m_keyDrawErrType3D == DRAW_ERR_ALL || m_keyDrawErrType3D == DRAW_ERR_MEAN) {
        m_keyDrawDepTypeCMP.Press();
        //while(m_keyDrawDepTypeCMP == m_keyDrawDepType)
        //  m_keyDrawDepTypeCMP.Press();
      }
      return true;
    case VW_KEY_3D_DRAW_CAMERA_SIZE_INCREASE:
    case VW_KEY_3D_DRAW_CAMERA_SIZE_DECREASE:
      m_keyDrawCamSize.Press(key == VW_KEY_3D_DRAW_CAMERA_SIZE_INCREASE);
      m_frustrum.SetSize(m_keyDrawCamSize);
      m_frustrumActive.SetSize(m_keyDrawCamSize * VW_CAMERA_SIZE_ACTIVE_RATIO);
      return true;
    case VW_KEY_3D_DRAW_CAMERA_VELOCITY:      m_keyDrawCamVelocity.Press(); break;
    case VW_KEY_3D_DRAW_CAMERA_TEXTURE:       m_keyDrawCamTex.Press();      break;
#ifdef CFG_GROUND_TRUTH
    case VW_KEY_3D_DRAW_CAMERA_GROUND_TRUTH:  m_keyDrawCamGT.Press();       break;
#endif
    case VW_KEY_3D_DRAW_ERROR_TYPE:
      m_keyDrawErrType3D.Press();
      return true;
    case VW_KEY_3D_DRAW_BACKGROUND_COLOR:
      m_keyDrawBgClr.Press();
      Update3DBackgroundColor();
      return true;
    case VW_KEY_3D_RESET_VIEW_POINT_ACTIVE:
    case VW_KEY_3D_RESET_VIEW_POINT_VIRTUAL:
      Reset3DViewPoint(key == VW_KEY_3D_RESET_VIEW_POINT_ACTIVE);
      return true;
    }
  }
  return false;
}