public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            var        subset       = new List <List <Vector3> >();
            Data       flatData     = null;
            List <int> result       = null;
            var        currentIndex = 0;

            List <int> triList = null;

            foreach (var sub in feature.Points)
            {
                //earcut is built to handle one polygon with multiple holes
                //point data can contain multiple polygons though, so we're handling them separately here
                if (IsClockwise(sub) && md.Vertices.Count > 0)
                {
                    flatData = EarcutLibrary.Flatten(subset);
                    result   = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);

                    if (triList == null)
                    {
                        triList = new List <int>(result.Count);
                    }

                    for (int i = 0; i < result.Count; i++)
                    {
                        triList.Add(result[i] + currentIndex);
                    }
                    currentIndex = md.Vertices.Count;
                    subset.Clear();
                }

                subset.Add(sub);
                var c = md.Vertices.Count;
                for (int i = 0; i < sub.Count; i++)
                {
                    md.Edges.Add(c + ((i + 1) % sub.Count));
                    md.Edges.Add(c + i);
                    md.Vertices.Add(sub[i]);
                    md.Normals.Add(Constants.Math.Vector3Up);
                }
            }

            flatData = EarcutLibrary.Flatten(subset);
            result   = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
            if (triList == null)
            {
                triList = new List <int>(result.Count);
            }
            for (int i = 0; i < result.Count; i++)
            {
                triList.Add(result[i] + currentIndex);
            }

            md.Triangles.Add(triList);
        }
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            _secondCounter = feature.Points.Count;
            var            subset = new List <List <Vector3> >(_secondCounter);
            Data           flatData = null;
            List <int>     result = null;
            var            currentIndex = 0;
            int            vertCount = 0, c2 = 0;
            List <int>     triList = null;
            List <Vector3> sub     = null;

            for (int i = 0; i < _secondCounter; i++)
            {
                sub = feature.Points[i];
                //earcut is built to handle one polygon with multiple holes
                //point data can contain multiple polygons though, so we're handling them separately here

                vertCount = md.Vertices.Count;
                if (IsClockwise(sub) && vertCount > 0)
                {
                    flatData = EarcutLibrary.Flatten(subset);
                    result   = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
                    c2       = result.Count;
                    if (triList == null)
                    {
                        triList = new List <int>(c2);
                    }
                    else
                    {
                        triList.Capacity = triList.Count + c2;
                    }

                    for (int j = 0; j < c2; j++)
                    {
                        triList.Add(result[j] + currentIndex);
                    }
                    currentIndex = vertCount;
                    subset.Clear();
                }

                subset.Add(sub);

                c2 = sub.Count;
                md.Vertices.Capacity = md.Vertices.Count + c2;
                md.Normals.Capacity  = md.Normals.Count + c2;
                md.Edges.Capacity    = md.Edges.Count + c2 * 2;
                for (int j = 0; j < c2; j++)
                {
                    md.Edges.Add(vertCount + ((j + 1) % c2));
                    md.Edges.Add(vertCount + j);
                    md.Vertices.Add(sub[j]);
                    md.Tangents.Add(Constants.Math.Vector3Forward);
                    md.Normals.Add(Constants.Math.Vector3Up);
                }
            }

            flatData = EarcutLibrary.Flatten(subset);
            result   = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
            c2       = result.Count;
            if (triList == null)
            {
                triList = new List <int>(c2);
            }
            else
            {
                triList.Capacity = triList.Count + c2;
            }
            for (int i = 0; i < c2; i++)
            {
                triList.Add(result[i] + currentIndex);
            }

            md.Triangles.Add(triList);
        }
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (Criteria != null && Criteria.Count > 0)
            {
                foreach (var criterion in Criteria)
                {
                    if (criterion.ShouldReplaceFeature(feature))
                    {
                        return;
                    }
                }
            }

            var            _counter = feature.Points.Count;
            var            subset = new List <List <Vector3> >(_counter);
            Data           flatData = null;
            List <int>     result = null;
            var            currentIndex = 0;
            int            vertCount = 0, polygonVertexCount = 0;
            List <int>     triList = null;
            List <Vector3> sub     = null;



            for (int i = 0; i < _counter; i++)
            {
                sub = feature.Points[i];
                //earcut is built to handle one polygon with multiple holes
                //point data can contain multiple polygons though, so we're handling them separately here

                vertCount = md.Vertices.Count;
                if (IsClockwise(sub) && vertCount > 0)
                {
                    flatData           = EarcutLibrary.Flatten(subset);
                    result             = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
                    polygonVertexCount = result.Count;
                    if (triList == null)
                    {
                        triList = new List <int>(polygonVertexCount);
                    }
                    else
                    {
                        triList.Capacity = triList.Count + polygonVertexCount;
                    }

                    for (int j = 0; j < polygonVertexCount; j++)
                    {
                        triList.Add(result[j] + currentIndex);
                    }

                    currentIndex = vertCount;
                    subset.Clear();
                }

                subset.Add(sub);

                polygonVertexCount   = sub.Count;
                md.Vertices.Capacity = md.Vertices.Count + polygonVertexCount;
                md.Normals.Capacity  = md.Normals.Count + polygonVertexCount;
                md.Edges.Capacity    = md.Edges.Count + polygonVertexCount * 2;
                var _size = md.TileRect.Size;

                for (int j = 0; j < polygonVertexCount; j++)
                {
                    md.Edges.Add(vertCount + ((j + 1) % polygonVertexCount));
                    md.Edges.Add(vertCount + j);
                    md.Vertices.Add(sub[j]);
                    md.Tangents.Add(Constants.Math.Vector3Forward);
                    md.Normals.Add(Constants.Math.Vector3Up);

                    if (_options.style == StyleTypes.Satellite)
                    {
                        var fromBottomLeft = new Vector2(
                            (float)(((sub[j].x + md.PositionInTile.x) / tile.TileScale + _size.x / 2) / _size.x),
                            (float)(((sub[j].z + md.PositionInTile.z) / tile.TileScale + _size.x / 2) / _size.x));
                        md.UV[0].Add(fromBottomLeft);
                    }
                    else if (_options.texturingType == UvMapType.Tiled)
                    {
                        md.UV[0].Add(new Vector2(sub[j].x, sub[j].z));
                    }
                }
            }

            flatData           = EarcutLibrary.Flatten(subset);
            result             = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
            polygonVertexCount = result.Count;

            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[md.Vertices.Count];
                _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 < md.Vertices.Count; 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 < md.Vertices.Count; i++)
                {
                    md.UV[0].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));
                }
            }

            if (triList == null)
            {
                triList = new List <int>(polygonVertexCount);
            }
            else
            {
                triList.Capacity = triList.Count + polygonVertexCount;
            }

            for (int i = 0; i < polygonVertexCount; i++)
            {
                triList.Add(result[i] + currentIndex);
            }

            md.Triangles.Add(triList);
        }
