/Sauron/Assets/Mapbox/Unity/Map/QuadTreeTileProvider.cs

https://bitbucket.org/laurentantoine/sauron_bitbucket_repository · C# · 144 lines · 105 code · 24 blank · 15 comment · 11 complexity · 17763987e3a5cd69e589a6983103fa14 MD5 · raw file

  1. namespace Mapbox.Unity.Map
  2. {
  3. using UnityEngine;
  4. using Mapbox.Map;
  5. using Mapbox.Unity.Utilities;
  6. using Mapbox.Utils;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System;
  10. public class QuadTreeTileProvider : AbstractTileProvider
  11. {
  12. Plane _groundPlane;
  13. float _elapsedTime;
  14. bool _shouldUpdate;
  15. CameraBoundsTileProviderOptions _cbtpOptions;
  16. public override void OnInitialized()
  17. {
  18. _cbtpOptions = (CameraBoundsTileProviderOptions)_options;
  19. if (_cbtpOptions.camera == null)
  20. {
  21. _cbtpOptions.camera = Camera.main;
  22. }
  23. _groundPlane = new Plane(Vector3.up, 0);
  24. _shouldUpdate = true;
  25. }
  26. void Update()
  27. {
  28. //Camera Debugging
  29. //Vector3[] frustumCorners = new Vector3[4];
  30. //_cbtpOptions.camera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), _cbtpOptions.camera.transform.position.y, Camera.MonoOrStereoscopicEye.Mono, frustumCorners);
  31. //for (int i = 0; i < 4; i++)
  32. //{
  33. // var worldSpaceCorner = _cbtpOptions.camera.transform.TransformVector(frustumCorners[i]);
  34. // Debug.DrawRay(_cbtpOptions.camera.transform.position, worldSpaceCorner, Color.blue);
  35. //}
  36. if (!_shouldUpdate)
  37. {
  38. return;
  39. }
  40. _elapsedTime += Time.deltaTime;
  41. if (_elapsedTime >= _cbtpOptions.updateInterval)
  42. {
  43. _elapsedTime = 0f;
  44. //update viewport in case it was changed by switching zoom level
  45. Vector2dBounds _viewPortWebMercBounds = getcurrentViewPortWebMerc();
  46. var tilesToRequest = TileCover.GetWithWebMerc(_viewPortWebMercBounds, _map.AbsoluteZoom);
  47. var activeTiles = _activeTiles.Keys.ToList();
  48. List<UnwrappedTileId> toRemove = activeTiles.Except(tilesToRequest).ToList();
  49. foreach (var t2r in toRemove) { RemoveTile(t2r); }
  50. var finalTilesNeeded = tilesToRequest.Except(activeTiles);
  51. foreach (var tile in activeTiles)
  52. {
  53. // Reposition tiles in case we panned.
  54. RepositionTile(tile);
  55. }
  56. foreach (var tile in finalTilesNeeded)
  57. {
  58. AddTile(tile);
  59. }
  60. }
  61. }
  62. private Vector2dBounds getcurrentViewPortWebMerc(bool useGroundPlane = true)
  63. {
  64. Vector3[] hitPnt = new Vector3[4];
  65. if (useGroundPlane)
  66. {
  67. // rays from camera to groundplane: lower left and upper right
  68. Ray ray00 = _cbtpOptions.camera.ViewportPointToRay(new Vector3(0, 0));
  69. Ray ray01 = _cbtpOptions.camera.ViewportPointToRay(new Vector3(0, 1));
  70. Ray ray10 = _cbtpOptions.camera.ViewportPointToRay(new Vector3(1, 0));
  71. Ray ray11 = _cbtpOptions.camera.ViewportPointToRay(new Vector3(1, 1));
  72. hitPnt[0] = getGroundPlaneHitPoint(ray00);
  73. hitPnt[1] = getGroundPlaneHitPoint(ray01);
  74. hitPnt[2] = getGroundPlaneHitPoint(ray10);
  75. hitPnt[3] = getGroundPlaneHitPoint(ray11);
  76. }
  77. // Find min max bounding box.
  78. // TODO : Find a better way of doing this.
  79. float minX = float.MaxValue;
  80. float minZ = float.MaxValue;
  81. float maxX = float.MinValue;
  82. float maxZ = float.MinValue;
  83. for (int i = 0; i < 4; i++)
  84. {
  85. if (minX > hitPnt[i].x)
  86. {
  87. minX = hitPnt[i].x;
  88. }
  89. if (minZ > hitPnt[i].z)
  90. {
  91. minZ = hitPnt[i].z;
  92. }
  93. if (maxX < hitPnt[i].x)
  94. {
  95. maxX = hitPnt[i].x;
  96. }
  97. if (maxZ < hitPnt[i].z)
  98. {
  99. maxZ = hitPnt[i].z;
  100. }
  101. }
  102. Vector3 hitPntLL = new Vector3(minX, 0, minZ);
  103. Vector3 hitPntUR = new Vector3(maxX, 0, maxZ);
  104. //Debug.Log(hitPntLL + " - " + hitPntUR);
  105. var llLatLong = _map.WorldToGeoPosition(hitPntLL);
  106. var urLatLong = _map.WorldToGeoPosition(hitPntUR);
  107. Vector2dBounds tileBounds = new Vector2dBounds(Conversions.LatLonToMeters(llLatLong), Conversions.LatLonToMeters(urLatLong));
  108. // Bounds debugging.
  109. Debug.DrawLine(_cbtpOptions.camera.transform.position, hitPntLL, Color.blue);
  110. Debug.DrawLine(_cbtpOptions.camera.transform.position, hitPntUR, Color.red);
  111. return tileBounds;
  112. }
  113. private Vector3 getGroundPlaneHitPoint(Ray ray)
  114. {
  115. float distance;
  116. if (!_groundPlane.Raycast(ray, out distance)) { return Vector3.zero; }
  117. return ray.GetPoint(distance);
  118. }
  119. }
  120. }