Ejemplo n.º 1
0
 public override void Run(VectorEntity ve, UnityTile tile)
 {
     ve.MeshRenderer.enabled = false;
 }
Ejemplo n.º 2
0
        private void CreateBaseMesh(UnityTile tile)
        {
            //TODO use arrays instead of lists
            _newVertexList.Clear();
            _newNormalList.Clear();
            _newUvList.Clear();
            _newTriangleList.Clear();

            var cap = (_sampleCount - 1);

            for (float y = 0; y < cap; y++)
            {
                for (float x = 0; x < cap; x++)
                {
                    var x1 = tile.TileScale * (float)(Mathd.Lerp(tile.Rect.Min.x, tile.Rect.Max.x, x / cap) - tile.Rect.Center.x);
                    var y1 = tile.TileScale * (float)(Mathd.Lerp(tile.Rect.Min.y, tile.Rect.Max.y, y / cap) - tile.Rect.Center.y);
                    var x2 = tile.TileScale * (float)(Mathd.Lerp(tile.Rect.Min.x, tile.Rect.Max.x, (x + 1) / cap) - tile.Rect.Center.x);
                    var y2 = tile.TileScale * (float)(Mathd.Lerp(tile.Rect.Min.y, tile.Rect.Max.y, (y + 1) / cap) - tile.Rect.Center.y);

                    var triStart = _newVertexList.Count;
                    _newVertexList.Add(new Vector3(x1, 0, y1));
                    _newVertexList.Add(new Vector3(x2, 0, y1));
                    _newVertexList.Add(new Vector3(x1, 0, y2));
                    //--
                    _newVertexList.Add(new Vector3(x2, 0, y1));
                    _newVertexList.Add(new Vector3(x2, 0, y2));
                    _newVertexList.Add(new Vector3(x1, 0, y2));

                    _newNormalList.Add(Unity.Constants.Math.Vector3Up);
                    _newNormalList.Add(Unity.Constants.Math.Vector3Up);
                    _newNormalList.Add(Unity.Constants.Math.Vector3Up);
                    //--
                    _newNormalList.Add(Unity.Constants.Math.Vector3Up);
                    _newNormalList.Add(Unity.Constants.Math.Vector3Up);
                    _newNormalList.Add(Unity.Constants.Math.Vector3Up);


                    _newUvList.Add(new Vector2(x / cap, 1 - y / cap));
                    _newUvList.Add(new Vector2((x + 1) / cap, 1 - y / cap));
                    _newUvList.Add(new Vector2(x / cap, 1 - (y + 1) / cap));
                    //--
                    _newUvList.Add(new Vector2((x + 1) / cap, 1 - y / cap));
                    _newUvList.Add(new Vector2((x + 1) / cap, 1 - (y + 1) / cap));
                    _newUvList.Add(new Vector2(x / cap, 1 - (y + 1) / cap));

                    _newTriangleList.Add(triStart);
                    _newTriangleList.Add(triStart + 1);
                    _newTriangleList.Add(triStart + 2);
                    //--
                    _newTriangleList.Add(triStart + 3);
                    _newTriangleList.Add(triStart + 4);
                    _newTriangleList.Add(triStart + 5);
                }
            }


            var mesh = tile.MeshFilter.mesh;

            mesh.SetVertices(_newVertexList);
            mesh.SetNormals(_newNormalList);
            mesh.SetUVs(0, _newUvList);
            mesh.SetTriangles(_newTriangleList, 0);
            mesh.RecalculateBounds();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates the non-flat terrain mesh, using a grid by defined resolution (_sampleCount). Vertex order goes right & up. Normals are calculated manually and UV map is fitted/stretched 1-1.
        /// Any additional scripts or logic, like MeshCollider or setting layer, can be done here.
        /// </summary>
        /// <param name="tile"></param>
        /// <param name="heightMultiplier">Multiplier for queried height value</param>
        private void GenerateTerrainMesh(UnityTile tile)
        {
            tile.MeshFilter.mesh.GetVertices(_currentTileMeshData.Vertices);
            tile.MeshFilter.mesh.GetNormals(_currentTileMeshData.Normals);

            var cap = (_sampleCount - 1);

            for (float y = 0; y < cap; y++)
            {
                for (float x = 0; x < cap; x++)
                {
                    _currentTileMeshData.Vertices[(int)(y * cap + x) * 6] = new Vector3(
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6].x,
                        tile.QueryHeightData(x / cap, 1 - y / cap),
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6].z);

                    _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 1] = new Vector3(
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 1].x,
                        tile.QueryHeightData((x + 1) / cap, 1 - y / cap),
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 1].z);

                    _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 2] = new Vector3(
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 2].x,
                        tile.QueryHeightData(x / cap, 1 - (y + 1) / cap),
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 2].z);

                    //--

                    _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 3] = new Vector3(
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 3].x,
                        tile.QueryHeightData((x + 1) / cap, 1 - y / cap),
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 3].z);

                    _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 4] = new Vector3(
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 4].x,
                        tile.QueryHeightData((x + 1) / cap, 1 - (y + 1) / cap),
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 4].z);

                    _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 5] = new Vector3(
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 5].x,
                        tile.QueryHeightData(x / cap, 1 - (y + 1) / cap),
                        _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 5].z);



                    _newDir = Vector3.Cross(_currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 1] - _currentTileMeshData.Vertices[(int)(y * cap + x) * 6], _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 2] - _currentTileMeshData.Vertices[(int)(y * cap + x) * 6]);
                    _currentTileMeshData.Normals[(int)(y * cap + x) * 6 + 0] = _newDir;
                    _currentTileMeshData.Normals[(int)(y * cap + x) * 6 + 1] = _newDir;
                    _currentTileMeshData.Normals[(int)(y * cap + x) * 6 + 2] = _newDir;
                    //--
                    _newDir = Vector3.Cross(_currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 4] - _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 3], _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 5] - _currentTileMeshData.Vertices[(int)(y * cap + x) * 6 + 3]);
                    _currentTileMeshData.Normals[(int)(y * cap + x) * 6 + 3] = _newDir;
                    _currentTileMeshData.Normals[(int)(y * cap + x) * 6 + 4] = _newDir;
                    _currentTileMeshData.Normals[(int)(y * cap + x) * 6 + 5] = _newDir;
                }
            }
            FixStitches(tile.UnwrappedTileId, _currentTileMeshData);
            tile.MeshFilter.mesh.SetVertices(_currentTileMeshData.Vertices);
            tile.MeshFilter.mesh.SetNormals(_currentTileMeshData.Normals);
            tile.MeshFilter.mesh.RecalculateBounds();

            if (!_meshData.ContainsKey(tile.UnwrappedTileId))
            {
                _meshData.Add(tile.UnwrappedTileId, tile.MeshFilter.mesh);
            }
        }
