void TransitionToWorldPointStage::Update(float dt) { if(m_jumpIfFar && ShouldJumpTo(m_endTransitionInterestPointEcef)) { m_transitionTime = m_transitionDuration; // Calling SetView here instead of just doing an early-out so that anything that depends on the camera's position will work // (such as mapscene startup searches) [MPLY-8855] Eegeo::v3 endHeadingVector = ComputeHeadingVector(m_endTransitionInterestPointEcef, m_endInterestHeading); Eegeo::Space::EcefTangentBasis newInterestBasis(m_endTransitionInterestPointEcef, endHeadingVector); m_gpsGlobeCameraController.SetView(newInterestBasis, m_endInterestDistance); 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_gpsGlobeCameraController.SetView(newInterestBasis, interpolatedDistance); }
void PinOverModelExample::MyModelRenderable::Render(Eegeo::Rendering::GLState& glState) const { Eegeo::m44 transform; Eegeo::dv3 location = Eegeo::Space::LatLong::FromDegrees(37.7858,-122.401).ToECEF(); Eegeo::v3 up(location.Norm().ToSingle()); Eegeo::v3 forward = (location - Eegeo::v3(0.f, 1.f, 0.f)).Norm().ToSingle(); Eegeo::v3 right(Eegeo::v3::Cross(up, forward).Norm()); forward = Eegeo::v3::Cross(up, right); Eegeo::v3 cameraRelativePos = (location - m_renderContext.GetCameraOriginEcef()).ToSingle(); Eegeo::m44 scaleMatrix; scaleMatrix.Scale(1.f); Eegeo::m44 cameraRelativeTransform; cameraRelativeTransform.SetFromBasis(right, up, forward, cameraRelativePos); Eegeo::m44::Mul(transform, cameraRelativeTransform, scaleMatrix); transform.SetRow(3, Eegeo::v4(cameraRelativePos, 1.f)); glState.DepthTest.Enable(); glState.DepthFunc(GL_LEQUAL); //loaded model faces are ccw glState.FrontFace(GL_CCW); m_model.GetRootNode()->SetVisible(true); m_model.GetRootNode()->SetLocalMatrix(transform); m_model.GetRootNode()->UpdateRecursive(); m_model.GetRootNode()->UpdateSphereRecursive(); m_model.GetRootNode()->DrawRecursive(m_renderContext, m_globalFogging, NULL, true, false); glState.FrontFace(GL_CW); Eegeo::EffectHandler::Reset(); }
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 PODAnimationExample::Draw() { //create basis around a known location off coast of SF Eegeo::m44 transform; Eegeo::dv3 location = Eegeo::dv3(4256955.9749164,3907407.6184668,-2700108.75541722); Eegeo::v3 up(location.Norm().ToSingle()); Eegeo::v3 forward = (location - Eegeo::v3(0.f, 1.f, 0.f)).Norm().ToSingle(); Eegeo::v3 right(Eegeo::v3::Cross(up, forward).Norm()); forward = Eegeo::v3::Cross(up, right); Eegeo::v3 cameraRelativePos = (location - cameraModel.GetWorldPosition()).ToSingle(); Eegeo::m44 scaleMatrix; scaleMatrix.Scale(1.f); Eegeo::m44 cameraRelativeTransform; cameraRelativeTransform.SetFromBasis(right, up, forward, cameraRelativePos); Eegeo::m44::Mul(transform, cameraRelativeTransform, scaleMatrix); transform.SetRow(3, Eegeo::v4(cameraRelativePos, 1.f)); //loaded model faces are ccw renderContext.GetGLState().FrontFace(GL_CCW); pModel->GetRootNode()->SetVisible(true); pModel->GetRootNode()->SetLocalMatrix(transform); pModel->GetRootNode()->UpdateRecursive(); pModel->GetRootNode()->UpdateSphereRecursive(); pModel->GetRootNode()->DrawRecursive(renderContext, globalFogging, NULL, true, false); renderContext.GetGLState().FrontFace(GL_CW); }
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(); } }
bool GpsMarkerModel::UpdateGpsPosition(float dt) { Eegeo::Space::LatLong locationServiceLatLong(0,0); if(!m_locationService.GetLocation(locationServiceLatLong)) { return false; } float terrainHeight = 0.0f; Eegeo::dv3 ecefPositionFlat = locationServiceLatLong.ToECEF(); if(m_locationService.IsIndoors()) { double altitude; m_locationService.GetAltitude(altitude); terrainHeight = static_cast<float>(altitude); } Eegeo::dv3 newLocationEcef = ecefPositionFlat + (ecefPositionFlat.Norm() * terrainHeight); float halfLife = 0.25f; float jumpThreshold = 50.0f; if(m_currentLocationEcef.SquareDistanceTo(newLocationEcef) < jumpThreshold * jumpThreshold) { m_currentLocationEcef = m_currentLocationEcef.Norm() * newLocationEcef.Length(); m_currentLocationEcef = Eegeo::Helpers::MathsHelpers::ExpMoveTowards(m_currentLocationEcef, newLocationEcef, halfLife, dt, 0.01f); } else { m_currentLocationEcef = newLocationEcef; } const Eegeo::Space::LatLong& coord = Eegeo::Space::LatLong::FromECEF(m_currentLocationEcef); m_blueSphereModel.SetCoordinate(coord); const Eegeo::Resources::Interiors::InteriorId& locationServiceInteriorId = m_locationService.GetInteriorId(); int indoorMapFloorId = 0; if (TryGetLocationServiceIndoorMapFloorId(locationServiceInteriorId, indoorMapFloorId)) { m_blueSphereModel.SetIndoorMap(locationServiceInteriorId.Value(), indoorMapFloorId); } else { m_blueSphereModel.SetIndoorMap(std::string(), 0); } if(!m_locationService.GetHorizontalAccuracy(m_currentAccuracyMeters)) { m_currentAccuracyMeters = 0.0f; } // return true regardless of whether or not we successfully found an indoorMapFloorId return true; }
Eegeo::v3 ComputeHeadingVector(Eegeo::dv3 interestPosition, float heading) { Eegeo::v3 m_heading(0,1,0); Eegeo::dv3 interestEcefUp = interestPosition.Norm(); Eegeo::v3 m_interestUp = Eegeo::v3(interestEcefUp.GetX(), interestEcefUp.GetY(), interestEcefUp.GetZ()); Eegeo::v3 m_interestRight = Eegeo::v3::Cross(m_interestUp, m_heading); m_interestRight = m_interestRight.Norm(); m_heading = Eegeo::v3::Cross(m_interestRight, m_interestUp); m_heading = m_heading.Norm(); Eegeo::Quaternion headingRot; headingRot.Set(m_interestUp, heading); m_heading = headingRot.RotatePoint(m_heading); return m_heading; }
//EnvironmentNotifierExampleTerrainStreamObserver/// void EnvironmentNotifierExampleTerrainStreamObserver::AddSphere(const Eegeo::Streaming::MortonKey& key) { Eegeo::Space::CubeMap::CubeMapCellInfo cellInfo(key); const Eegeo::dv2& resourceQuadtreeCellCenter = cellInfo.GetFaceCentre(); Eegeo::dv3 worldSpaceCellCenter = Eegeo::Space::CubeMap::FacePointToWorld(cellInfo.GetFaceIndex(), resourceQuadtreeCellCenter, Eegeo::Space::EarthConstants::CubeSideLengthHalf); Eegeo::dv3 up = worldSpaceCellCenter.Norm(); Eegeo::dv3 spherePosition = Eegeo::dv3::Scale(up, Eegeo::Space::EarthConstants::Radius + SPHERE_HEIGHT_ABOVE_SEA); Eegeo::v4 color(1.f, 0.f, 1.f, 0.75f); SphereData sphereData(spherePosition, color); m_spheres.insert(std::make_pair(key,sphereData)); }
Eegeo::v3 ComputeHeadingVector(Eegeo::dv3 interestPosition, float heading) { Eegeo::v3 interestForward(0,1,0); Eegeo::dv3 interestEcefUp = interestPosition.Norm(); Eegeo::v3 interestUp = interestEcefUp.ToSingle(); Eegeo::v3 interestRight = Eegeo::v3::Cross(interestUp, interestForward); interestRight = interestRight.Norm(); interestForward = Eegeo::v3::Cross(interestRight, interestUp); interestForward = interestForward.Norm(); Eegeo::Quaternion rotation; rotation.Set(interestUp, heading); interestForward = rotation.RotatePoint(interestForward); return interestForward; }
void SplashScreen::Show() { Eegeo::Space::EcefTangentBasis basis; Eegeo::dv3 p = Eegeo::Space::LatLongAltitude::FromDegrees(56.456160, -2.966101, 241.5f).ToECEF(); Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(p, -60.53f, basis); Eegeo::dv3 top(p.ToSingle().Norm()); Eegeo::dv3 forward(basis.GetForward().Norm()); Eegeo::dv3 right(Eegeo::dv3::Cross(top, forward)); m_pStateButtonBuilding->SetEcefPosition((forward*310.f) + (right*4.f) + p); m_pStateButtonPOI->SetEcefPosition((forward*310.f) + (right*-28.f) + p); m_pStateButtonLocation->SetEcefPosition((forward*310.f) + (right*37.f) + p); m_pPlayButton->SetEcefPosition((forward*270.f) + (right*5.f) + (top*-35.f) + p); m_pStateButtonLocation->Show(); m_pStateButtonBuilding->Show(); m_pStateButtonPOI->Show(); m_pPlayButton->SetItemShouldRender(true); m_pSplashScreenModel->SetShouldDisplay(true); }
bool PoiRingTouchController::PerformRayPick(const Eegeo::dv3 &rayOrigin, Eegeo::dv3 &rayDirection, Eegeo::dv3 &out_rayIntersectionPoint, double &out_intersectionParam, float &out_terrainHeight, float &out_heightAboveTerrain) { bool rayPick = false; if(m_appModeModel.GetAppMode() == AppModes::SdkModel::InteriorMode && m_interiorTransitionModel.InteriorIsVisible()) { const Eegeo::Resources::Interiors::InteriorsModel* interiorsModel = m_interiorInteractionModel.GetInteriorModel(); Eegeo_ASSERT(interiorsModel, "Couldn't get current interiorsModel"); const Eegeo::dv3 originNormal = interiorsModel->GetTangentBasis().GetUp(); const int selectedFloorIndex = m_interiorInteractionModel.GetSelectedFloorIndex(); float floorHeightAboveSeaLevel = Helpers::InteriorHeightHelpers::GetFloorHeightAboveSeaLevel(*interiorsModel, selectedFloorIndex); const Eegeo::dv3 point = originNormal * (floorHeightAboveSeaLevel + Eegeo::Space::EarthConstants::Radius); out_terrainHeight = interiorsModel->GetTangentSpaceBounds().GetMin().y; out_heightAboveTerrain = floorHeightAboveSeaLevel - out_terrainHeight; rayPick = Eegeo::Geometry::IntersectionTests::RayIntersectsWithPlane(rayOrigin, rayDirection, originNormal, point, out_intersectionParam, out_rayIntersectionPoint); } else { rayPick = m_rayPicker.TryGetRayIntersection(rayOrigin, rayDirection, out_rayIntersectionPoint, out_intersectionParam); if(rayPick) { out_terrainHeight = static_cast<float>(out_rayIntersectionPoint.Length() - Eegeo::Space::EarthConstants::Radius); out_heightAboveTerrain = 0.0f; } } if(!rayPick) { rayPick = Eegeo::Geometry::IntersectionTests::GetRayEarthSphereIntersection(rayOrigin, rayDirection, out_rayIntersectionPoint, Eegeo::Space::EarthConstants::RadiusSquared); if(rayPick) { out_terrainHeight = 0.0f; out_heightAboveTerrain = 0.0f; out_intersectionParam = (out_rayIntersectionPoint - rayOrigin).Length(); } } return rayPick; }
void WorldPinsInFocusController::Update(float deltaSeconds, const Eegeo::dv3& ecefInterestPoint, const Eegeo::Camera::RenderCamera& renderCamera) { const IWorldPinsInFocusModel* pClosest = NULL; double minDistanceSq = std::numeric_limits<double>::max(); Eegeo::v2 closestScreenPinLocation; Eegeo::v2 screenInterestPoint = ProjectEcefToScreen(ecefInterestPoint, renderCamera); if(m_focusEnabled) { for(size_t i = 0; i < m_worldPinsRepository.GetItemCount(); ++i) { ExampleApp::WorldPins::SdkModel::WorldPinItemModel* worldPinItemModel = m_worldPinsRepository.GetItemAtIndex(i); if (!worldPinItemModel->IsFocusable()) { continue; } Eegeo::dv3 ecefPinLocation; Eegeo::v2 screenPinLocation; m_worldPinsService.GetPinEcefAndScreenLocations(*worldPinItemModel, ecefPinLocation, screenPinLocation); Eegeo::v3 cameraLocal = (ecefPinLocation - renderCamera.GetEcefLocation()).ToSingle(); Eegeo::v3 cameraSurfaceNormal = cameraLocal.Norm(); Eegeo::v3 upNormal = ecefPinLocation.Norm().ToSingle(); float dp = Eegeo::v3::Dot(cameraSurfaceNormal, upNormal); if(dp > 0.0f) { continue; } screenPinLocation = ProjectEcefToScreen(ecefPinLocation, renderCamera); double distanceToFocusSq = (screenInterestPoint - screenPinLocation).LengthSq(); if(distanceToFocusSq < minDistanceSq && worldPinItemModel->IsVisible()) { pClosest = &worldPinItemModel->GetInFocusModel(); minDistanceSq = distanceToFocusSq; closestScreenPinLocation = screenPinLocation; } } } if(m_pLastFocussedModel != pClosest) { m_pLastFocussedModel = pClosest; if(m_pLastFocussedModel != NULL) { m_messageBus.Publish(WorldPinGainedFocusMessage(WorldPinsInFocusModel(m_pLastFocussedModel->GetPinId(), m_pLastFocussedModel->GetTitle(), m_pLastFocussedModel->GetSubtitle(), m_pLastFocussedModel->GetVendor(), m_pLastFocussedModel->GetJsonData(), m_pLastFocussedModel->GetRatingsImage(), m_pLastFocussedModel->GetReviewCount()), closestScreenPinLocation)); } else { m_messageBus.Publish(WorldPinLostFocusMessage()); } } else { if(m_pLastFocussedModel != NULL) { m_messageBus.Publish(WorldPinInFocusChangedLocationMessage(closestScreenPinLocation)); } } }
void WorldMenuController::PositionItems() { if(!m_menuItemsShouldRender) return; Eegeo::m33 headTrackedOrientation; Eegeo::m33::Mul(headTrackedOrientation, m_uiCameraProvider.GetBaseOrientation(), m_cachedHeadTracker); float halfCount = m_viewsByModel.size()/2; if(m_viewsByModel.size()%2==0) halfCount-=0.5f; Eegeo::dv3 center = m_uiCameraProvider.GetRenderCameraForUI().GetEcefLocation(); Eegeo::v3 forward(headTrackedOrientation.GetRow(2)); Eegeo::v3 top(center.ToSingle().Norm()); Eegeo::v3 right(Eegeo::v3::Cross(top, forward)); Eegeo::v3 vA = center.ToSingle(); Eegeo::v3 vB = m_uiCameraProvider.GetOrientation().GetRow(2); float angle = Eegeo::Math::Rad2Deg(Eegeo::Math::ACos(Eegeo::v3::Dot(vA, vB)/(vA.Length()*vB.Length()))); const float MarginAngle = 85; const int PositionMultiplier = 600; bool shouldUpdatePosition = false; if(!m_isMenuShown && angle<=MarginAngle) { m_isMenuShown = true; shouldUpdatePosition = true; m_cachedHeadTracker = m_uiCameraProvider.GetHeadTrackerOrientation(); m_cachedCenter = center; } else if(m_isMenuShown && angle>MarginAngle) { m_isMenuShown = false; shouldUpdatePosition = true; } if ((m_cachedCenter - center).LengthSq() > 1) { m_cachedCenter = center; shouldUpdatePosition = true; } if(shouldUpdatePosition || m_isMenuShown) { std::vector<WorldMenuItemView*> items; for(TViewsByModel::iterator it = m_viewsByModel.begin(); it != m_viewsByModel.end(); ++it) { std::vector<WorldMenuItemView*>::iterator itItems = items.begin(); for(; itItems != items.end(); ++itItems) { if((*itItems)->GetWorldMenuItem().GetId() < it->second->GetWorldMenuItem().GetId()) { break; } } items.insert(itItems, it->second); } float margin = 0.f; for(std::vector<WorldMenuItemView*>::iterator it = items.begin(); it != items.end(); ++it) { WorldMenuItemView* pView = *it; if(!m_isMenuShown) { pView->SetItemShouldRender(false); m_pSelectedArrow->SetItemShouldRender(false); continue; } margin += pView->GetWorldMenuItem().GetMarginRight(); Eegeo::dv3 position(center + (forward*PositionMultiplier) + (top*45) + ((right*55*halfCount)-(right*margin))); pView->SetEcefPosition(position); pView->SetItemShouldRender(true); m_pSelectedArrow->SetItemShouldRender(true); if(m_menuItemId==pView->GetWorldMenuItem().GetId()) { m_pSelectedArrow->SetEcefPosition(center + (forward*PositionMultiplier) + (top*92) + (right*55*halfCount)-(right*margin)); } halfCount-=1; margin += pView->GetWorldMenuItem().GetMarginLeft(); pView->SetItemShouldRender(m_menuItemsShouldRender); } items.clear(); m_lastCameraPosition = center; } }