void CameraTransitionController::Update(float dt) { if(!IsTransitioning()) { return; } ICameraTransitionStage* pCurrentStage = m_transitionStages.front(); pCurrentStage->Update(dt); if(pCurrentStage->StageIsComplete() && !m_appCameraController.IsTransitionInFlight()) { pCurrentStage->End(); Eegeo_DELETE pCurrentStage; m_transitionStages.pop(); if(m_transitionStages.size() > 0) { pCurrentStage = m_transitionStages.front(); pCurrentStage->Start(); } else { StopCurrentTransition(); } } else if(pCurrentStage->StageHasFailed()) { StopCurrentTransition(); } }
void CameraTransitioner::Update(float dt) { if(!IsTransitioning()) { return; } m_transitionTime += dt; double transitionParam = Eegeo::Math::SmoothStep(0.0, 1.0, m_transitionTime / m_transitionDuration); float interpolatedDistance = Eegeo::Math::Lerp(m_startInterestDistance, m_endInterestDistance, transitionParam); Eegeo::dv3 interpolatedInterestPosition = Eegeo::dv3::Lerp(m_startTransitionInterestPoint, m_endTransitionInterestPoint, transitionParam); if(interpolatedInterestPosition.LengthSq() < Eegeo::Space::EarthConstants::RadiusSquared) { interpolatedInterestPosition = interpolatedInterestPosition.Norm() * Eegeo::Space::EarthConstants::Radius; } float interpolatedHeading = ((1-transitionParam) * m_startTransitionHeading) + (transitionParam * m_endTransitionHeading); Eegeo::v3 interpolatedHeadingVector = ComputeHeadingVector(interpolatedInterestPosition, interpolatedHeading); Eegeo::Space::EcefTangentBasis newInterestBasis(interpolatedInterestPosition, interpolatedHeadingVector); m_cameraController.SetView(newInterestBasis, interpolatedDistance); if(transitionParam >= 1.f) { StopCurrentTransition(); } }
void CameraTransitionController::Update(float dt) { if(!IsTransitioning()) { return; } m_transitionTime += dt; float transitionParam = Eegeo::Math::SmoothStep(0.f, 1.f, m_transitionTime / m_transitionDuration); float interpolatedDistance = Eegeo::Math::Lerp(m_startInterestDistance, m_endInterestDistance, transitionParam); Eegeo::dv3 interpolatedInterestPosition = Eegeo::dv3::Lerp(m_startTransitionInterestPointEcef, m_endTransitionInterestPointEcef, transitionParam); float currentAssumedAltitude = 0; m_terrainHeightProvider.TryGetHeight(interpolatedInterestPosition, 0, currentAssumedAltitude); if(interpolatedInterestPosition.Length() < Eegeo::Space::EarthConstants::Radius + currentAssumedAltitude) { interpolatedInterestPosition = interpolatedInterestPosition.Norm() * (Eegeo::Space::EarthConstants::Radius + currentAssumedAltitude); } float interpolatedHeading = Eegeo::Math::Lerp<float>(m_startInterestHeading, m_endInterestHeading, transitionParam); Eegeo::v3 interpolatedHeadingVector = ComputeHeadingVector(interpolatedInterestPosition, interpolatedHeading); Eegeo::Space::EcefTangentBasis newInterestBasis(interpolatedInterestPosition, interpolatedHeadingVector); m_cameraController.SetView(newInterestBasis, interpolatedDistance); if(transitionParam >= 1.f) { StopCurrentTransition(); } }
void CameraTransitioner::StartTransitionTo(Eegeo::dv3 newInterestPoint, double distanceFromInterest, float newHeading, bool jumpIfFarAway) { if(IsTransitioning()) { StopCurrentTransition(); } if(jumpIfFarAway && ShouldJumpTo(newInterestPoint)) { Eegeo::Space::EcefTangentBasis newInterestBasis; Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(newInterestPoint, Eegeo::Math::Rad2Deg(newHeading), newInterestBasis); m_cameraController.SetView(newInterestBasis, distanceFromInterest); StopCurrentTransition(); return; } const Eegeo::Space::EcefTangentBasis& currentInterestBasis = m_cameraController.GetInterestBasis(); m_startTransitionInterestPoint = currentInterestBasis.GetPointEcef(); m_startInterestDistance = m_cameraController.GetDistanceToInterest(); float bearingRadians = Eegeo::Camera::CameraHelpers::GetAbsoluteBearingRadians(currentInterestBasis.GetPointEcef(), currentInterestBasis.GetForward()); m_startTransitionHeading = bearingRadians; m_endTransitionHeading = newHeading; m_endTransitionInterestPoint = newInterestPoint; m_endInterestDistance = distanceFromInterest; m_transitionTime = 0.f; const float CAMERA_TRANSITION_SPEED_IN_METERS_PER_SECOND = 100.0f; const float MIN_TRANSITION_TIME = 2.0f; const float MAX_TRANSITION_TIME = 10.0f; float distance = (m_endTransitionInterestPoint - m_startTransitionInterestPoint).Length(); m_transitionDuration = Eegeo::Clamp(distance/CAMERA_TRANSITION_SPEED_IN_METERS_PER_SECOND, MIN_TRANSITION_TIME, MAX_TRANSITION_TIME); m_isTransitioning = true; if(abs(m_endTransitionHeading - m_startTransitionHeading) > M_PI) { if(m_endTransitionHeading > m_startTransitionHeading) m_endTransitionHeading -= 2 * M_PI; else m_startTransitionHeading -= 2 * M_PI; } }
void CameraTransitionController::StartTransitionTo(Eegeo::dv3 newInterestPoint, float distanceFromInterest, float newHeadingRadians, bool jumpIfFar) { if(IsTransitioning()) { StopCurrentTransition(); } m_navigationService.SetGpsMode(Eegeo::Location::NavigationService::GpsModeOff); if(jumpIfFar && ShouldJumpTo(newInterestPoint)) { Eegeo::Space::EcefTangentBasis newInterestBasis; Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(newInterestPoint, Eegeo::Math::Rad2Deg(newHeadingRadians), newInterestBasis); m_cameraController.SetView(newInterestBasis, distanceFromInterest); return; } const Eegeo::Space::EcefTangentBasis& currentInterestBasis = m_cameraController.GetInterestBasis(); m_startTransitionInterestPointEcef = currentInterestBasis.GetPointEcef(); m_startInterestDistance = m_cameraController.GetDistanceToInterest(); m_startInterestHeading = Eegeo::Camera::CameraHelpers::GetAbsoluteBearingRadians(currentInterestBasis.GetPointEcef(), currentInterestBasis.GetForward());; m_endTransitionInterestPointEcef = newInterestPoint; m_endInterestDistance = distanceFromInterest; m_endInterestHeading = newHeadingRadians; m_transitionTime = 0.0f; const float CAMERA_TRANSITION_SPEED_IN_METERS_PER_SECOND = 1000.0f; const float MIN_TRANSITION_TIME = 0.5f; const float MAX_TRANSITION_TIME = 2.0f; float distance = (m_endTransitionInterestPointEcef - m_startTransitionInterestPointEcef).ToSingle().Length(); m_transitionDuration = Eegeo::Clamp(distance/CAMERA_TRANSITION_SPEED_IN_METERS_PER_SECOND, MIN_TRANSITION_TIME, MAX_TRANSITION_TIME); m_isTransitioning = true; if(std::abs(m_endInterestHeading - m_startInterestHeading) > Eegeo::Math::kPI) { if(m_endInterestHeading > m_startInterestHeading) m_endInterestHeading -= 2.f * Eegeo::Math::kPI; else m_startInterestHeading -= 2.f * Eegeo::Math::kPI; } }
void CameraTransitionController::StartTransitionTo(const Eegeo::dv3& newInterestPoint, float distanceFromInterest, float newHeadingRadians, const Eegeo::Resources::Interiors::InteriorId& interiorId, int targetFloorIndex, bool jumpIfFar) { if(IsTransitioning()) { StopCurrentTransition(); } m_navigationService.SetGpsMode(Eegeo::Location::NavigationService::GpsModeOff); if(m_appModeModel.GetAppMode() == ExampleApp::AppModes::SdkModel::InteriorMode) { const double exitInteriorDistanceSquared = 100*100; double interestDifferenceSquared = (m_interiorsCameraController.GetInterestLocation() - newInterestPoint).LengthSq(); if(m_interiorSelectionModel.GetSelectedInteriorId() == interiorId) { Eegeo_ASSERT(interiorId != Eegeo::Resources::Interiors::InteriorId::NullId(), "Invalid state. Have selected null Interior while in Interior mode"); EnqueueTransitionToInteriorStage(newInterestPoint, distanceFromInterest, interiorId, targetFloorIndex); StartQueuedTransition(); return; } else if(interiorId != Eegeo::Resources::Interiors::InteriorId::NullId() && interestDifferenceSquared < exitInteriorDistanceSquared) { EnqueueTransitionToInteriorPointStage(newInterestPoint, distanceFromInterest, newHeadingRadians, interiorId, targetFloorIndex, jumpIfFar); StartQueuedTransition(); return; } else { EnqueueExitInteriorStage(); } } EnqueueTransitionToPointStage(newInterestPoint, distanceFromInterest, newHeadingRadians, jumpIfFar); if(interiorId != m_interiorSelectionModel.GetSelectedInteriorId() && interiorId != Eegeo::Resources::Interiors::InteriorId::NullId()) { EnqueueTransitionToInteriorStage(newInterestPoint, distanceFromInterest, interiorId, targetFloorIndex); } StartQueuedTransition(); }