/* INFINITY CODE */ /* https://infinity-code.com */ using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; #if UPANO using InfinityCode.uPano; using InfinityCode.uPano.Controls; using InfinityCode.uPano.Directions; using InfinityCode.uPano.HotSpots; using InfinityCode.uPano.InteractiveElements; using InfinityCode.uPano.Plugins; using InfinityCode.uPano.Renderers; using InfinityCode.uPano.Requests; using InfinityCode.uPano.Services; using InfinityCode.uPano.Transitions; #endif /// /// Plugin for displaying Google Street View panoramas using uPano. /// [AddComponentMenu("Infinity Code/Online Maps/Plugins/uPano Connector")] [OnlineMapsPlugin("uPano Connector", typeof(OnlineMapsControlBase))] public class OnlineMapsPanoConnector : MonoBehaviour { private const string overlayURL = "https://maps.google.com/maps/vt?pb=!1m5!1m4!1i{0}!2i{1}!3i{2}!4i256!2m8!1e2!2ssvv!4m2!1scb_client!2sapiv3!4m2!1scc!2s*211m3*211e3*212b1*213e2*211m3*211e2*212b1*213e2!3m5!3sUS!12m1!1e40!12m1!1e18"; /// /// Google API key /// public string googleApiKey = ""; /// /// The minimum map zoom for which overlay will be displayed /// public int minZoom = 10; /// /// Maximum panorama zoom level (0 - 4) /// public int panoramaMaxZoom = 3; /// /// Use progressive loading panoramas (zoom - 0, 1, 2, 3, 4) /// public bool usePreview = true; /// /// Check the color of the overlay texture before opening the panorama. /// public bool checkOverlayColor = true; /// /// Use rotation from Online Maps Camera Orbit /// public bool useRotation = true; /// /// Overlay layer will be drawn /// public OverlayLayer overlayLayer = OverlayLayer.front; /// /// Prefab of the arrow to go to the next panorama /// public GameObject nextDirectionPrefab; /// /// Prefab of UI button to close the panorama /// [Header("Panorama close settings")] public GameObject closeButtonPrefab; /// /// Hot key to close the panorama /// public KeyCode closeByKeyCode = KeyCode.Escape; /// /// Radius of the panorama sphere /// [Header("Panorama mesh settings")] public int radius = 10; /// /// Number of segments of the panorama sphere /// public int segments = 32; /// /// The shader that will be used to display the panorama /// [Header("Transitions")] public Shader shader; /// /// Prefab which contains the transition that is played before the panorama is closed /// public GameObject beforeTransitionPrefab; /// /// Prefab which contains the transition that is played after the panorama is closed /// public GameObject afterTransitionPrefab; /// /// Use global transitions if they are not in this component /// public bool useGlobalTransitions = true; /// /// Use transitions when a panorama is shown /// public bool showPanoramaTransition = true; /// /// Use transitions when a panorama is closing /// public bool closePanoramaTransition = true; private OnlineMaps map; private Dictionary overlays; private GameObject closeButtonInstance; #if UPANO private SphericalPanoRenderer panoRenderer; private GoogleStreetViewRequest currentRequest; private double lng, lat; private int zoom; public GoogleStreetViewMeta meta; private bool CheckOverlayColor(double clng, double clat) { double tx, ty; map.projection.CoordinatesToTile(clng, clat, map.zoom, out tx, out ty); OnlineMapsTile tile = map.tileManager.GetTile(map.zoom, (int) tx, (int) ty); if (tile == null) return false; while (tile.status != OnlineMapsTileStatus.loaded) { tile = tile.parent; if (tile == null) return false; } Texture2D overlay = null; if (overlayLayer == OverlayLayer.front) overlay = tile.overlayFrontTexture; else if (overlayLayer == OverlayLayer.back) overlay = tile.overlayBackTexture; else if (overlayLayer == OverlayLayer.traffic) overlay = (tile as OnlineMapsRasterTile).trafficTexture; if (overlay == null) return false; int px = (int) Math.Round((tx - (int) tx) * 255); int py = 255 - (int) Math.Round((ty - (int) ty) * 255); for (int x = Mathf.Max(0, px - 2); x < Mathf.Min(255, px + 3); x++) { for (int y = Mathf.Max(0, py - 2); y < Mathf.Min(255, py + 3); y++) { if (overlay.GetPixel(x, y) != Color.clear) return true; } } return false; } /// /// Closes the active instance of the panorama. /// public void Close() { if (closePanoramaTransition) StartCloseTransition(); else CloseImmediately(); } private void CloseImmediately() { if (panoRenderer != null) { if (panoRenderer.texture != null) Destroy(panoRenderer.texture); Destroy(panoRenderer.gameObject); panoRenderer = null; } if (closeButtonInstance != null) { Destroy(closeButtonInstance); closeButtonInstance = null; } if (currentRequest != null) { currentRequest.Dispose(); currentRequest = null; } if (map != null) map.control.allowUserControl = true; } private void CreateDirections(DirectionManager directionManager) { directionManager.Clear(); try { foreach (GoogleStreetViewDirection item in meta.nearestDirections) { Direction direction = directionManager.Create(item.pan, nextDirectionPrefab); if (!string.IsNullOrEmpty(item.title)) direction.title = item.title; direction["id"] = item.id; direction.OnClick.AddListener(LoadNextPanorama); } } catch (Exception e) { Debug.LogException(e); } } private void LoadNextPanorama(InteractiveElement element) { if (currentRequest != null) currentRequest.Dispose(); zoom = usePreview? 0: panoramaMaxZoom; GoogleStreetViewRequest request = new GoogleStreetViewRequest(googleApiKey, element["id"] as string, zoom, true); request.OnSuccess += OnGoogleStreetViewSuccess; } private void OnDisable() { if (map != null) { if (map.tileManager != null && map.tileManager.tiles != null) { foreach (OnlineMapsTile tile in map.tileManager.tiles) SetOverlay(tile as OnlineMapsRasterTile, null); } map.Redraw(); } } private void OnEnable() { if (string.IsNullOrEmpty(googleApiKey)) { Debug.LogWarning("Please specify Online Maps Pano Connector/Google Api Key!!!"); Destroy(this); return; } if (overlays == null) overlays = new Dictionary(); foreach (KeyValuePair pair in overlays) { if (!map.tileManager.dTiles.ContainsKey(pair.Key)) continue; SetOverlay(map.tileManager.dTiles[pair.Key] as OnlineMapsRasterTile, pair.Value); } if (map != null) map.Redraw(); } private void OnGoogleStreetViewSuccess(GoogleStreetViewRequest request) { currentRequest = null; if (request.hasErrors) { Debug.Log(request.error); return; } string panoID = request.panoID; if (panoRenderer == null) { map.control.allowUserControl = false; panoRenderer = SphericalPanoRenderer.CreateSphere(request.texture, radius, segments); if (useRotation && OnlineMapsCameraOrbit.instance != null) panoRenderer.pano.pan = OnlineMapsCameraOrbit.instance.rotation.y; else panoRenderer.pano.pan = 0; panoRenderer.shader = shader != null ? shader : Shader.Find("Unlit/Texture"); panoRenderer.gameObject.AddComponent(); panoRenderer.gameObject.AddComponent(); panoRenderer.gameObject.AddComponent(); panoRenderer.gameObject.AddComponent(); panoRenderer.gameObject.AddComponent(); if (closeButtonPrefab != null && closeButtonInstance == null) { Canvas canvas = CanvasUtils.GetCanvas(); if (canvas != null) { closeButtonInstance = Instantiate(closeButtonPrefab); closeButtonInstance.transform.SetParent(canvas.transform, false); closeButtonInstance.GetComponentInChildren