using System.Collections.Generic; using UnityEngine; using Mapbox.Unity.MeshGeneration.Data; using Mapbox.Unity.Map; using Mapbox.Utils; using Mapbox.Unity.Utilities; namespace Mapbox.Unity.MeshGeneration.Factories.TerrainStrategies { public class FlatSphereTerrainStrategy : TerrainStrategy { public float Radius { get { return _elevationOptions.modificationOptions.earthRadius; } } public override int RequiredVertexCount { get { return _elevationOptions.modificationOptions.sampleCount * _elevationOptions.modificationOptions.sampleCount; } } public override void Initialize(ElevationLayerProperties elOptions) { _elevationOptions = elOptions; } public override void RegisterTile(UnityTile tile) { if (_elevationOptions.unityLayerOptions.addToLayer && tile.gameObject.layer != _elevationOptions.unityLayerOptions.layerId) { tile.gameObject.layer = _elevationOptions.unityLayerOptions.layerId; } if ((int)tile.ElevationType != (int)ElevationLayerType.GlobeTerrain || tile.MeshFilter.sharedMesh.vertexCount != RequiredVertexCount) { tile.MeshFilter.sharedMesh.Clear(); tile.ElevationType = TileTerrainType.Globe; } GenerateTerrainMesh(tile); } void GenerateTerrainMesh(UnityTile tile) { var verts = new List(); var _sampleCount = _elevationOptions.modificationOptions.sampleCount; var _radius = _elevationOptions.modificationOptions.earthRadius; for (float x = 0; x < _sampleCount; x++) { for (float y = 0; y < _sampleCount; y++) { var xx = Mathf.Lerp((float)tile.Rect.Min.x, ((float)tile.Rect.Min.x + (float)tile.Rect.Size.x), x / (_sampleCount - 1)); var yy = Mathf.Lerp((float)tile.Rect.Max.y, ((float)tile.Rect.Max.y + (float)tile.Rect.Size.y), y / (_sampleCount - 1)); var ll = Conversions.MetersToLatLon(new Vector2d(xx, yy)); var latitude = (float)(Mathf.Deg2Rad * ll.x); var longitude = (float)(Mathf.Deg2Rad * ll.y); float xPos = (_radius) * Mathf.Cos(latitude) * Mathf.Cos(longitude); float zPos = (_radius) * Mathf.Cos(latitude) * Mathf.Sin(longitude); float yPos = (_radius) * Mathf.Sin(latitude); var pp = new Vector3(xPos, yPos, zPos); verts.Add(pp); } } var trilist = new List(); for (int y = 0; y < _sampleCount - 1; y++) { for (int x = 0; x < _sampleCount - 1; x++) { trilist.Add((y * _sampleCount) + x); trilist.Add((y * _sampleCount) + x + _sampleCount + 1); trilist.Add((y * _sampleCount) + x + _sampleCount); trilist.Add((y * _sampleCount) + x); trilist.Add((y * _sampleCount) + x + 1); trilist.Add((y * _sampleCount) + x + _sampleCount + 1); } } var uvlist = new List(); var step = 1f / (_sampleCount - 1); for (int i = 0; i < _sampleCount; i++) { for (int j = 0; j < _sampleCount; j++) { uvlist.Add(new Vector2(i * step, (j * step))); } } tile.MeshFilter.sharedMesh.SetVertices(verts); tile.MeshFilter.sharedMesh.SetTriangles(trilist, 0); tile.MeshFilter.sharedMesh.SetUVs(0, uvlist); tile.MeshFilter.sharedMesh.RecalculateBounds(); tile.MeshFilter.sharedMesh.RecalculateNormals(); tile.transform.localPosition = Mapbox.Unity.Constants.Math.Vector3Zero; } public override void UnregisterTile(UnityTile tile) { } } }