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 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 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 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)); } } }