Ejemplo n.º 4
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (md.Vertices.Count == 0 || feature == null || feature.Points.Count < 1)
            {
                return;
            }

            _uv.Clear();
            _mdVertexCount = md.Vertices.Count;
            _size          = md.TileRect.Size;

            if (_options.texturingType != UvMapType.Atlas && _options.texturingType != UvMapType.AtlasWithColorPalette)
            {
                for (int i = 0; i < _mdVertexCount; i++)
                {
                    _vert = md.Vertices[i];

                    if (_options.style == StyleTypes.Satellite)
                    {
                        var fromBottomLeft = new Vector2((float)(((_vert.x + md.PositionInTile.x) / tile.TileScale + _size.x / 2) / _size.x),
                                                         (float)(((_vert.z + md.PositionInTile.z) / tile.TileScale + _size.x / 2) / _size.x));
                        _uv.Add(fromBottomLeft);
                    }
                    else if (_options.texturingType == UvMapType.Tiled)
                    {
                        _uv.Add(new Vector2(_vert.x, _vert.z));
                    }
                }
            }
            else if (_options.texturingType == UvMapType.Atlas || _options.texturingType == UvMapType.AtlasWithColorPalette)
            {
                _currentFacade = _options.atlasInfo.Roofs[UnityEngine.Random.Range(0, _options.atlasInfo.Roofs.Count)];

                minx = float.MaxValue;
                miny = float.MaxValue;
                maxx = float.MinValue;
                maxy = float.MinValue;

                _textureUvCoordinates    = new Vector2[_mdVertexCount];
                _textureDirection        = Quaternion.FromToRotation((md.Vertices[0] - md.Vertices[1]), Mapbox.Unity.Constants.Math.Vector3Right);
                _textureUvCoordinates[0] = new Vector2(0, 0);
                _firstVert = md.Vertices[0];
                for (int i = 1; i < _mdVertexCount; i++)
                {
                    _vert = md.Vertices[i];
                    _vertexRelativePos       = _vert - _firstVert;
                    _vertexRelativePos       = _textureDirection * _vertexRelativePos;
                    _textureUvCoordinates[i] = new Vector2(_vertexRelativePos.x, _vertexRelativePos.z);
                    if (_vertexRelativePos.x < minx)
                    {
                        minx = _vertexRelativePos.x;
                    }
                    if (_vertexRelativePos.x > maxx)
                    {
                        maxx = _vertexRelativePos.x;
                    }
                    if (_vertexRelativePos.z < miny)
                    {
                        miny = _vertexRelativePos.z;
                    }
                    if (_vertexRelativePos.z > maxy)
                    {
                        maxy = _vertexRelativePos.z;
                    }
                }

                var width  = maxx - minx;
                var height = maxy - miny;

                for (int i = 0; i < _mdVertexCount; i++)
                {
                    _uv.Add(new Vector2(
                                (((_textureUvCoordinates[i].x - minx) / width) * _currentFacade.TextureRect.width) + _currentFacade.TextureRect.x,
                                (((_textureUvCoordinates[i].y - miny) / height) * _currentFacade.TextureRect.height) + _currentFacade.TextureRect.y));
                }
            }

            md.UV[0].AddRange(_uv);
        }
Ejemplo n.º 5
0
 public override void Register(UnityTile tile)
 {
     base.Register(tile);
     _tiles.Add(tile.TileCoordinate, tile);
     Run(tile);
 }
Ejemplo n.º 6
0
 //public event Action FeaturePreProcessEvent;
 //public event Action FeaturePostProcessEvent;
 public abstract void Create(VectorTileLayer layer, UnityTile tile, Action <UnityTile, LayerVisualizerBase> callback = null);
Ejemplo n.º 7
0
 public virtual void OnUnregisterTile(UnityTile tile)
 {
 }
