private void Update()
    {
        // First case handles when the map is selected and being dragged and/or zoomed.
        var isPanning = _pointer != null;

        if (isPanning &&
            CoreServices.InputSystem.FocusProvider.TryGetFocusDetails(_pointer, out FocusDetails focusDetails))
        {
            // Now we can raycast an imaginary plane orignating from the updated _targetPointInLocalSpace.
            var rayPositionInMapLocalSpace  = _mapRenderer.transform.InverseTransformPoint(_pointer.Position);
            var rayDirectionInMapLocalSpace = _mapRenderer.transform.InverseTransformDirection(_pointer.Rotation * Vector3.forward).normalized;
            var rayInMapLocalSpace          = new Ray(rayPositionInMapLocalSpace, rayDirectionInMapLocalSpace.normalized);
            var hitPlaneInMapLocalSpace     = new Plane(Vector3.up, _targetPointInLocalSpace);
            if (hitPlaneInMapLocalSpace.Raycast(rayInMapLocalSpace, out float enter))
            {
                // This point will be used to determine how much to translate the map.
                // Decaying the resulting position applies some smoothing to the input.
                var panSmoothness = Mathf.Lerp(0.0f, 0.5f, _panSmoothness);
                _currentPointInLocalSpace =
                    DynamicExpDecay(_currentPointInLocalSpace, rayInMapLocalSpace.GetPoint(enter), panSmoothness);
            }

            // Reconstruct ray from pointer position to focus details.
            var rayTargetPoint = _mapRenderer.transform.TransformPoint(_currentPointInLocalSpace);
            var ray            = new Ray(_pointer.Position, (rayTargetPoint - _pointer.Position).normalized);
            var zoomToApply    = ComputeZoomToApply();
            _mapInteractionController.PanAndZoom(ray, _targetPointInMercator, _startingAltitudeInMeters, zoomToApply);

            // Update starting point so that the focus point tracks with this point.
            _targetPointInLocalSpace =
                _mapRenderer.TransformMercatorWithAltitudeToLocalPoint(_targetPointInMercator, _startingAltitudeInMeters);

            // Also override the FocusDetails so that the pointer ray tracks the target coordinate.
            focusDetails.Point           = _mapRenderer.transform.TransformPoint(_targetPointInLocalSpace);
            focusDetails.PointLocalSpace = _targetPointInLocalSpace;
            CoreServices.InputSystem.FocusProvider.TryOverrideFocusDetails(_pointer, focusDetails);
        }
        else if (_zoomPointer != null && _isFocused) // This case handles when the map is just focused, not selected, and being zoomed.
        {
            var zoomToApply = ComputeZoomToApply();
            if (zoomToApply != 0)
            {
                var pointerRayPosition  = _zoomPointer.Position;
                var pointerRayDirection = (_zoomPointer.Rotation * Vector3.forward).normalized;
                _mapInteractionController.Zoom(zoomToApply, new Ray(pointerRayPosition, pointerRayDirection));
            }
        }
    }
Ejemplo n.º 2
0
    private void Update()
    {
        // First case handles when the map is selected and being dragged and/or zoomed.
        if (_isInteracting &&
            _pointer != null &&
            CoreServices.InputSystem.FocusProvider.TryGetFocusDetails(_pointer, out var focusDetails) &&
            focusDetails.Object == gameObject)
        {
            // The current point the ray is targeting has been calculated in OnPointerDragged. Smooth it here.
            var panSmoothness = Mathf.Lerp(0.0f, 0.5f, _panSmoothness);
            _smoothedPointInLocalSpace = DynamicExpDecay(_smoothedPointInLocalSpace, _currentPointInLocalSpace, panSmoothness);

            // Reconstruct ray from pointer position to focus details.
            var rayTargetPoint = MapRenderer.transform.TransformPoint(_smoothedPointInLocalSpace);
            var ray            = new Ray(_pointer.Position, (rayTargetPoint - _pointer.Position).normalized);
            MapInteractionController.PanAndZoom(ray, _targetPointInMercator, _targetAltitudeInMeters, ComputeZoomToApply());

            // Update starting point so that the focus point tracks with this point.
            _targetPointInLocalSpace =
                MapRenderer.TransformMercatorWithAltitudeToLocalPoint(_targetPointInMercator, _targetAltitudeInMeters);

            // Also override the FocusDetails so that the pointer ray tracks the target coordinate.
            focusDetails.Point           = MapRenderer.transform.TransformPoint(_targetPointInLocalSpace);
            focusDetails.PointLocalSpace = _targetPointInLocalSpace;
            CoreServices.InputSystem.FocusProvider.TryOverrideFocusDetails(_pointer, focusDetails);

            // Reset timings used for tap-and-hold and double tap.
            _lastPointerDownTime = float.MaxValue;
            _lastClickTime       = float.MinValue;
        }
        else if (_zoomPointer != null && _isFocused) // This case handles when the map is just focused, not selected, and being zoomed.
        {
            var zoomToApply = ComputeZoomToApply();
            if (zoomToApply != 0)
            {
                if (!_isInteracting)
                {
                    _isInteracting = true;
                    MapInteractionController.OnInteractionStarted?.Invoke();
                }
                var pointerRayPosition  = _zoomPointer.Position;
                var pointerRayDirection = (_zoomPointer.Rotation * Vector3.forward).normalized;
                MapInteractionController.Zoom(zoomToApply, new Ray(pointerRayPosition, pointerRayDirection));

                // Reset timings used for tap-and-hold and double tap.
                _lastPointerDownTime = float.MaxValue;
                _lastClickTime       = float.MinValue;
            }
            else
            {
                if (_zoomPointer != null && _isInteracting)
                {
                    // We were zooming last frame. End the interaction.
                    MapInteractionController.OnInteractionEnded?.Invoke();
                    _isInteracting = false;
                    _zoomPointer   = null;
                }
            }
        }
        else
        {
            if (_isInteracting)
            {
                // Last frame there was interaction happening. This is the first frame where the interaction has ended.
                MapInteractionController.OnInteractionEnded?.Invoke();
                _isInteracting = false;
            }
        }

        // Check for a tap and hold.
        if (_pointer != null && (Time.time - _lastPointerDownTime) > TapAndHoldThresholdInSeconds)
        {
            MapInteractionController.OnTapAndHold?.Invoke(new LatLonAlt(_targetPointInMercator.ToLatLon(), _targetAltitudeInMeters));

            // Reset timings used for tap-and-hold and double tap.
            _lastPointerDownTime = float.MaxValue;
            _lastClickTime       = float.MinValue;
        }
    }