diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/FactoryEditor.cs b/sdkproject/Assets/Mapbox/Core/Unity/Editor/FactoryEditor.cs new file mode 100644 index 000000000..6a8164105 --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/FactoryEditor.cs @@ -0,0 +1,12 @@ +using UnityEngine; +using System.Collections; +using UnityEditor; +using Mapbox.Unity.MeshGeneration.Factories; + +[CustomEditor(typeof(Factory))] +public class FactoryEditor : Editor +{ + public override void OnInspectorGUI() + { + } +} diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/FactoryEditor.cs.meta b/sdkproject/Assets/Mapbox/Core/Unity/Editor/FactoryEditor.cs.meta new file mode 100644 index 000000000..7333a382c --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/FactoryEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a71b284f467d4de4584d5f813a75c7c0 +timeCreated: 1490923136 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/MapImageFactoryEditor.cs b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MapImageFactoryEditor.cs new file mode 100644 index 000000000..027a25406 --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MapImageFactoryEditor.cs @@ -0,0 +1,100 @@ +using UnityEngine; +using System.Collections; +using UnityEditor; +using Mapbox.Unity.MeshGeneration.Factories; + +[CustomEditor(typeof(MapImageFactory))] +public class MapImageFactoryEditor : FactoryEditor +{ + private MapImageFactory _factory; + public SerializedProperty + mapIdType_Prop, + material_Prop, + basicMaps_Prop, + customMapId_Prop, + mapId_Prop; + private MonoScript script; + + private string[] _basicMapIds = new string[6] { + "mapbox://styles/mapbox/streets-v10", + "mapbox://styles/mapbox/outdoors-v10", + "mapbox://styles/mapbox/dark-v9", + "mapbox://styles/mapbox/light-v9", + "mapbox://styles/mapbox/satellite-v9", + "mapbox://styles/mapbox/satellite-streets-v10"}; + + private string[] _basicMapNames = new string[6] { + "Streets", + "Outdoors", + "Dark", + "Light", + "Satellite", + "Satellite Street"}; + + private int _choiceIndex = 0; + void OnEnable() + { + _factory = target as MapImageFactory; + customMapId_Prop = serializedObject.FindProperty("_customMapId"); + mapIdType_Prop = serializedObject.FindProperty("_mapIdType"); + mapId_Prop = serializedObject.FindProperty("_mapId"); + material_Prop = serializedObject.FindProperty("_baseMaterial"); + basicMaps_Prop = serializedObject.FindProperty("_basicMapIds"); + + script = MonoScript.FromScriptableObject((MapImageFactory)target); + for (int i = 0; i < _basicMapIds.Length; i++) + { + if (_basicMapIds[i] == mapId_Prop.stringValue) + { + _choiceIndex = i; + break; + } + } + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + GUI.enabled = false; + script = EditorGUILayout.ObjectField("Script", script, typeof(MonoScript), false) as MonoScript; + GUI.enabled = true; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(mapIdType_Prop, new GUIContent("Map Type")); + EditorGUILayout.Space(); + var st = (MapImageType)mapIdType_Prop.enumValueIndex; + EditorGUI.indentLevel++; + + switch (st) + { + case MapImageType.BasicMapboxStyle: + { + _choiceIndex = EditorGUILayout.Popup("Style", _choiceIndex, _basicMapNames); + mapId_Prop.stringValue = _basicMapIds[_choiceIndex]; + GUI.enabled = false; + EditorGUILayout.PropertyField(mapId_Prop, new GUIContent("Map Id")); + GUI.enabled = true; + EditorGUILayout.PropertyField(material_Prop, new GUIContent("Material")); + break; + } + case MapImageType.Custom: + { + EditorGUILayout.PropertyField(customMapId_Prop, new GUIContent("Map Id")); + mapId_Prop.stringValue = customMapId_Prop.stringValue; + EditorGUILayout.PropertyField(material_Prop, new GUIContent("Material")); + break; + } + case MapImageType.None: + break; + + } + EditorGUI.indentLevel--; + + if (GUILayout.Button("Update")) + { + _factory.Update(); + } + serializedObject.ApplyModifiedProperties(); + } +} diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/MapImageFactoryEditor.cs.meta b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MapImageFactoryEditor.cs.meta new file mode 100644 index 000000000..f3a661ede --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MapImageFactoryEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 26b414693cf1ad341bd50344ab4198f8 +timeCreated: 1490923136 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/MeshFactoryEditor.cs b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MeshFactoryEditor.cs new file mode 100644 index 000000000..92d13d901 --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MeshFactoryEditor.cs @@ -0,0 +1,59 @@ +using UnityEngine; +using System.Collections; +using UnityEditor; +using Mapbox.Unity.MeshGeneration.Factories; +using Mapbox.Unity.MeshGeneration.Interfaces; + +[CustomEditor(typeof(MeshFactory))] +public class MeshFactoryEditor : FactoryEditor +{ + private MonoScript script; + private MeshFactory _factory; + SerializedProperty _visualizerList; + private int ListSize; + void OnEnable() + { + _factory = target as MeshFactory; + _visualizerList = serializedObject.FindProperty("Visualizers"); + script = MonoScript.FromScriptableObject(_factory); + } + public override void OnInspectorGUI() + { + serializedObject.Update(); + + GUI.enabled = false; + script = EditorGUILayout.ObjectField("Script", script, typeof(MonoScript), false) as MonoScript; + GUI.enabled = true; + + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Layer Visualizers"); + + EditorGUILayout.Space(); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Key"); + EditorGUILayout.LabelField("Visualizers"); + EditorGUILayout.EndHorizontal(); + for (int i = 0; i < _factory.Visualizers.Count; i++) + { + EditorGUILayout.BeginHorizontal(); + if(_factory.Visualizers[i] != null) + _factory.Visualizers[i].Key = EditorGUILayout.TextField(_factory.Visualizers[i].Key, GUILayout.MaxWidth(100)); + _factory.Visualizers[i] = (LayerVisualizerBase)EditorGUILayout.ObjectField(_factory.Visualizers[i], typeof(LayerVisualizerBase)); + + if (GUILayout.Button("-", GUILayout.MaxWidth(20))) + { + _visualizerList.DeleteArrayElementAtIndex(i); + } + + EditorGUILayout.EndHorizontal(); + } + + if (GUILayout.Button("Add New Visualizer")) + { + _factory.Visualizers.Add(null); + } + + serializedObject.ApplyModifiedProperties(); + } +} diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/MeshFactoryEditor.cs.meta b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MeshFactoryEditor.cs.meta new file mode 100644 index 000000000..e8cd3ea12 --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/MeshFactoryEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e4de6b3d7ad9fbb4797cb1e85dcbb9e9 +timeCreated: 1490923136 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/TerrainFactoryEditor.cs b/sdkproject/Assets/Mapbox/Core/Unity/Editor/TerrainFactoryEditor.cs new file mode 100644 index 000000000..988ed45a6 --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/TerrainFactoryEditor.cs @@ -0,0 +1,108 @@ +using UnityEngine; +using System.Collections; +using UnityEditor; +using Mapbox.Unity.MeshGeneration.Factories; + +[CustomEditor(typeof(TerrainFactory))] +public class TerrainFactoryEditor : FactoryEditor +{ + private string _defaultMapId = "mapbox.terrain-rgb"; + private TerrainFactory _factory; + public SerializedProperty + state_Prop, + sampleCount_Prop, + mapIdType_Prop, + heightMod_Prop, + customMapId_Prop, + material_Prop, + mapId_Prop; + private MonoScript script; + + void OnEnable() + { + _factory = target as TerrainFactory; + state_Prop = serializedObject.FindProperty("_generationType"); + mapIdType_Prop = serializedObject.FindProperty("_mapIdType"); + sampleCount_Prop = serializedObject.FindProperty("_sampleCount"); + heightMod_Prop = serializedObject.FindProperty("_heightModifier"); + mapId_Prop = serializedObject.FindProperty("_mapId"); + material_Prop = serializedObject.FindProperty("_baseMaterial"); + + customMapId_Prop = serializedObject.FindProperty("_customMapId"); + + script = MonoScript.FromScriptableObject((TerrainFactory)target); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + GUI.enabled = false; + script = EditorGUILayout.ObjectField("Script", script, typeof(MonoScript), false) as MonoScript; + GUI.enabled = true; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(state_Prop, new GUIContent("Map Type")); + EditorGUILayout.Space(); + var st = (TerrainGenerationType)state_Prop.enumValueIndex; + EditorGUI.indentLevel++; + switch (st) + { + case TerrainGenerationType.Flat: + + break; + + case TerrainGenerationType.Height: + { + EditorGUILayout.PropertyField(mapIdType_Prop); + switch ((MapIdType)mapIdType_Prop.enumValueIndex) + { + case MapIdType.StandardHeight: + GUI.enabled = false; + EditorGUILayout.PropertyField(mapId_Prop, new GUIContent("Map Id")); + mapId_Prop.stringValue = _defaultMapId; + GUI.enabled = true; + break; + case MapIdType.Custom: + EditorGUILayout.PropertyField(customMapId_Prop, new GUIContent("Map Id")); + mapId_Prop.stringValue = customMapId_Prop.stringValue; + break; + } + break; + } + case TerrainGenerationType.ModifiedHeight: + EditorGUILayout.PropertyField(mapIdType_Prop); + switch ((MapIdType)mapIdType_Prop.enumValueIndex) + { + case MapIdType.StandardHeight: + GUI.enabled = false; + EditorGUILayout.PropertyField(mapId_Prop, new GUIContent("Map Id")); + mapId_Prop.stringValue = _defaultMapId; + GUI.enabled = true; + break; + case MapIdType.Custom: + EditorGUILayout.PropertyField(customMapId_Prop, new GUIContent("Map Id")); + mapId_Prop.stringValue = customMapId_Prop.stringValue; + break; + } + EditorGUILayout.PropertyField(heightMod_Prop, new GUIContent("Height Multiplier")); + break; + + } + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(sampleCount_Prop, new GUIContent("Resolution")); + EditorGUILayout.LabelField("x " + sampleCount_Prop.intValue); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.PropertyField(material_Prop, new GUIContent("Material")); + + if (GUILayout.Button("Update")) + { + _factory.Update(); + } + + serializedObject.ApplyModifiedProperties(); + } +} diff --git a/sdkproject/Assets/Mapbox/Core/Unity/Editor/TerrainFactoryEditor.cs.meta b/sdkproject/Assets/Mapbox/Core/Unity/Editor/TerrainFactoryEditor.cs.meta new file mode 100644 index 000000000..6b8effe09 --- /dev/null +++ b/sdkproject/Assets/Mapbox/Core/Unity/Editor/TerrainFactoryEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f20150ceca635c44dab37cfe0460aa36 +timeCreated: 1490923136 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/MeshData.cs b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/MeshData.cs index e274c7517..4e2ec6b53 100644 --- a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/MeshData.cs +++ b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/MeshData.cs @@ -8,13 +8,15 @@ public class MeshData { public Vector2 MercatorCenter { get; set; } public RectD TileRect { get; set; } - public List Vertices { get; set; } + public List Vertices { get; set; } + public List Normals { get; set; } public List> Triangles { get; set; } public List> UV { get; set; } public MeshData() { Vertices = new List(); + Normals = new List(); Triangles = new List>(); UV = new List>(); UV.Add(new List()); diff --git a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/UnityTile.cs b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/UnityTile.cs index 56b085688..7aa6dcc12 100644 --- a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/UnityTile.cs +++ b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Data/UnityTile.cs @@ -10,6 +10,31 @@ namespace Mapbox.Unity.MeshGeneration.Data [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))] public class UnityTile : MonoBehaviour, INotifyPropertyChanged { + private MeshRenderer _meshRenderer; + public MeshRenderer MeshRenderer + { + get + { + if (_meshRenderer == null) + _meshRenderer = GetComponent(); + return _meshRenderer; + } + + } + + private MeshFilter _meshFilter; + public MeshFilter MeshFilter + { + get + { + if (_meshFilter == null) + _meshFilter = GetComponent(); + return _meshFilter; + } + } + + public MeshData MeshData { get; set; } + #region basic properties //move to a base class? [SerializeField] private Texture2D _heightData; @@ -73,7 +98,7 @@ public float QueryHeightData(float x, float y) public delegate void TileEventArgs(UnityTile sender, object param); public event TileEventArgs HeightDataChanged; - public event TileEventArgs SatelliteDataChanged; + public event TileEventArgs ImageDataChanged; public event TileEventArgs VectorDataChanged; [NotifyPropertyChangedInvocator] @@ -93,7 +118,7 @@ protected virtual void OnHeightDataChanged() [NotifyPropertyChangedInvocator] protected virtual void OnSatelliteDataChanged() { - var handler = SatelliteDataChanged; + var handler = ImageDataChanged; if (handler != null) handler(this, null); } diff --git a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/Factory.cs b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/Factory.cs index f2334709a..91b2499a0 100644 --- a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/Factory.cs +++ b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/Factory.cs @@ -17,5 +17,10 @@ public virtual void Register(UnityTile tile) { } + + public virtual void Update() + { + + } } } diff --git a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MapImageFactory.cs b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MapImageFactory.cs index c17596a32..71cb034b5 100644 --- a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MapImageFactory.cs +++ b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MapImageFactory.cs @@ -8,15 +8,24 @@ namespace Mapbox.Unity.MeshGeneration.Factories using Mapbox.Unity.MeshGeneration.Data; using Mapbox.Platform; + public enum MapImageType + { + BasicMapboxStyle, + Custom, + None + } + [CreateAssetMenu(menuName = "Mapbox/Factories/Map Image Factory")] public class MapImageFactory : Factory { [SerializeField] - public string _mapId; + private MapImageType _mapIdType; [SerializeField] - public Material _baseMaterial; + private string _customMapId = ""; + [SerializeField] + private string _mapId = ""; [SerializeField] - private bool _createImagery = true; + public Material _baseMaterial; private Dictionary _tiles; @@ -33,6 +42,15 @@ public override void Register(UnityTile tile) Run(tile); } + public override void Update() + { + base.Update(); + foreach (var tile in _tiles.Values) + { + Run(tile); + } + } + private void Run(UnityTile tile) { if (!string.IsNullOrEmpty(_mapId)) diff --git a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MeshFactory.cs b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MeshFactory.cs index f50a83a62..39b1897f9 100644 --- a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MeshFactory.cs +++ b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/MeshFactory.cs @@ -47,17 +47,8 @@ private void Run(UnityTile tile) if (tile.HeightDataState == TilePropertyState.Loading || tile.ImageDataState == TilePropertyState.Loading) { - tile.HeightDataChanged += (t, e) => - { - if (tile.ImageDataState != TilePropertyState.Loading) - CreateMeshes(t, e); - }; - - tile.SatelliteDataChanged += (t, e) => - { - if (tile.HeightDataState != TilePropertyState.Loading) - CreateMeshes(t, e); - }; + tile.HeightDataChanged += HeightDataChangedHandler; + tile.ImageDataChanged += ImageDataChangedHandler; } else { @@ -65,8 +56,23 @@ private void Run(UnityTile tile) } } + private void HeightDataChangedHandler(UnityTile t, object e) + { + if (t.ImageDataState != TilePropertyState.Loading) + CreateMeshes(t, e); + } + + private void ImageDataChangedHandler(UnityTile t, object e) + { + if (t.HeightDataState != TilePropertyState.Loading) + CreateMeshes(t, e); + } + private void CreateMeshes(UnityTile tile, object e) { + tile.HeightDataChanged -= HeightDataChangedHandler; + tile.ImageDataChanged -= ImageDataChangedHandler; + var parameters = new Mapbox.Map.Tile.Parameters { Fs = this.FileSource, diff --git a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/TerrainFactory.cs b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/TerrainFactory.cs index 8d49919f4..569b3b893 100644 --- a/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/TerrainFactory.cs +++ b/sdkproject/Assets/Mapbox/Core/Unity/MeshGeneration/Factories/TerrainFactory.cs @@ -9,21 +9,40 @@ namespace Mapbox.Unity.MeshGeneration.Factories using Mapbox.Unity.Utilities; using Utils; + public enum TerrainGenerationType + { + Flat, + Height, + ModifiedHeight + } + + public enum MapIdType + { + StandardHeight, + Custom + } + [CreateAssetMenu(menuName = "Mapbox/Factories/Terrain Factory")] public class TerrainFactory : Factory { [SerializeField] - private bool _createFlatBase = false; + private TerrainGenerationType _generationType; [SerializeField] - private Material _flatTileMaterial; + private Material _baseMaterial; + + [SerializeField] + private MapIdType _mapIdType; + [SerializeField] + private string _customMapId = "mapbox.terrain-rgb"; [SerializeField] - private bool _createRealTerrain = true; + private string _mapId = ""; [SerializeField] - private string _mapId; + private float _heightModifier = 1f; + [SerializeField] + private int _sampleCount = 40; private Dictionary _tiles; - [SerializeField] - private int sampleCount = 40; + private Vector2 _stitchTarget; public override void Initialize(IFileSource fs) { @@ -34,212 +53,322 @@ public override void Initialize(IFileSource fs) public override void Register(UnityTile tile) { base.Register(tile); - if (_createRealTerrain) + _tiles.Add(tile.TileCoordinate, tile); + Run(tile); + } + + public override void Update() + { + base.Update(); + foreach (var tile in _tiles.Values) { - _tiles.Add(tile.TileCoordinate, tile); - Run(tile); + tile.MeshData = null; } - else + foreach (var tile in _tiles.Values) { - if (_createFlatBase) - { - CreateTileBase(tile); - } + Run(tile); } } private void Run(UnityTile tile) { - var parameters = new Tile.Parameters + if (_generationType == TerrainGenerationType.Height) { - Fs = this.FileSource, - Id = new CanonicalTileId(tile.Zoom, (int)tile.TileCoordinate.x, (int)tile.TileCoordinate.y), - MapId = _mapId - }; - - tile.HeightDataState = TilePropertyState.Loading; - var pngRasterTile = new RawPngRasterTile(); + CreateTerrainHeight(tile); + } + else if (_generationType == TerrainGenerationType.ModifiedHeight) + { + CreateTerrainHeight(tile, _heightModifier); + } + else if (_generationType == TerrainGenerationType.Flat) + { + CreateFlatMesh(tile); + } + } - pngRasterTile.Initialize(parameters, () => + private void CreateTerrainHeight(UnityTile tile, float heightMultiplier = 1) + { + if (tile.HeightData == null) { - if (pngRasterTile.Error != null) + var parameters = new Tile.Parameters { - tile.HeightDataState = TilePropertyState.Error; - return; - } - - var texture = new Texture2D(256, 256); - texture.wrapMode = TextureWrapMode.Clamp; - texture.LoadImage(pngRasterTile.Data); - CreateTerrain(tile, texture); + Fs = this.FileSource, + Id = new CanonicalTileId(tile.Zoom, (int)tile.TileCoordinate.x, (int)tile.TileCoordinate.y), + MapId = _mapId + }; - tile.HeightData = texture; - tile.HeightDataState = TilePropertyState.Loaded; - - FixStitches(tile); - }); + tile.HeightDataState = TilePropertyState.Loading; + var pngRasterTile = new RawPngRasterTile(); + pngRasterTile.Initialize(parameters, () => + { + if (pngRasterTile.Error != null) + { + tile.HeightDataState = TilePropertyState.Error; + return; + } + var texture = new Texture2D(256, 256); + texture.wrapMode = TextureWrapMode.Clamp; + texture.LoadImage(pngRasterTile.Data); + tile.HeightData = texture; + tile.HeightDataState = TilePropertyState.Loaded; + GenerateTerrainMesh(tile, heightMultiplier); + }); + } + else + { + GenerateTerrainMesh(tile, heightMultiplier); + } } - private void CreateTerrain(UnityTile tile, Texture2D texture) + private void GenerateTerrainMesh(UnityTile tile, float heightMultiplier) { var go = tile.gameObject; - var mesh = new Mesh(); - var verts = new List(sampleCount* sampleCount); - - for (float x = 0; x < sampleCount; x++) + var mesh = new MeshData(); + mesh.Vertices = new List(_sampleCount * _sampleCount); + mesh.Normals = new List(_sampleCount * _sampleCount); + var step = 1f / (_sampleCount - 1); + for (float y = 0; y < _sampleCount; y++) { - for (float y = 0; y < sampleCount; y++) + var yrat = y / (_sampleCount - 1); + for (float x = 0; x < _sampleCount; x++) { - var xx = Mathd.Lerp(tile.Rect.Min.x, tile.Rect.Max.x, - x / (sampleCount - 1)); - var yy = Mathd.Lerp(tile.Rect.Min.y, tile.Rect.Max.y, - y / (sampleCount - 1)); + var xrat = x / (_sampleCount - 1); + + var xx = Mathd.Lerp(tile.Rect.Min.x, tile.Rect.Max.x, xrat); + var yy = Mathd.Lerp(tile.Rect.Min.y, tile.Rect.Max.y, yrat); - verts.Add(new Vector3( + mesh.Vertices.Add(new Vector3( (float)(xx - tile.Rect.Center.x), - Conversions.GetRelativeHeightFromColor(texture.GetPixel((int)Mathf.Clamp((x / (sampleCount - 1) * 256), 0, 255), - (int)Mathf.Clamp((256 - (y / (sampleCount - 1) * 256)), 0, 255)), tile.RelativeScale), + heightMultiplier * Conversions.GetRelativeHeightFromColor(tile.HeightData.GetPixel( + (int)(xrat * 255), + (int)((1 - yrat) * 255)), + tile.RelativeScale), (float)(yy - tile.Rect.Center.y))); + mesh.Normals.Add(Vector3.up); + mesh.UV[0].Add(new Vector2(x * step, 1 - (y * step))); } } - mesh.SetVertices(verts); - //we can read these from a hardcoded dictionary as well //no need to calculate this every single time unless we need a really high range for sampleCount - var trilist = new List(sampleCount * sampleCount * 3); - for (int y = 0; y < sampleCount - 1; y++) + var trilist = new List(); + var dir = Vector3.zero; + int vertA, vertB, vertC; + for (int y = 0; y < _sampleCount - 1; y++) { - for (int x = 0; x < sampleCount - 1; x++) + for (int x = 0; x < _sampleCount - 1; x++) { - trilist.Add((y * sampleCount) + x); - trilist.Add((y * sampleCount) + x + sampleCount); - trilist.Add((y * sampleCount) + x + sampleCount + 1); + vertA = (y * _sampleCount) + x; + vertB = (y * _sampleCount) + x + _sampleCount + 1; + vertC = (y * _sampleCount) + x + _sampleCount; + trilist.Add(vertA); + trilist.Add(vertB); + trilist.Add(vertC); + dir = Vector3.Cross(mesh.Vertices[vertB] - mesh.Vertices[vertA], mesh.Vertices[vertC] - mesh.Vertices[vertA]); + mesh.Normals[vertA] += dir; + mesh.Normals[vertB] += dir; + mesh.Normals[vertC] += dir; - trilist.Add((y * sampleCount) + x); - trilist.Add((y * sampleCount) + x + sampleCount + 1); - trilist.Add((y * sampleCount) + x + 1); + vertA = (y * _sampleCount) + x; + vertB = (y * _sampleCount) + x + 1; + vertC = (y * _sampleCount) + x + _sampleCount + 1; + trilist.Add(vertA); + trilist.Add(vertB); + trilist.Add(vertC); + dir = Vector3.Cross(mesh.Vertices[vertB] - mesh.Vertices[vertA], mesh.Vertices[vertC] - mesh.Vertices[vertA]); + mesh.Normals[vertA] += dir; + mesh.Normals[vertB] += dir; + mesh.Normals[vertC] += dir; } } - mesh.SetTriangles(trilist, 0); + mesh.Triangles.Add(trilist); - var uvlist = new List(sampleCount * sampleCount); - var step = 1f / (sampleCount - 1); - for (int i = 0; i < sampleCount; i++) + for (int i = 0; i < mesh.Vertices.Count; i++) { - for (int j = 0; j < sampleCount; j++) - { - uvlist.Add(new Vector2(i * step, 1 - (j * step))); - } + mesh.Normals[i].Normalize(); } - mesh.SetUVs(0, uvlist); + + FixStitches(tile, mesh); + + tile.MeshData = mesh; + var uMesh = new Mesh(); + uMesh.SetVertices(mesh.Vertices); + uMesh.SetUVs(0, mesh.UV[0]); + uMesh.SetNormals(mesh.Normals); + uMesh.SetTriangles(mesh.Triangles[0], 0); + tile.MeshFilter.sharedMesh = uMesh; + + if (tile.MeshRenderer.material == null) + tile.MeshRenderer.material = _baseMaterial; + //BRNKHY Optional stuff + //go.AddComponent(); + //go.layer = LayerMask.NameToLayer("terrain"); + } + + private void CreateFlatMesh(UnityTile tile) + { + var mesh = new Mesh(); + var verts = new Vector3[4]; + + verts[0] = ((tile.Rect.Min - tile.Rect.Center).ToVector3xz()); + verts[2] = (new Vector3((float)(tile.Rect.Min.x - tile.Rect.Center.x), 0, (float)(tile.Rect.Max.y - tile.Rect.Center.y))); + verts[1] = (new Vector3((float)(tile.Rect.Max.x - tile.Rect.Center.x), 0, (float)(tile.Rect.Min.y - tile.Rect.Center.y))); + verts[3] = ((tile.Rect.Max - tile.Rect.Center).ToVector3xz()); + + mesh.vertices = verts; + var trilist = new int[6] { 0, 1, 2, 1, 3, 2 }; + mesh.SetTriangles(trilist, 0); + var uvlist = new Vector2[4] + { + new Vector2(0,1), + new Vector2(1,1), + new Vector2(0,0), + new Vector2(1,0) + }; + mesh.uv = uvlist; mesh.RecalculateNormals(); - go.GetComponent().sharedMesh = mesh; - + tile.MeshFilter.sharedMesh = mesh; + if (tile.MeshRenderer.material == null) + tile.MeshRenderer.material = _baseMaterial; + + //BRNKHY Optional stuff //go.AddComponent(); //go.layer = LayerMask.NameToLayer("terrain"); } - //BRNKHY there has to be a better way to do this - private void FixStitches(UnityTile tile) + private void FixStitches(UnityTile tile, MeshData tmesh) { - var tmesh = tile.GetComponent().mesh; - var left = new Vector2(tile.TileCoordinate.x - 1, tile.TileCoordinate.y); - if (_tiles.ContainsKey(left) && _tiles[left].HeightData != null) + _stitchTarget.Set(tile.TileCoordinate.x, tile.TileCoordinate.y - 1); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) { - var t2mesh = _tiles[left].GetComponent().mesh; + var t2mesh = _tiles[_stitchTarget].MeshData; - var verts = tmesh.vertices; - for (int i = 0; i < sampleCount; i++) + for (int i = 0; i < _sampleCount; i++) { - verts[i].Set(verts[i].x, t2mesh.vertices[verts.Length - sampleCount + i].y, verts[i].z); + //just snapping the y because vertex pos is relative and we'll have to do tile pos + vertex pos for x&z otherwise + tmesh.Vertices[i] = new Vector3( + tmesh.Vertices[i].x, + t2mesh.Vertices[tmesh.Vertices.Count - _sampleCount + i].y, + tmesh.Vertices[i].z); + tmesh.Normals[i] = new Vector3(t2mesh.Normals[tmesh.Vertices.Count - _sampleCount + i].x, + t2mesh.Normals[tmesh.Vertices.Count - _sampleCount + i].y, + t2mesh.Normals[tmesh.Vertices.Count - _sampleCount + i].z); } - tmesh.vertices = verts; } - var right = new Vector2(tile.TileCoordinate.x + 1, tile.TileCoordinate.y); - if (_tiles.ContainsKey(right) && _tiles[right].HeightData != null) + _stitchTarget.Set(tile.TileCoordinate.x, tile.TileCoordinate.y + 1); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) { - var t2mesh = _tiles[right].GetComponent().mesh; - - var verts = tmesh.vertices; - for (int i = 0; i < sampleCount; i++) + var t2mesh = _tiles[_stitchTarget].MeshData; + for (int i = 0; i < _sampleCount; i++) { - verts[verts.Length - sampleCount + i].Set(verts[verts.Length - sampleCount + i].x, t2mesh.vertices[i].y, - verts[verts.Length - sampleCount + i].z); + tmesh.Vertices[tmesh.Vertices.Count - _sampleCount + i] = new Vector3( + tmesh.Vertices[tmesh.Vertices.Count - _sampleCount + i].x, + t2mesh.Vertices[i].y, + tmesh.Vertices[tmesh.Vertices.Count - _sampleCount + i].z); + + tmesh.Normals[tmesh.Vertices.Count - _sampleCount + i] = new Vector3( + t2mesh.Normals[i].x, + t2mesh.Normals[i].y, + t2mesh.Normals[i].z); } - tmesh.vertices = verts; } - var up = new Vector2(tile.TileCoordinate.x, tile.TileCoordinate.y - 1); - if (_tiles.ContainsKey(up) && _tiles[up].HeightData != null) + _stitchTarget.Set(tile.TileCoordinate.x - 1, tile.TileCoordinate.y); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) { - var t2mesh = _tiles[up].GetComponent().mesh; - var verts = tmesh.vertices; - for (int i = 0; i < sampleCount; i++) + var t2mesh = _tiles[_stitchTarget].MeshData; + for (int i = 0; i < _sampleCount; i++) { - verts[i * sampleCount].Set(verts[i * sampleCount].x, t2mesh.vertices[i * sampleCount + sampleCount - 1].y, - verts[i * sampleCount].z); + tmesh.Vertices[i * _sampleCount] = new Vector3( + tmesh.Vertices[i * _sampleCount].x, + t2mesh.Vertices[i * _sampleCount + _sampleCount - 1].y, + tmesh.Vertices[i * _sampleCount].z); + tmesh.Normals[i * _sampleCount] = new Vector3( + t2mesh.Normals[i * _sampleCount + _sampleCount - 1].x, + t2mesh.Normals[i * _sampleCount + _sampleCount - 1].y, + t2mesh.Normals[i * _sampleCount + _sampleCount - 1].z); } - tmesh.vertices = verts; } - var down = new Vector2(tile.TileCoordinate.x, tile.TileCoordinate.y + 1); - if (_tiles.ContainsKey(down) && _tiles[down].HeightData != null) + _stitchTarget.Set(tile.TileCoordinate.x + 1, tile.TileCoordinate.y); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) { - var t2mesh = _tiles[down].GetComponent().mesh; - - var verts = tmesh.vertices; - for (int i = 0; i < sampleCount; i++) + var t2mesh = _tiles[_stitchTarget].MeshData; + for (int i = 0; i < _sampleCount; i++) { - verts[i * sampleCount + sampleCount - 1].Set(verts[i * sampleCount + sampleCount - 1].x, t2mesh.vertices[i * sampleCount].y, - verts[i * sampleCount + sampleCount - 1].z); + tmesh.Vertices[i * _sampleCount + _sampleCount - 1] = new Vector3( + tmesh.Vertices[i * _sampleCount + _sampleCount - 1].x, + t2mesh.Vertices[i * _sampleCount].y, + tmesh.Vertices[i * _sampleCount + _sampleCount - 1].z); + tmesh.Normals[i * _sampleCount + _sampleCount - 1] = new Vector3( + t2mesh.Normals[i * _sampleCount].x, + t2mesh.Normals[i * _sampleCount].y, + t2mesh.Normals[i * _sampleCount].z); } - tmesh.vertices = verts; } - tmesh.RecalculateNormals(); - } + _stitchTarget.Set(tile.TileCoordinate.x - 1, tile.TileCoordinate.y - 1); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) + { + var t2mesh = _tiles[_stitchTarget].MeshData; + tmesh.Vertices[0] = new Vector3( + tmesh.Vertices[0].x, + t2mesh.Vertices[t2mesh.Vertices.Count - 1].y, + tmesh.Vertices[0].z); + tmesh.Normals[0] = new Vector3( + t2mesh.Normals[t2mesh.Vertices.Count - 1].x, + t2mesh.Normals[t2mesh.Vertices.Count - 1].y, + t2mesh.Normals[t2mesh.Vertices.Count - 1].z); + } - private void CreateTileBase(UnityTile tile) - { - var mesh = new Mesh(); - var verts = new List(); - - verts.Add((tile.Rect.Min - tile.Rect.Center).ToVector3xz()); - verts.Add( - new Vector3( - (float)(tile.Rect.Max.x - tile.Rect.Center.x), - 0, - (float)(tile.Rect.Min.y - tile.Rect.Center.y))); - verts.Add( - new Vector3( - (float)(tile.Rect.Min.x - tile.Rect.Center.x), - 0, - (float)(tile.Rect.Max.y - tile.Rect.Center.y))); - verts.Add((tile.Rect.Max - tile.Rect.Center).ToVector3xz()); - - mesh.SetVertices(verts); - var trilist = new List() { 0, 1, 2, 1, 3, 2 }; - mesh.SetTriangles(trilist, 0); - var uvlist = new List() + _stitchTarget.Set(tile.TileCoordinate.x + 1, tile.TileCoordinate.y - 1); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) { - new Vector2(0,1), - new Vector2(1,1), - new Vector2(0,0), - new Vector2(1,0) - }; - mesh.SetUVs(0, uvlist); - mesh.RecalculateNormals(); - tile.GetComponent().sharedMesh = mesh; - tile.GetComponent().material = _flatTileMaterial; - tile.gameObject.AddComponent(); + var t2mesh = _tiles[_stitchTarget].MeshData; + tmesh.Vertices[_sampleCount - 1] = new Vector3( + tmesh.Vertices[_sampleCount - 1].x, + t2mesh.Vertices[t2mesh.Vertices.Count - _sampleCount].y, + tmesh.Vertices[_sampleCount - 1].z); + tmesh.Normals[_sampleCount - 1] = new Vector3( + t2mesh.Normals[t2mesh.Vertices.Count - _sampleCount].x, + t2mesh.Normals[t2mesh.Vertices.Count - _sampleCount].y, + t2mesh.Normals[t2mesh.Vertices.Count - _sampleCount].z); + } + + _stitchTarget.Set(tile.TileCoordinate.x - 1, tile.TileCoordinate.y + 1); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) + { + var t2mesh = _tiles[_stitchTarget].MeshData; + tmesh.Vertices[tmesh.Vertices.Count - _sampleCount] = new Vector3( + tmesh.Vertices[tmesh.Vertices.Count - _sampleCount].x, + t2mesh.Vertices[_sampleCount - 1].y, + tmesh.Vertices[tmesh.Vertices.Count - _sampleCount].z); + tmesh.Normals[tmesh.Vertices.Count - _sampleCount] = new Vector3( + t2mesh.Normals[_sampleCount - 1].x, + t2mesh.Normals[_sampleCount - 1].y, + t2mesh.Normals[_sampleCount - 1].z); + } + + _stitchTarget.Set(tile.TileCoordinate.x + 1, tile.TileCoordinate.y + 1); + if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null) + { + var t2mesh = _tiles[_stitchTarget].MeshData; + tmesh.Vertices[t2mesh.Vertices.Count - 1] = new Vector3( + tmesh.Vertices[t2mesh.Vertices.Count - 1].x, + t2mesh.Vertices[0].y, + tmesh.Vertices[t2mesh.Vertices.Count - 1].z); + tmesh.Normals[t2mesh.Vertices.Count - 1] = new Vector3( + t2mesh.Normals[0].x, + t2mesh.Normals[0].y, + t2mesh.Normals[0].z); + } } private float GetHeightFromColor(Color c) { //additional *256 to switch from 0-1 to 0-256 - return (float)(-10000 + ((c.r * 256 * 256 * 256 + c.g * 256 * 256 + c.b * 256) * 0.1)); + return (float)(-10000 + ((c.r * 16777216 + c.g * 65536 + c.b * 256) * 0.1)); } } }