Ejemplo n.º 8
0
    public override void Run(VectorEntity ve, UnityTile tile)
    {
        int selpos = ve.Feature.Points[0].Count / 2;
        var met    = ve.Feature.Points[0][selpos];

        IFeaturePropertySettable settable = null;
        GameObject go = null;

        if (!allTypes.Contains(ve.Feature.Properties["type"] as string))
        {
            allTypes.Add(ve.Feature.Properties["type"] as string);
        }

        if (_objects.ContainsKey(ve.GameObject))
        {
            go       = _objects[ve.GameObject];
            settable = go.GetComponent <IFeaturePropertySettable>();
            if (settable != null)
            {
                go = (settable as MonoBehaviour).gameObject;
                bool usedType = false;
                for (int i = 0; i < resourceLocationData.Count; i++)
                {
                    if (resourceLocationData[i].LocTypes.Contains(ve.Feature.Properties["type"] as string))
                    {
                        //go.GetComponent<MapMarker>().Set(ve.Feature.Properties);
                        go.GetComponent <MapMarker>().Init(ve.Feature.Data.Id, resourceLocationData[i].ResourceType, resourceLocationData[i].Icon, resourceLocationData[i].BackColor);
                        usedType = true;
                        break;
                    }
                }
                go.SetActive(usedType && PlacesManager.Instance.CanAddMarker(ve.Feature.Data.Id));
                go.name = ve.Feature.Data.Id.ToString();
                go.transform.localPosition = met;
                go.transform.localScale    = Vector3.one;
                //settable.Set(ve.Feature.Properties);
                if (!_scaleDownWithWorld)
                {
                    go.transform.localScale = Vector3.one / tile.TileScale;
                }
                return;
            }
        }
        else
        {
            for (int i = 0; i < resourceLocationData.Count; i++)
            {
                if (resourceLocationData[i].LocTypes.Contains(ve.Feature.Properties["type"] as string))
                {
                    go = Instantiate(MarkerPrefab);
                    //go.GetComponent<MapMarker>().Set(ve.Feature.Properties);
                    go.GetComponent <MapMarker>().Init(ve.Feature.Data.Id, resourceLocationData[i].ResourceType, resourceLocationData[i].Icon, resourceLocationData[i].BackColor);
                    _objects.Add(ve.GameObject, go);
                    break;
                }
            }
        }

        if (go != null && go.activeSelf)
        {
            go.SetActive(PlacesManager.Instance.CanAddMarker(ve.Feature.Data.Id));
            go.name = ve.Feature.Data.Id.ToString();
            go.transform.position = met;
            go.transform.SetParent(ve.GameObject.transform, false);
            go.transform.localScale = Vector3.one;

            /*settable = go.GetComponent<IFeaturePropertySettable>();
             * if (settable != null)
             * {
             *  settable.Set(ve.Feature.Properties);
             * }*/

            if (!_scaleDownWithWorld)
            {
                go.transform.localScale = Vector3.one / tile.TileScale;
            }
        }
    }
Ejemplo n.º 9
0
        public override GameObject Execute(UnityTile tile, VectorFeatureUnity feature, MeshData meshData, GameObject parent = null, string type = "")
        {
            _counter       = feature.Points.Count;
            _secondCounter = 0;

            if (moveFeaturePositionTo != PositionTargetType.TileCenter)
            {
                _tempPoint = Constants.Math.Vector3Zero;
                if (moveFeaturePositionTo == PositionTargetType.FirstVertex)
                {
                    _tempPoint = feature.Points[0][0];
                }
                else if (moveFeaturePositionTo == PositionTargetType.CenterOfVertices)
                {
                    //this is not precisely the center because of the duplicates  (first/last vertex) but close to center
                    _tempPoint  = feature.Points[0][0];
                    vertexIndex = 1;

                    for (int i = 0; i < _counter; i++)
                    {
                        _secondCounter = feature.Points[i].Count;
                        for (int j = 0; j < _secondCounter; j++)
                        {
                            _tempPoint += feature.Points[i][j];
                            vertexIndex++;
                        }
                    }
                    _tempPoint /= vertexIndex;
                }

                for (int i = 0; i < _counter; i++)
                {
                    _secondCounter = feature.Points[i].Count;
                    for (int j = 0; j < _secondCounter; j++)
                    {
                        feature.Points[i][j] = new Vector3(feature.Points[i][j].x - _tempPoint.x, 0, feature.Points[i][j].z - _tempPoint.z);
                    }
                }
                meshData.PositionInTile = _tempPoint;
            }

            meshData.PositionInTile = _tempPoint;
            _counter = MeshModifiers.Count;
            for (int i = 0; i < _counter; i++)
            {
                if (MeshModifiers[i] != null && MeshModifiers[i].Active)
                {
                    MeshModifiers[i].Run(feature, meshData, tile);
                }
            }

            _tempVectorEntity = _pool.GetObject();

            // It is possible that we changed scenes in the middle of map generation.
            // This object can be null as a result of Unity cleaning up game objects in the scene.
            // Let's bail if we don't have our object.
            if (_tempVectorEntity.GameObject == null)
            {
                return(null);
            }

            _tempVectorEntity.GameObject.SetActive(true);
            _tempVectorEntity.Mesh.Clear();
            _tempVectorEntity.Feature = feature;

#if UNITY_EDITOR
            if (feature.Data != null)
            {
                _tempVectorEntity.GameObject.name = type + " - " + feature.Data.Id;
            }
            else
            {
                _tempVectorEntity.GameObject.name = type;
            }
#endif
            _tempVectorEntity.Mesh.subMeshCount = meshData.Triangles.Count;
            _tempVectorEntity.Mesh.SetVertices(meshData.Vertices);
            _tempVectorEntity.Mesh.SetNormals(meshData.Normals);
            if (meshData.Tangents.Count > 0)
            {
                _tempVectorEntity.Mesh.SetTangents(meshData.Tangents);
            }

            _counter = meshData.Triangles.Count;
            for (int i = 0; i < _counter; i++)
            {
                _tempVectorEntity.Mesh.SetTriangles(meshData.Triangles[i], i);
            }
            _counter = meshData.UV.Count;
            for (int i = 0; i < _counter; i++)
            {
                _tempVectorEntity.Mesh.SetUVs(i, meshData.UV[i]);
            }

            _tempVectorEntity.Transform.SetParent(parent.transform, false);

            if (!_activeObjects.ContainsKey(tile))
            {
                _activeObjects.Add(tile, _listPool.GetObject());
            }
            _activeObjects[tile].Add(_tempVectorEntity);


            _tempVectorEntity.Transform.localPosition = meshData.PositionInTile;

            _counter = GoModifiers.Count;
            for (int i = 0; i < _counter; i++)
            {
                if (GoModifiers[i].Active)
                {
                    GoModifiers[i].Run(_tempVectorEntity, tile);
                }
            }

            return(_tempVectorEntity.GameObject);
        }