Example #4
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (feature.Points.Count < 1)
            {
                return;
            }

            foreach (var roadSegment in feature.Points)
            {
                _counter = roadSegment.Count;
                if (_counter <= 1)
                {
                    continue;
                }

                var vl    = new List <Vector3>(_sliceCount * _counter);
                var edges = new List <Vector3>(_counter);
                int co    = 0;

                for (int j = 0; j < _counter; j++)
                {
                    var current = Constants.Math.Vector3Zero;

                    current = roadSegment[j];
                    Vector3 dirCurrent, dir1, dir2;
                    if (j > 0 && j < (_counter - 1))
                    {
                        dir1       = (roadSegment[j] - roadSegment[j - 1]).normalized;
                        dir2       = (roadSegment[j + 1] - roadSegment[j]).normalized;
                        dirCurrent = (dir2 + dir1).normalized;
                    }
                    else if (j == 0) //first
                    {
                        dirCurrent = (roadSegment[j + 1] - roadSegment[j]).normalized;
                    }
                    else //last
                    {
                        dirCurrent = (roadSegment[j] - roadSegment[j - 1]).normalized;
                    }
                    var q = Quaternion.LookRotation(dirCurrent);

                    co = _slice.Count;
                    for (int i = 0; i < co; i++)
                    {
                        var p = q * _slice[i];
                        vl.Add(p + current);
                        if (i == co - 1) //last item capped
                        {
                            edges.Add(p + current);
                        }
                    }
                }

                if (md.Triangles.Count == 0)
                {
                    md.Triangles.Add(new List <int>());
                }
                md.Vertices.Capacity  = md.Vertices.Count + (vl.Count - _sliceCount) * 4;
                md.Normals.Capacity   = md.Normals.Count + (vl.Count - _sliceCount) * 4;
                md.Triangles.Capacity = md.Triangles.Count + (vl.Count - _sliceCount) * 6;

                var   uvDist = 0f;
                float edMag = 0f, h = 0f;
                co = 0;
                Vector3 norm;

                for (int i = 0; i < _counter - 1; i++)
                {
                    for (int j = 0; j < _sliceCount - 1; j++)
                    {
                        var ind = i * _sliceCount + j;
                        var ed  = vl[ind + _sliceCount] - vl[ind];
                        edMag = ed.magnitude;
                        co    = md.Vertices.Count;
                        norm  = Vector3.Cross(vl[ind] - vl[ind + 1], vl[ind + _sliceCount] - vl[ind]).normalized;
                        md.Vertices.Add(vl[ind]);
                        md.Vertices.Add(vl[ind + 1]);
                        md.Vertices.Add(vl[ind + _sliceCount]);
                        md.Vertices.Add(vl[ind + _sliceCount + 1]);

                        h = (float)j / _sliceCount;

                        md.UV[0].Add(new Vector2(uvDist, ((float)j - 1) / _sliceCount));
                        md.UV[0].Add(new Vector2(uvDist, h));
                        md.UV[0].Add(new Vector2(uvDist + edMag, ((float)j - 1) / _sliceCount));
                        md.UV[0].Add(new Vector2(uvDist + edMag, h));

                        md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));
                        md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));
                        md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));
                        md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));

                        md.Normals.Add(norm);
                        md.Normals.Add(norm);
                        md.Normals.Add(norm);
                        md.Normals.Add(norm);

                        md.Triangles[0].Add(co);
                        md.Triangles[0].Add(co + 2);
                        md.Triangles[0].Add(co + 1);

                        md.Triangles[0].Add(co + 1);
                        md.Triangles[0].Add(co + 2);
                        md.Triangles[0].Add(co + 3);
                    }
                    uvDist += edMag;
                }

                if (_closeEdges && edges.Count > 2)
                {
                    if (md.Triangles.Count < 2)
                    {
                        md.Triangles.Add(new List <int>());
                    }

                    var flatData = EarcutLibrary.Flatten(new List <List <Vector3> >()
                    {
                        edges
                    });
                    var result = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);

                    md.Triangles[1].AddRange(result.Select(x => md.Vertices.Count + x).ToList());
                    for (int i = 0; i < edges.Count; i++)
                    {
                        md.Vertices.Add(edges[i]);
                        md.Normals.Add(Constants.Math.Vector3Up);
                        md.UV[0].Add(new Vector2(edges[i].x, edges[i].z));
                        md.Tangents.Add(new Vector4(1, 0, 0, 1));
                    }
                }
            }
        }