bool PoiRingTouchController::HandleTouchMove(const AppInterface::TouchData &data, const Eegeo::Camera::RenderCamera &renderCamera, Eegeo::Camera::GlobeCamera::GlobeCameraController& globeCameraController)
                {
                    if (m_myPinCreationModel.GetCreationStage() != Ring)
                    {
                        return false;
                    }

                    if (m_isDragging)
                    {
                        float screenPixelX = data.point.GetX();
                        float screenPixelY = data.point.GetY();

                        Eegeo::dv3 rayDirection;
                        Eegeo::Camera::CameraHelpers::GetScreenPickRay(renderCamera, screenPixelX, screenPixelY, rayDirection);

                        Eegeo::dv3 rayOrigin = globeCameraController.ComputeNonFlattenedCameraPosition();
                        Eegeo::dv3 rayIntersectionPoint;
                        double intersectionParam;
                        bool rayPick = PerformRayPick(rayOrigin, rayDirection, rayIntersectionPoint, intersectionParam);

                        if (rayPick)
                        {
                            m_myPinCreationModel.SetPosition(rayIntersectionPoint);
                        }

                        return true;
                    }

                    return false;
                }
                bool PoiRingTouchController::HandleTouchMove(const AppInterface::TouchData &data, const Eegeo::Camera::RenderCamera &renderCamera, const Eegeo::dv3& nonFlattenedCameraPosition)
                {
                    if (m_myPinCreationModel.GetCreationStage() != Ring)
                    {
                        return false;
                    }

                    if (m_isDragging)
                    {
                        float screenPixelX = data.point.GetX();
                        float screenPixelY = data.point.GetY();
                        
                        Eegeo::dv3 rayDirection;
                        Eegeo::Camera::CameraHelpers::GetScreenPickRay(renderCamera, screenPixelX, screenPixelY, rayDirection);

                        Eegeo::dv3 rayOrigin = nonFlattenedCameraPosition;
                        Eegeo::dv3 rayIntersectionPoint;
                        double intersectionParam;
                        float terrainHeight;
                        float heightAboveTerrain;
                        bool rayPick = PerformRayPick(rayOrigin, rayDirection, rayIntersectionPoint, intersectionParam, terrainHeight, heightAboveTerrain);
                        
                        if (rayPick)
                        {
                            const float currentCameraAltitiude = renderCamera.GetAltitude();
                            
                            float offsetScale = 0.0f;
                            if(currentCameraAltitiude != 0.0f && m_initialCameraAltitiude != 0.0f)
                            {
                                offsetScale = currentCameraAltitiude /m_initialCameraAltitiude;
                            }
                            
                            Eegeo::Space::LatLong latLong = Eegeo::Space::LatLong::FromECEF(rayIntersectionPoint - (m_dragOffset * offsetScale));
                            m_myPinCreationModel.SetLatLong(latLong);
                            m_myPinCreationModel.SetTerrainHeight(terrainHeight);
                            m_myPinCreationModel.SetHeightAboveTerrain(heightAboveTerrain);
                        }
                        
                        return true;
                    }
                    
                    return false;
                }
                bool PoiRingTouchController::TouchDownRaycast(const AppInterface::TouchData &data,
                                                              const Eegeo::Camera::RenderCamera &renderCamera,
                                                              const Eegeo::dv3 &rayOrigin)
                {
                    float screenPixelX = data.point.GetX();
                    float screenPixelY = data.point.GetY();
                    
                    Eegeo::dv3 rayDirection;
                    Eegeo::Camera::CameraHelpers::GetScreenPickRay(renderCamera, screenPixelX, screenPixelY, rayDirection);

                    Eegeo::dv3 rayIntersectionPoint;
                    double intersectionParam;
                    float terrainHeight;
                    float heightAboveTerrain;
                    bool rayPick = PerformRayPick(rayOrigin, rayDirection, rayIntersectionPoint, intersectionParam, terrainHeight, heightAboveTerrain);

                    if (rayPick)
                    {
                        Eegeo::dv3 iconPosition;
                        float iconSize;
                        m_poiRingController.GetIconPositionAndSize(iconPosition, iconSize);
                        
                        Eegeo::dv3 spherePosition;
                        float sphereRadius;
                        m_poiRingController.GetSpherePositionAndRadius(spherePosition, sphereRadius);
                        
                        m_initialCameraAltitiude =  renderCamera.GetAltitude();
                        
                        bool hitIcon = Eegeo::Geometry::IntersectionTests::TestRaySphere(rayOrigin, rayDirection, iconPosition, iconSize/2.0f);
                        if ((rayIntersectionPoint - spherePosition).Length() < sphereRadius || hitIcon)
                        {
                            m_dragOffset = rayIntersectionPoint - spherePosition;
                            m_isDragging = true;
                            return true;
                        }
                    }
                    
                    return false;
                }
                bool PoiRingTouchController::HandleTouchDown(const AppInterface::TouchData& data, const Eegeo::Camera::RenderCamera& renderCamera, Eegeo::Camera::GlobeCamera::GlobeCameraController& globeCameraController)
                {
                    if (m_myPinCreationModel.GetCreationStage() != Ring)
                    {
                        return false;
                    }

                    float screenPixelX = data.point.GetX();
                    float screenPixelY = data.point.GetY();

                    Eegeo::dv3 rayDirection;
                    Eegeo::Camera::CameraHelpers::GetScreenPickRay(renderCamera, screenPixelX, screenPixelY, rayDirection);

                    Eegeo::dv3 rayOrigin = globeCameraController.ComputeNonFlattenedCameraPosition();
                    Eegeo::dv3 rayIntersectionPoint;
                    double intersectionParam;

                    bool rayPick = PerformRayPick(rayOrigin, rayDirection, rayIntersectionPoint, intersectionParam);

                    if (rayPick)
                    {
                        Eegeo::dv3 iconPosition;
                        float iconSize;
                        m_poiRingController.GetIconPositionAndSize(iconPosition, iconSize);
                        
                        Eegeo::dv3 spherePosition;
                        float sphereRadius;
                        m_poiRingController.GetSpherePositionAndRadius(spherePosition, sphereRadius);

                        bool hitIcon = Eegeo::Geometry::IntersectionTests::TestRaySphere(rayOrigin, rayDirection, iconPosition, iconSize/2.0f);
                        if ((rayIntersectionPoint - spherePosition).Length() < sphereRadius || hitIcon)
                        {
                            m_isDragging = true;
                            return true;
                        }
                    }

                    return false;
                }