Ejemplo n.º 10
0
        public override void Run(FeatureBehaviour fb, UnityTile tile)
        {
            var ts = fb.gameObject.AddComponent <TextureSelector>();

            ts.Initialize(fb, _textureTop, _useSatelliteTexture, _topMaterials, _textureSides, _sideMaterials);
        }
Ejemplo n.º 11
0
        //BRNKHY there has to be a better way to do this
        private void FixStitches(UnityTile tile)
        {
            var tmesh = tile.GetComponent <MeshFilter>().mesh;
            var left  = new Vector2(tile.TileCoordinate.x - 1, tile.TileCoordinate.y);

            if (_tiles.ContainsKey(left) && _tiles[left].HeightData != null)
            {
                var t2mesh = _tiles[left].GetComponent <MeshFilter>().mesh;

                var verts = tmesh.vertices;
                for (int i = 0; i < sampleCount; i++)
                {
                    verts[i].Set(verts[i].x, t2mesh.vertices[verts.Length - sampleCount + i].y, verts[i].z);
                }
                tmesh.vertices = verts;
            }

            var right = new Vector2(tile.TileCoordinate.x + 1, tile.TileCoordinate.y);

            if (_tiles.ContainsKey(right) && _tiles[right].HeightData != null)
            {
                var t2mesh = _tiles[right].GetComponent <MeshFilter>().mesh;

                var verts = tmesh.vertices;
                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 = verts;
            }

            var up = new Vector2(tile.TileCoordinate.x, tile.TileCoordinate.y - 1);

            if (_tiles.ContainsKey(up) && _tiles[up].HeightData != null)
            {
                var t2mesh = _tiles[up].GetComponent <MeshFilter>().mesh;
                var verts  = tmesh.vertices;
                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 = verts;
            }

            var down = new Vector2(tile.TileCoordinate.x, tile.TileCoordinate.y + 1);

            if (_tiles.ContainsKey(down) && _tiles[down].HeightData != null)
            {
                var t2mesh = _tiles[down].GetComponent <MeshFilter>().mesh;

                var verts = tmesh.vertices;
                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 = verts;
            }

            tmesh.RecalculateNormals();
        }
Ejemplo n.º 12
0
 public virtual void DataErrorOccurred(UnityTile tile, TileErrorEventArgs e)
 {
 }
Ejemplo n.º 13
0
 public virtual void PostProcessTile(UnityTile tile)
 {
 }
Ejemplo n.º 14
0
 public virtual void RegisterTile(UnityTile tile)
 {
 }
Ejemplo n.º 15
0
        public GameObject End(UnityTile tile, GameObject parent, string name = "")
        {
            var c2 = 0;

            if (_cached.ContainsKey(tile))
            {
                _tempMeshData.Clear();

                //concat mesh data into _tempMeshData
                _counter = _cached[tile].Count;
                for (int i = 0; i < _counter; i++)
                {
                    _temp2MeshData = _cached[tile][i];
                    if (_temp2MeshData.Vertices.Count <= 3)
                    {
                        continue;
                    }

                    var st = _tempMeshData.Vertices.Count;
                    _tempMeshData.Vertices.AddRange(_temp2MeshData.Vertices);
                    _tempMeshData.Normals.AddRange(_temp2MeshData.Normals);

                    c2 = _temp2MeshData.UV.Count;
                    for (int j = 0; j < c2; j++)
                    {
                        if (_tempMeshData.UV.Count <= j)
                        {
                            _tempMeshData.UV.Add(new List <Vector2>(_temp2MeshData.UV[j].Count));
                        }
                    }

                    c2 = _temp2MeshData.UV.Count;
                    for (int j = 0; j < c2; j++)
                    {
                        _tempMeshData.UV[j].AddRange(_temp2MeshData.UV[j]);
                    }

                    c2 = _temp2MeshData.Triangles.Count;
                    for (int j = 0; j < c2; j++)
                    {
                        if (_tempMeshData.Triangles.Count <= j)
                        {
                            _tempMeshData.Triangles.Add(new List <int>(_temp2MeshData.Triangles[j].Count));
                        }
                    }

                    for (int j = 0; j < c2; j++)
                    {
                        for (int k = 0; k < _temp2MeshData.Triangles[j].Count; k++)
                        {
                            _tempMeshData.Triangles[j].Add(_temp2MeshData.Triangles[j][k] + st);
                        }
                    }
                }

                //update pooled vector entity with new data
                if (_tempMeshData.Vertices.Count > 3)
                {
                    _cached[tile].Clear();
                    _cacheVertexCount[tile] = 0;
                    _tempVectorEntity       = null;
                    _tempVectorEntity       = _pool.GetObject();
                    _tempVectorEntity.GameObject.SetActive(true);
                    _tempVectorEntity.Mesh.Clear();

                    _tempVectorEntity.GameObject.name   = name;
                    _tempVectorEntity.Mesh.subMeshCount = _tempMeshData.Triangles.Count;
                    _tempVectorEntity.Mesh.SetVertices(_tempMeshData.Vertices);
                    _tempVectorEntity.Mesh.SetNormals(_tempMeshData.Normals);

                    _counter = _tempMeshData.Triangles.Count;
                    for (int i = 0; i < _counter; i++)
                    {
                        _tempVectorEntity.Mesh.SetTriangles(_tempMeshData.Triangles[i], i);
                    }

                    _counter = _tempMeshData.UV.Count;
                    for (int i = 0; i < _counter; i++)
                    {
                        _tempVectorEntity.Mesh.SetUVs(i, _tempMeshData.UV[i]);
                    }

                    _tempVectorEntity.GameObject.transform.SetParent(tile.transform, false);

                    if (!_activeObjects.ContainsKey(tile))
                    {
                        _activeObjects.Add(tile, _listPool.GetObject());
                    }
                    _activeObjects[tile].Add(_tempVectorEntity);

                    _counter = GoModifiers.Count;
                    for (int i = 0; i < _counter; i++)
                    {
                        if (GoModifiers[i].Active)
                        {
                            GoModifiers[i].Run(_tempVectorEntity, tile);
                        }
                    }

                    return(_tempVectorEntity.GameObject);
                }
            }
            return(null);
        }
        /// <summary>
        /// Creates the non-flat terrain mesh, using a grid by defined resolution (_sampleCount). Vertex order goes right & up. Normals are calculated manually and UV map is fitted/stretched 1-1.
        /// Any additional scripts or logic, like MeshCollider or setting layer, can be done here.
        /// </summary>
        /// <param name="tile"></param>
        // <param name="heightMultiplier">Multiplier for queried height value</param>
        private void GenerateTerrainMesh(UnityTile tile)
        {
            tile.MeshFilter.sharedMesh.GetVertices(_currentTileMeshData.Vertices);
            tile.MeshFilter.sharedMesh.GetNormals(_currentTileMeshData.Normals);

            var _sampleCount = _elevationOptions.modificationOptions.sampleCount;
            int sideStart    = _sampleCount * _sampleCount;

            for (float y = 0; y < _sampleCount; y++)
            {
                for (float x = 0; x < _sampleCount; x++)
                {
                    _currentTileMeshData.Vertices[(int)(y * _sampleCount + x)] = new Vector3(
                        _currentTileMeshData.Vertices[(int)(y * _sampleCount + x)].x,
                        tile.QueryHeightData(x / (_sampleCount - 1), 1 - y / (_sampleCount - 1)),
                        _currentTileMeshData.Vertices[(int)(y * _sampleCount + x)].z);
                    _currentTileMeshData.Normals[(int)(y * _sampleCount + x)] = Mapbox.Unity.Constants.Math.Vector3Zero;

                    if (y == 0)
                    {
                        _currentTileMeshData.Vertices[(int)(sideStart + 8 * x)] = _currentTileMeshData.Vertices[(int)(y * _sampleCount + x)];
                    }
                    else if (y == _sampleCount - 1)
                    {
                        _currentTileMeshData.Vertices[(int)(sideStart + 8 * x + 6)] = _currentTileMeshData.Vertices[(int)(y * _sampleCount + x)];
                    }

                    if (x == 0)
                    {
                        _currentTileMeshData.Vertices[(int)(sideStart + 8 * y + 2)] = _currentTileMeshData.Vertices[(int)(y * _sampleCount + x)];
                    }
                    else if (x == _sampleCount - 1)
                    {
                        _currentTileMeshData.Vertices[(int)(sideStart + 8 * y + 4)] = _currentTileMeshData.Vertices[(int)(y * _sampleCount + x)];
                    }
                }
            }

            tile.MeshFilter.sharedMesh.SetVertices(_currentTileMeshData.Vertices);

            for (int y = 0; y < _sampleCount - 1; y++)
            {
                for (int x = 0; x < _sampleCount - 1; x++)
                {
                    _vertA  = (y * _sampleCount) + x;
                    _vertB  = (y * _sampleCount) + x + _sampleCount + 1;
                    _vertC  = (y * _sampleCount) + x + _sampleCount;
                    _newDir = Vector3.Cross(_currentTileMeshData.Vertices[_vertB] - _currentTileMeshData.Vertices[_vertA], _currentTileMeshData.Vertices[_vertC] - _currentTileMeshData.Vertices[_vertA]);
                    _currentTileMeshData.Normals[_vertA] += _newDir;
                    _currentTileMeshData.Normals[_vertB] += _newDir;
                    _currentTileMeshData.Normals[_vertC] += _newDir;

                    _vertA  = (y * _sampleCount) + x;
                    _vertB  = (y * _sampleCount) + x + 1;
                    _vertC  = (y * _sampleCount) + x + _sampleCount + 1;
                    _newDir = Vector3.Cross(_currentTileMeshData.Vertices[_vertB] - _currentTileMeshData.Vertices[_vertA], _currentTileMeshData.Vertices[_vertC] - _currentTileMeshData.Vertices[_vertA]);
                    _currentTileMeshData.Normals[_vertA] += _newDir;
                    _currentTileMeshData.Normals[_vertB] += _newDir;
                    _currentTileMeshData.Normals[_vertC] += _newDir;
                }
            }

            FixStitches(tile.UnwrappedTileId, _currentTileMeshData);

            tile.MeshFilter.sharedMesh.SetNormals(_currentTileMeshData.Normals);
            tile.MeshFilter.sharedMesh.SetVertices(_currentTileMeshData.Vertices);

            tile.MeshFilter.sharedMesh.RecalculateBounds();

            if (!_meshData.ContainsKey(tile.UnwrappedTileId))
            {
                _meshData.Add(tile.UnwrappedTileId, tile.MeshFilter.sharedMesh);
            }

            if (_elevationOptions.colliderOptions.addCollider)
            {
                var meshCollider = tile.Collider as MeshCollider;
                if (meshCollider)
                {
                    meshCollider.sharedMesh = tile.MeshFilter.sharedMesh;
                }
            }
        }
Ejemplo n.º 17
0
 protected override void OnPostProcess(UnityTile tile)
 {
 }
 public override void DataErrorOccurred(UnityTile t, TileErrorEventArgs e)
 {
     ResetToFlatMesh(t);
 }
Ejemplo n.º 19
0
 public void UnregisterTile(UnityTile tile)
 {
     OnUnregisterTile(tile);
 }
        private void CreateBaseMesh(UnityTile tile)
        {
            //TODO use arrays instead of lists
            _newVertexList.Clear();
            _newNormalList.Clear();
            _newUvList.Clear();
            _newTriangleList.Clear();

            var _sampleCount = _elevationOptions.modificationOptions.sampleCount;

            for (float y = 0; y < _sampleCount; y++)
            {
                var yrat = y / (_sampleCount - 1);
                for (float x = 0; x < _sampleCount; x++)
                {
                    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);

                    _newVertexList.Add(new Vector3(
                                           (float)(xx - tile.Rect.Center.x) * tile.TileScale,
                                           0,
                                           (float)(yy - tile.Rect.Center.y) * tile.TileScale));
                    _newNormalList.Add(Mapbox.Unity.Constants.Math.Vector3Up);
                    _newUvList.Add(new Vector2(x * 1f / (_sampleCount - 1), 1 - (y * 1f / (_sampleCount - 1))));
                }
            }

            int vertA, vertB, vertC;

            for (int y = 0; y < _sampleCount - 1; y++)
            {
                for (int x = 0; x < _sampleCount - 1; x++)
                {
                    vertA = (y * _sampleCount) + x;
                    vertB = (y * _sampleCount) + x + _sampleCount + 1;
                    vertC = (y * _sampleCount) + x + _sampleCount;
                    _newTriangleList.Add(vertA);
                    _newTriangleList.Add(vertB);
                    _newTriangleList.Add(vertC);

                    vertA = (y * _sampleCount) + x;
                    vertB = (y * _sampleCount) + x + 1;
                    vertC = (y * _sampleCount) + x + _sampleCount + 1;
                    _newTriangleList.Add(vertA);
                    _newTriangleList.Add(vertB);
                    _newTriangleList.Add(vertC);
                }
            }

            var sideVertBase = _newVertexList.Count;

            var lastRow     = (_sampleCount - 1) * _sampleCount;
            var baseTriList = new List <int>();

            for (int x = 0; x < _sampleCount; x++)
            {
                //side wall
                //024
                //135
                _newVertexList.Add(_newVertexList[x]);
                _newVertexList.Add(new Vector3(
                                       _newVertexList[x].x,
                                       -_elevationOptions.sideWallOptions.wallHeight,
                                       _newVertexList[x].z));
                _newNormalList.Add(Mapbox.Unity.Constants.Math.Vector3Forward);
                _newNormalList.Add(Mapbox.Unity.Constants.Math.Vector3Forward);
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 1));
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 0));

                //---

                _newVertexList.Add(_newVertexList[x * _sampleCount]);
                _newVertexList.Add(new Vector3(
                                       _newVertexList[x * _sampleCount].x,
                                       -_elevationOptions.sideWallOptions.wallHeight,
                                       _newVertexList[x * _sampleCount].z));
                _newNormalList.Add(Vector3.left);
                _newNormalList.Add(Vector3.left);
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 1));
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 0));

                //---

                _newVertexList.Add(_newVertexList[(x + 1) * _sampleCount - 1]);
                _newVertexList.Add(new Vector3(
                                       _newVertexList[(x + 1) * _sampleCount - 1].x,
                                       -_elevationOptions.sideWallOptions.wallHeight,
                                       _newVertexList[(x + 1) * _sampleCount - 1].z));
                _newNormalList.Add(Vector3.right);
                _newNormalList.Add(Vector3.right);
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 1));
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 0));

                //---

                _newVertexList.Add(_newVertexList[lastRow + x]);
                _newVertexList.Add(new Vector3(
                                       _newVertexList[lastRow + x].x,
                                       -_elevationOptions.sideWallOptions.wallHeight,
                                       _newVertexList[lastRow + x].z));
                _newNormalList.Add(Vector3.back);
                _newNormalList.Add(Vector3.back);
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 1));
                _newUvList.Add(new Vector2(_newUvList[x * _sampleCount].y, 0));

                if (x > 0)
                {
                    baseTriList.Add(sideVertBase + 8 * x);
                    baseTriList.Add(sideVertBase + 8 * x - 8);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1);

                    baseTriList.Add(sideVertBase + 8 * x);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1);
                    baseTriList.Add(sideVertBase + 8 * x + 1);

                    //---

                    baseTriList.Add(sideVertBase + 8 * x + 2);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1 + 2);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 2);

                    baseTriList.Add(sideVertBase + 8 * x + 2);
                    baseTriList.Add(sideVertBase + 8 * x + 1 + 2);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1 + 2);

                    //---

                    baseTriList.Add(sideVertBase + 8 * x + 4);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 4);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1 + 4);

                    baseTriList.Add(sideVertBase + 8 * x + 4);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1 + 4);
                    baseTriList.Add(sideVertBase + 8 * x + 1 + 4);

                    //---

                    baseTriList.Add(sideVertBase + 8 * x + 6);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1 + 6);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 6);

                    baseTriList.Add(sideVertBase + 8 * x + 6);
                    baseTriList.Add(sideVertBase + 8 * x + 1 + 6);
                    baseTriList.Add(sideVertBase + 8 * x - 8 + 1 + 6);
                }
            }


            var mesh = tile.MeshFilter.sharedMesh;

            mesh.SetVertices(_newVertexList);
            mesh.SetNormals(_newNormalList);
            mesh.SetUVs(0, _newUvList);
            mesh.subMeshCount = 2;
            mesh.SetTriangles(_newTriangleList, 0);
            mesh.SetTriangles(baseTriList, 1);
        }
 public override void UnregisterTile(UnityTile tile)
 {
     _meshData.Remove(tile.UnwrappedTileId);
 }
Ejemplo n.º 22
0
 public virtual void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
 {
 }
Ejemplo n.º 23
0
        public override void Run(VectorEntity ve, UnityTile tile)
        {
            var ts = ve.GameObject.AddComponent <TextureSelector>();

            ts.Initialize(ve, _textureTop, _useSatelliteTexture, _topMaterials, _textureSides, _sideMaterials);
        }
Ejemplo n.º 24
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (feature.Points.Count < 1)
            {
                return;
            }

            foreach (var roadSegment in feature.Points)
            {
                var count = roadSegment.Count;
                for (int i = 1; i < count * 2; i++)
                {
                    md.Edges.Add(md.Vertices.Count + i);
                    md.Edges.Add(md.Vertices.Count + i - 1);
                }
                md.Edges.Add(md.Vertices.Count);
                md.Edges.Add(md.Vertices.Count + (count * 2) - 1);

                var     newVerticeList = new Vector3[count * 2];
                var     uvList         = new Vector2[count * 2];
                Vector3 norm;
                var     lastUv = 0f;
                var     p1     = Mapbox.Unity.Constants.Math.Vector3Zero;
                var     p2     = Mapbox.Unity.Constants.Math.Vector3Zero;
                var     p3     = Mapbox.Unity.Constants.Math.Vector3Zero;
                for (int i = 1; i < count; i++)
                {
                    p1 = roadSegment[i - 1];
                    p2 = roadSegment[i];
                    p3 = p2;
                    if (i + 1 < roadSegment.Count)
                    {
                        p3 = roadSegment[i + 1];
                    }

                    if (i == 1)
                    {
                        norm = GetNormal(p1, p1, p2) * Width; //road width
                        newVerticeList[0]             = (p1 + norm);
                        newVerticeList[count * 2 - 1] = (p1 - norm);
                        uvList[0]             = new Vector2(0, 0);
                        uvList[count * 2 - 1] = new Vector2(1, 0);
                    }
                    var dist = Vector3.Distance(p1, p2);
                    lastUv           += dist;
                    norm              = GetNormal(p1, p2, p3) * Width;
                    newVerticeList[i] = (p2 + norm);
                    newVerticeList[2 * count - 1 - i] = (p2 - norm);

                    uvList[i] = new Vector2(0, lastUv);
                    uvList[2 * count - 1 - i] = new Vector2(1, lastUv);
                }

                //if (_mergeStartEnd)
                //{
                //    //brnkhy -2 because first and last items are same
                //    p1 = segment[count - 2];
                //    p2 = segment[0];
                //    p3 = segment[1];

                //    norm = GetNormal(p1, p2, p3) * Width;
                //    newVerticeList[count - 1] = p2 + norm;
                //    newVerticeList[0] = p2 + norm;
                //    newVerticeList[count] = p2 - norm;
                //    newVerticeList[2 * count - 1] = p2 - norm;
                //}

                var pcount = md.Vertices.Count;
                md.Vertices.AddRange(newVerticeList);
                md.UV[0].AddRange(uvList);
                var lineTri = new List <int>();
                var n       = count;

                for (int i = 0; i < n - 1; i++)
                {
                    lineTri.Add(pcount + i);
                    lineTri.Add(pcount + i + 1);
                    lineTri.Add(pcount + 2 * n - 1 - i);

                    lineTri.Add(pcount + i + 1);
                    lineTri.Add(pcount + 2 * n - i - 2);
                    lineTri.Add(pcount + 2 * n - i - 1);
                }

                if (md.Triangles.Count < 1)
                {
                    md.Triangles.Add(new List <int>());
                }
                md.Triangles[0].AddRange(lineTri);
            }
        }
Ejemplo n.º 25
0
 protected abstract void PlaceTile(UnwrappedTileId tileId, UnityTile tile, IMapReadable map);
Ejemplo n.º 26
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (md.Vertices.Count == 0 || feature == null || feature.Points.Count < 1)
            {
                return;
            }

            if (tile != null)
            {
                _scale = tile.TileScale;
            }

            //facade texture to decorate this building
            _currentFacade =
                _options.atlasInfo.Textures[UnityEngine.Random.Range(0, _options.atlasInfo.Textures.Count)];
            //rect is a struct so we're caching this
            _currentTextureRect = _currentFacade.TextureRect;

            //this can be moved to initialize or in an if clause if you're sure all your tiles will be same level/scale
            _singleFloorHeight         = (tile.TileScale * _currentFacade.FloorHeight) / _currentFacade.MidFloorCount;
            _scaledFirstFloorHeight    = tile.TileScale * _currentFacade.FirstFloorHeight;
            _scaledTopFloorHeight      = tile.TileScale * _currentFacade.TopFloorHeight;
            _scaledPreferredWallLength = tile.TileScale * _currentFacade.PreferredEdgeSectionLength;
            _scaledFloorHeight         = _scaledPreferredWallLength * _currentFacade.WallToFloorRatio;
            _singleColumnLength        = _scaledPreferredWallLength / _currentFacade.ColumnCount;

            //read or force height
            float maxHeight = 1, minHeight = 0;

            //query height and push polygon up to create roof
            //can we do this vice versa and create roof at last?
            QueryHeight(feature, md, tile, out maxHeight, out minHeight);
            maxHeight = maxHeight * _options.extrusionScaleFactor * _scale;
            minHeight = minHeight * _options.extrusionScaleFactor * _scale;
            height    = (maxHeight - minHeight);
            GenerateRoofMesh(md, minHeight, maxHeight);

            if (_options.extrusionGeometryType != ExtrusionGeometryType.RoofOnly)
            {
                //limiting section heights, first floor gets priority, then we draw top floor, then mid if we still have space
                finalFirstHeight = Mathf.Min(height, _scaledFirstFloorHeight);
                finalTopHeight   = (height - finalFirstHeight) < _scaledTopFloorHeight ? 0 : _scaledTopFloorHeight;
                finalMidHeight   = Mathf.Max(0, height - (finalFirstHeight + finalTopHeight));
                //scaledFloorHeight = midHeight / floorCount;
                wallTriangles = new List <int>();

                //cuts long edges into smaller ones using PreferredEdgeSectionLength
                currentWallLength    = 0;
                start                = Constants.Math.Vector3Zero;
                wallSegmentDirection = Constants.Math.Vector3Zero;

                finalLeftOverRowHeight = 0f;
                if (finalMidHeight > 0)
                {
                    finalLeftOverRowHeight = finalMidHeight;
                    finalLeftOverRowHeight = finalLeftOverRowHeight % _singleFloorHeight;
                    finalMidHeight        -= finalLeftOverRowHeight;
                }
                else
                {
                    finalLeftOverRowHeight = finalTopHeight;
                }

                for (int i = 0; i < md.Edges.Count; i += 2)
                {
                    var v1 = md.Vertices[md.Edges[i]];
                    var v2 = md.Vertices[md.Edges[i + 1]];

                    wallDirection = v2 - v1;

                    currentWallLength     = Vector3.Distance(v1, v2);
                    _leftOverColumnLength = currentWallLength % _singleColumnLength;
                    start = v1;
                    wallSegmentDirection = (v2 - v1).normalized;

                    //half of leftover column (if _centerSegments ofc) at the begining
                    if (_centerSegments && currentWallLength > _singleColumnLength)
                    {
                        //save left,right vertices and wall length
                        wallSegmentFirstVertex = start;
                        wallSegmentLength      = (_leftOverColumnLength / 2);
                        start += wallSegmentDirection * wallSegmentLength;
                        wallSegmentSecondVertex = start;

                        _leftOverColumnLength = _leftOverColumnLength / 2;
                        CreateWall(md);
                    }

                    while (currentWallLength > _singleColumnLength)
                    {
                        wallSegmentFirstVertex = start;
                        //columns fitting wall / max column we have in texture
                        var stepRatio =
                            (float)Math.Min(_currentFacade.ColumnCount,
                                            Math.Floor(currentWallLength / _singleColumnLength)) / _currentFacade.ColumnCount;
                        wallSegmentLength       = stepRatio * _scaledPreferredWallLength;
                        start                  += wallSegmentDirection * wallSegmentLength;
                        wallSegmentSecondVertex = start;

                        currentWallLength -= (stepRatio * _scaledPreferredWallLength);
                        CreateWall(md);
                    }

                    //left over column at the end
                    if (_leftOverColumnLength > 0)
                    {
                        wallSegmentFirstVertex  = start;
                        wallSegmentSecondVertex = v2;
                        wallSegmentLength       = _leftOverColumnLength;
                        CreateWall(md);
                    }
                }

                //this first loop is for columns
                if (_separateSubmesh)
                {
                    md.Triangles.Add(wallTriangles);
                }
                else
                {
                    md.Triangles.Capacity = md.Triangles.Count + wallTriangles.Count;
                    md.Triangles[0].AddRange(wallTriangles);
                }
            }
        }
Ejemplo n.º 27
0
 internal override void OnUnregistered(UnityTile tile)
 {
     _meshData.Remove(tile.UnwrappedTileId);
 }
Ejemplo n.º 28
0
 public TileProcessFinishedEventArgs(AbstractTileFactory vectorTileFactory, UnityTile tile)
 {
     Factory = vectorTileFactory;
     Tile    = tile;
 }
 private void CalculateEdgeList(MeshData md, UnityTile tile, float preferredEdgeSectionLength)
 {
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Checkes all neighbours of the given tile and stitches the edges to achieve a smooth mesh surface.
        /// </summary>
        /// <param name="tile"></param>
        /// <param name="tmesh"></param>
        private void FixStitches(UnityTile tile, MeshData tmesh)
        {
            _stitchTarget.Set(tile.TileCoordinate.x, tile.TileCoordinate.y - 1);
            if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null)
            {
                var t2mesh = _tiles[_stitchTarget].MeshData;

                for (int i = 0; i < _sampleCount; i++)
                {
                    //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);
                }
            }

            _stitchTarget.Set(tile.TileCoordinate.x, tile.TileCoordinate.y + 1);
            if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null)
            {
                var t2mesh = _tiles[_stitchTarget].MeshData;
                for (int i = 0; i < _sampleCount; i++)
                {
                    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);
                }
            }

            _stitchTarget.Set(tile.TileCoordinate.x - 1, tile.TileCoordinate.y);
            if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null)
            {
                var t2mesh = _tiles[_stitchTarget].MeshData;
                for (int i = 0; i < _sampleCount; i++)
                {
                    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);
                }
            }

            _stitchTarget.Set(tile.TileCoordinate.x + 1, tile.TileCoordinate.y);
            if (_tiles.ContainsKey(_stitchTarget) && _tiles[_stitchTarget].MeshData != null)
            {
                var t2mesh = _tiles[_stitchTarget].MeshData;
                for (int i = 0; i < _sampleCount; i++)
                {
                    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);
                }
            }

            _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);
            }

            _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[_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);
            }
        }